ShellWindowTracker: complete WM_CLASS fix

Chromium (but not google-chrome) has a StartupWMClass in the desktop
file, so we must match the instance part first to have chrome
web apps working.
Also, we must take care of apps without a wm_class or instance at
all.

https://bugzilla.gnome.org/show_bug.cgi?id=673657
This commit is contained in:
Giovanni Campagna 2013-08-08 10:40:01 +02:00
parent d393bc45a4
commit 2a95273b79
2 changed files with 21 additions and 13 deletions

View File

@ -541,7 +541,7 @@ shell_app_system_lookup_heuristic_basename (ShellAppSystem *system,
/** /**
* shell_app_system_lookup_desktop_wmclass: * shell_app_system_lookup_desktop_wmclass:
* @system: a #ShellAppSystem * @system: a #ShellAppSystem
* @wmclass: A WM_CLASS value * @wmclass: (allow-none): A WM_CLASS value
* *
* Find a valid application whose .desktop file, without the extension * Find a valid application whose .desktop file, without the extension
* and properly canonicalized, matches @wmclass. * and properly canonicalized, matches @wmclass.
@ -578,7 +578,7 @@ shell_app_system_lookup_desktop_wmclass (ShellAppSystem *system,
/** /**
* shell_app_system_lookup_startup_wmclass: * shell_app_system_lookup_startup_wmclass:
* @system: a #ShellAppSystem * @system: a #ShellAppSystem
* @wmclass: A WM_CLASS value * @wmclass: (allow-none): A WM_CLASS value
* *
* Find a valid application whose .desktop file contains a * Find a valid application whose .desktop file contains a
* StartupWMClass entry matching @wmclass. * StartupWMClass entry matching @wmclass.
@ -589,6 +589,9 @@ ShellApp *
shell_app_system_lookup_startup_wmclass (ShellAppSystem *system, shell_app_system_lookup_startup_wmclass (ShellAppSystem *system,
const char *wmclass) const char *wmclass)
{ {
if (wmclass == NULL)
return NULL;
return g_hash_table_lookup (system->priv->startup_wm_class_to_app, wmclass); return g_hash_table_lookup (system->priv->startup_wm_class_to_app, wmclass);
} }

View File

@ -225,31 +225,36 @@ get_app_from_window_wmclass (MetaWindow *window)
with with
StartupWMClass=crx_blpcfgokakmgnkcojhhkbfbldkacnbeo StartupWMClass=crx_blpcfgokakmgnkcojhhkbfbldkacnbeo
Note that chromium (but not google-chrome!) includes a StartupWMClass=chromium
in their .desktop file, so we must match the instance first.
Also note that in the good case (regular gtk+ app without hacks), instance and
class are the same except for case and there is no StartupWMClass at all.
*/ */
/* first try a match from WM_CLASS to StartupWMClass */ /* first try a match from WM_CLASS (instance part) to StartupWMClass */
wm_class = meta_window_get_wm_class (window);
app = shell_app_system_lookup_startup_wmclass (appsys, wm_class);
if (app != NULL)
return g_object_ref (app);
/* then try a match from WM_CLASS (instance part) to StartupWMClass */
wm_instance = meta_window_get_wm_class_instance (window); wm_instance = meta_window_get_wm_class_instance (window);
app = shell_app_system_lookup_startup_wmclass (appsys, wm_instance); app = shell_app_system_lookup_startup_wmclass (appsys, wm_instance);
if (app != NULL) if (app != NULL)
return g_object_ref (app); return g_object_ref (app);
/* then try a match from WM_CLASS to .desktop */ /* then try a match from WM_CLASS to StartupWMClass */
app = shell_app_system_lookup_desktop_wmclass (appsys, wm_class); wm_class = meta_window_get_wm_class (window);
app = shell_app_system_lookup_startup_wmclass (appsys, wm_class);
if (app != NULL) if (app != NULL)
return g_object_ref (app); return g_object_ref (app);
/* finally, try a match from WM_CLASS (instance part) to .desktop /* then try a match from WM_CLASS (instance part) to .desktop */
(unlikely to find anything at this point, but still worth a try) */
app = shell_app_system_lookup_desktop_wmclass (appsys, wm_instance); app = shell_app_system_lookup_desktop_wmclass (appsys, wm_instance);
if (app != NULL) if (app != NULL)
return g_object_ref (app); return g_object_ref (app);
/* finally, try a match from WM_CLASS to .desktop */
app = shell_app_system_lookup_desktop_wmclass (appsys, wm_class);
if (app != NULL)
return g_object_ref (app);
return NULL; return NULL;
} }