From 0790e3978a771328b276cf5ee73fcf31a41fa051 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 9 Dec 2013 14:58:00 -0500 Subject: [PATCH] westoy: Port the toy toolkit over to xdg-shell --- Makefile.am | 9 +- clients/.gitignore | 2 + clients/window.c | 338 +++++++++++++++++++++++---------------------- 3 files changed, 180 insertions(+), 169 deletions(-) diff --git a/Makefile.am b/Makefile.am index e9d897645..603216435 100644 --- a/Makefile.am +++ b/Makefile.am @@ -424,7 +424,10 @@ libtoytoolkit_la_SOURCES = \ clients/scaler-protocol.c \ clients/scaler-client-protocol.h \ clients/workspaces-protocol.c \ - clients/workspaces-client-protocol.h + clients/workspaces-client-protocol.h \ + clients/xdg-shell-protocol.c \ + clients/xdg-shell-client-protocol.h + libtoytoolkit_la_LIBADD = \ $(CLIENT_LIBS) \ @@ -596,7 +599,9 @@ BUILT_SOURCES += \ clients/scaler-client-protocol.h \ clients/scaler-protocol.c \ clients/workspaces-client-protocol.h \ - clients/workspaces-protocol.c + clients/workspaces-protocol.c \ + clients/xdg-shell-protocol.c \ + clients/xdg-shell-client-protocol.h westondatadir = $(datadir)/weston diff --git a/clients/.gitignore b/clients/.gitignore index d23027ce5..4112bbc0d 100644 --- a/clients/.gitignore +++ b/clients/.gitignore @@ -47,3 +47,5 @@ weston-multi-resource workspaces-client-protocol.h workspaces-protocol.c weston-simple-im +xdg-shell-client-protocol.h +xdg-shell-protocol.c diff --git a/clients/window.c b/clients/window.c index 5934447c3..5a1ccbc4a 100644 --- a/clients/window.c +++ b/clients/window.c @@ -65,6 +65,7 @@ typedef void *EGLContext; #include #include #include "../shared/cairo-util.h" +#include "xdg-shell-client-protocol.h" #include "text-cursor-position-client-protocol.h" #include "workspaces-client-protocol.h" #include "../shared/os-compatibility.h" @@ -85,11 +86,11 @@ struct display { struct wl_registry *registry; struct wl_compositor *compositor; struct wl_subcompositor *subcompositor; - struct wl_shell *shell; struct wl_shm *shm; struct wl_data_device_manager *data_device_manager; struct text_cursor_position *text_cursor_position; struct workspace_manager *workspace_manager; + struct xdg_shell *xdg_shell; EGLDisplay dpy; EGLConfig argb_config; EGLContext argb_ctx; @@ -134,13 +135,6 @@ struct display { int seat_version; }; -enum { - TYPE_NONE, - TYPE_TOPLEVEL, - TYPE_MENU, - TYPE_CUSTOM -}; - struct window_output { struct output *output; struct wl_list link; @@ -229,11 +223,10 @@ struct window { int redraw_task_scheduled; struct task redraw_task; int resize_needed; - int type; - int focus_count; + int custom; + int focused; int resizing; - int configure_requests; int fullscreen; int maximized; @@ -249,7 +242,8 @@ struct window { window_output_handler_t output_handler; struct surface *main_surface; - struct wl_shell_surface *shell_surface; + struct xdg_surface *xdg_surface; + struct xdg_popup *xdg_popup; struct window_frame *frame; @@ -1364,28 +1358,7 @@ surface_flush(struct surface *surface) int window_has_focus(struct window *window) { - return window->focus_count > 0; -} - -static void -window_flush(struct window *window) -{ - struct surface *surface; - - if (window->type == TYPE_NONE) { - window->type = TYPE_TOPLEVEL; - if (window->shell_surface) - wl_shell_surface_set_toplevel(window->shell_surface); - } - - wl_list_for_each(surface, &window->subsurface_list, link) { - if (surface == window->main_surface) - continue; - - surface_flush(surface); - } - - surface_flush(window->main_surface); + return window->focused; } struct display * @@ -1549,8 +1522,10 @@ window_destroy(struct window *window) if (window->frame) window_frame_destroy(window->frame); - if (window->shell_surface) - wl_shell_surface_destroy(window->shell_surface); + if (window->xdg_surface) + xdg_surface_destroy(window->xdg_surface); + if (window->xdg_popup) + xdg_popup_destroy(window->xdg_popup); surface_destroy(window->main_surface); @@ -2230,7 +2205,7 @@ frame_redraw_handler(struct widget *widget, void *data) if (window->fullscreen) return; - if (window->focus_count) { + if (window->focused) { frame_set_flag(frame->frame, FRAME_FLAG_ACTIVE); } else { frame_unset_flag(frame->frame, FRAME_FLAG_ACTIVE); @@ -2249,7 +2224,7 @@ frame_get_pointer_image_for_location(struct window_frame *frame, { struct window *window = frame->widget->window; - if (window->type != TYPE_TOPLEVEL) + if (window->custom) return CURSOR_LEFT_PTR; switch (location) { @@ -2408,23 +2383,23 @@ frame_handle_status(struct window_frame *frame, struct input *input, return; } - if ((status & FRAME_STATUS_MOVE) && window->shell_surface) { + if ((status & FRAME_STATUS_MOVE) && window->xdg_surface) { input_ungrab(input); - wl_shell_surface_move(window->shell_surface, - input_get_seat(input), - window->display->serial); + xdg_surface_move(window->xdg_surface, + input_get_seat(input), + window->display->serial); frame_status_clear(frame->frame, FRAME_STATUS_MOVE); } - if ((status & FRAME_STATUS_RESIZE) && window->shell_surface) { + if ((status & FRAME_STATUS_RESIZE) && window->xdg_surface) { input_ungrab(input); window->resizing = 1; - wl_shell_surface_resize(window->shell_surface, - input_get_seat(input), - window->display->serial, - location); + xdg_surface_resize(window->xdg_surface, + input_get_seat(input), + window->display->serial, + location); frame_status_clear(frame->frame, FRAME_STATUS_RESIZE); } @@ -2472,7 +2447,7 @@ window_frame_create(struct window *window, void *data) struct window_frame *frame; uint32_t buttons; - if (window->type == TYPE_CUSTOM) { + if (window->custom) { buttons = FRAME_BUTTON_NONE; } else { buttons = FRAME_BUTTON_ALL; @@ -2784,7 +2759,6 @@ input_remove_keyboard_focus(struct input *input) if (!window) return; - window->focus_count--; if (window->keyboard_focus_handler) (*window->keyboard_focus_handler)(window, NULL, window->user_data); @@ -2883,7 +2857,6 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, input->keyboard_focus = wl_surface_get_user_data(surface); window = input->keyboard_focus; - window->focus_count++; if (window->keyboard_focus_handler) (*window->keyboard_focus_handler)(window, input, window->user_data); @@ -3656,10 +3629,10 @@ input_receive_selection_data_to_fd(struct input *input, void window_move(struct window *window, struct input *input, uint32_t serial) { - if (!window->shell_surface) + if (!window->xdg_surface) return; - wl_shell_surface_move(window->shell_surface, input->seat, serial); + xdg_surface_move(window->xdg_surface, input->seat, serial); } static void @@ -3868,22 +3841,104 @@ widget_schedule_resize(struct widget *widget, int32_t width, int32_t height) } static void -handle_ping(void *data, struct wl_shell_surface *shell_surface, - uint32_t serial) +handle_surface_ping(void *data, struct xdg_surface *xdg_surface, uint32_t serial) { - wl_shell_surface_pong(shell_surface, serial); + xdg_surface_pong(xdg_surface, serial); } static void -handle_configure(void *data, struct wl_shell_surface *shell_surface, - uint32_t edges, int32_t width, int32_t height) +handle_surface_configure(void *data, struct xdg_surface *xdg_surface, + uint32_t edges, int32_t width, int32_t height) { struct window *window = data; window->resize_edges = edges; + window_schedule_resize(window, width, height); } +static void +handle_surface_focused_set(void *data, struct xdg_surface *xdg_surface) +{ + struct window *window = data; + window->focused = 1; + window_schedule_redraw(window); +} + +static void +handle_surface_focused_unset(void *data, struct xdg_surface *xdg_surface) +{ + struct window *window = data; + window->focused = 0; + window_schedule_redraw(window); +} + +static void +handle_surface_request_set_maximized(void *data, struct xdg_surface *xdg_surface) +{ + struct window *window = data; + window_set_maximized(window, 1); +} + +static void +handle_surface_request_unset_maximized(void *data, struct xdg_surface *xdg_surface) +{ + struct window *window = data; + window_set_maximized(window, 0); +} + +static void +handle_surface_request_set_fullscreen(void *data, struct xdg_surface *xdg_surface) +{ + struct window *window = data; + window_set_fullscreen(window, 1); +} + +static void +handle_surface_request_unset_fullscreen(void *data, struct xdg_surface *xdg_surface) +{ + struct window *window = data; + window_set_fullscreen(window, 0); +} + +static const struct xdg_surface_listener xdg_surface_listener = { + handle_surface_ping, + handle_surface_configure, + handle_surface_request_set_maximized, + handle_surface_request_unset_maximized, + handle_surface_request_set_fullscreen, + handle_surface_request_unset_fullscreen, + handle_surface_focused_set, + handle_surface_focused_unset, +}; + +static void +window_flush(struct window *window) +{ + struct surface *surface; + + if (!window->custom) { + if (!window->xdg_popup && !window->xdg_surface) { + window->xdg_surface = xdg_shell_get_xdg_surface(window->display->xdg_shell, + window->main_surface->surface); + fail_on_null(window->xdg_surface); + + xdg_surface_set_user_data(window->xdg_surface, window); + xdg_surface_add_listener(window->xdg_surface, + &xdg_surface_listener, window); + } + } + + wl_list_for_each(surface, &window->subsurface_list, link) { + if (surface == window->main_surface) + continue; + + surface_flush(surface); + } + + surface_flush(window->main_surface); +} + static void menu_destroy(struct menu *menu) { @@ -3893,27 +3948,6 @@ menu_destroy(struct menu *menu) free(menu); } -static void -handle_popup_done(void *data, struct wl_shell_surface *shell_surface) -{ - struct window *window = data; - struct menu *menu = window->main_surface->widget->user_data; - - /* FIXME: Need more context in this event, at least the input - * device. Or just use wl_callback. And this really needs to - * be a window vfunc that the menu can set. And we need the - * time. */ - - input_ungrab(menu->input); - menu_destroy(menu); -} - -static const struct wl_shell_surface_listener shell_surface_listener = { - handle_ping, - handle_configure, - handle_popup_done -}; - void window_get_allocation(struct window *window, struct rectangle *allocation) @@ -4045,8 +4079,6 @@ idle_redraw(struct task *task, uint32_t events) static void window_schedule_redraw_task(struct window *window) { - if (window->configure_requests) - return; if (!window->redraw_task_scheduled) { window->redraw_task.run = idle_redraw; display_defer(window->display, &window->redraw_task); @@ -4073,69 +4105,20 @@ window_is_fullscreen(struct window *window) return window->fullscreen; } -static void -configure_request_completed(void *data, struct wl_callback *callback, uint32_t time) -{ - struct window *window = data; - - wl_callback_destroy(callback); - window->configure_requests--; - - if (!window->configure_requests) - window_schedule_redraw(window); -} - -static struct wl_callback_listener configure_request_listener = { - configure_request_completed, -}; - -static void -window_defer_redraw_until_configure(struct window* window) -{ - struct wl_callback *callback; - - if (window->redraw_task_scheduled) { - wl_list_remove(&window->redraw_task.link); - window->redraw_task_scheduled = 0; - } - - callback = wl_display_sync(window->display->display); - wl_callback_add_listener(callback, &configure_request_listener, window); - window->configure_requests++; -} - -static void -window_sync_type(struct window *window) -{ - if (window->fullscreen) { - window->saved_allocation = window->main_surface->allocation; - wl_shell_surface_set_fullscreen(window->shell_surface, - WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, - 0, NULL); - } else if (window->maximized) { - window->saved_allocation = window->main_surface->allocation; - wl_shell_surface_set_maximized(window->shell_surface, NULL); - } else { - wl_shell_surface_set_toplevel(window->shell_surface); - window_schedule_resize(window, - window->saved_allocation.width, - window->saved_allocation.height); - } - - window_defer_redraw_until_configure(window); -} - void window_set_fullscreen(struct window *window, int fullscreen) { - if (!window->display->shell) + if (!window->xdg_surface) return; if (window->fullscreen == fullscreen) return; window->fullscreen = fullscreen; - window_sync_type(window); + if (window->fullscreen) + xdg_surface_set_fullscreen(window->xdg_surface); + else + xdg_surface_unset_fullscreen(window->xdg_surface); } int @@ -4147,15 +4130,17 @@ window_is_maximized(struct window *window) void window_set_maximized(struct window *window, int maximized) { - if (!window->display->shell) + if (!window->xdg_surface) return; if (window->maximized == maximized) return; window->maximized = maximized; - if (!window->fullscreen) - window_sync_type(window); + if (window->maximized) + xdg_surface_set_maximized(window->xdg_surface); + else + xdg_surface_unset_maximized(window->xdg_surface); } void @@ -4226,8 +4211,8 @@ window_set_title(struct window *window, const char *title) frame_set_title(window->frame->frame, title); widget_schedule_redraw(window->frame->widget); } - if (window->shell_surface) - wl_shell_surface_set_title(window->shell_surface, title); + if (window->xdg_surface) + xdg_surface_set_title(window->xdg_surface, title); } const char * @@ -4340,7 +4325,7 @@ surface_create(struct window *window) } static struct window * -window_create_internal(struct display *display, int type) +window_create_internal(struct display *display, int custom) { struct window *window; struct surface *surface; @@ -4352,15 +4337,9 @@ window_create_internal(struct display *display, int type) surface = surface_create(window); window->main_surface = surface; - if (type != TYPE_CUSTOM && display->shell) { - window->shell_surface = - wl_shell_get_shell_surface(display->shell, - surface->surface); - fail_on_null(window->shell_surface); - } + fail_on_null(display->xdg_shell); - window->type = type; - window->configure_requests = 0; + window->custom = custom; window->preferred_format = WINDOW_PREFERRED_FORMAT_NONE; if (display->argb_device) @@ -4376,12 +4355,6 @@ window_create_internal(struct display *display, int type) wl_list_insert(display->window_list.prev, &window->link); wl_list_init(&window->redraw_task.link); - if (window->shell_surface) { - wl_shell_surface_set_user_data(window->shell_surface, window); - wl_shell_surface_add_listener(window->shell_surface, - &shell_surface_listener, window); - } - wl_list_init (&window->window_output_list); return window; @@ -4390,13 +4363,13 @@ window_create_internal(struct display *display, int type) struct window * window_create(struct display *display) { - return window_create_internal(display, TYPE_NONE); + return window_create_internal(display, 0); } struct window * window_create_custom(struct display *display) { - return window_create_internal(display, TYPE_CUSTOM); + return window_create_internal(display, 1); } static void @@ -4509,6 +4482,27 @@ menu_redraw_handler(struct widget *widget, void *data) cairo_destroy(cr); } +static void +handle_popup_ping(void *data, struct xdg_popup *xdg_popup, uint32_t serial) +{ + xdg_popup_pong(xdg_popup, serial); +} + +static void +handle_popup_popup_done(void *data, struct xdg_popup *xdg_popup, uint32_t serial) +{ + struct window *window = data; + struct menu *menu = window->main_surface->widget->user_data; + + input_ungrab(menu->input); + menu_destroy(menu); +} + +static const struct xdg_popup_listener xdg_popup_listener = { + handle_popup_ping, + handle_popup_popup_done, +}; + void window_show_menu(struct display *display, struct input *input, uint32_t time, struct window *parent, @@ -4523,7 +4517,7 @@ window_show_menu(struct display *display, if (!menu) return; - window = window_create_internal(parent->display, TYPE_MENU); + window = window_create_internal(parent->display, 0); if (!window) { free(menu); return; @@ -4544,7 +4538,6 @@ window_show_menu(struct display *display, menu->time = time; menu->func = func; menu->input = input; - window->type = TYPE_MENU; window->x = x; window->y = y; @@ -4563,10 +4556,20 @@ window_show_menu(struct display *display, frame_height(menu->frame)); frame_interior(menu->frame, &ix, &iy, NULL, NULL); - wl_shell_surface_set_popup(window->shell_surface, input->seat, - display_get_serial(window->display), - parent->main_surface->surface, - window->x - ix, window->y - iy, 0); + + window->xdg_popup = xdg_shell_get_xdg_popup(display->xdg_shell, + window->main_surface->surface, + parent->main_surface->surface, + input->seat, + display_get_serial(window->display), + window->x - ix, + window->y - iy, + 0); + fail_on_null(window->xdg_popup); + + xdg_popup_set_user_data(window->xdg_popup, window); + xdg_popup_add_listener(window->xdg_popup, + &xdg_popup_listener, window); } void @@ -4941,9 +4944,6 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, } else if (strcmp(interface, "wl_seat") == 0) { d->seat_version = version; display_add_input(d, id); - } else if (strcmp(interface, "wl_shell") == 0) { - d->shell = wl_registry_bind(registry, - id, &wl_shell_interface, 1); } else if (strcmp(interface, "wl_shm") == 0) { d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); wl_shm_add_listener(d->shm, &shm_listener, d); @@ -4951,6 +4951,10 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, d->data_device_manager = wl_registry_bind(registry, id, &wl_data_device_manager_interface, 1); + } else if (strcmp(interface, "xdg_shell") == 0) { + d->xdg_shell = wl_registry_bind(registry, id, + &xdg_shell_interface, 1); + xdg_shell_use_unstable_version(d->xdg_shell, XDG_SHELL_VERSION_CURRENT); } else if (strcmp(interface, "text_cursor_position") == 0) { d->text_cursor_position = wl_registry_bind(registry, id, @@ -5257,8 +5261,8 @@ display_destroy(struct display *display) if (display->subcompositor) wl_subcompositor_destroy(display->subcompositor); - if (display->shell) - wl_shell_destroy(display->shell); + if (display->xdg_shell) + xdg_shell_destroy(display->xdg_shell); if (display->shm) wl_shm_destroy(display->shm);