Commit 44fc1be9 authored by Emmanuel Gil Peyrot's avatar Emmanuel Gil Peyrot Committed by Daniel Stone

xwm: Fix icon surface ownership

The cairo surface used for the icon must be completely given to the
frame as soon as said frame has been created.  To prevent both the
window and the frame from sharing ownership of the icon, we set
window->icon_surface back to NULL right after creating or changing the
frame, only keeping it there when no frame has been created yet.

Fixes https://lists.freedesktop.org/archives/wayland-devel/2018-January/036655.htmlReported-by: default avatarDerek Foreman <derekf@osg.samsung.com>
Tested-by: default avatarDerek Foreman <derekf@osg.samsung.com>
Signed-off-by: default avatarEmmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parent 5e12b553
......@@ -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);
......
......@@ -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)
{
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment