diff --git a/src/core/window-private.h b/src/core/window-private.h index 70ebb3006..77248c8fd 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -43,7 +43,6 @@ #include #include -#include "x11/iconcache.h" #include "x11/group-private.h" #include "wayland/meta-wayland-types.h" @@ -107,9 +106,6 @@ struct _MetaWindow GdkPixbuf *icon; GdkPixbuf *mini_icon; - MetaIconCache icon_cache; - Pixmap wm_hints_pixmap; - Pixmap wm_hints_mask; MetaWindowType type; @@ -488,6 +484,9 @@ struct _MetaWindowClass void (*get_default_skip_hints) (MetaWindow *window, gboolean *skip_taskbar_out, gboolean *skip_pager_out); + gboolean (*update_icon) (MetaWindow *window, + GdkPixbuf **icon, + GdkPixbuf **mini_icon); }; /* These differ from window->has_foo_func in that they consider diff --git a/src/core/window.c b/src/core/window.c index 3d666a8af..1debad3ee 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -233,6 +233,16 @@ meta_window_real_get_default_skip_hints (MetaWindow *window, *skip_pager_out = FALSE; } +static gboolean +meta_window_real_update_icon (MetaWindow *window, + GdkPixbuf **icon, + GdkPixbuf **mini_icon) +{ + *icon = NULL; + *mini_icon = NULL; + return FALSE; +} + static void meta_window_finalize (GObject *object) { @@ -395,6 +405,7 @@ meta_window_class_init (MetaWindowClass *klass) klass->current_workspace_changed = meta_window_real_current_workspace_changed; klass->update_struts = meta_window_real_update_struts; klass->get_default_skip_hints = meta_window_real_get_default_skip_hints; + klass->update_icon = meta_window_real_update_icon; obj_props[PROP_TITLE] = g_param_spec_string ("title", @@ -819,9 +830,6 @@ _meta_window_shared_new (MetaDisplay *display, window->title = NULL; window->icon = NULL; window->mini_icon = NULL; - meta_icon_cache_init (&window->icon_cache); - window->wm_hints_pixmap = None; - window->wm_hints_mask = None; window->frame = NULL; window->has_focus = FALSE; @@ -4821,36 +4829,98 @@ redraw_icon (MetaWindow *window) meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow); } +static GdkPixbuf * +get_default_window_icon (void) +{ + static GdkPixbuf *default_icon = NULL; + + if (default_icon == NULL) + { + GtkIconTheme *theme; + gboolean icon_exists; + + theme = gtk_icon_theme_get_default (); + + icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME); + + if (icon_exists) + default_icon = gtk_icon_theme_load_icon (theme, + META_DEFAULT_ICON_NAME, + META_ICON_WIDTH, + 0, + NULL); + else + default_icon = gtk_icon_theme_load_icon (theme, + "image-missing", + META_ICON_WIDTH, + 0, + NULL); + + g_assert (default_icon); + } + + return g_object_ref (default_icon); +} + +static GdkPixbuf * +get_default_mini_icon (void) +{ + static GdkPixbuf *default_icon = NULL; + + if (default_icon == NULL) + { + GtkIconTheme *theme; + gboolean icon_exists; + + theme = gtk_icon_theme_get_default (); + + icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME); + + if (icon_exists) + default_icon = gtk_icon_theme_load_icon (theme, + META_DEFAULT_ICON_NAME, + META_MINI_ICON_WIDTH, + 0, + NULL); + else + default_icon = gtk_icon_theme_load_icon (theme, + "image-missing", + META_MINI_ICON_WIDTH, + 0, + NULL); + + g_assert (default_icon); + } + + return g_object_ref (default_icon); +} + static void meta_window_update_icon_now (MetaWindow *window) { - GdkPixbuf *icon; + gboolean changed; + GdkPixbuf *icon = NULL; GdkPixbuf *mini_icon; g_return_if_fail (!window->override_redirect); - icon = NULL; - mini_icon = NULL; + changed = META_WINDOW_GET_CLASS (window)->update_icon (window, &icon, &mini_icon); - if (meta_read_icons (window->screen, - window->xwindow, - &window->icon_cache, - window->wm_hints_pixmap, - window->wm_hints_mask, - &icon, - META_ICON_WIDTH, META_ICON_HEIGHT, - &mini_icon, - META_MINI_ICON_WIDTH, - META_MINI_ICON_HEIGHT)) + if (changed) { if (window->icon) - g_object_unref (G_OBJECT (window->icon)); + g_object_unref (window->icon); + if (icon) + window->icon = icon; + else + window->icon = get_default_window_icon (); if (window->mini_icon) - g_object_unref (G_OBJECT (window->mini_icon)); - - window->icon = icon; - window->mini_icon = mini_icon; + g_object_unref (window->mini_icon); + if (mini_icon) + window->mini_icon = mini_icon; + else + window->mini_icon = get_default_mini_icon (); g_object_freeze_notify (G_OBJECT (window)); g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_ICON]); diff --git a/src/ui/ui.c b/src/ui/ui.c index f018fd8c5..c4d21ddc2 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -555,76 +555,6 @@ meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap, return retval; } -GdkPixbuf* -meta_ui_get_default_window_icon (MetaUI *ui) -{ - static GdkPixbuf *default_icon = NULL; - - if (default_icon == NULL) - { - GtkIconTheme *theme; - gboolean icon_exists; - - theme = gtk_icon_theme_get_default (); - - icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME); - - if (icon_exists) - default_icon = gtk_icon_theme_load_icon (theme, - META_DEFAULT_ICON_NAME, - META_ICON_WIDTH, - 0, - NULL); - else - default_icon = gtk_icon_theme_load_icon (theme, - "image-missing", - META_ICON_WIDTH, - 0, - NULL); - - g_assert (default_icon); - } - - g_object_ref (G_OBJECT (default_icon)); - - return default_icon; -} - -GdkPixbuf* -meta_ui_get_default_mini_icon (MetaUI *ui) -{ - static GdkPixbuf *default_icon = NULL; - - if (default_icon == NULL) - { - GtkIconTheme *theme; - gboolean icon_exists; - - theme = gtk_icon_theme_get_default (); - - icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME); - - if (icon_exists) - default_icon = gtk_icon_theme_load_icon (theme, - META_DEFAULT_ICON_NAME, - META_MINI_ICON_WIDTH, - 0, - NULL); - else - default_icon = gtk_icon_theme_load_icon (theme, - "image-missing", - META_MINI_ICON_WIDTH, - 0, - NULL); - - g_assert (default_icon); - } - - g_object_ref (G_OBJECT (default_icon)); - - return default_icon; -} - gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay, Window xwindow) diff --git a/src/ui/ui.h b/src/ui/ui.h index af0e72a82..8bc6d4587 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -121,9 +121,6 @@ GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap, int width, int height); -GdkPixbuf* meta_ui_get_default_window_icon (MetaUI *ui); -GdkPixbuf* meta_ui_get_default_mini_icon (MetaUI *ui); - gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay, Window xwindow); diff --git a/src/x11/iconcache.c b/src/x11/iconcache.c index e03558a39..45a8679e4 100644 --- a/src/x11/iconcache.c +++ b/src/x11/iconcache.c @@ -28,22 +28,6 @@ /* The icon-reading code is also in libwnck, please sync bugfixes */ -static void -get_fallback_icons (MetaScreen *screen, - GdkPixbuf **iconp, - int ideal_width, - int ideal_height, - GdkPixbuf **mini_iconp, - int ideal_mini_width, - int ideal_mini_height) -{ - /* we don't scale, should be fixed if we ever un-hardcode the icon - * size - */ - *iconp = meta_ui_get_default_window_icon (screen->ui); - *mini_iconp = meta_ui_get_default_mini_icon (screen->ui); -} - static gboolean find_largest_sizes (gulong *data, gulong nitems, @@ -668,7 +652,6 @@ meta_read_icons (MetaScreen *screen, if (icon_cache->origin <= USING_NET_WM_ICON && icon_cache->net_wm_icon_dirty) - { guchar *pixdata; int w, h; @@ -764,14 +747,9 @@ meta_read_icons (MetaScreen *screen, if (icon_cache->origin < USING_FALLBACK_ICON) { - get_fallback_icons (screen, - iconp, - ideal_width, - ideal_height, - mini_iconp, - ideal_mini_width, - ideal_mini_height); icon_cache->origin = USING_FALLBACK_ICON; + *iconp = NULL; + *mini_iconp = NULL; return TRUE; } diff --git a/src/x11/window-props.c b/src/x11/window-props.c index 88c7beb70..d2ba87ebc 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -281,7 +281,10 @@ static void reload_icon (MetaWindow *window, Atom atom) { - meta_icon_cache_property_changed (&window->icon_cache, + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + + meta_icon_cache_property_changed (&priv->icon_cache, window->display, atom); meta_window_queue(window, META_QUEUE_UPDATE_ICON); @@ -1495,6 +1498,8 @@ reload_wm_hints (MetaWindow *window, MetaPropValue *value, gboolean initial) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; Window old_group_leader; gboolean urgent; @@ -1504,8 +1509,8 @@ reload_wm_hints (MetaWindow *window, window->input = TRUE; window->initially_iconic = FALSE; window->xgroup_leader = None; - window->wm_hints_pixmap = None; - window->wm_hints_mask = None; + priv->wm_hints_pixmap = None; + priv->wm_hints_mask = None; urgent = FALSE; if (value->type != META_PROP_VALUE_INVALID) @@ -1522,10 +1527,10 @@ reload_wm_hints (MetaWindow *window, window->xgroup_leader = hints->window_group; if (hints->flags & IconPixmapHint) - window->wm_hints_pixmap = hints->icon_pixmap; + priv->wm_hints_pixmap = hints->icon_pixmap; if (hints->flags & IconMaskHint) - window->wm_hints_mask = hints->icon_mask; + priv->wm_hints_mask = hints->icon_mask; if (hints->flags & XUrgencyHint) urgent = TRUE; @@ -1533,8 +1538,8 @@ reload_wm_hints (MetaWindow *window, meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx\n", window->input, window->initially_iconic, window->xgroup_leader, - window->wm_hints_pixmap, - window->wm_hints_mask); + priv->wm_hints_pixmap, + priv->wm_hints_mask); } if (window->xgroup_leader != old_group_leader) @@ -1547,7 +1552,7 @@ reload_wm_hints (MetaWindow *window, meta_window_set_urgent (window, urgent); - meta_icon_cache_property_changed (&window->icon_cache, + meta_icon_cache_property_changed (&priv->icon_cache, window->display, XA_WM_HINTS); diff --git a/src/x11/window-x11-private.h b/src/x11/window-x11-private.h index 0fe90b895..d909a0cee 100644 --- a/src/x11/window-x11-private.h +++ b/src/x11/window-x11-private.h @@ -24,6 +24,7 @@ #define META_WINDOW_X11_PRIVATE_H #include "window-private.h" +#include "x11/iconcache.h" #include "ui/resizepopup.h" G_BEGIN_DECLS @@ -60,6 +61,10 @@ struct _MetaWindowX11Private /* These are in server coordinates. If we have a frame, it's * relative to the frame. */ MetaRectangle client_rect; + + MetaIconCache icon_cache; + Pixmap wm_hints_pixmap; + Pixmap wm_hints_mask; }; G_END_DECLS diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 76098ec5c..d75be06d3 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -503,6 +503,10 @@ static void meta_window_x11_manage (MetaWindow *window) { MetaDisplay *display = window->display; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + meta_icon_cache_init (&priv->icon_cache); meta_display_register_x_window (display, &window->xwindow, window); meta_window_x11_update_shape_region (window); @@ -544,9 +548,6 @@ meta_window_x11_manage (MetaWindow *window) if (window->override_redirect) { - MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); - MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); - priv->client_rect = window->rect; window->buffer_rect = window->rect; } @@ -1448,6 +1449,25 @@ meta_window_x11_get_default_skip_hints (MetaWindow *window, *skip_pager_out = priv->wm_state_skip_pager; } +static gboolean +meta_window_x11_update_icon (MetaWindow *window, + GdkPixbuf **icon, + GdkPixbuf **mini_icon) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + return meta_read_icons (window->screen, + window->xwindow, + &priv->icon_cache, + priv->wm_hints_pixmap, + priv->wm_hints_mask, + icon, + META_ICON_WIDTH, META_ICON_HEIGHT, + mini_icon, + META_MINI_ICON_WIDTH, META_MINI_ICON_HEIGHT); +} + static void meta_window_x11_class_init (MetaWindowX11Class *klass) { @@ -1465,6 +1485,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) window_class->move_resize_internal = meta_window_x11_move_resize_internal; window_class->update_struts = meta_window_x11_update_struts; window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints; + window_class->update_icon = meta_window_x11_update_icon; } void