mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-12-23 02:19:49 +01:00
xdg-shell: don't destroy role resources on unmap, move toplevel fields
Ports5233801530
and334bab543d
to xdg-shell stable.
This commit is contained in:
parent
334bab543d
commit
171e28eaff
3 changed files with 89 additions and 57 deletions
|
@ -74,9 +74,22 @@ struct wlr_xdg_toplevel {
|
|||
struct wlr_xdg_surface *base;
|
||||
struct wlr_xdg_surface *parent;
|
||||
bool added;
|
||||
|
||||
struct wlr_xdg_toplevel_state next; // client protocol requests
|
||||
struct wlr_xdg_toplevel_state pending; // user configure requests
|
||||
struct wlr_xdg_toplevel_state current;
|
||||
|
||||
char *title;
|
||||
char *app_id;
|
||||
|
||||
struct {
|
||||
struct wl_signal request_maximize;
|
||||
struct wl_signal request_fullscreen;
|
||||
struct wl_signal request_minimize;
|
||||
struct wl_signal request_move;
|
||||
struct wl_signal request_resize;
|
||||
struct wl_signal request_show_window_menu;
|
||||
} events;
|
||||
};
|
||||
|
||||
struct wlr_xdg_surface_configure {
|
||||
|
@ -106,10 +119,6 @@ struct wlr_xdg_surface {
|
|||
uint32_t configure_next_serial;
|
||||
struct wl_list configure_list;
|
||||
|
||||
// Only for toplevel
|
||||
char *title;
|
||||
char *app_id;
|
||||
|
||||
bool has_next_geometry;
|
||||
struct wlr_box next_geometry;
|
||||
struct wlr_box geometry;
|
||||
|
@ -122,13 +131,6 @@ struct wlr_xdg_surface {
|
|||
struct wl_signal new_popup;
|
||||
struct wl_signal map;
|
||||
struct wl_signal unmap;
|
||||
|
||||
struct wl_signal request_maximize;
|
||||
struct wl_signal request_fullscreen;
|
||||
struct wl_signal request_minimize;
|
||||
struct wl_signal request_move;
|
||||
struct wl_signal request_resize;
|
||||
struct wl_signal request_show_window_menu;
|
||||
} events;
|
||||
|
||||
void *data;
|
||||
|
|
|
@ -339,7 +339,7 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, desktop, xdg_shell_surface);
|
||||
|
||||
wlr_log(L_DEBUG, "new xdg toplevel: title=%s, app_id=%s",
|
||||
surface->title, surface->app_id);
|
||||
surface->toplevel->title, surface->toplevel->app_id);
|
||||
wlr_xdg_surface_ping(surface);
|
||||
|
||||
struct roots_xdg_surface *roots_surface =
|
||||
|
@ -357,15 +357,16 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
|
|||
roots_surface->unmap.notify = handle_unmap;
|
||||
wl_signal_add(&surface->events.unmap, &roots_surface->unmap);
|
||||
roots_surface->request_move.notify = handle_request_move;
|
||||
wl_signal_add(&surface->events.request_move, &roots_surface->request_move);
|
||||
wl_signal_add(&surface->toplevel->events.request_move,
|
||||
&roots_surface->request_move);
|
||||
roots_surface->request_resize.notify = handle_request_resize;
|
||||
wl_signal_add(&surface->events.request_resize,
|
||||
wl_signal_add(&surface->toplevel->events.request_resize,
|
||||
&roots_surface->request_resize);
|
||||
roots_surface->request_maximize.notify = handle_request_maximize;
|
||||
wl_signal_add(&surface->events.request_maximize,
|
||||
wl_signal_add(&surface->toplevel->events.request_maximize,
|
||||
&roots_surface->request_maximize);
|
||||
roots_surface->request_fullscreen.notify = handle_request_fullscreen;
|
||||
wl_signal_add(&surface->events.request_fullscreen,
|
||||
wl_signal_add(&surface->toplevel->events.request_fullscreen,
|
||||
&roots_surface->request_fullscreen);
|
||||
roots_surface->new_popup.notify = handle_new_popup;
|
||||
wl_signal_add(&surface->events.new_popup, &roots_surface->new_popup);
|
||||
|
|
|
@ -198,16 +198,15 @@ static void xdg_surface_unmap(struct wlr_xdg_surface *surface) {
|
|||
wlr_signal_emit_safe(&surface->events.unmap, surface);
|
||||
}
|
||||
|
||||
if (surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
|
||||
wl_resource_set_user_data(surface->toplevel->resource, NULL);
|
||||
free(surface->toplevel);
|
||||
surface->toplevel = NULL;
|
||||
}
|
||||
|
||||
if (surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
|
||||
wl_resource_set_user_data(surface->popup->resource, NULL);
|
||||
|
||||
if (surface->popup->seat) {
|
||||
switch (surface->role) {
|
||||
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
||||
free(surface->toplevel->title);
|
||||
surface->toplevel->title = NULL;
|
||||
free(surface->toplevel->app_id);
|
||||
surface->toplevel->app_id = NULL;
|
||||
break;
|
||||
case WLR_XDG_SURFACE_ROLE_POPUP:
|
||||
if (surface->popup->seat != NULL) {
|
||||
struct wlr_xdg_popup_grab *grab =
|
||||
xdg_shell_popup_grab_from_seat(surface->client->shell,
|
||||
surface->popup->seat);
|
||||
|
@ -222,11 +221,12 @@ static void xdg_surface_unmap(struct wlr_xdg_surface *surface) {
|
|||
wlr_seat_keyboard_end_grab(grab->seat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wl_list_remove(&surface->popup->link);
|
||||
free(surface->popup);
|
||||
surface->popup = NULL;
|
||||
surface->popup->seat = NULL;
|
||||
}
|
||||
break;
|
||||
case WLR_XDG_SURFACE_ROLE_NONE:
|
||||
assert(false && "not reached");
|
||||
}
|
||||
|
||||
struct wlr_xdg_surface_configure *configure, *tmp;
|
||||
|
@ -234,13 +234,7 @@ static void xdg_surface_unmap(struct wlr_xdg_surface *surface) {
|
|||
xdg_surface_configure_destroy(configure);
|
||||
}
|
||||
|
||||
surface->role = WLR_XDG_SURFACE_ROLE_NONE;
|
||||
free(surface->title);
|
||||
surface->title = NULL;
|
||||
free(surface->app_id);
|
||||
surface->app_id = NULL;
|
||||
|
||||
surface->added = surface->configured = surface->mapped = false;
|
||||
surface->configured = surface->mapped = false;
|
||||
surface->configure_serial = 0;
|
||||
if (surface->configure_idle) {
|
||||
wl_event_source_remove(surface->configure_idle);
|
||||
|
@ -253,6 +247,29 @@ static void xdg_surface_unmap(struct wlr_xdg_surface *surface) {
|
|||
memset(&surface->next_geometry, 0, sizeof(struct wlr_box));
|
||||
}
|
||||
|
||||
static void xdg_toplevel_destroy(struct wlr_xdg_surface *surface) {
|
||||
assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
|
||||
xdg_surface_unmap(surface);
|
||||
|
||||
wl_resource_set_user_data(surface->toplevel->resource, NULL);
|
||||
free(surface->toplevel);
|
||||
surface->toplevel = NULL;
|
||||
|
||||
surface->role = WLR_XDG_SURFACE_ROLE_NONE;
|
||||
}
|
||||
|
||||
static void xdg_popup_destroy(struct wlr_xdg_surface *surface) {
|
||||
assert(surface->role == WLR_XDG_SURFACE_ROLE_POPUP);
|
||||
xdg_surface_unmap(surface);
|
||||
|
||||
wl_resource_set_user_data(surface->popup->resource, NULL);
|
||||
wl_list_remove(&surface->popup->link);
|
||||
free(surface->popup);
|
||||
surface->popup = NULL;
|
||||
|
||||
surface->role = WLR_XDG_SURFACE_ROLE_NONE;
|
||||
}
|
||||
|
||||
static void xdg_surface_destroy(struct wlr_xdg_surface *surface) {
|
||||
if (surface->role != WLR_XDG_SURFACE_ROLE_NONE) {
|
||||
xdg_surface_unmap(surface);
|
||||
|
@ -260,6 +277,18 @@ static void xdg_surface_destroy(struct wlr_xdg_surface *surface) {
|
|||
|
||||
wlr_signal_emit_safe(&surface->events.destroy, surface);
|
||||
|
||||
switch (surface->role) {
|
||||
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
||||
xdg_toplevel_destroy(surface);
|
||||
break;
|
||||
case WLR_XDG_SURFACE_ROLE_POPUP:
|
||||
xdg_popup_destroy(surface);
|
||||
break;
|
||||
case WLR_XDG_SURFACE_ROLE_NONE:
|
||||
// This space is intentionally left blank
|
||||
break;
|
||||
}
|
||||
|
||||
wl_resource_set_user_data(surface->resource, NULL);
|
||||
wl_list_remove(&surface->link);
|
||||
wl_list_remove(&surface->surface_destroy_listener.link);
|
||||
|
@ -574,7 +603,7 @@ static void xdg_popup_resource_destroy(struct wl_resource *resource) {
|
|||
struct wlr_xdg_surface *surface =
|
||||
xdg_surface_from_xdg_popup_resource(resource);
|
||||
if (surface != NULL) {
|
||||
xdg_surface_unmap(surface);
|
||||
xdg_popup_destroy(surface);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -673,8 +702,8 @@ static void xdg_toplevel_handle_set_title(struct wl_client *client,
|
|||
return;
|
||||
}
|
||||
|
||||
free(surface->title);
|
||||
surface->title = tmp;
|
||||
free(surface->toplevel->title);
|
||||
surface->toplevel->title = tmp;
|
||||
}
|
||||
|
||||
static void xdg_toplevel_handle_set_app_id(struct wl_client *client,
|
||||
|
@ -688,8 +717,8 @@ static void xdg_toplevel_handle_set_app_id(struct wl_client *client,
|
|||
return;
|
||||
}
|
||||
|
||||
free(surface->app_id);
|
||||
surface->app_id = tmp;
|
||||
free(surface->toplevel->app_id);
|
||||
surface->toplevel->app_id = tmp;
|
||||
}
|
||||
|
||||
static void xdg_toplevel_handle_show_window_menu(struct wl_client *client,
|
||||
|
@ -720,7 +749,7 @@ static void xdg_toplevel_handle_show_window_menu(struct wl_client *client,
|
|||
.y = y,
|
||||
};
|
||||
|
||||
wlr_signal_emit_safe(&surface->events.request_show_window_menu, &event);
|
||||
wlr_signal_emit_safe(&surface->toplevel->events.request_show_window_menu, &event);
|
||||
}
|
||||
|
||||
static void xdg_toplevel_handle_move(struct wl_client *client,
|
||||
|
@ -749,7 +778,7 @@ static void xdg_toplevel_handle_move(struct wl_client *client,
|
|||
.serial = serial,
|
||||
};
|
||||
|
||||
wlr_signal_emit_safe(&surface->events.request_move, &event);
|
||||
wlr_signal_emit_safe(&surface->toplevel->events.request_move, &event);
|
||||
}
|
||||
|
||||
static void xdg_toplevel_handle_resize(struct wl_client *client,
|
||||
|
@ -779,7 +808,7 @@ static void xdg_toplevel_handle_resize(struct wl_client *client,
|
|||
.edges = edges,
|
||||
};
|
||||
|
||||
wlr_signal_emit_safe(&surface->events.request_resize, &event);
|
||||
wlr_signal_emit_safe(&surface->toplevel->events.request_resize, &event);
|
||||
}
|
||||
|
||||
static void xdg_toplevel_handle_set_max_size(struct wl_client *client,
|
||||
|
@ -803,7 +832,7 @@ static void xdg_toplevel_handle_set_maximized(struct wl_client *client,
|
|||
struct wlr_xdg_surface *surface =
|
||||
xdg_surface_from_xdg_toplevel_resource(resource);
|
||||
surface->toplevel->next.maximized = true;
|
||||
wlr_signal_emit_safe(&surface->events.request_maximize, surface);
|
||||
wlr_signal_emit_safe(&surface->toplevel->events.request_maximize, surface);
|
||||
}
|
||||
|
||||
static void xdg_toplevel_handle_unset_maximized(struct wl_client *client,
|
||||
|
@ -811,7 +840,7 @@ static void xdg_toplevel_handle_unset_maximized(struct wl_client *client,
|
|||
struct wlr_xdg_surface *surface =
|
||||
xdg_surface_from_xdg_toplevel_resource(resource);
|
||||
surface->toplevel->next.maximized = false;
|
||||
wlr_signal_emit_safe(&surface->events.request_maximize, surface);
|
||||
wlr_signal_emit_safe(&surface->toplevel->events.request_maximize, surface);
|
||||
}
|
||||
|
||||
static void xdg_toplevel_handle_set_fullscreen(struct wl_client *client,
|
||||
|
@ -832,7 +861,7 @@ static void xdg_toplevel_handle_set_fullscreen(struct wl_client *client,
|
|||
.output = output,
|
||||
};
|
||||
|
||||
wlr_signal_emit_safe(&surface->events.request_fullscreen, &event);
|
||||
wlr_signal_emit_safe(&surface->toplevel->events.request_fullscreen, &event);
|
||||
}
|
||||
|
||||
static void xdg_toplevel_handle_unset_fullscreen(struct wl_client *client,
|
||||
|
@ -848,14 +877,14 @@ static void xdg_toplevel_handle_unset_fullscreen(struct wl_client *client,
|
|||
.output = NULL,
|
||||
};
|
||||
|
||||
wlr_signal_emit_safe(&surface->events.request_fullscreen, &event);
|
||||
wlr_signal_emit_safe(&surface->toplevel->events.request_fullscreen, &event);
|
||||
}
|
||||
|
||||
static void xdg_toplevel_handle_set_minimized(struct wl_client *client,
|
||||
struct wl_resource *resource) {
|
||||
struct wlr_xdg_surface *surface =
|
||||
xdg_surface_from_xdg_toplevel_resource(resource);
|
||||
wlr_signal_emit_safe(&surface->events.request_minimize, surface);
|
||||
wlr_signal_emit_safe(&surface->toplevel->events.request_minimize, surface);
|
||||
}
|
||||
|
||||
static const struct xdg_toplevel_interface xdg_toplevel_implementation = {
|
||||
|
@ -887,7 +916,7 @@ static void xdg_toplevel_resource_destroy(struct wl_resource *resource) {
|
|||
struct wlr_xdg_surface *surface =
|
||||
xdg_surface_from_xdg_toplevel_resource(resource);
|
||||
if (surface != NULL) {
|
||||
xdg_surface_unmap(surface);
|
||||
xdg_toplevel_destroy(surface);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -905,6 +934,12 @@ static void xdg_surface_handle_get_toplevel(struct wl_client *client,
|
|||
wl_resource_post_no_memory(resource);
|
||||
return;
|
||||
}
|
||||
wl_signal_init(&surface->toplevel->events.request_maximize);
|
||||
wl_signal_init(&surface->toplevel->events.request_fullscreen);
|
||||
wl_signal_init(&surface->toplevel->events.request_minimize);
|
||||
wl_signal_init(&surface->toplevel->events.request_move);
|
||||
wl_signal_init(&surface->toplevel->events.request_resize);
|
||||
wl_signal_init(&surface->toplevel->events.request_show_window_menu);
|
||||
|
||||
surface->role = WLR_XDG_SURFACE_ROLE_TOPLEVEL;
|
||||
surface->toplevel->base = surface;
|
||||
|
@ -1349,12 +1384,6 @@ static void xdg_shell_handle_get_xdg_surface(struct wl_client *wl_client,
|
|||
wl_list_init(&surface->configure_list);
|
||||
wl_list_init(&surface->popups);
|
||||
|
||||
wl_signal_init(&surface->events.request_maximize);
|
||||
wl_signal_init(&surface->events.request_fullscreen);
|
||||
wl_signal_init(&surface->events.request_minimize);
|
||||
wl_signal_init(&surface->events.request_move);
|
||||
wl_signal_init(&surface->events.request_resize);
|
||||
wl_signal_init(&surface->events.request_show_window_menu);
|
||||
wl_signal_init(&surface->events.destroy);
|
||||
wl_signal_init(&surface->events.ping_timeout);
|
||||
wl_signal_init(&surface->events.new_popup);
|
||||
|
|
Loading…
Reference in a new issue