Protect window callbacks from deleted windows
Calling window_destroy() was able to cause segfault for callbacks triggering afterwards.
This commit is contained in:
committed by
Kristian Høgsberg
parent
b9af479f02
commit
6e1e385d51
+11
-3
@@ -165,6 +165,8 @@ struct window {
|
|||||||
window_close_handler_t close_handler;
|
window_close_handler_t close_handler;
|
||||||
window_fullscreen_handler_t fullscreen_handler;
|
window_fullscreen_handler_t fullscreen_handler;
|
||||||
|
|
||||||
|
struct wl_callback *frame_cb;
|
||||||
|
|
||||||
struct frame *frame;
|
struct frame *frame;
|
||||||
struct widget *widget;
|
struct widget *widget;
|
||||||
|
|
||||||
@@ -992,6 +994,8 @@ window_destroy(struct window *window)
|
|||||||
if (window->cairo_surface != NULL)
|
if (window->cairo_surface != NULL)
|
||||||
cairo_surface_destroy(window->cairo_surface);
|
cairo_surface_destroy(window->cairo_surface);
|
||||||
|
|
||||||
|
if (window->frame_cb)
|
||||||
|
wl_callback_destroy(window->frame_cb);
|
||||||
free(window->title);
|
free(window->title);
|
||||||
free(window);
|
free(window);
|
||||||
}
|
}
|
||||||
@@ -2003,6 +2007,9 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer,
|
|||||||
input->sx = sx;
|
input->sx = sx;
|
||||||
input->sy = sy;
|
input->sy = sy;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!(input->grab && input->grab_button)) {
|
if (!(input->grab && input->grab_button)) {
|
||||||
widget = widget_find_widget(window->widget, sx, sy);
|
widget = widget_find_widget(window->widget, sx, sy);
|
||||||
input_set_focus_widget(input, widget, sx, sy);
|
input_set_focus_widget(input, widget, sx, sy);
|
||||||
@@ -2871,7 +2878,9 @@ frame_callback(void *data, struct wl_callback *callback, uint32_t time)
|
|||||||
{
|
{
|
||||||
struct window *window = data;
|
struct window *window = data;
|
||||||
|
|
||||||
|
assert(callback == window->frame_cb);
|
||||||
wl_callback_destroy(callback);
|
wl_callback_destroy(callback);
|
||||||
|
window->frame_cb = 0;
|
||||||
window->redraw_scheduled = 0;
|
window->redraw_scheduled = 0;
|
||||||
if (window->redraw_needed)
|
if (window->redraw_needed)
|
||||||
window_schedule_redraw(window);
|
window_schedule_redraw(window);
|
||||||
@@ -2885,7 +2894,6 @@ static void
|
|||||||
idle_redraw(struct task *task, uint32_t events)
|
idle_redraw(struct task *task, uint32_t events)
|
||||||
{
|
{
|
||||||
struct window *window = container_of(task, struct window, redraw_task);
|
struct window *window = container_of(task, struct window, redraw_task);
|
||||||
struct wl_callback *callback;
|
|
||||||
|
|
||||||
if (window->resize_needed)
|
if (window->resize_needed)
|
||||||
idle_resize(window);
|
idle_resize(window);
|
||||||
@@ -2896,8 +2904,8 @@ idle_redraw(struct task *task, uint32_t events)
|
|||||||
window->redraw_needed = 0;
|
window->redraw_needed = 0;
|
||||||
wl_list_init(&window->redraw_task.link);
|
wl_list_init(&window->redraw_task.link);
|
||||||
|
|
||||||
callback = wl_surface_frame(window->surface);
|
window->frame_cb = wl_surface_frame(window->surface);
|
||||||
wl_callback_add_listener(callback, &listener, window);
|
wl_callback_add_listener(window->frame_cb, &listener, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user