commit 516f9e79ae9aebdf840478282312a3aebd97885b
parent ae9813080bb100482eb30288ecad81a49b7f26f6
Author: Michael Forney <mforney@mforney.org>
Date: Tue, 3 Dec 2013 20:49:49 -0800
Move window cleanup to swc_window_finalize
This avoids the case where the window implementation surface destroy
listener is called before the window's destroy listener, resulting in
accesses to freed memory.
It also matches better with the initialize/finalize style.
Diffstat:
5 files changed, 13 insertions(+), 23 deletions(-)
diff --git a/libswc/shell_surface.c b/libswc/shell_surface.c
@@ -183,6 +183,7 @@ static void destroy_shell_surface(struct wl_resource * resource)
struct swc_shell_surface * shell_surface
= wl_resource_get_user_data(resource);
+ swc_window_finalize(&shell_surface->window.base);
free(shell_surface);
}
diff --git a/libswc/surface.c b/libswc/surface.c
@@ -355,6 +355,7 @@ struct swc_surface * swc_surface_new(struct wl_client * client,
surface->geometry.width = 0;
surface->geometry.height = 0;
surface->pending.commit = 0;
+ surface->window = NULL;
surface->class = NULL;
surface->class_state = NULL;
diff --git a/libswc/surface.h b/libswc/surface.h
@@ -112,6 +112,7 @@ struct swc_surface
int32_t x, y;
} pending;
+ struct swc_window * window;
const struct swc_surface_class * class;
void * class_state;
diff --git a/libswc/window.c b/libswc/window.c
@@ -44,7 +44,7 @@ static void handle_window_enter(struct wl_listener * listener, void * data)
if (event->type != SWC_INPUT_FOCUS_EVENT_CHANGED)
return;
- if (!event_data->new || !(window = swc_window_get(event_data->new)))
+ if (!event_data->new || !(window = event_data->new->window))
return;
swc_send_event(&window->event_signal, SWC_WINDOW_ENTERED, NULL);
@@ -96,29 +96,20 @@ void swc_window_set_border(struct swc_window * window,
swc_compositor_surface_set_border_width(surface, border_width);
}
-static void handle_surface_destroy(struct wl_listener * listener, void * data)
-{
- struct swc_window * window = &CONTAINER_OF
- (listener, struct swc_window_internal, surface_destroy_listener)->base;
-
- swc_send_event(&window->event_signal, SWC_WINDOW_DESTROYED, NULL);
- swc_surface_set_class(INTERNAL(window)->surface, NULL);
-}
-
bool swc_window_initialize(struct swc_window * window,
const struct swc_window_impl * impl,
struct swc_surface * surface)
{
+ DEBUG("Initializing window, %p\n", window);
+
window->title = NULL;
window->class = NULL;
window->state = SWC_WINDOW_STATE_WITHDRAWN;
wl_signal_init(&window->event_signal);
INTERNAL(window)->surface = surface;
- INTERNAL(window)->surface_destroy_listener.notify = &handle_surface_destroy;
INTERNAL(window)->impl = impl;
- wl_resource_add_destroy_listener
- (surface->resource, &INTERNAL(window)->surface_destroy_listener);
+ surface->window = window;
swc_surface_set_class(surface, &swc.compositor->compositor_class);
swc.manager->new_window(window);
@@ -126,16 +117,13 @@ bool swc_window_initialize(struct swc_window * window,
return true;
}
-struct swc_window * swc_window_get(struct swc_surface * surface)
+void swc_window_finalize(struct swc_window * window)
{
- struct wl_listener * listener;
-
- listener = wl_resource_get_destroy_listener(surface->resource,
- &handle_surface_destroy);
+ DEBUG("Finalizing window, %p\n", window);
- return listener ? &CONTAINER_OF(listener, struct swc_window_internal,
- surface_destroy_listener)->base
- : NULL;
+ swc_send_event(&window->event_signal, SWC_WINDOW_DESTROYED, NULL);
+ swc_surface_set_class(INTERNAL(window)->surface, NULL);
+ INTERNAL(window)->surface->window = NULL;
}
void swc_window_set_title(struct swc_window * window,
diff --git a/libswc/window.h b/libswc/window.h
@@ -41,7 +41,6 @@ struct swc_window_internal
struct swc_window base;
struct swc_surface * surface;
- struct wl_listener surface_destroy_listener;
const struct swc_window_impl * impl;
};
@@ -51,7 +50,7 @@ bool swc_window_initialize(struct swc_window * window,
const struct swc_window_impl * impl,
struct swc_surface * surface);
-struct swc_window * swc_window_get(struct swc_surface * surface);
+void swc_window_finalize(struct swc_window * window);
void swc_window_set_title(struct swc_window * window,
const char * title, size_t length);