diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h index e768d9d5..bea92b8b 100644 --- a/include/wlr/types/wlr_wl_shell.h +++ b/include/wlr/types/wlr_wl_shell.h @@ -69,8 +69,8 @@ struct wlr_wl_shell_surface { struct wl_listener surface_commit_listener; struct wlr_wl_shell_surface *parent; - struct wl_list child_link; - struct wl_list children; // transient and popups + struct wl_list popup_link; + struct wl_list popups; struct { struct wl_signal destroy; @@ -124,8 +124,6 @@ void wlr_wl_shell_destroy(struct wlr_wl_shell *wlr_wl_shell); void wlr_wl_shell_surface_ping(struct wlr_wl_shell_surface *surface); void wlr_wl_shell_surface_configure(struct wlr_wl_shell_surface *surface, enum wl_shell_surface_resize edges, int32_t width, int32_t height); -void wlr_wl_shell_surface_popup_done(struct wlr_wl_shell_surface *surface); -bool wlr_wl_shell_surface_is_transient(struct wlr_wl_shell_surface *surface); /** * Find a popup within this surface at the surface-local coordinates. Returns diff --git a/rootston/output.c b/rootston/output.c index 29a4413f..2c061739 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -103,11 +103,11 @@ static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, struct if (is_child || surface->state != WLR_WL_SHELL_SURFACE_STATE_POPUP) { render_surface(surface->surface, desktop, wlr_output, when, lx, ly, rotation); - struct wlr_wl_shell_surface *child; - wl_list_for_each(child, &surface->children, child_link) { - render_wl_shell_surface(child, desktop, wlr_output, when, - lx + child->transient_state->x, - ly + child->transient_state->y, + struct wlr_wl_shell_surface *popup; + wl_list_for_each(popup, &surface->popups, popup_link) { + render_wl_shell_surface(popup, desktop, wlr_output, when, + lx + popup->transient_state->x, + ly + popup->transient_state->y, rotation, true); } } diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index a629575b..34f53c7a 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -138,40 +138,3 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { roots_surface->view = view; list_add(desktop->views, view); } - -struct wlr_wl_shell_surface *wlr_wl_shell_surface_popup_at( - struct wlr_wl_shell_surface *surface, double sx, double sy, - double *popup_sx, double *popup_sy) { - struct wlr_wl_shell_surface *popup; - wl_list_for_each(popup, &surface->children, child_link) { - double _popup_sx = popup->transient_state->x; - double _popup_sy = popup->transient_state->y; - int popup_width = - popup->surface->current->buffer_width; - int popup_height = - popup->surface->current->buffer_height; - - struct wlr_wl_shell_surface *_popup = - wlr_wl_shell_surface_popup_at(popup, - popup->transient_state->x, - popup->transient_state->y, - popup_sx, popup_sy); - if (_popup) { - *popup_sx = sx + _popup_sx; - *popup_sy = sy + _popup_sy; - return _popup; - } - - if ((sx > _popup_sx && sx < _popup_sx + popup_width) && - (sy > _popup_sy && sy < _popup_sy + popup_height)) { - if (pixman_region32_contains_point(&popup->surface->current->input, - sx - _popup_sx, sy - _popup_sy, NULL)) { - *popup_sx = _popup_sx; - *popup_sy = _popup_sy; - return popup; - } - } - } - - return NULL; -} diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index de018865..5851c63a 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -10,7 +10,7 @@ #include #include -static const char *wlr_wl_shell_surface_role = "wl_shell_surface"; +static const char *wlr_wl_shell_surface_role = "wl-shell-surface"; static void shell_pointer_grab_end(struct wlr_seat_pointer_grab *grab) { struct wlr_wl_shell_popup_grab *popup_grab = grab->data; @@ -67,7 +67,7 @@ static const struct wlr_pointer_grab_interface shell_pointer_grab_impl = { .axis = shell_pointer_grab_axis, }; -static void shell_surface_pong(struct wl_client *client, +static void shell_surface_protocol_pong(struct wl_client *client, struct wl_resource *resource, uint32_t serial) { wlr_log(L_DEBUG, "got shell surface pong"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); @@ -79,7 +79,7 @@ static void shell_surface_pong(struct wl_client *client, surface->ping_serial = 0; } -static void shell_surface_move(struct wl_client *client, +static void shell_surface_protocol_move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial) { wlr_log(L_DEBUG, "got shell surface move"); @@ -128,7 +128,8 @@ static struct wlr_wl_shell_popup_grab *shell_popup_grab_from_seat( return shell_grab; } -static void shell_destroy_popup_state(struct wlr_wl_shell_surface *surface) { +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 = @@ -145,7 +146,7 @@ static void shell_destroy_popup_state(struct wlr_wl_shell_surface *surface) { } -static void shell_surface_resize(struct wl_client *client, +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) { wlr_log(L_DEBUG, "got shell surface resize"); @@ -177,13 +178,13 @@ static void shell_surface_set_state(struct wlr_wl_shell_surface *surface, surface->state = state; free(surface->transient_state); surface->transient_state = transient_state; - shell_destroy_popup_state(surface); + shell_surface_destroy_popup_state(surface); surface->popup_state = popup_state; wl_signal_emit(&surface->events.set_state, surface); } -static void shell_surface_set_toplevel(struct wl_client *client, +static void shell_surface_protocol_set_toplevel(struct wl_client *client, struct wl_resource *resource) { wlr_log(L_DEBUG, "got shell surface toplevel"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); @@ -191,7 +192,7 @@ static void shell_surface_set_toplevel(struct wl_client *client, NULL); } -static void popup_set_parent(struct wlr_wl_shell_surface *surface, +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) { @@ -199,13 +200,13 @@ static void popup_set_parent(struct wlr_wl_shell_surface *surface, } surface->parent = parent; if (parent) { - wl_list_remove(&surface->child_link); - wl_list_insert(&parent->children, &surface->child_link); + wl_list_remove(&surface->popup_link); + wl_list_insert(&parent->popups, &surface->popup_link); } } -static struct wlr_wl_shell_surface *shell_get_shell_surface(struct wlr_wl_shell *shell, - struct wlr_surface *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) { @@ -217,7 +218,7 @@ static struct wlr_wl_shell_surface *shell_get_shell_surface(struct wlr_wl_shell return NULL; } -static void shell_surface_set_transient(struct wl_client *client, +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(L_DEBUG, "got shell surface transient"); @@ -226,7 +227,8 @@ static void shell_surface_set_transient(struct wl_client *client, wl_resource_get_user_data(parent_resource); // TODO: check if parent_resource == NULL? - struct wlr_wl_shell_surface *wl_parent = shell_get_shell_surface(surface->shell, parent); + struct wlr_wl_shell_surface *wl_parent = + shell_find_shell_surface(surface->shell, parent); if (!wl_parent) { return; @@ -248,7 +250,7 @@ static void shell_surface_set_transient(struct wl_client *client, transient_state, NULL); } -static void shell_surface_set_fullscreen(struct wl_client *client, +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) { @@ -281,7 +283,7 @@ static void shell_surface_set_fullscreen(struct wl_client *client, } -static void shell_surface_set_popup(struct wl_client *client, +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) { @@ -298,12 +300,12 @@ static void shell_surface_set_popup(struct wl_client *client, } struct wlr_wl_shell_surface *wl_parent = - shell_get_shell_surface(surface->shell, 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; - popup_set_parent(surface, wl_parent); + shell_surface_popup_set_parent(surface, wl_parent); grab->client = surface->client; wlr_seat_pointer_start_grab(seat_handle->wlr_seat, &grab->pointer_grab); return; @@ -332,13 +334,13 @@ static void shell_surface_set_popup(struct wl_client *client, shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_POPUP, transient_state, popup_state); - popup_set_parent(surface, wl_parent); + shell_surface_popup_set_parent(surface, wl_parent); grab->client = surface->client; wl_list_insert(&grab->popups, &surface->grab_link); wlr_seat_pointer_start_grab(seat_handle->wlr_seat, &grab->pointer_grab); } -static void shell_surface_set_maximized(struct wl_client *client, +static void shell_surface_protocol_set_maximized(struct wl_client *client, struct wl_resource *resource, struct wl_resource *output_resource) { wlr_log(L_DEBUG, "got shell surface maximized"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); @@ -366,7 +368,7 @@ static void shell_surface_set_maximized(struct wl_client *client, free(event); } -static void shell_surface_set_title(struct wl_client *client, +static void shell_surface_protocol_set_title(struct wl_client *client, struct wl_resource *resource, const char *title) { wlr_log(L_DEBUG, "new shell surface title: %s", title); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); @@ -382,7 +384,7 @@ static void shell_surface_set_title(struct wl_client *client, wl_signal_emit(&surface->events.set_title, surface); } -static void shell_surface_set_class(struct wl_client *client, +static void shell_surface_protocol_set_class(struct wl_client *client, struct wl_resource *resource, const char *class) { wlr_log(L_DEBUG, "new shell surface class: %s", class); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); @@ -398,29 +400,29 @@ static void shell_surface_set_class(struct wl_client *client, wl_signal_emit(&surface->events.set_class, surface); } -struct wl_shell_surface_interface shell_surface_interface = { - .pong = shell_surface_pong, - .move = shell_surface_move, - .resize = shell_surface_resize, - .set_toplevel = shell_surface_set_toplevel, - .set_transient = shell_surface_set_transient, - .set_fullscreen = shell_surface_set_fullscreen, - .set_popup = shell_surface_set_popup, - .set_maximized = shell_surface_set_maximized, - .set_title = shell_surface_set_title, - .set_class = shell_surface_set_class, +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 wl_shell_surface_destroy(struct wlr_wl_shell_surface *surface) { +static void shell_surface_destroy(struct wlr_wl_shell_surface *surface) { wl_signal_emit(&surface->events.destroy, surface); - shell_destroy_popup_state(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->children, child_link) { - popup_set_parent(child, NULL); + wl_list_for_each(child, &surface->popups, popup_link) { + shell_surface_popup_set_parent(child, NULL); } - wl_list_remove(&surface->child_link); + wl_list_remove(&surface->popup_link); wl_list_remove(&surface->link); wl_list_remove(&surface->surface_destroy_listener.link); @@ -432,10 +434,10 @@ static void wl_shell_surface_destroy(struct wlr_wl_shell_surface *surface) { free(surface); } -static void wl_shell_surface_resource_destroy(struct wl_resource *resource) { +static void shell_surface_resource_destroy(struct wl_resource *resource) { struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); if (surface != NULL) { - wl_shell_surface_destroy(surface); + shell_surface_destroy(surface); } } @@ -443,7 +445,7 @@ static void handle_wlr_surface_destroyed(struct wl_listener *listener, void *data) { struct wlr_wl_shell_surface *surface = wl_container_of(listener, surface, surface_destroy_listener); - wl_shell_surface_destroy(surface); + shell_surface_destroy(surface); } static void handle_wlr_surface_committed(struct wl_listener *listener, void *data) { @@ -457,7 +459,7 @@ static void handle_wlr_surface_committed(struct wl_listener *listener, } } -static int wlr_wl_shell_surface_ping_timeout(void *user_data) { +static int shell_surface_ping_timeout(void *user_data) { struct wlr_wl_shell_surface *surface = user_data; wl_signal_emit(&surface->events.ping_timeout, surface); @@ -465,7 +467,7 @@ static int wlr_wl_shell_surface_ping_timeout(void *user_data) { return 1; } -static void wl_shell_get_shell_surface(struct wl_client *client, +static void shell_protocol_get_shell_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource) { struct wlr_surface *surface = wl_resource_get_user_data(surface_resource); @@ -482,8 +484,8 @@ static void wl_shell_get_shell_surface(struct wl_client *client, return; } wl_list_init(&wl_surface->grab_link); - wl_list_init(&wl_surface->child_link); - wl_list_init(&wl_surface->children); + wl_list_init(&wl_surface->popup_link); + wl_list_init(&wl_surface->popups); wl_surface->shell = wl_shell; wl_surface->client = client; @@ -494,8 +496,8 @@ static void wl_shell_get_shell_surface(struct wl_client *client, wlr_log(L_DEBUG, "new wl_shell %p (res %p)", wl_surface, wl_surface->resource); wl_resource_set_implementation(wl_surface->resource, - &shell_surface_interface, wl_surface, - wl_shell_surface_resource_destroy); + &shell_surface_impl, wl_surface, + shell_surface_resource_destroy); wl_signal_init(&wl_surface->events.destroy); wl_signal_init(&wl_surface->events.ping_timeout); @@ -518,7 +520,7 @@ static void wl_shell_get_shell_surface(struct wl_client *client, 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, - wlr_wl_shell_surface_ping_timeout, wl_surface); + shell_surface_ping_timeout, wl_surface); if (wl_surface->ping_timer == NULL) { wl_client_post_no_memory(client); } @@ -526,15 +528,15 @@ static void wl_shell_get_shell_surface(struct wl_client *client, wl_list_insert(&wl_shell->surfaces, &wl_surface->link); } -static struct wl_shell_interface wl_shell_impl = { - .get_shell_surface = wl_shell_get_shell_surface +static struct wl_shell_interface shell_impl = { + .get_shell_surface = shell_protocol_get_shell_surface }; -static void wl_shell_destroy(struct wl_resource *resource) { +static void shell_destroy(struct wl_resource *resource) { wl_list_remove(wl_resource_get_link(resource)); } -static void wl_shell_bind(struct wl_client *wl_client, void *_wl_shell, +static void shell_bind(struct wl_client *wl_client, void *_wl_shell, uint32_t version, uint32_t id) { struct wlr_wl_shell *wl_shell = _wl_shell; assert(wl_client && wl_shell); @@ -546,8 +548,8 @@ static void wl_shell_bind(struct wl_client *wl_client, void *_wl_shell, } struct wl_resource *wl_resource = wl_resource_create(wl_client, &wl_shell_interface, version, id); - wl_resource_set_implementation(wl_resource, &wl_shell_impl, wl_shell, - wl_shell_destroy); + wl_resource_set_implementation(wl_resource, &shell_impl, wl_shell, + shell_destroy); wl_list_insert(&wl_shell->wl_resources, wl_resource_get_link(wl_resource)); } @@ -558,7 +560,7 @@ struct wlr_wl_shell *wlr_wl_shell_create(struct wl_display *display) { } wl_shell->ping_timeout = 10000; struct wl_global *wl_global = wl_global_create(display, &wl_shell_interface, - 1, wl_shell, wl_shell_bind); + 1, wl_shell, shell_bind); if (!wl_global) { free(wl_shell); return NULL; @@ -604,10 +606,39 @@ void wlr_wl_shell_surface_configure(struct wlr_wl_shell_surface *surface, wl_shell_surface_send_configure(surface->resource, edges, width, height); } -void wlr_wl_shell_surface_popup_done(struct wlr_wl_shell_surface *surface) { - wl_shell_surface_send_popup_done(surface->resource); -} +struct wlr_wl_shell_surface *wlr_wl_shell_surface_popup_at( + struct wlr_wl_shell_surface *surface, double sx, double sy, + double *popup_sx, double *popup_sy) { + struct wlr_wl_shell_surface *popup; + wl_list_for_each(popup, &surface->popups, popup_link) { + double _popup_sx = popup->transient_state->x; + double _popup_sy = popup->transient_state->y; + int popup_width = + popup->surface->current->buffer_width; + int popup_height = + popup->surface->current->buffer_height; -bool wlr_wl_shell_surface_is_transient(struct wlr_wl_shell_surface *surface) { - return surface->parent != NULL; + struct wlr_wl_shell_surface *_popup = + wlr_wl_shell_surface_popup_at(popup, + popup->transient_state->x, + popup->transient_state->y, + popup_sx, popup_sy); + if (_popup) { + *popup_sx = sx + _popup_sx; + *popup_sy = sy + _popup_sy; + return _popup; + } + + if ((sx > _popup_sx && sx < _popup_sx + popup_width) && + (sy > _popup_sy && sy < _popup_sy + popup_height)) { + if (pixman_region32_contains_point(&popup->surface->current->input, + sx - _popup_sx, sy - _popup_sy, NULL)) { + *popup_sx = _popup_sx; + *popup_sy = _popup_sy; + return popup; + } + } + } + + return NULL; }