summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Kareh <[email protected]>2021-05-26 14:14:59 -0400
committerraveit65 <[email protected]>2021-06-04 17:02:28 +0200
commit60e6fbfb093d63c46ca8e77750c54f31c9780c1c (patch)
tree5ef3ac5375f5e306676efb3329758eca6fa4c05d
parentf2ca234719034c5ead3c94b8717913b8a4b67773 (diff)
downloadmarco-60e6fbfb093d63c46ca8e77750c54f31c9780c1c.tar.bz2
marco-60e6fbfb093d63c46ca8e77750c54f31c9780c1c.tar.xz
iconcache: Use GDesktopAppInfo to find correct application icons
Some files do not report their application icons correctly in the window properties. This patch allows the marco UI to search for the corresponding .desktop file and render the icon in the desktop info on both the alt-tab popup and the window mini-icon.
-rw-r--r--src/core/iconcache.c23
-rw-r--r--src/core/iconcache.h1
-rw-r--r--src/core/window.c1
-rw-r--r--src/include/ui.h2
-rw-r--r--src/ui/ui.c74
5 files changed, 94 insertions, 7 deletions
diff --git a/src/core/iconcache.c b/src/core/iconcache.c
index aa1d4339..a45d3d99 100644
--- a/src/core/iconcache.c
+++ b/src/core/iconcache.c
@@ -25,6 +25,7 @@
#include "iconcache.h"
#include "ui.h"
#include "errors.h"
+#include "window-private.h"
#include <X11/Xatom.h>
@@ -690,6 +691,7 @@ scaled_from_pixdata (guchar *pixdata,
gboolean
meta_read_icons (MetaScreen *screen,
Window xwindow,
+ char *res_name,
MetaIconCache *icon_cache,
Pixmap wm_hints_pixmap,
Pixmap wm_hints_mask,
@@ -847,13 +849,20 @@ meta_read_icons (MetaScreen *screen,
{
icon_cache->fallback_icon_dirty_forced = FALSE;
- get_fallback_icons (screen,
- iconp,
- ideal_width,
- ideal_height,
- mini_iconp,
- ideal_mini_width,
- ideal_mini_height);
+ if (res_name != NULL)
+ {
+ *iconp = meta_ui_get_window_icon_from_name (screen->ui, res_name);
+ *mini_iconp = meta_ui_get_mini_icon_from_name (screen->ui, res_name);
+ }
+
+ if (*iconp == NULL || *mini_iconp == NULL)
+ get_fallback_icons (screen,
+ iconp,
+ ideal_width,
+ ideal_height,
+ mini_iconp,
+ ideal_mini_width,
+ ideal_mini_height);
replace_cache (icon_cache, USING_FALLBACK_ICON,
*iconp, *mini_iconp);
diff --git a/src/core/iconcache.h b/src/core/iconcache.h
index d46abda0..7e9a1f6d 100644
--- a/src/core/iconcache.h
+++ b/src/core/iconcache.h
@@ -67,6 +67,7 @@ gboolean meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache);
gboolean meta_read_icons (MetaScreen *screen,
Window xwindow,
+ char *res_name,
MetaIconCache *icon_cache,
Pixmap wm_hints_pixmap,
Pixmap wm_hints_mask,
diff --git a/src/core/window.c b/src/core/window.c
index 68ac89ab..b301dbd9 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -6124,6 +6124,7 @@ meta_window_update_icon_now (MetaWindow *window)
if (meta_read_icons (window->screen,
window->xwindow,
+ window->res_name,
&window->icon_cache,
window->wm_hints_pixmap,
window->wm_hints_mask,
diff --git a/src/include/ui.h b/src/include/ui.h
index 26d0d462..c02e78a2 100644
--- a/src/include/ui.h
+++ b/src/include/ui.h
@@ -155,6 +155,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_name (MetaUI *ui, char *name);
+GdkPixbuf* meta_ui_get_mini_icon_from_name (MetaUI *ui, char *name);
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 44c72938..4935f77c 100644
--- a/src/ui/ui.c
+++ b/src/ui/ui.c
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <cairo-xlib.h>
+#include <gio/gdesktopappinfo.h>
static void meta_ui_accelerator_parse(const char* accel, guint* keysym, guint* keycode, GdkModifierType* keymask);
@@ -647,6 +648,79 @@ meta_ui_get_default_mini_icon (MetaUI *ui)
return default_icon;
}
+static GdkPixbuf *
+load_window_icon_from_name (char *name, int size, int scale)
+{
+ GtkIconTheme *theme = gtk_icon_theme_get_default ();
+ GdkPixbuf *pixbuf = NULL;
+
+ /* If the res_name window property maps to an icon, use that */
+ pixbuf = gtk_icon_theme_load_icon_for_scale (theme, name, size, scale, GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
+ if (pixbuf != NULL)
+ return pixbuf;
+
+ char ***results;
+ gchar *desktop_id = NULL;
+ gint i, j;
+ GDesktopAppInfo *info;
+ GIcon *gicon;
+ GtkIconInfo *icon_info;
+
+ /* Find a proper desktop file based on the window property name */
+ results = g_desktop_app_info_search (name);
+
+ for (i = 0; results[i]; i++)
+ {
+ for (j = 0; results[i][j]; j++)
+ {
+ /* We are only interested in the top ranking result, so we use that and free up the rest */
+ if (desktop_id == NULL)
+ desktop_id = g_strdup(results[i][j]);
+ }
+ g_strfreev (results[i]);
+ }
+ g_free (results);
+
+ if (desktop_id == NULL)
+ 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);
+ 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);
+
+ pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
+
+ g_object_unref (icon_info);
+ g_free (desktop_id);
+
+ return pixbuf;
+}
+
+GdkPixbuf*
+meta_ui_get_window_icon_from_name (MetaUI *ui, char *name)
+{
+ 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_name (name, size, scale);
+}
+
+GdkPixbuf*
+meta_ui_get_mini_icon_from_name (MetaUI *ui, char *name)
+{
+ 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_name (name, size, scale);
+}
+
gboolean
meta_ui_window_should_not_cause_focus (Display *xdisplay,
Window xwindow)