Skip to content

Commit

Permalink
window: Parse _BAMF_DESKTOP_FILE property
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vkareh authored and lukefromdc committed Jun 18, 2024
1 parent cb83a91 commit 96a4b36
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 20 deletions.
5 changes: 5 additions & 0 deletions src/core/atomnames.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions src/core/iconcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
{
Expand Down
2 changes: 1 addition & 1 deletion src/core/iconcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions src/core/window-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
24 changes: 24 additions & 0 deletions src/core/window-props.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 },
};

Expand Down
37 changes: 35 additions & 2 deletions src/core/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
{
Expand All @@ -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,
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions src/include/ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
18 changes: 7 additions & 11 deletions src/ui/ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -682,27 +678,27 @@ 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;

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;

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
Expand Down

0 comments on commit 96a4b36

Please sign in to comment.