diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 97ff4786..67d937fe 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -74,9 +74,22 @@ struct wlr_xdg_toplevel_v6 { struct wlr_xdg_surface_v6 *base; struct wlr_xdg_surface_v6 *parent; bool added; + struct wlr_xdg_toplevel_v6_state next; // client protocol requests struct wlr_xdg_toplevel_v6_state pending; // user configure requests struct wlr_xdg_toplevel_v6_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_v6_configure { @@ -106,10 +119,6 @@ struct wlr_xdg_surface_v6 { 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_v6 { 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; diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 001232ab..2be9e00e 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -339,7 +339,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { wl_container_of(listener, desktop, xdg_shell_v6_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_v6_ping(surface); struct roots_xdg_surface_v6 *roots_surface = @@ -357,15 +357,16 @@ void handle_xdg_shell_v6_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); diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 3975dd67..4c40e129 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -198,24 +198,35 @@ static void xdg_surface_unmap(struct wlr_xdg_surface_v6 *surface) { wlr_signal_emit_safe(&surface->events.unmap, surface); } - if (surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP && - surface->popup->seat != NULL) { - struct wlr_xdg_popup_grab_v6 *grab = - 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); + switch (surface->role) { + case WLR_XDG_SURFACE_V6_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_V6_ROLE_POPUP: + if (surface->popup->seat != NULL) { + struct wlr_xdg_popup_grab_v6 *grab = + 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; + surface->popup->seat = NULL; + } + break; + case WLR_XDG_SURFACE_V6_ROLE_NONE: + assert(false && "not reached"); } struct wlr_xdg_surface_v6_configure *configure, *tmp; @@ -223,11 +234,6 @@ static void xdg_surface_unmap(struct wlr_xdg_surface_v6 *surface) { xdg_surface_configure_destroy(configure); } - free(surface->title); - surface->title = NULL; - free(surface->app_id); - surface->app_id = NULL; - surface->configured = surface->mapped = false; surface->configure_serial = 0; if (surface->configure_idle) { @@ -666,8 +672,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, @@ -680,8 +686,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, @@ -712,7 +718,8 @@ 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, @@ -741,7 +748,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, @@ -771,7 +778,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, @@ -795,7 +802,7 @@ static void xdg_toplevel_handle_set_maximized(struct wl_client *client, struct wlr_xdg_surface_v6 *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, @@ -803,7 +810,7 @@ static void xdg_toplevel_handle_unset_maximized(struct wl_client *client, struct wlr_xdg_surface_v6 *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, @@ -824,7 +831,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, @@ -840,14 +847,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_v6 *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 zxdg_toplevel_v6_interface @@ -897,6 +904,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_V6_ROLE_TOPLEVEL; surface->toplevel->base = surface; @@ -1341,12 +1354,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);