diff --git a/shared/cairo-util.h b/shared/cairo-util.h index bab48083..6fd11f6b 100644 --- a/shared/cairo-util.h +++ b/shared/cairo-util.h @@ -135,6 +135,10 @@ frame_destroy(struct frame *frame); int frame_set_title(struct frame *frame, const char *title); +/* May set FRAME_STATUS_REPAINT */ +void +frame_set_icon(struct frame *frame, cairo_surface_t *icon); + /* May set FRAME_STATUS_REPAINT */ void frame_set_flag(struct frame *frame, enum frame_flag flag); diff --git a/shared/frame.c b/shared/frame.c index acac2ca8..e8a5cad6 100644 --- a/shared/frame.c +++ b/shared/frame.c @@ -448,6 +448,20 @@ frame_set_title(struct frame *frame, const char *title) return 0; } +void +frame_set_icon(struct frame *frame, cairo_surface_t *icon) +{ + struct frame_button *button; + wl_list_for_each(button, &frame->buttons, link) { + if (button->status_effect != FRAME_STATUS_MENU) + continue; + if (button->icon) + cairo_surface_destroy(button->icon); + button->icon = icon; + frame->status |= FRAME_STATUS_REPAINT; + } +} + void frame_set_flag(struct frame *frame, enum frame_flag flag) { diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c index ac44a29a..c307e199 100644 --- a/xwayland/window-manager.c +++ b/xwayland/window-manager.c @@ -139,7 +139,7 @@ struct weston_wm_window { struct frame *frame; cairo_surface_t *cairo_surface; int icon; - cairo_surface_t *icon_surface; + cairo_surface_t *icon_surface; /* A temporary slot, to be passed to frame on creation */ uint32_t surface_id; struct weston_surface *surface; struct weston_desktop_xwayland_surface *shsurf; @@ -994,6 +994,7 @@ weston_wm_window_create_frame(struct weston_wm_window *window) window->width, window->height, buttons, window->name, window->icon_surface); + window->icon_surface = NULL; frame_resize_inside(window->frame, window->width, window->height); weston_wm_window_get_frame_size(window, &width, &height); @@ -1392,10 +1393,10 @@ weston_wm_handle_icon(struct weston_wm *wm, struct weston_wm_window *window) return; } - if (window->icon_surface) - cairo_surface_destroy(window->icon_surface); - - window->icon_surface = new_surface; + if (window->frame) + frame_set_icon(window->frame, new_surface); + else /* We don’t have a frame yet */ + window->icon_surface = new_surface; } static void @@ -1422,7 +1423,10 @@ weston_wm_handle_property_notify(struct weston_wm *wm, xcb_generic_event_t *even if (property_notify->state != XCB_PROPERTY_DELETE) { weston_wm_handle_icon(wm, window); } else { - cairo_surface_destroy(window->icon_surface); + if (window->frame) + frame_set_icon(window->frame, NULL); + if (window->icon_surface) + cairo_surface_destroy(window->icon_surface); window->icon_surface = NULL; } weston_wm_window_schedule_repaint(window);