From: "Jasper St. Pierre" <jstpie...@mecheye.net> --- clients/.gitignore | 2 + clients/Makefile.am | 8 +- clients/window.c | 281 ++++++++++++++++++++++++++-------------------------- src/shell.c | 8 +- 4 files changed, 156 insertions(+), 143 deletions(-)
diff --git a/clients/.gitignore b/clients/.gitignore index 92e1659..4fef697 100644 --- a/clients/.gitignore +++ b/clients/.gitignore @@ -43,3 +43,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/Makefile.am b/clients/Makefile.am index 032d900..91174bf 100644 --- a/clients/Makefile.am +++ b/clients/Makefile.am @@ -98,7 +98,9 @@ libtoytoolkit_la_SOURCES = \ text-cursor-position-protocol.c \ text-cursor-position-client-protocol.h \ workspaces-protocol.c \ - workspaces-client-protocol.h + workspaces-client-protocol.h \ + xdg-shell-protocol.c \ + xdg-shell-client-protocol.h libtoytoolkit_la_LIBADD = \ $(CLIENT_LIBS) \ @@ -226,7 +228,9 @@ BUILT_SOURCES = \ tablet-shell-client-protocol.h \ tablet-shell-protocol.c \ workspaces-client-protocol.h \ - workspaces-protocol.c + workspaces-protocol.c \ + xdg-shell-protocol.c \ + xdg-shell-client-protocol.h CLEANFILES = $(BUILT_SOURCES) endif diff --git a/clients/window.c b/clients/window.c index 65ebed0..5cac1e1 100644 --- a/clients/window.c +++ b/clients/window.c @@ -65,6 +65,7 @@ typedef void *EGLContext; #include <linux/input.h> #include <wayland-client.h> #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,8 +223,8 @@ 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; @@ -249,7 +243,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; @@ -1355,28 +1350,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 * @@ -1540,8 +1514,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); @@ -2207,7 +2183,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); @@ -2226,7 +2202,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) { @@ -2385,23 +2361,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); } @@ -2754,7 +2730,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); @@ -2853,7 +2828,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); @@ -3604,10 +3578,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 @@ -3787,51 +3761,78 @@ 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 -menu_destroy(struct menu *menu) +handle_surface_focused_set(void *data, struct xdg_surface *xdg_surface) { - widget_destroy(menu->widget); - window_destroy(menu->window); - frame_destroy(menu->frame); - free(menu); + struct window *window = data; + window->focused = 1; } static void -handle_popup_done(void *data, struct wl_shell_surface *shell_surface) +handle_surface_focused_unset(void *data, struct xdg_surface *xdg_surface) { struct window *window = data; - struct menu *menu = window->main_surface->widget->user_data; + window->focused = 0; +} - /* 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. */ +static const struct xdg_surface_listener xdg_surface_listener = { + handle_surface_ping, + handle_surface_configure, + handle_surface_focused_set, + handle_surface_focused_unset, +}; - input_ungrab(menu->input); - menu_destroy(menu); +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 const struct wl_shell_surface_listener shell_surface_listener = { - handle_ping, - handle_configure, - handle_popup_done -}; +static void +menu_destroy(struct menu *menu) +{ + widget_destroy(menu->widget); + window_destroy(menu->window); + frame_destroy(menu->frame); + free(menu); +} void window_get_allocation(struct window *window, @@ -3965,19 +3966,19 @@ window_is_fullscreen(struct window *window) } static void -configure_request_completed(void *data, struct wl_callback *callback, uint32_t time) +configure_request_completed(void *data, struct wl_callback *callback, uint32_t time) { - struct window *window = data; + struct window *window = data; - wl_callback_destroy(callback); - window->configure_requests--; + wl_callback_destroy(callback); + window->configure_requests--; - if (!window->configure_requests) - window_schedule_redraw(window); + if (!window->configure_requests) + window_schedule_redraw(window); } static struct wl_callback_listener configure_request_listener = { - configure_request_completed, + configure_request_completed, }; static void @@ -3995,38 +3996,19 @@ window_defer_redraw_until_configure(struct window* 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; + if (fullscreen) + xdg_surface_set_fullscreen(window->xdg_surface); + else + xdg_surface_unset_fullscreen(window->xdg_surface); window->fullscreen = fullscreen; - window_sync_type(window); + window_defer_redraw_until_configure(window); } int @@ -4038,15 +4020,16 @@ 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; + if (maximized) + xdg_surface_set_maximized(window->xdg_surface); + else + xdg_surface_unset_maximized(window->xdg_surface); window->maximized = maximized; - if (!window->fullscreen) - window_sync_type(window); + window_defer_redraw_until_configure(window); } void @@ -4117,8 +4100,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 * @@ -4231,7 +4214,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; @@ -4243,15 +4226,10 @@ 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) @@ -4267,12 +4245,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; @@ -4281,13 +4253,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 @@ -4400,6 +4372,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, @@ -4414,7 +4407,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; @@ -4434,7 +4427,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; @@ -4453,10 +4445,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 @@ -4831,9 +4833,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); @@ -4841,6 +4840,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, @@ -5147,8 +5150,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); diff --git a/src/shell.c b/src/shell.c index db8e815..5d1dcd1 100644 --- a/src/shell.c +++ b/src/shell.c @@ -266,6 +266,7 @@ struct shell_surface { enum shell_surface_class_interface shell_class; enum shell_surface_type type, next_type; char *title, *class; + int32_t width, height; int32_t saved_x, saved_y; int32_t saved_width, saved_height; bool saved_position_valid; @@ -2122,8 +2123,8 @@ set_full_output(struct shell_surface *shsurf) { shsurf->saved_x = shsurf->view->geometry.x; shsurf->saved_y = shsurf->view->geometry.y; - shsurf->saved_width = shsurf->surface->width; - shsurf->saved_height = shsurf->surface->height; + shsurf->saved_width = shsurf->width; + shsurf->saved_height = shsurf->height; shsurf->saved_size_valid = true; shsurf->saved_position_valid = true; @@ -4910,6 +4911,9 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32 shsurf->view->geometry.y + to_y - from_y, width, height); } + + shsurf->width = width; + shsurf->height = height; } static void launch_desktop_shell_process(void *data); -- 1.8.3.1 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel