From 96a4b36b9feca559a512fe26cb7359178f1577cc Mon Sep 17 00:00:00 2001 From: Victor Kareh Date: Mon, 8 Apr 2024 12:23:57 -0400 Subject: window: Parse _BAMF_DESKTOP_FILE property In systems with bamfdaemon running, windows get this property for finding the dekstop spec file of an application. This can be used to find the defined icon for any application window that reports this attribute and provider much better icon matching. --- src/core/atomnames.h | 5 +++++ src/core/iconcache.c | 8 ++++---- src/core/iconcache.h | 2 +- src/core/window-private.h | 1 + src/core/window-props.c | 24 ++++++++++++++++++++++++ src/core/window.c | 37 +++++++++++++++++++++++++++++++++++-- 6 files changed, 70 insertions(+), 7 deletions(-) (limited to 'src/core') diff --git a/src/core/atomnames.h b/src/core/atomnames.h index 4b99f163..2e9e6c8d 100644 --- a/src/core/atomnames.h +++ b/src/core/atomnames.h @@ -77,6 +77,11 @@ item(TIMESTAMP) item(VERSION) item(ATOM_PAIR) +/* This is only used if BAMF is installed and the daemon is running. + * Otherwise it's a no-op + */ +item(_BAMF_DESKTOP_FILE) + /* Oddities: These are used, and we need atoms for them, * but when we need all _NET_WM hints (i.e. when we're making * lists of which _NET_WM hints we support in order to advertise diff --git a/src/core/iconcache.c b/src/core/iconcache.c index 32107781..580a521c 100644 --- a/src/core/iconcache.c +++ b/src/core/iconcache.c @@ -702,7 +702,7 @@ scaled_from_pixdata (guchar *pixdata, gboolean meta_read_icons (MetaScreen *screen, Window xwindow, - char *app_id, + char *desktop_id, MetaIconCache *icon_cache, Pixmap wm_hints_pixmap, Pixmap wm_hints_mask, @@ -756,12 +756,12 @@ meta_read_icons (MetaScreen *screen, if (icon_cache->origin <= USING_G_DESKTOP_APP && icon_cache->g_desktop_app_icon_dirty && - app_id != NULL) + desktop_id != NULL) { icon_cache->g_desktop_app_icon_dirty = FALSE; - *iconp = meta_ui_get_window_icon_from_app (screen->ui, app_id); - *mini_iconp = meta_ui_get_mini_icon_from_app (screen->ui, app_id); + *iconp = meta_ui_get_window_icon_from_desktop_id (screen->ui, desktop_id); + *mini_iconp = meta_ui_get_mini_icon_from_desktop_id (screen->ui, desktop_id); if (*iconp && *mini_iconp) { diff --git a/src/core/iconcache.h b/src/core/iconcache.h index 9aee499b..353787c7 100644 --- a/src/core/iconcache.h +++ b/src/core/iconcache.h @@ -69,7 +69,7 @@ gboolean meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache); gboolean meta_read_icons (MetaScreen *screen, Window xwindow, - char *app_id, + char *desktop_id, MetaIconCache *icon_cache, Pixmap wm_hints_pixmap, Pixmap wm_hints_mask, diff --git a/src/core/window-private.h b/src/core/window-private.h index c6117654..52864a86 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -134,6 +134,7 @@ struct _MetaWindow char *startup_id; char *gtk_theme_variant; char *gtk_application_id; + char *bamf_desktop_file; int net_wm_pid; diff --git a/src/core/window-props.c b/src/core/window-props.c index fd08d33f..4d9600c2 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -1627,6 +1627,29 @@ reload_gtk_application_id (MetaWindow *window, } } +static void +reload_bamf_desktop_file (MetaWindow *window, + MetaPropValue *value, + gboolean initial) +{ + char *requested = NULL; + char *current = window->bamf_desktop_file; + + if (value->type != META_PROP_VALUE_INVALID) + { + requested = value->v.str; + meta_verbose ("Requested _BAMF_DESKTOP_FILE \"%s\" for window %s.\n", + requested, window->desc); + } + + if (g_strcmp0 (requested, current) != 0) + { + g_free (current); + + window->bamf_desktop_file = g_strdup (requested); + } +} + /** * Initialises the property hooks system. Each row in the table named "hooks" * represents an action to take when a property is found on a newly-created @@ -1677,6 +1700,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) { display->atom__GTK_THEME_VARIANT, META_PROP_VALUE_UTF8, reload_gtk_theme_variant, }, { display->atom__GTK_FRAME_EXTENTS, META_PROP_VALUE_CARDINAL_LIST, reload_gtk_frame_extents }, { display->atom__GTK_APPLICATION_ID, META_PROP_VALUE_UTF8, reload_gtk_application_id }, + { display->atom__BAMF_DESKTOP_FILE, META_PROP_VALUE_STRING, reload_bamf_desktop_file }, { 0 }, }; diff --git a/src/core/window.c b/src/core/window.c index b58aff2f..050c89f8 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -263,7 +263,7 @@ meta_window_new_with_attrs (MetaDisplay *display, gulong existing_wm_state; gulong event_mask; MetaMoveResizeFlags flags; -#define N_INITIAL_PROPS 21 +#define N_INITIAL_PROPS 22 Atom initial_props[N_INITIAL_PROPS]; int i; gboolean has_shape; @@ -564,6 +564,7 @@ meta_window_new_with_attrs (MetaDisplay *display, window->startup_id = NULL; window->gtk_theme_variant = NULL; window->gtk_application_id = NULL; + window->bamf_desktop_file = NULL; window->net_wm_pid = -1; @@ -623,6 +624,7 @@ meta_window_new_with_attrs (MetaDisplay *display, initial_props[i++] = display->atom__NET_WM_FULLSCREEN_MONITORS; initial_props[i++] = display->atom__GTK_THEME_VARIANT; initial_props[i++] = display->atom__GTK_APPLICATION_ID; + initial_props[i++] = display->atom__BAMF_DESKTOP_FILE; g_assert (N_INITIAL_PROPS == i); meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS, TRUE); @@ -6109,6 +6111,33 @@ redraw_icon (MetaWindow *window) meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow); } +static gchar* +meta_window_get_desktop_id (MetaWindow *window) +{ + gchar* desktop_id = NULL; + + if (window->gtk_application_id != NULL) + { + meta_verbose ("Request desktop ID from _GTK_APPLICATION_ID '%s'\n", window->gtk_application_id); + + /* Generate a desktop extension to the application ID (e.g. org.mate.Caja.desktop). */ + desktop_id = g_strconcat(window->gtk_application_id, ".desktop", NULL); + } + else if (window->bamf_desktop_file != NULL) + { + meta_verbose ("Request desktop ID from _BAMF_DESKTOP_FILE '%s'\n", window->bamf_desktop_file); + + /* Remove any paths to separate the application ID */ + gchar **path_parts = g_strsplit (window->bamf_desktop_file, "/", -1); + /* Generate a desktop ID the application ID (e.g. org.mate.Caja.desktop). */ + if (g_strv_length(path_parts) > 0) + desktop_id = g_strdup (path_parts[g_strv_length(path_parts)-1]); + g_strfreev (path_parts); + } + + return desktop_id; +} + void meta_window_update_icon_now (MetaWindow *window) { @@ -6119,10 +6148,11 @@ meta_window_update_icon_now (MetaWindow *window) mini_icon = NULL; int icon_size = meta_prefs_get_icon_size(); + gchar* desktop_id = meta_window_get_desktop_id (window); if (meta_read_icons (window->screen, window->xwindow, - window->gtk_application_id, + desktop_id, &window->icon_cache, window->wm_hints_pixmap, window->wm_hints_mask, @@ -6145,6 +6175,8 @@ meta_window_update_icon_now (MetaWindow *window) redraw_icon (window); } + g_free (desktop_id); + g_assert (window->icon); g_assert (window->mini_icon); } @@ -9018,6 +9050,7 @@ meta_window_finalize (GObject *object) g_clear_pointer (&window->desc, g_free); g_clear_pointer (&window->gtk_theme_variant, g_free); g_clear_pointer (&window->gtk_application_id, g_free); + g_clear_pointer (&window->bamf_desktop_file, g_free); G_OBJECT_CLASS (meta_window_parent_class)->finalize (object); } -- cgit v1.2.1