From 736632ad4ed349bd5aea0c2120977b745325672d Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 26 Apr 2019 11:06:45 -0400 Subject: [PATCH] Remove wlr_wl_shell --- include/rootston/desktop.h | 4 - include/rootston/view.h | 29 -- include/wlr/types/meson.build | 1 - include/wlr/types/wlr_wl_shell.h | 183 -------- rootston/desktop.c | 19 - rootston/meson.build | 1 - rootston/output.c | 1 - rootston/wl_shell.c | 312 ------------- types/meson.build | 1 - types/wlr_wl_shell.c | 736 ------------------------------- 10 files changed, 1287 deletions(-) delete mode 100644 include/wlr/types/wlr_wl_shell.h delete mode 100644 rootston/wl_shell.c delete mode 100644 types/wlr_wl_shell.c diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index fdd3abe0..bc582334 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -46,7 +45,6 @@ struct roots_desktop { struct wlr_xcursor_manager *xcursor_manager; struct wlr_compositor *compositor; - struct wlr_wl_shell *wl_shell; struct wlr_xdg_shell_v6 *xdg_shell_v6; struct wlr_xdg_shell *xdg_shell; struct wlr_gamma_control_manager *gamma_control_manager; @@ -76,7 +74,6 @@ struct roots_desktop { struct wl_listener layout_change; struct wl_listener xdg_shell_v6_surface; struct wl_listener xdg_shell_surface; - struct wl_listener wl_shell_surface; struct wl_listener layer_shell_surface; struct wl_listener xdg_toplevel_decoration; struct wl_listener input_inhibit_activate; @@ -107,7 +104,6 @@ struct wlr_surface *desktop_surface_at(struct roots_desktop *desktop, void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data); void handle_xdg_shell_surface(struct wl_listener *listener, void *data); void handle_xdg_toplevel_decoration(struct wl_listener *listener, void *data); -void handle_wl_shell_surface(struct wl_listener *listener, void *data); void handle_layer_shell_surface(struct wl_listener *listener, void *data); void handle_xwayland_surface(struct wl_listener *listener, void *data); diff --git a/include/rootston/view.h b/include/rootston/view.h index 531c615b..1a56de4b 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -26,7 +26,6 @@ struct roots_view_interface { }; enum roots_view_type { - ROOTS_WL_SHELL_VIEW, ROOTS_XDG_SHELL_V6_VIEW, ROOTS_XDG_SHELL_VIEW, #if WLR_HAS_XWAYLAND @@ -78,24 +77,6 @@ struct roots_view { } events; }; -struct roots_wl_shell_surface { - struct roots_view view; - - struct wlr_wl_shell_surface *wl_shell_surface; - - struct wl_listener destroy; - struct wl_listener new_popup; - struct wl_listener request_move; - struct wl_listener request_resize; - struct wl_listener request_maximize; - struct wl_listener request_fullscreen; - struct wl_listener set_state; - struct wl_listener set_title; - struct wl_listener set_class; - - struct wl_listener surface_commit; -}; - struct roots_xdg_surface_v6 { struct roots_view view; @@ -187,14 +168,6 @@ struct roots_subsurface { struct wl_listener unmap; }; -struct roots_wl_shell_popup { - struct roots_view_child view_child; - struct wlr_wl_shell_surface *wlr_wl_shell_surface; - struct wl_listener destroy; - struct wl_listener set_state; - struct wl_listener new_popup; -}; - struct roots_xdg_popup_v6 { struct roots_view_child view_child; struct wlr_xdg_popup_v6 *wlr_popup; @@ -255,8 +228,6 @@ void view_get_deco_box(const struct roots_view *view, struct wlr_box *box); void view_for_each_surface(struct roots_view *view, wlr_surface_iterator_func_t iterator, void *user_data); -struct roots_wl_shell_surface *roots_wl_shell_surface_from_view( - struct roots_view *view); struct roots_xdg_surface *roots_xdg_surface_from_view(struct roots_view *view); struct roots_xdg_surface_v6 *roots_xdg_surface_v6_from_view( struct roots_view *view); diff --git a/include/wlr/types/meson.build b/include/wlr/types/meson.build index fe82aeb5..c7e7bdbf 100644 --- a/include/wlr/types/meson.build +++ b/include/wlr/types/meson.build @@ -45,7 +45,6 @@ install_headers( 'wlr_text_input_v3.h', 'wlr_touch.h', 'wlr_virtual_keyboard_v1.h', - 'wlr_wl_shell.h', 'wlr_xcursor_manager.h', 'wlr_xdg_decoration_v1.h', 'wlr_xdg_output_v1.h', diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h deleted file mode 100644 index 67abc1b3..00000000 --- a/include/wlr/types/wlr_wl_shell.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * This protocol is obsolete and will be removed in a future version. The - * recommended replacement is xdg-shell. - */ - -/* - * This an unstable interface of wlroots. No guarantees are made regarding the - * future consistency of this API. - */ -#ifndef WLR_USE_UNSTABLE -#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features" -#endif - -#ifndef WLR_TYPES_WLR_WL_SHELL_H -#define WLR_TYPES_WLR_WL_SHELL_H - -#include -#include -#include - -/** - * A very basic interface to provide desktop-style user interfaces. - */ -struct wlr_wl_shell { - struct wl_global *global; - struct wl_list resources; - struct wl_list surfaces; - struct wl_list popup_grabs; - uint32_t ping_timeout; - - struct wl_listener display_destroy; - - struct { - struct wl_signal new_surface; - struct wl_signal destroy; - } events; - - void *data; -}; - -struct wlr_wl_shell_surface_transient_state { - int32_t x; - int32_t y; - enum wl_shell_surface_transient flags; -}; - -struct wlr_wl_shell_surface_popup_state { - struct wlr_seat *seat; - uint32_t serial; -}; - -// each seat gets a popup grab -struct wlr_wl_shell_popup_grab { - struct wl_client *client; - struct wlr_seat_pointer_grab pointer_grab; - struct wlr_seat *seat; - struct wl_list popups; - struct wl_list link; // wlr_wl_shell::popup_grabs -}; - -enum wlr_wl_shell_surface_state { - WLR_WL_SHELL_SURFACE_STATE_NONE, - WLR_WL_SHELL_SURFACE_STATE_TOPLEVEL, - WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED, - WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN, - WLR_WL_SHELL_SURFACE_STATE_TRANSIENT, - WLR_WL_SHELL_SURFACE_STATE_POPUP, -}; - -struct wlr_wl_shell_surface { - struct wlr_wl_shell *shell; - struct wl_client *client; - struct wl_resource *resource; - struct wlr_surface *surface; - bool configured; - struct wl_list link; // wlr_wl_shell::surfaces - - uint32_t ping_serial; - struct wl_event_source *ping_timer; - - enum wlr_wl_shell_surface_state state; - struct wlr_wl_shell_surface_transient_state *transient_state; - struct wlr_wl_shell_surface_popup_state *popup_state; - struct wl_list grab_link; // wlr_wl_shell_popup_grab::popups - - char *title; - char *class; - - struct wl_listener surface_destroy; - - struct wlr_wl_shell_surface *parent; - struct wl_list popup_link; - struct wl_list popups; - bool popup_mapped; - - struct { - struct wl_signal destroy; - struct wl_signal ping_timeout; - struct wl_signal new_popup; - - struct wl_signal request_move; - struct wl_signal request_resize; - struct wl_signal request_fullscreen; - struct wl_signal request_maximize; - - struct wl_signal set_state; - struct wl_signal set_title; - struct wl_signal set_class; - } events; - - void *data; -}; - -struct wlr_wl_shell_surface_move_event { - struct wlr_wl_shell_surface *surface; - struct wlr_seat_client *seat; - uint32_t serial; -}; - -struct wlr_wl_shell_surface_resize_event { - struct wlr_wl_shell_surface *surface; - struct wlr_seat_client *seat; - uint32_t serial; - enum wl_shell_surface_resize edges; -}; - -struct wlr_wl_shell_surface_set_fullscreen_event { - struct wlr_wl_shell_surface *surface; - enum wl_shell_surface_fullscreen_method method; - uint32_t framerate; - struct wlr_output *output; -}; - -struct wlr_wl_shell_surface_maximize_event { - struct wlr_wl_shell_surface *surface; - struct wlr_output *output; -}; - -/** - * Create a wl_shell for this display. - */ -struct wlr_wl_shell *wlr_wl_shell_create(struct wl_display *display); - -/** - * Destroy this surface. - */ -void wlr_wl_shell_destroy(struct wlr_wl_shell *wlr_wl_shell); - -/** - * Send a ping to the surface. If the surface does not respond with a pong - * within a reasonable amount of time, the ping timeout event will be emitted. - */ -void wlr_wl_shell_surface_ping(struct wlr_wl_shell_surface *surface); - -/** - * Request that the surface configure itself to be the given size. - */ -void wlr_wl_shell_surface_configure(struct wlr_wl_shell_surface *surface, - enum wl_shell_surface_resize edges, int32_t width, int32_t height); - -/** - * Find a surface within this wl-shell surface tree at the given surface-local - * coordinates. Returns the surface and coordinates in the leaf surface - * coordinate system or NULL if no surface is found at that location. - */ -struct wlr_surface *wlr_wl_shell_surface_surface_at( - struct wlr_wl_shell_surface *surface, double sx, double sy, - double *sub_sx, double *sub_sy); - -bool wlr_surface_is_wl_shell_surface(struct wlr_surface *surface); - -struct wlr_wl_shell_surface *wlr_wl_shell_surface_from_wlr_surface( - struct wlr_surface *surface); - -/** - * Call `iterator` on each surface in the shell surface tree, with the surface's - * position relative to the root xdg-surface. The function is called from root to - * leaves (in rendering order). - */ -void wlr_wl_shell_surface_for_each_surface(struct wlr_wl_shell_surface *surface, - wlr_surface_iterator_func_t iterator, void *user_data); - -#endif diff --git a/rootston/desktop.c b/rootston/desktop.c index 880849be..96063995 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -38,13 +37,6 @@ static bool view_at(struct roots_view *view, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { - if (view->type == ROOTS_WL_SHELL_VIEW) { - struct wlr_wl_shell_surface *wl_shell_surface = - roots_wl_shell_surface_from_view(view)->wl_shell_surface; - if (wl_shell_surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP) { - return false; - } - } if (view->wlr_surface == NULL) { return false; } @@ -69,12 +61,6 @@ static bool view_at(struct roots_view *view, double lx, double ly, _surface = wlr_xdg_surface_surface_at(xdg_surface->xdg_surface, view_sx, view_sy, &_sx, &_sy); break; - case ROOTS_WL_SHELL_VIEW:; - struct roots_wl_shell_surface *wl_shell_surface = - roots_wl_shell_surface_from_view(view); - _surface = wlr_wl_shell_surface_surface_at( - wl_shell_surface->wl_shell_surface, view_sx, view_sy, &_sx, &_sy); - break; #if WLR_HAS_XWAYLAND case ROOTS_XWAYLAND_VIEW: _surface = wlr_surface_surface_at(view->wlr_surface, @@ -330,11 +316,6 @@ struct roots_desktop *desktop_create(struct roots_server *server, &desktop->xdg_shell_surface); desktop->xdg_shell_surface.notify = handle_xdg_shell_surface; - desktop->wl_shell = wlr_wl_shell_create(server->wl_display); - wl_signal_add(&desktop->wl_shell->events.new_surface, - &desktop->wl_shell_surface); - desktop->wl_shell_surface.notify = handle_wl_shell_surface; - desktop->layer_shell = wlr_layer_shell_v1_create(server->wl_display); wl_signal_add(&desktop->layer_shell->events.new_surface, &desktop->layer_shell_surface); diff --git a/rootston/meson.build b/rootston/meson.build index c2f9a250..853fecc8 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -15,7 +15,6 @@ sources = [ 'text_input.c', 'view.c', 'virtual_keyboard.c', - 'wl_shell.c', 'xdg_shell_v6.c', 'xdg_shell.c', ] diff --git a/rootston/output.c b/rootston/output.c index 32300c9e..66a43694 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c deleted file mode 100644 index 1590378c..00000000 --- a/rootston/wl_shell.c +++ /dev/null @@ -1,312 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "rootston/desktop.h" -#include "rootston/input.h" -#include "rootston/server.h" - -static const struct roots_view_child_interface popup_impl; - -static void popup_destroy(struct roots_view_child *child) { - assert(child->impl == &popup_impl); - struct roots_wl_shell_popup *popup = (struct roots_wl_shell_popup *)child; - wl_list_remove(&popup->destroy.link); - wl_list_remove(&popup->set_state.link); - wl_list_remove(&popup->new_popup.link); - free(popup); -} - -static const struct roots_view_child_interface popup_impl = { - .destroy = popup_destroy, -}; - -static void popup_handle_destroy(struct wl_listener *listener, void *data) { - struct roots_wl_shell_popup *popup = - wl_container_of(listener, popup, destroy); - view_child_destroy(&popup->view_child); -} - -static void popup_handle_set_state(struct wl_listener *listener, void *data) { - struct roots_wl_shell_popup *popup = - wl_container_of(listener, popup, set_state); - view_child_destroy(&popup->view_child); -} - -static struct roots_wl_shell_popup *popup_create(struct roots_view *view, - struct wlr_wl_shell_surface *wlr_wl_shell_surface); - -static void popup_handle_new_popup(struct wl_listener *listener, void *data) { - struct roots_wl_shell_popup *popup = - wl_container_of(listener, popup, new_popup); - struct wlr_wl_shell_surface *wlr_wl_shell_surface = data; - popup_create(popup->view_child.view, wlr_wl_shell_surface); -} - -static struct roots_wl_shell_popup *popup_create(struct roots_view *view, - struct wlr_wl_shell_surface *wlr_wl_shell_surface) { - struct roots_wl_shell_popup *popup = - calloc(1, sizeof(struct roots_wl_shell_popup)); - if (popup == NULL) { - return NULL; - } - popup->wlr_wl_shell_surface = wlr_wl_shell_surface; - view_child_init(&popup->view_child, &popup_impl, - view, wlr_wl_shell_surface->surface); - popup->destroy.notify = popup_handle_destroy; - wl_signal_add(&wlr_wl_shell_surface->events.destroy, &popup->destroy); - popup->set_state.notify = popup_handle_set_state; - wl_signal_add(&wlr_wl_shell_surface->events.set_state, &popup->set_state); - popup->new_popup.notify = popup_handle_new_popup; - wl_signal_add(&wlr_wl_shell_surface->events.new_popup, &popup->new_popup); - return popup; -} - - -static void resize(struct roots_view *view, uint32_t width, uint32_t height) { - struct wlr_wl_shell_surface *surf = - roots_wl_shell_surface_from_view(view)->wl_shell_surface; - wlr_wl_shell_surface_configure(surf, WL_SHELL_SURFACE_RESIZE_NONE, width, - height); -} - -static void close(struct roots_view *view) { - struct wlr_wl_shell_surface *surf = - roots_wl_shell_surface_from_view(view)->wl_shell_surface; - wl_client_destroy(surf->client); -} - -static void for_each_surface(struct roots_view *view, - wlr_surface_iterator_func_t iterator, void *user_data) { - struct wlr_wl_shell_surface *surf = - roots_wl_shell_surface_from_view(view)->wl_shell_surface; - wlr_wl_shell_surface_for_each_surface(surf, iterator, user_data); -} - -static void destroy(struct roots_view *view) { - struct roots_wl_shell_surface *roots_surface = - roots_wl_shell_surface_from_view(view); - wl_list_remove(&roots_surface->destroy.link); - wl_list_remove(&roots_surface->request_move.link); - wl_list_remove(&roots_surface->request_resize.link); - wl_list_remove(&roots_surface->request_maximize.link); - wl_list_remove(&roots_surface->request_fullscreen.link); - wl_list_remove(&roots_surface->set_state.link); - wl_list_remove(&roots_surface->set_title.link); - wl_list_remove(&roots_surface->set_class.link); - wl_list_remove(&roots_surface->surface_commit.link); - free(roots_surface); -} - -static const struct roots_view_interface view_impl = { - .resize = resize, - .close = close, - .for_each_surface = for_each_surface, - .destroy = destroy, -}; - -static void handle_request_move(struct wl_listener *listener, void *data) { - struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, request_move); - struct roots_view *view = &roots_surface->view; - struct roots_input *input = view->desktop->server->input; - struct wlr_wl_shell_surface_move_event *e = data; - struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); - if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { - return; - } - roots_seat_begin_move(seat, view); -} - -static void handle_request_resize(struct wl_listener *listener, void *data) { - struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, request_resize); - struct roots_view *view = &roots_surface->view; - struct roots_input *input = view->desktop->server->input; - struct wlr_wl_shell_surface_resize_event *e = data; - struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); - if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { - return; - } - roots_seat_begin_resize(seat, view, e->edges); -} - -static void handle_request_maximize(struct wl_listener *listener, - void *data) { - struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, request_maximize); - struct roots_view *view = &roots_surface->view; - //struct wlr_wl_shell_surface_maximize_event *e = data; - view_maximize(view, true); -} - -static void handle_request_fullscreen(struct wl_listener *listener, - void *data) { - struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, request_fullscreen); - struct roots_view *view = &roots_surface->view; - struct wlr_wl_shell_surface_set_fullscreen_event *e = data; - view_set_fullscreen(view, true, e->output); -} - -static void handle_set_state(struct wl_listener *listener, void *data) { - struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, set_state); - struct roots_view *view = &roots_surface->view; - struct wlr_wl_shell_surface *surface = roots_surface->wl_shell_surface; - if (view->maximized && - surface->state != WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED) { - view_maximize(view, false); - } - if (view->fullscreen_output != NULL && - surface->state != WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN) { - view_set_fullscreen(view, false, NULL); - } -} - -static void handle_set_title(struct wl_listener *listener, void *data) { - struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, set_state); - view_set_title(&roots_surface->view, - roots_surface->wl_shell_surface->title); -} - -static void handle_set_class(struct wl_listener *listener, void *data) { - struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, set_state); - view_set_app_id(&roots_surface->view, - roots_surface->wl_shell_surface->class); -} - -static void handle_surface_commit(struct wl_listener *listener, void *data) { - struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, surface_commit); - struct roots_view *view = &roots_surface->view; - struct wlr_surface *wlr_surface = view->wlr_surface; - - view_apply_damage(view); - - int width = wlr_surface->current.width; - int height = wlr_surface->current.height; - view_update_size(view, width, height); - - double x = view->box.x; - double y = view->box.y; - if (view->pending_move_resize.update_x) { - x = view->pending_move_resize.x + view->pending_move_resize.width - - width; - view->pending_move_resize.update_x = false; - } - if (view->pending_move_resize.update_y) { - y = view->pending_move_resize.y + view->pending_move_resize.height - - height; - view->pending_move_resize.update_y = false; - } - view_update_position(view, x, y); -} - -static void handle_new_popup(struct wl_listener *listener, void *data) { - struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, new_popup); - struct wlr_wl_shell_surface *wlr_wl_shell_surface = data; - popup_create(&roots_surface->view, wlr_wl_shell_surface); -} - -static void handle_destroy(struct wl_listener *listener, void *data) { - struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, destroy); - view_destroy(&roots_surface->view); -} - -void handle_wl_shell_surface(struct wl_listener *listener, void *data) { - struct roots_desktop *desktop = - wl_container_of(listener, desktop, wl_shell_surface); - struct wlr_wl_shell_surface *surface = data; - - if (surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP) { - wlr_log(WLR_DEBUG, "new wl shell popup"); - return; - } - - wlr_log(WLR_DEBUG, "new wl shell surface: title=%s, class=%s", - surface->title, surface->class); - wlr_wl_shell_surface_ping(surface); - - struct roots_wl_shell_surface *roots_surface = - calloc(1, sizeof(struct roots_wl_shell_surface)); - if (!roots_surface) { - return; - } - - view_init(&roots_surface->view, &view_impl, ROOTS_WL_SHELL_VIEW, desktop); - roots_surface->view.box.width = surface->surface->current.width; - roots_surface->view.box.height = surface->surface->current.height; - roots_surface->wl_shell_surface = surface; - - roots_surface->destroy.notify = handle_destroy; - wl_signal_add(&surface->events.destroy, &roots_surface->destroy); - roots_surface->new_popup.notify = handle_new_popup; - wl_signal_add(&surface->events.new_popup, &roots_surface->new_popup); - roots_surface->request_move.notify = handle_request_move; - wl_signal_add(&surface->events.request_move, &roots_surface->request_move); - roots_surface->request_resize.notify = handle_request_resize; - wl_signal_add(&surface->events.request_resize, - &roots_surface->request_resize); - roots_surface->request_maximize.notify = handle_request_maximize; - wl_signal_add(&surface->events.request_maximize, - &roots_surface->request_maximize); - roots_surface->request_fullscreen.notify = - handle_request_fullscreen; - wl_signal_add(&surface->events.request_fullscreen, - &roots_surface->request_fullscreen); - - roots_surface->set_state.notify = handle_set_state; - wl_signal_add(&surface->events.set_state, &roots_surface->set_state); - roots_surface->set_title.notify = handle_set_title; - wl_signal_add(&surface->events.set_title, &roots_surface->set_title); - roots_surface->set_class.notify = handle_set_class; - wl_signal_add(&surface->events.set_class, &roots_surface->set_class); - roots_surface->surface_commit.notify = handle_surface_commit; - wl_signal_add(&surface->surface->events.commit, &roots_surface->surface_commit); - - view_map(&roots_surface->view, surface->surface); - view_setup(&roots_surface->view); - - wlr_foreign_toplevel_handle_v1_set_title(roots_surface->view.toplevel_handle, - surface->title ?: "none"); - wlr_foreign_toplevel_handle_v1_set_app_id(roots_surface->view.toplevel_handle, - surface->class ?: "none"); - - if (surface->state == WLR_WL_SHELL_SURFACE_STATE_TRANSIENT) { - // We need to map it relative to the parent - bool found = false; - struct roots_view *parent; - wl_list_for_each(parent, &desktop->views, link) { - if (parent->type != ROOTS_WL_SHELL_VIEW) { - continue; - } - - struct roots_wl_shell_surface *parent_surf = - roots_wl_shell_surface_from_view(parent); - if (parent_surf->wl_shell_surface == surface->parent) { - found = true; - break; - } - } - if (found) { - view_move(&roots_surface->view, - parent->box.x + surface->transient_state->x, - parent->box.y + surface->transient_state->y); - } - } -} - -struct roots_wl_shell_surface *roots_wl_shell_surface_from_view( - struct roots_view *view) { - assert(view->impl == &view_impl); - return (struct roots_wl_shell_surface *)view; -} diff --git a/types/meson.build b/types/meson.build index d507a1ca..72d3f84a 100644 --- a/types/meson.build +++ b/types/meson.build @@ -66,7 +66,6 @@ lib_wlr_types = static_library( 'wlr_text_input_v3.c', 'wlr_touch.c', 'wlr_virtual_keyboard_v1.c', - 'wlr_wl_shell.c', 'wlr_xcursor_manager.c', 'wlr_xdg_decoration_v1.c', 'wlr_xdg_output_v1.c', diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c deleted file mode 100644 index e0514708..00000000 --- a/types/wlr_wl_shell.c +++ /dev/null @@ -1,736 +0,0 @@ -#ifndef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 200809L -#endif -#include -#include -#include -#include -#include -#include -#include -#include "util/signal.h" - -static const struct wlr_surface_role shell_surface_role; - -bool wlr_surface_is_wl_shell_surface(struct wlr_surface *surface) { - return surface->role == &shell_surface_role; -} - -struct wlr_wl_shell_surface *wlr_wl_shell_surface_from_wlr_surface( - struct wlr_surface *surface) { - assert(wlr_surface_is_wl_shell_surface(surface)); - return (struct wlr_wl_shell_surface *)surface->role_data; -} - -static void shell_pointer_grab_end(struct wlr_seat_pointer_grab *grab) { - struct wlr_wl_shell_popup_grab *popup_grab = grab->data; - - struct wlr_wl_shell_surface *popup, *tmp = NULL; - wl_list_for_each_safe(popup, tmp, &popup_grab->popups, grab_link) { - if (popup->popup_mapped) { - wl_shell_surface_send_popup_done(popup->resource); - popup->popup_mapped = false; - } - } - - if (grab->seat->pointer_state.grab == grab) { - wlr_seat_pointer_end_grab(grab->seat); - } -} - -static void shell_pointer_grab_maybe_end(struct wlr_seat_pointer_grab *grab) { - struct wlr_wl_shell_popup_grab *popup_grab = grab->data; - - if (grab->seat->pointer_state.grab != grab) { - return; - } - - bool has_mapped = false; - - struct wlr_wl_shell_surface *popup, *tmp = NULL; - wl_list_for_each_safe(popup, tmp, &popup_grab->popups, grab_link) { - if (popup->popup_mapped) { - has_mapped = true; - break; - } - } - - if (!has_mapped) { - shell_pointer_grab_end(grab); - } -} - -static void shell_pointer_grab_enter(struct wlr_seat_pointer_grab *grab, - struct wlr_surface *surface, double sx, double sy) { - struct wlr_wl_shell_popup_grab *popup_grab = grab->data; - if (wl_resource_get_client(surface->resource) == popup_grab->client) { - wlr_seat_pointer_enter(grab->seat, surface, sx, sy); - } else { - wlr_seat_pointer_clear_focus(grab->seat); - } -} - -static void shell_pointer_grab_motion(struct wlr_seat_pointer_grab *grab, - uint32_t time, double sx, double sy) { - wlr_seat_pointer_send_motion(grab->seat, time, sx, sy); -} - -static uint32_t shell_pointer_grab_button(struct wlr_seat_pointer_grab *grab, - uint32_t time, uint32_t button, uint32_t state) { - uint32_t serial = - wlr_seat_pointer_send_button(grab->seat, time, button, state); - if (serial) { - return serial; - } else { - shell_pointer_grab_end(grab); - return 0; - } -} - -static void shell_pointer_grab_cancel(struct wlr_seat_pointer_grab *grab) { - shell_pointer_grab_end(grab); -} - -static void shell_pointer_grab_axis(struct wlr_seat_pointer_grab *grab, - uint32_t time, enum wlr_axis_orientation orientation, double value, - int32_t value_discrete, enum wlr_axis_source source) { - wlr_seat_pointer_send_axis(grab->seat, time, orientation, value, - value_discrete, source); -} - -static void shell_pointer_grab_frame(struct wlr_seat_pointer_grab *grab) { - wlr_seat_pointer_send_frame(grab->seat); -} - -static const struct wlr_pointer_grab_interface shell_pointer_grab_impl = { - .enter = shell_pointer_grab_enter, - .motion = shell_pointer_grab_motion, - .button = shell_pointer_grab_button, - .cancel = shell_pointer_grab_cancel, - .axis = shell_pointer_grab_axis, - .frame = shell_pointer_grab_frame, -}; - -static const struct wl_shell_surface_interface shell_surface_impl; - -static struct wlr_wl_shell_surface *shell_surface_from_resource( - struct wl_resource *resource) { - assert(wl_resource_instance_of(resource, &wl_shell_surface_interface, - &shell_surface_impl)); - return wl_resource_get_user_data(resource); -} - -static void shell_surface_protocol_pong(struct wl_client *client, - struct wl_resource *resource, uint32_t serial) { - wlr_log(WLR_DEBUG, "got shell surface pong"); - struct wlr_wl_shell_surface *surface = shell_surface_from_resource(resource); - if (surface->ping_serial != serial) { - return; - } - - wl_event_source_timer_update(surface->ping_timer, 0); - surface->ping_serial = 0; -} - -static void shell_surface_protocol_move(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *seat_resource, - uint32_t serial) { - struct wlr_wl_shell_surface *surface = shell_surface_from_resource(resource); - struct wlr_seat_client *seat = wlr_seat_client_from_resource(seat_resource); - - if (!wlr_seat_validate_grab_serial(seat->seat, serial)) { - wlr_log(WLR_DEBUG, "invalid serial for grab"); - return; - } - - struct wlr_wl_shell_surface_move_event event = { - .surface = surface, - .seat = seat, - .serial = serial, - }; - - wlr_signal_emit_safe(&surface->events.request_move, &event); -} - -static struct wlr_wl_shell_popup_grab *shell_popup_grab_from_seat( - struct wlr_wl_shell *shell, struct wlr_seat *seat) { - struct wlr_wl_shell_popup_grab *shell_grab; - wl_list_for_each(shell_grab, &shell->popup_grabs, link) { - if (shell_grab->seat == seat) { - return shell_grab; - } - } - - shell_grab = calloc(1, sizeof(struct wlr_wl_shell_popup_grab)); - if (!shell_grab) { - return NULL; - } - - shell_grab->pointer_grab.data = shell_grab; - shell_grab->pointer_grab.interface = &shell_pointer_grab_impl; - - wl_list_init(&shell_grab->popups); - - wl_list_insert(&shell->popup_grabs, &shell_grab->link); - shell_grab->seat = seat; - - return shell_grab; -} - -static void shell_surface_destroy_popup_state( - struct wlr_wl_shell_surface *surface) { - if (surface->popup_state) { - wl_list_remove(&surface->grab_link); - struct wlr_wl_shell_popup_grab *grab = - shell_popup_grab_from_seat(surface->shell, - surface->popup_state->seat); - if (wl_list_empty(&grab->popups)) { - if (grab->seat->pointer_state.grab == &grab->pointer_grab) { - wlr_seat_pointer_end_grab(grab->seat); - } - } - free(surface->popup_state); - surface->popup_state = NULL; - } -} - -static void shell_surface_protocol_resize(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *seat_resource, - uint32_t serial, enum wl_shell_surface_resize edges) { - struct wlr_wl_shell_surface *surface = shell_surface_from_resource(resource); - struct wlr_seat_client *seat = wlr_seat_client_from_resource(seat_resource); - - if (!wlr_seat_validate_grab_serial(seat->seat, serial)) { - wlr_log(WLR_DEBUG, "invalid serial for grab"); - return; - } - - struct wlr_wl_shell_surface_resize_event event = { - .surface = surface, - .seat = seat, - .serial = serial, - .edges = edges, - }; - - wlr_signal_emit_safe(&surface->events.request_resize, &event); -} - -static void shell_surface_set_state(struct wlr_wl_shell_surface *surface, - enum wlr_wl_shell_surface_state state, - struct wlr_wl_shell_surface_transient_state *transient_state, - struct wlr_wl_shell_surface_popup_state *popup_state) { - surface->state = state; - free(surface->transient_state); - surface->transient_state = transient_state; - shell_surface_destroy_popup_state(surface); - surface->popup_state = popup_state; - - wlr_signal_emit_safe(&surface->events.set_state, surface); -} - -static void shell_surface_protocol_set_toplevel(struct wl_client *client, - struct wl_resource *resource) { - wlr_log(WLR_DEBUG, "got shell surface toplevel"); - struct wlr_wl_shell_surface *surface = shell_surface_from_resource(resource); - shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_TOPLEVEL, NULL, - NULL); -} - -static void shell_surface_popup_set_parent(struct wlr_wl_shell_surface *surface, - struct wlr_wl_shell_surface *parent) { - assert(surface && surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP); - if (surface->parent == parent) { - return; - } - surface->parent = parent; - if (parent) { - wl_list_remove(&surface->popup_link); - wl_list_insert(&parent->popups, &surface->popup_link); - wlr_signal_emit_safe(&parent->events.new_popup, surface); - } -} - -static struct wlr_wl_shell_surface *shell_find_shell_surface( - struct wlr_wl_shell *shell, struct wlr_surface *surface) { - if (surface) { - struct wlr_wl_shell_surface *wl_surface; - wl_list_for_each(wl_surface, &shell->surfaces, link) { - if (wl_surface->surface == surface) { - return wl_surface; - } - } - } - return NULL; -} - -static void shell_surface_protocol_set_transient(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *parent_resource, - int32_t x, int32_t y, enum wl_shell_surface_transient flags) { - wlr_log(WLR_DEBUG, "got shell surface transient"); - struct wlr_wl_shell_surface *surface = shell_surface_from_resource(resource); - struct wlr_surface *parent = wlr_surface_from_resource(parent_resource); - // TODO: check if parent_resource == NULL? - - struct wlr_wl_shell_surface *wl_parent = - shell_find_shell_surface(surface->shell, parent); - - if (!wl_parent) { - return; - } - - struct wlr_wl_shell_surface_transient_state *transient_state = - calloc(1, sizeof(struct wlr_wl_shell_surface_transient_state)); - if (transient_state == NULL) { - wl_client_post_no_memory(client); - return; - } - - surface->parent = wl_parent; - transient_state->x = x; - transient_state->y = y; - transient_state->flags = flags; - - shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_TRANSIENT, - transient_state, NULL); -} - -static void shell_surface_protocol_set_fullscreen(struct wl_client *client, - struct wl_resource *resource, - enum wl_shell_surface_fullscreen_method method, uint32_t framerate, - struct wl_resource *output_resource) { - struct wlr_wl_shell_surface *surface = shell_surface_from_resource(resource); - struct wlr_output *output = NULL; - if (output_resource != NULL) { - output = wlr_output_from_resource(output_resource); - } - - shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN, - NULL, NULL); - - struct wlr_wl_shell_surface_set_fullscreen_event event = { - .surface = surface, - .method = method, - .framerate = framerate, - .output = output, - }; - - wlr_signal_emit_safe(&surface->events.request_fullscreen, &event); -} - -static void shell_surface_protocol_set_popup(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *seat_resource, - uint32_t serial, struct wl_resource *parent_resource, int32_t x, - int32_t y, enum wl_shell_surface_transient flags) { - struct wlr_wl_shell_surface *surface = shell_surface_from_resource(resource); - struct wlr_seat_client *seat_client = - wlr_seat_client_from_resource(seat_resource); - struct wlr_surface *parent = wlr_surface_from_resource(parent_resource); - struct wlr_wl_shell_popup_grab *grab = - shell_popup_grab_from_seat(surface->shell, seat_client->seat); - if (!grab) { - wl_client_post_no_memory(client); - return; - } - - struct wlr_wl_shell_surface *wl_parent = - shell_find_shell_surface(surface->shell, parent); - - if (surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP) { - surface->transient_state->x = x; - surface->transient_state->y = y; - shell_surface_popup_set_parent(surface, wl_parent); - grab->client = surface->client; - surface->popup_mapped = true; - wlr_seat_pointer_start_grab(seat_client->seat, &grab->pointer_grab); - return; - } - - struct wlr_wl_shell_surface_transient_state *transient_state = - calloc(1, sizeof(struct wlr_wl_shell_surface_transient_state)); - if (transient_state == NULL) { - wl_client_post_no_memory(client); - return; - } - transient_state->x = x; - transient_state->y = y; - transient_state->flags = flags; - - struct wlr_wl_shell_surface_popup_state *popup_state = - calloc(1, sizeof(struct wlr_wl_shell_surface_popup_state)); - if (popup_state == NULL) { - free(transient_state); - wl_client_post_no_memory(client); - return; - } - popup_state->seat = seat_client->seat; - popup_state->serial = serial; - - shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_POPUP, - transient_state, popup_state); - - shell_surface_popup_set_parent(surface, wl_parent); - grab->client = surface->client; - wl_list_insert(&grab->popups, &surface->grab_link); - surface->popup_mapped = true; - wlr_seat_pointer_start_grab(seat_client->seat, &grab->pointer_grab); -} - -static void shell_surface_protocol_set_maximized(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *output_resource) { - struct wlr_wl_shell_surface *surface = shell_surface_from_resource(resource); - struct wlr_output *output = NULL; - if (output_resource != NULL) { - output = wlr_output_from_resource(output_resource); - } - - shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED, - NULL, NULL); - - struct wlr_wl_shell_surface_maximize_event event = { - .surface = surface, - .output = output, - }; - - wlr_signal_emit_safe(&surface->events.request_maximize, &event); -} - -static void shell_surface_protocol_set_title(struct wl_client *client, - struct wl_resource *resource, const char *title) { - wlr_log(WLR_DEBUG, "new shell surface title: %s", title); - struct wlr_wl_shell_surface *surface = shell_surface_from_resource(resource); - - char *tmp = strdup(title); - if (tmp == NULL) { - return; - } - - free(surface->title); - surface->title = tmp; - - wlr_signal_emit_safe(&surface->events.set_title, surface); -} - -static void shell_surface_protocol_set_class(struct wl_client *client, - struct wl_resource *resource, const char *class) { - wlr_log(WLR_DEBUG, "new shell surface class: %s", class); - struct wlr_wl_shell_surface *surface = shell_surface_from_resource(resource); - - char *tmp = strdup(class); - if (tmp == NULL) { - return; - } - - free(surface->class); - surface->class = tmp; - - wlr_signal_emit_safe(&surface->events.set_class, surface); -} - -static const struct wl_shell_surface_interface shell_surface_impl = { - .pong = shell_surface_protocol_pong, - .move = shell_surface_protocol_move, - .resize = shell_surface_protocol_resize, - .set_toplevel = shell_surface_protocol_set_toplevel, - .set_transient = shell_surface_protocol_set_transient, - .set_fullscreen = shell_surface_protocol_set_fullscreen, - .set_popup = shell_surface_protocol_set_popup, - .set_maximized = shell_surface_protocol_set_maximized, - .set_title = shell_surface_protocol_set_title, - .set_class = shell_surface_protocol_set_class, -}; - -static void shell_surface_destroy(struct wlr_wl_shell_surface *surface) { - wlr_signal_emit_safe(&surface->events.destroy, surface); - shell_surface_destroy_popup_state(surface); - wl_resource_set_user_data(surface->resource, NULL); - - struct wlr_wl_shell_surface *child; - wl_list_for_each(child, &surface->popups, popup_link) { - shell_surface_popup_set_parent(child, NULL); - } - wl_list_remove(&surface->popup_link); - - surface->surface->role_data = NULL; - wl_list_remove(&surface->link); - wl_list_remove(&surface->surface_destroy.link); - wl_event_source_remove(surface->ping_timer); - free(surface->transient_state); - free(surface->title); - free(surface->class); - free(surface); -} - -static void shell_surface_resource_destroy(struct wl_resource *resource) { - struct wlr_wl_shell_surface *surface = shell_surface_from_resource(resource); - if (surface != NULL) { - shell_surface_destroy(surface); - } -} - -static void shell_surface_handle_surface_destroy(struct wl_listener *listener, - void *data) { - struct wlr_wl_shell_surface *surface = - wl_container_of(listener, surface, surface_destroy); - shell_surface_destroy(surface); -} - -static void shell_surface_role_commit(struct wlr_surface *wlr_surface) { - struct wlr_wl_shell_surface *surface = - wlr_wl_shell_surface_from_wlr_surface(wlr_surface); - if (surface == NULL) { - return; - } - - if (!surface->configured && - wlr_surface_has_buffer(surface->surface) && - surface->state != WLR_WL_SHELL_SURFACE_STATE_NONE) { - surface->configured = true; - wlr_signal_emit_safe(&surface->shell->events.new_surface, surface); - } - - if (surface->popup_mapped && - surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP && - !wlr_surface_has_buffer(surface->surface)) { - surface->popup_mapped = false; - struct wlr_wl_shell_popup_grab *grab = - shell_popup_grab_from_seat(surface->shell, - surface->popup_state->seat); - shell_pointer_grab_maybe_end(&grab->pointer_grab); - } -} - -static const struct wlr_surface_role shell_surface_role = { - .name = "wl_shell_surface", - .commit = shell_surface_role_commit, -}; - -static int shell_surface_ping_timeout(void *user_data) { - struct wlr_wl_shell_surface *surface = user_data; - wlr_signal_emit_safe(&surface->events.ping_timeout, surface); - - surface->ping_serial = 0; - return 1; -} - -static const struct wl_shell_interface shell_impl; - -static struct wlr_wl_shell *shell_from_resource( - struct wl_resource *resource) { - assert(wl_resource_instance_of(resource, &wl_shell_interface, &shell_impl)); - return wl_resource_get_user_data(resource); -} - -static void shell_protocol_get_shell_surface(struct wl_client *client, - struct wl_resource *shell_resource, uint32_t id, - struct wl_resource *surface_resource) { - struct wlr_surface *surface = wlr_surface_from_resource(surface_resource); - - struct wlr_wl_shell *wl_shell = shell_from_resource(shell_resource); - struct wlr_wl_shell_surface *wl_surface = - calloc(1, sizeof(struct wlr_wl_shell_surface)); - if (wl_surface == NULL) { - wl_resource_post_no_memory(shell_resource); - return; - } - - if (!wlr_surface_set_role(surface, &shell_surface_role, wl_surface, - shell_resource, WL_SHELL_ERROR_ROLE)) { - free(wl_surface); - return; - } - - wl_list_init(&wl_surface->grab_link); - wl_list_init(&wl_surface->popup_link); - wl_list_init(&wl_surface->popups); - - wl_surface->shell = wl_shell; - wl_surface->client = client; - wl_surface->surface = surface; - - wl_surface->resource = wl_resource_create(client, - &wl_shell_surface_interface, wl_resource_get_version(shell_resource), - id); - if (wl_surface->resource == NULL) { - free(wl_surface); - wl_resource_post_no_memory(shell_resource); - return; - } - wl_resource_set_implementation(wl_surface->resource, - &shell_surface_impl, wl_surface, - shell_surface_resource_destroy); - - wlr_log(WLR_DEBUG, "new wl_shell %p (res %p)", wl_surface, - wl_surface->resource); - - wl_signal_init(&wl_surface->events.destroy); - wl_signal_init(&wl_surface->events.ping_timeout); - wl_signal_init(&wl_surface->events.new_popup); - wl_signal_init(&wl_surface->events.request_move); - wl_signal_init(&wl_surface->events.request_resize); - wl_signal_init(&wl_surface->events.request_fullscreen); - wl_signal_init(&wl_surface->events.request_maximize); - wl_signal_init(&wl_surface->events.set_state); - wl_signal_init(&wl_surface->events.set_title); - wl_signal_init(&wl_surface->events.set_class); - - wl_signal_add(&wl_surface->surface->events.destroy, - &wl_surface->surface_destroy); - wl_surface->surface_destroy.notify = shell_surface_handle_surface_destroy; - - struct wl_display *display = wl_client_get_display(client); - struct wl_event_loop *loop = wl_display_get_event_loop(display); - wl_surface->ping_timer = wl_event_loop_add_timer(loop, - shell_surface_ping_timeout, wl_surface); - if (wl_surface->ping_timer == NULL) { - wl_client_post_no_memory(client); - } - - wl_list_insert(&wl_shell->surfaces, &wl_surface->link); -} - -static const struct wl_shell_interface shell_impl = { - .get_shell_surface = shell_protocol_get_shell_surface -}; - -static void shell_destroy(struct wl_resource *resource) { - wl_list_remove(wl_resource_get_link(resource)); -} - -static void shell_bind(struct wl_client *wl_client, void *data, - uint32_t version, uint32_t id) { - struct wlr_wl_shell *wl_shell = data; - assert(wl_client && wl_shell); - - struct wl_resource *wl_resource = wl_resource_create(wl_client, - &wl_shell_interface, version, id); - if (wl_resource == NULL) { - wl_client_post_no_memory(wl_client); - return; - } - wl_resource_set_implementation(wl_resource, &shell_impl, wl_shell, - shell_destroy); - wl_list_insert(&wl_shell->resources, wl_resource_get_link(wl_resource)); -} - -static void handle_display_destroy(struct wl_listener *listener, void *data) { - struct wlr_wl_shell *wl_shell = - wl_container_of(listener, wl_shell, display_destroy); - wlr_wl_shell_destroy(wl_shell); -} - -struct wlr_wl_shell *wlr_wl_shell_create(struct wl_display *display) { - struct wlr_wl_shell *wl_shell = calloc(1, sizeof(struct wlr_wl_shell)); - if (!wl_shell) { - return NULL; - } - wl_shell->ping_timeout = 10000; - struct wl_global *global = wl_global_create(display, &wl_shell_interface, - 1, wl_shell, shell_bind); - if (!global) { - free(wl_shell); - return NULL; - } - wl_shell->global = global; - wl_list_init(&wl_shell->resources); - wl_list_init(&wl_shell->surfaces); - wl_list_init(&wl_shell->popup_grabs); - wl_signal_init(&wl_shell->events.new_surface); - - wl_shell->display_destroy.notify = handle_display_destroy; - wl_display_add_destroy_listener(display, &wl_shell->display_destroy); - - return wl_shell; -} - -void wlr_wl_shell_destroy(struct wlr_wl_shell *wlr_wl_shell) { - if (!wlr_wl_shell) { - return; - } - wl_list_remove(&wlr_wl_shell->display_destroy.link); - struct wl_resource *resource = NULL, *temp = NULL; - wl_resource_for_each_safe(resource, temp, &wlr_wl_shell->resources) { - // shell_destroy will remove the resource from the list - wl_resource_destroy(resource); - } - // TODO: destroy surfaces - wl_global_destroy(wlr_wl_shell->global); - free(wlr_wl_shell); -} - -void wlr_wl_shell_surface_ping(struct wlr_wl_shell_surface *surface) { - if (surface->ping_serial != 0) { - // already pinged - return; - } - - surface->ping_serial = - wl_display_next_serial(wl_client_get_display(surface->client)); - wl_event_source_timer_update(surface->ping_timer, - surface->shell->ping_timeout); - wl_shell_surface_send_ping(surface->resource, surface->ping_serial); -} - -void wlr_wl_shell_surface_configure(struct wlr_wl_shell_surface *surface, - uint32_t edges, int32_t width, int32_t height) { - wl_shell_surface_send_configure(surface->resource, edges, width, height); -} - -struct wlr_surface *wlr_wl_shell_surface_surface_at( - struct wlr_wl_shell_surface *surface, double sx, double sy, - double *sub_sx, double *sub_sy) { - struct wlr_wl_shell_surface *popup; - wl_list_for_each(popup, &surface->popups, popup_link) { - if (!popup->popup_mapped) { - continue; - } - - double popup_sx = popup->transient_state->x; - double popup_sy = popup->transient_state->y; - struct wlr_surface *sub = wlr_wl_shell_surface_surface_at(popup, - sx - popup_sx, sy - popup_sy, sub_sx, sub_sy); - if (sub != NULL) { - return sub; - } - } - - return wlr_surface_surface_at(surface->surface, sx, sy, sub_sx, sub_sy); -} - -struct wl_shell_surface_iterator_data { - wlr_surface_iterator_func_t user_iterator; - void *user_data; - int x, y; -}; - -static void wl_shell_surface_iterator(struct wlr_surface *surface, - int sx, int sy, void *data) { - struct wl_shell_surface_iterator_data *iter_data = data; - iter_data->user_iterator(surface, iter_data->x + sx, iter_data->y + sy, - iter_data->user_data); -} - -static void wl_shell_surface_for_each_surface( - struct wlr_wl_shell_surface *surface, int x, int y, - wlr_surface_iterator_func_t iterator, void *user_data) { - struct wl_shell_surface_iterator_data data = { - .user_iterator = iterator, - .user_data = user_data, - .x = x, .y = y, - }; - wlr_surface_for_each_surface(surface->surface, wl_shell_surface_iterator, - &data); - - struct wlr_wl_shell_surface *popup; - wl_list_for_each(popup, &surface->popups, popup_link) { - double popup_x = popup->transient_state->x; - double popup_y = popup->transient_state->y; - - wl_shell_surface_for_each_surface(popup, x + popup_x, y + popup_y, - iterator, user_data); - } -} - -void wlr_wl_shell_surface_for_each_surface(struct wlr_wl_shell_surface *surface, - wlr_surface_iterator_func_t iterator, void *user_data) { - wl_shell_surface_for_each_surface(surface, 0, 0, iterator, user_data); -}