xdg-shell: extract role-specific unmap logic

This commit is contained in:
Kirill Primak 2022-01-08 22:52:55 +03:00
parent e59aa3e0e7
commit c35d14ecfa
4 changed files with 46 additions and 41 deletions

View file

@ -30,17 +30,18 @@ struct wlr_xdg_positioner_resource *get_xdg_positioner_from_resource(
void create_xdg_popup(struct wlr_xdg_surface *surface,
struct wlr_xdg_surface *parent,
struct wlr_xdg_positioner_resource *positioner, uint32_t id);
void unmap_xdg_popup(struct wlr_xdg_popup *popup);
void handle_xdg_popup_committed(struct wlr_xdg_popup *popup);
struct wlr_xdg_popup_grab *get_xdg_shell_popup_grab_from_seat(
struct wlr_xdg_shell *shell, struct wlr_seat *seat);
void create_xdg_toplevel(struct wlr_xdg_surface *surface,
uint32_t id);
void unmap_xdg_toplevel(struct wlr_xdg_toplevel *toplevel);
void handle_xdg_toplevel_committed(struct wlr_xdg_toplevel *toplevel);
struct wlr_xdg_toplevel_configure *send_xdg_toplevel_configure(
struct wlr_xdg_toplevel *toplevel);
void handle_xdg_toplevel_ack_configure(struct wlr_xdg_toplevel *toplevel,
struct wlr_xdg_toplevel_configure *configure);
void destroy_xdg_toplevel(struct wlr_xdg_toplevel *toplevel);
#endif

View file

@ -355,6 +355,27 @@ void create_xdg_popup(struct wlr_xdg_surface *surface,
}
}
void unmap_xdg_popup(struct wlr_xdg_popup *popup) {
if (popup->seat != NULL) {
struct wlr_xdg_popup_grab *grab =
get_xdg_shell_popup_grab_from_seat(
popup->base->client->shell, popup->seat);
wl_list_remove(&popup->grab_link);
if (wl_list_empty(&grab->popups)) {
if (grab->seat->pointer_state.grab == &grab->pointer_grab) {
wlr_seat_pointer_end_grab(grab->seat);
}
if (grab->seat->keyboard_state.grab == &grab->keyboard_grab) {
wlr_seat_keyboard_end_grab(grab->seat);
}
}
popup->seat = NULL;
}
}
void wlr_xdg_popup_destroy(struct wlr_xdg_popup *popup) {
if (popup == NULL) {
return;

View file

@ -42,34 +42,10 @@ void unmap_xdg_surface(struct wlr_xdg_surface *surface) {
switch (surface->role) {
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
if (surface->toplevel->parent) {
wl_list_remove(&surface->toplevel->parent_unmap.link);
surface->toplevel->parent = NULL;
}
free(surface->toplevel->title);
surface->toplevel->title = NULL;
free(surface->toplevel->app_id);
surface->toplevel->app_id = NULL;
unmap_xdg_toplevel(surface->toplevel);
break;
case WLR_XDG_SURFACE_ROLE_POPUP:
if (surface->popup->seat != NULL) {
struct wlr_xdg_popup_grab *grab =
get_xdg_shell_popup_grab_from_seat(surface->client->shell,
surface->popup->seat);
wl_list_remove(&surface->popup->grab_link);
if (wl_list_empty(&grab->popups)) {
if (grab->seat->pointer_state.grab == &grab->pointer_grab) {
wlr_seat_pointer_end_grab(grab->seat);
}
if (grab->seat->keyboard_state.grab == &grab->keyboard_grab) {
wlr_seat_keyboard_end_grab(grab->seat);
}
}
surface->popup->seat = NULL;
}
unmap_xdg_popup(surface->popup);
break;
case WLR_XDG_SURFACE_ROLE_NONE:
assert(false && "not reached");
@ -436,21 +412,13 @@ void reset_xdg_surface(struct wlr_xdg_surface *surface) {
switch (surface->role) {
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
wl_resource_set_user_data(surface->toplevel->resource, NULL);
surface->toplevel->resource = NULL;
struct wlr_xdg_toplevel_requested *req =
&surface->toplevel->requested;
if (req->fullscreen_output) {
wl_list_remove(&req->fullscreen_output_destroy.link);
}
free(surface->toplevel);
surface->toplevel = NULL;
break;
case WLR_XDG_SURFACE_ROLE_POPUP:
wl_resource_set_user_data(surface->popup->resource, NULL);
surface->popup->resource = NULL;
wl_list_remove(&surface->popup->link);
wl_resource_set_user_data(surface->popup->resource, NULL);
free(surface->popup);
surface->popup = NULL;
break;

View file

@ -426,7 +426,10 @@ static const struct xdg_toplevel_interface xdg_toplevel_implementation = {
static void xdg_toplevel_handle_resource_destroy(struct wl_resource *resource) {
struct wlr_xdg_toplevel *toplevel =
wlr_xdg_toplevel_from_resource(resource);
destroy_xdg_toplevel(toplevel);
if (toplevel == NULL) {
return;
}
reset_xdg_surface(toplevel->base);
}
const struct wlr_surface_role xdg_toplevel_surface_role = {
@ -482,11 +485,23 @@ void create_xdg_toplevel(struct wlr_xdg_surface *surface,
surface->role = WLR_XDG_SURFACE_ROLE_TOPLEVEL;
}
void destroy_xdg_toplevel(struct wlr_xdg_toplevel *toplevel) {
if (toplevel == NULL) {
return;
void unmap_xdg_toplevel(struct wlr_xdg_toplevel *toplevel) {
if (toplevel->parent) {
wl_list_remove(&toplevel->parent_unmap.link);
toplevel->parent = NULL;
}
reset_xdg_surface(toplevel->base);
free(toplevel->title);
toplevel->title = NULL;
free(toplevel->app_id);
toplevel->app_id = NULL;
if (toplevel->requested.fullscreen_output) {
wl_list_remove(&toplevel->requested.fullscreen_output_destroy.link);
toplevel->requested.fullscreen_output = NULL;
}
toplevel->requested.fullscreen = false;
toplevel->requested.maximized = false;
toplevel->requested.minimized = false;
}
void wlr_xdg_toplevel_send_close(struct wlr_xdg_toplevel *toplevel) {