window-tracker: Consider Flatpak ID for window matching

Our window matching currently fails frequently with Flatpak
applications, as one of the primary hints used to link windows
with .desktop files - the WM_CLASS - no longer matches when
flatpak renames the exported .desktop file. Worse, as Flatpak
applications are run in their own PID namespace, different
apps frequently share a common _NET_WM_PID, resulting in
unrelated apps being grouped together by one of the fallback
paths. To match Flatpak applications reliably, take the newly
exported Flatpak ID into account.

https://bugzilla.gnome.org/show_bug.cgi?id=772615
This commit is contained in:
Florian Müllner 2016-10-07 17:54:09 +02:00
parent 70a0c4211c
commit 0c22a21a24

View File

@ -202,9 +202,39 @@ get_app_from_window_wmclass (MetaWindow *window)
return NULL; return NULL;
} }
/*
* get_app_from_id:
* @window: a #MetaWindow
*
* Looks only at the given window, and attempts to determine
* an application based on %id. If one can't be determined,
* return %NULL.
*
* Return value: (transfer full): A newly-referenced #ShellApp, or %NULL
*/
static ShellApp *
get_app_from_id (MetaWindow *window,
const char *id)
{
ShellApp *app;
ShellAppSystem *appsys;
char *desktop_file;
g_return_val_if_fail (id != NULL, NULL);
appsys = shell_app_system_get_default ();
desktop_file = g_strconcat (id, ".desktop", NULL);
app = shell_app_system_lookup_app (appsys, desktop_file);
if (app)
g_object_ref (app);
g_free (desktop_file);
return app;
}
/* /*
* get_app_from_gapplication_id: * get_app_from_gapplication_id:
* @monitor: a #ShellWindowTracker
* @window: a #MetaWindow * @window: a #MetaWindow
* *
* Looks only at the given window, and attempts to determine * Looks only at the given window, and attempts to determine
@ -216,24 +246,35 @@ get_app_from_window_wmclass (MetaWindow *window)
static ShellApp * static ShellApp *
get_app_from_gapplication_id (MetaWindow *window) get_app_from_gapplication_id (MetaWindow *window)
{ {
ShellApp *app;
ShellAppSystem *appsys;
const char *id; const char *id;
char *desktop_file;
appsys = shell_app_system_get_default ();
id = meta_window_get_gtk_application_id (window); id = meta_window_get_gtk_application_id (window);
if (!id) if (!id)
return NULL; return NULL;
desktop_file = g_strconcat (id, ".desktop", NULL); return get_app_from_id (window, id);
app = shell_app_system_lookup_app (appsys, desktop_file); }
if (app)
g_object_ref (app);
g_free (desktop_file); /*
return app; * get_app_from_flatpak_id:
* @window: a #MetaWindow
*
* Looks only at the given window, and attempts to determine
* an application based on its Flatpak ID. If one can't be determined,
* return %NULL.
*
* Return value: (transfer full): A newly-referenced #ShellApp, or %NULL
*/
static ShellApp *
get_app_from_flatpak_id (MetaWindow *window)
{
const char *id;
id = meta_window_get_flatpak_id (window);
if (!id)
return NULL;
return get_app_from_id (window, id);
} }
/* /*
@ -354,6 +395,13 @@ get_app_for_window (ShellWindowTracker *tracker,
if (meta_window_is_remote (window)) if (meta_window_is_remote (window))
return _shell_app_new_for_window (window); return _shell_app_new_for_window (window);
/* Check if the window was opened from within a Flatpak sandbox; if this
* is the case, a corresponding .desktop file is guaranteed to match;
*/
result = get_app_from_flatpak_id (window);
if (result != NULL)
return result;
/* Check if the window has a GApplication ID attached; this is /* Check if the window has a GApplication ID attached; this is
* canonical if it does * canonical if it does
*/ */