From 278a44caf12b5a0ce20451a4929ebefbb7cef9a2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 26 May 2009 17:22:51 -0400 Subject: [PATCH] Rework internals of ShellAppMonitor to use Metacity library The code here is significantly cleaner if we use the data Metacity already has cached and validated, rather than talking to X directly. Also some preparatory work for extending the monitor API by clarifying the name of the (current) main entry point. --- js/ui/appDisplay.js | 2 +- src/shell-app-monitor.c | 169 ++++++---------------------------------- src/shell-app-monitor.h | 10 ++- src/shell-global.h | 2 - 4 files changed, 30 insertions(+), 153 deletions(-) diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index b4c6076a0..d0ba6bb99 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -395,7 +395,7 @@ AppDisplay.prototype = { _setDefaultList : function() { // Ask or more app than we need, since the list of recently used apps // might contain an app we don't have a desktop file for - var apps = this._appMonitor.get_apps (0, Math.round(MAX_ITEMS * 1.5)); + var apps = this._appMonitor.get_most_used_apps (0, Math.round(MAX_ITEMS * 1.5)); this._matchedItems = []; for (let i = 0; i < apps.length; i++) { if (this._matchedItems.length > MAX_ITEMS) diff --git a/src/shell-app-monitor.c b/src/shell-app-monitor.c index d9f487d75..2a5f439ef 100644 --- a/src/shell-app-monitor.c +++ b/src/shell-app-monitor.c @@ -15,6 +15,7 @@ #include "shell-app-monitor.h" #include "shell-global.h" +#include "display.h" /* This file includes modified code from * desktop-data-engine/engine-dbus/hippo-application-monitor.c @@ -260,32 +261,32 @@ shell_app_monitor_finalize (GObject *object) } /** - * shell_app_monitor_get_apps: + * shell_app_monitor_get_most_used_apps: * * Get a list of desktop identifiers representing the most popular applications * for a given activity. * * @monitor: the app monitor instance to request * @activity: the activity for which stats are considered - * @max_count: how many applications are requested. Note that the actual + * @max_count: how many applications are requested. Note that the actual * list size may be less, or NULL if not enough applications are registered. * * Returns: (element-type utf8) (transfer full): List of application desktop * identifiers, in low case */ GSList * -shell_app_monitor_get_apps (ShellAppMonitor *monitor, - gint activity, - gint max_count) +shell_app_monitor_get_most_used_apps (ShellAppMonitor *monitor, + gint activity, + gint max_count) { GSList *list = NULL; GSList *popularity; AppPopularity *app_popularity; int i; - + popularity = g_hash_table_lookup (monitor->popularities, GINT_TO_POINTER (activity)); - + for (i = 0; i < max_count; i++) { if (!popularity) @@ -304,154 +305,28 @@ get_active_app_properties (ShellAppMonitor *monitor, char **wm_class, char **title) { - Display *xdisplay = GDK_DISPLAY_XDISPLAY (monitor->display); - int n_screens = gdk_display_get_n_screens (monitor->display); - Atom net_active_window_x = - gdk_x11_get_xatom_by_name_for_display (monitor->display, - "_NET_ACTIVE_WINDOW"); - GdkAtom net_active_window_gdk = - gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE); - Window active_window = None; - int i; + ShellGlobal *global; + MetaScreen *screen; + MetaDisplay *display; + MetaWindow *active; - Atom type; - int format; - unsigned long n_items; - unsigned long bytes_after; - guchar *data; - gboolean is_desktop = FALSE; + global = shell_global_get (); + g_object_get (global, "screen", &screen, NULL); + display = meta_screen_get_display (screen); + g_object_unref (screen); + + active = meta_display_get_focus_window (display); if (wm_class) *wm_class = NULL; if (title) *title = NULL; - /* Find the currently focused window by looking at the _NET_ACTIVE_WINDOW property - * on all the screens of the display. - */ - for (i = 0; i < n_screens; i++) - { - GdkScreen *screen = gdk_display_get_screen (monitor->display, i); - GdkWindow *root = gdk_screen_get_root_window (screen); + if (active == NULL) + return; - if (!gdk_x11_screen_supports_net_wm_hint (screen, net_active_window_gdk)) - continue; - - XGetWindowProperty (xdisplay, GDK_DRAWABLE_XID (root), - net_active_window_x, - 0, 1, False, XA_WINDOW, - &type, &format, &n_items, &bytes_after, &data); - if (type == XA_WINDOW) - { - active_window = *(Window *) data; - XFree (data); - break; - } - } - - /* Now that we have the active window, figure out the app name and WM class - */ - gdk_error_trap_push (); - - if (active_window && wm_class) - { - if (XGetWindowProperty (xdisplay, active_window, - XA_WM_CLASS, - 0, G_MAXLONG, False, XA_STRING, - &type, &format, &n_items, &bytes_after, - &data) == Success && type == XA_STRING) - { - if (format == 8) - { - char **list; - int count; - - count = - gdk_text_property_to_utf8_list_for_display (monitor->display, - GDK_TARGET_STRING, - 8, data, n_items, - &list); - - if (count > 1) - { - /* This is a check for Nautilus, which sets the instance to this - * value for the desktop window; we do this rather than check for - * the more general _NET_WM_WINDOW_TYPE_DESKTOP to avoid having - * to do another XGetProperty on every iteration. We generally - * don't want to count the desktop being focused as app - * usage because it frequently can be a false-positive on an - * empty workspace. - */ - if (strcmp (list[0], "desktop_window") == 0) - is_desktop = TRUE; - else - *wm_class = g_strdup (list[1]); - } - - if (list) - g_strfreev (list); - } - - XFree (data); - } - } - - if (is_desktop) - active_window = None; - - if (active_window && title) - { - Atom utf8_string = - gdk_x11_get_xatom_by_name_for_display (monitor->display, - "UTF8_STRING"); - - if (XGetWindowProperty (xdisplay, active_window, - gdk_x11_get_xatom_by_name_for_display - (monitor->display, "_NET_WM_NAME"), 0, - G_MAXLONG, False, utf8_string, &type, &format, - &n_items, &bytes_after, &data) == Success - && type == utf8_string) - { - if (format == 8 && g_utf8_validate ((char *) data, -1, NULL)) - { - *title = g_strdup ((char *) data); - } - - XFree (data); - } - } - - if (active_window && title && *title == NULL) - { - if (XGetWindowProperty (xdisplay, active_window, - XA_WM_NAME, - 0, G_MAXLONG, False, AnyPropertyType, - &type, &format, &n_items, &bytes_after, - &data) == Success && type != None) - { - if (format == 8) - { - char **list; - int count; - - count = - gdk_text_property_to_utf8_list_for_display (monitor->display, - gdk_x11_xatom_to_atom_for_display - (monitor->display, - type), 8, data, - n_items, &list); - - if (count > 0) - *title = g_strdup (list[0]); - - if (list) - g_strfreev (list); - } - - XFree (data); - } - } - gdk_error_trap_pop (); + *wm_class = g_strdup (meta_window_get_wm_class (active)); + *title = g_strdup (meta_window_get_description (active)); } void diff --git a/src/shell-app-monitor.h b/src/shell-app-monitor.h index f873c38e0..7a808f1a0 100644 --- a/src/shell-app-monitor.h +++ b/src/shell-app-monitor.h @@ -36,9 +36,13 @@ GType shell_app_monitor_get_type (void) G_GNUC_CONST; ShellAppMonitor* shell_app_monitor_new(void); /* Get the most popular applications for a given activity */ -GSList *shell_app_monitor_get_apps (ShellAppMonitor *monitor, - int activity, - gint number); +GSList *shell_app_monitor_get_most_used_apps (ShellAppMonitor *monitor, + int activity, + gint number); + +/* Get whatever's running right now */ +GSList *shell_app_monitor_get_running_apps (ShellAppMonitor *monitor, + int activity); G_END_DECLS diff --git a/src/shell-global.h b/src/shell-global.h index 06c19cc6e..0d43169ee 100644 --- a/src/shell-global.h +++ b/src/shell-global.h @@ -68,8 +68,6 @@ GList *shell_global_get_windows (ShellGlobal *global); void _shell_global_set_plugin (ShellGlobal *global, MutterPlugin *plugin); -MetaScreen * shell_global_get_screen (ShellGlobal *global); - gboolean shell_global_grab_keyboard (ShellGlobal *global); void shell_global_ungrab_keyboard (ShellGlobal *global);