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.html Reported-by: Derek Foreman <derekf@osg.samsung.com> Tested-by: Derek Foreman <derekf@osg.samsung.com> Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
This commit is contained in:
parent
5e12b553b1
commit
44fc1be913
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user