desktop-shell: destroy data before exiting.
desktop-shell never returned from display_run() since it was essentially killed when weston exited. To fix this, it is necessary to watch for EPOLLHUP in window.c so that toytoolkit clients will return from display_run() when weston quits. This allows for clients to clean up as needed. Signed-off-by: U. Artie Eoff <ullysses.a.eoff@intel.com>
This commit is contained in:
committed by
Kristian Høgsberg
parent
371805f76e
commit
44874d9f02
@@ -371,6 +371,16 @@ clock_timer_reset(struct panel_clock *clock)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
panel_destroy_clock(struct panel_clock *clock)
|
||||||
|
{
|
||||||
|
widget_destroy(clock->widget);
|
||||||
|
|
||||||
|
close(clock->clock_fd);
|
||||||
|
|
||||||
|
free(clock);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
panel_add_clock(struct panel *panel)
|
panel_add_clock(struct panel *panel)
|
||||||
{
|
{
|
||||||
@@ -447,6 +457,39 @@ panel_configure(void *data,
|
|||||||
window_schedule_resize(panel->window, width, 32);
|
window_schedule_resize(panel->window, width, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
panel_destroy_launcher(struct panel_launcher *launcher)
|
||||||
|
{
|
||||||
|
wl_array_release(&launcher->argv);
|
||||||
|
wl_array_release(&launcher->envp);
|
||||||
|
|
||||||
|
free(launcher->path);
|
||||||
|
|
||||||
|
cairo_surface_destroy(launcher->icon);
|
||||||
|
|
||||||
|
widget_destroy(launcher->widget);
|
||||||
|
wl_list_remove(&launcher->link);
|
||||||
|
|
||||||
|
free(launcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
panel_destroy(struct panel *panel)
|
||||||
|
{
|
||||||
|
struct panel_launcher *tmp;
|
||||||
|
struct panel_launcher *launcher;
|
||||||
|
|
||||||
|
panel_destroy_clock(panel->clock);
|
||||||
|
|
||||||
|
wl_list_for_each_safe(launcher, tmp, &panel->launcher_list, link)
|
||||||
|
panel_destroy_launcher(launcher);
|
||||||
|
|
||||||
|
widget_destroy(panel->widget);
|
||||||
|
window_destroy(panel->window);
|
||||||
|
|
||||||
|
free(panel);
|
||||||
|
}
|
||||||
|
|
||||||
static struct panel *
|
static struct panel *
|
||||||
panel_create(struct display *display)
|
panel_create(struct display *display)
|
||||||
{
|
{
|
||||||
@@ -885,6 +928,15 @@ static const struct desktop_shell_listener listener = {
|
|||||||
desktop_shell_grab_cursor
|
desktop_shell_grab_cursor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
background_destroy(struct background *background)
|
||||||
|
{
|
||||||
|
widget_destroy(background->widget);
|
||||||
|
window_destroy(background->window);
|
||||||
|
|
||||||
|
free(background);
|
||||||
|
}
|
||||||
|
|
||||||
static struct background *
|
static struct background *
|
||||||
background_create(struct desktop *desktop)
|
background_create(struct desktop *desktop)
|
||||||
{
|
{
|
||||||
@@ -911,6 +963,13 @@ grab_surface_enter_handler(struct widget *widget, struct input *input,
|
|||||||
return desktop->grab_cursor;
|
return desktop->grab_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grab_surface_destroy(struct desktop *desktop)
|
||||||
|
{
|
||||||
|
widget_destroy(desktop->grab_widget);
|
||||||
|
window_destroy(desktop->grab_window);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grab_surface_create(struct desktop *desktop)
|
grab_surface_create(struct desktop *desktop)
|
||||||
{
|
{
|
||||||
@@ -932,6 +991,27 @@ grab_surface_create(struct desktop *desktop)
|
|||||||
grab_surface_enter_handler);
|
grab_surface_enter_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
output_destroy(struct output *output)
|
||||||
|
{
|
||||||
|
background_destroy(output->background);
|
||||||
|
panel_destroy(output->panel);
|
||||||
|
wl_output_destroy(output->output);
|
||||||
|
wl_list_remove(&output->link);
|
||||||
|
|
||||||
|
free(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
desktop_destroy_outputs(struct desktop *desktop)
|
||||||
|
{
|
||||||
|
struct output *tmp;
|
||||||
|
struct output *output;
|
||||||
|
|
||||||
|
wl_list_for_each_safe(output, tmp, &desktop->outputs, link)
|
||||||
|
output_destroy(output);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_output(struct desktop *desktop, uint32_t id)
|
create_output(struct desktop *desktop, uint32_t id)
|
||||||
{
|
{
|
||||||
@@ -1043,5 +1123,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
display_run(desktop.display);
|
display_run(desktop.display);
|
||||||
|
|
||||||
|
/* Cleanup */
|
||||||
|
grab_surface_destroy(&desktop);
|
||||||
|
desktop_destroy_outputs(&desktop);
|
||||||
|
if (desktop.unlock_dialog)
|
||||||
|
unlock_dialog_destroy(desktop.unlock_dialog);
|
||||||
|
desktop_shell_destroy(desktop.shell);
|
||||||
|
display_destroy(desktop.display);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-3
@@ -84,6 +84,7 @@ struct display {
|
|||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
|
|
||||||
int display_fd;
|
int display_fd;
|
||||||
|
uint32_t display_fd_events;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
struct task display_task;
|
struct task display_task;
|
||||||
|
|
||||||
@@ -3728,6 +3729,13 @@ handle_display_data(struct task *task, uint32_t events)
|
|||||||
struct display *display =
|
struct display *display =
|
||||||
container_of(task, struct display, display_task);
|
container_of(task, struct display, display_task);
|
||||||
|
|
||||||
|
display->display_fd_events = events;
|
||||||
|
|
||||||
|
if (events & EPOLLERR || events & EPOLLHUP) {
|
||||||
|
display_exit(display);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wl_display_iterate(display->display, display->mask);
|
wl_display_iterate(display->display, display->mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3751,7 +3759,8 @@ display_create(int argc, char *argv[])
|
|||||||
d->epoll_fd = os_epoll_create_cloexec();
|
d->epoll_fd = os_epoll_create_cloexec();
|
||||||
d->display_fd = wl_display_get_fd(d->display, event_mask_update, d);
|
d->display_fd = wl_display_get_fd(d->display, event_mask_update, d);
|
||||||
d->display_task.run = handle_display_data;
|
d->display_task.run = handle_display_data;
|
||||||
display_watch_fd(d, d->display_fd, EPOLLIN, &d->display_task);
|
display_watch_fd(d, d->display_fd, EPOLLIN | EPOLLERR | EPOLLHUP,
|
||||||
|
&d->display_task);
|
||||||
|
|
||||||
wl_list_init(&d->deferred_list);
|
wl_list_init(&d->deferred_list);
|
||||||
wl_list_init(&d->input_list);
|
wl_list_init(&d->input_list);
|
||||||
@@ -3815,7 +3824,8 @@ void
|
|||||||
display_destroy(struct display *display)
|
display_destroy(struct display *display)
|
||||||
{
|
{
|
||||||
if (!wl_list_empty(&display->window_list))
|
if (!wl_list_empty(&display->window_list))
|
||||||
fprintf(stderr, "toytoolkit warning: windows exist.\n");
|
fprintf(stderr, "toytoolkit warning: %d windows exist.\n",
|
||||||
|
wl_list_length(&display->window_list));
|
||||||
|
|
||||||
if (!wl_list_empty(&display->deferred_list))
|
if (!wl_list_empty(&display->deferred_list))
|
||||||
fprintf(stderr, "toytoolkit warning: deferred tasks exist.\n");
|
fprintf(stderr, "toytoolkit warning: deferred tasks exist.\n");
|
||||||
@@ -3845,7 +3855,10 @@ display_destroy(struct display *display)
|
|||||||
|
|
||||||
close(display->epoll_fd);
|
close(display->epoll_fd);
|
||||||
|
|
||||||
wl_display_flush(display->display);
|
if (!(display->display_fd_events & EPOLLERR) &&
|
||||||
|
!(display->display_fd_events & EPOLLHUP))
|
||||||
|
wl_display_flush(display->display);
|
||||||
|
|
||||||
wl_display_disconnect(display->display);
|
wl_display_disconnect(display->display);
|
||||||
free(display);
|
free(display);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user