summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Kareh <[email protected]>2024-04-08 12:23:57 -0400
committerlukefromdc <[email protected]>2024-06-18 17:04:23 -0400
commit96a4b36b9feca559a512fe26cb7359178f1577cc (patch)
tree78d14df3c6b3d20b237b2f5193828c7ee3f3ee3a
parentcb83a91ed03c9e5ab2a1d8b932ffac3ba49e9fbb (diff)
downloadmarco-96a4b36b9feca559a512fe26cb7359178f1577cc.tar.bz2
marco-96a4b36b9feca559a512fe26cb7359178f1577cc.tar.xz
window: Parse _BAMF_DESKTOP_FILE propertyiconcache-use-gdesktopapp
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.
-rw-r--r--src/core/atomnames.h5
-rw-r--r--src/core/iconcache.c8
-rw-r--r--src/core/iconcache.h2
-rw-r--r--src/core/window-private.h1
-rw-r--r--src/core/window-props.c24
-rw-r--r--src/core/window.c37
-rw-r--r--src/include/ui.h4
-rw-r--r--src/ui/ui.c18
8 files changed, 79 insertions, 20 deletions
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);
}
diff --git a/src/include/ui.h b/src/include/ui.h
index f4728e32..8eb6dd5e 100644
--- a/src/include/ui.h
+++ b/src/include/ui.h
@@ -157,8 +157,8 @@ void meta_ui_pop_delay_exposes (MetaUI *ui);
GdkPixbuf* meta_ui_get_default_window_icon (MetaUI *ui);
GdkPixbuf* meta_ui_get_default_mini_icon (MetaUI *ui);
-GdkPixbuf* meta_ui_get_window_icon_from_app (MetaUI *ui, char *name);
-GdkPixbuf* meta_ui_get_mini_icon_from_app (MetaUI *ui, char *name);
+GdkPixbuf* meta_ui_get_window_icon_from_desktop_id (MetaUI *ui, char *desktop_id);
+GdkPixbuf* meta_ui_get_mini_icon_from_desktop_id (MetaUI *ui, char *desktop_id);
gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay,
Window xwindow);
diff --git a/src/ui/ui.c b/src/ui/ui.c
index 3c32c909..00500c03 100644
--- a/src/ui/ui.c
+++ b/src/ui/ui.c
@@ -650,7 +650,7 @@ meta_ui_get_default_mini_icon (MetaUI *ui)
}
static GdkPixbuf *
-load_window_icon_from_app (char *app_id, int size, int scale)
+load_window_icon_from_desktop_id (char *desktop_id, int size, int scale)
{
GtkIconTheme *theme = gtk_icon_theme_get_default ();
GdkPixbuf *pixbuf = NULL;
@@ -659,17 +659,13 @@ load_window_icon_from_app (char *app_id, int size, int scale)
GIcon *gicon;
GtkIconInfo *icon_info;
- /* Generate a desktop ID the GTK Application ID name (e.g. org.mate.Caja.desktop). */
- gchar *desktop_id = g_strconcat(app_id, ".desktop", NULL);
-
- if (desktop_id == NULL)
+ if (desktop_id == NULL || !g_str_has_suffix (desktop_id, ".desktop"))
return NULL;
- /* Now that we have the desktop file ID, we extract the icon from it and render it */
info = g_desktop_app_info_new (desktop_id);
- g_free(desktop_id);
if (info == NULL)
return NULL;
+
gicon = g_app_info_get_icon (G_APP_INFO (info));
icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, gicon, size, scale, GTK_ICON_LOOKUP_FORCE_SIZE);
if (icon_info)
@@ -682,7 +678,7 @@ load_window_icon_from_app (char *app_id, int size, int scale)
}
GdkPixbuf*
-meta_ui_get_window_icon_from_app (MetaUI *ui, char *name)
+meta_ui_get_window_icon_from_desktop_id (MetaUI *ui, char *desktop_id)
{
int scale;
int size;
@@ -690,11 +686,11 @@ meta_ui_get_window_icon_from_app (MetaUI *ui, char *name)
scale = gtk_widget_get_scale_factor (GTK_WIDGET (ui->frames));
size = meta_prefs_get_icon_size() / scale;
- return load_window_icon_from_app (name, size, scale);
+ return load_window_icon_from_desktop_id (desktop_id, size, scale);
}
GdkPixbuf*
-meta_ui_get_mini_icon_from_app (MetaUI *ui, char *name)
+meta_ui_get_mini_icon_from_desktop_id (MetaUI *ui, char *desktop_id)
{
int scale;
int size;
@@ -702,7 +698,7 @@ meta_ui_get_mini_icon_from_app (MetaUI *ui, char *name)
scale = gtk_widget_get_scale_factor (GTK_WIDGET (ui->frames));
size = META_MINI_ICON_WIDTH / scale;
- return load_window_icon_from_app (name, size, scale);
+ return load_window_icon_from_desktop_id (desktop_id, size, scale);
}
gboolean