aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Primak <vyivel@eclair.cafe>2022-04-11 21:33:15 +0300
committerSimon Ser <contact@emersion.fr>2022-04-13 17:00:06 +0000
commitdec2565f2b6b0a723d08f025967ac8ff1b7ee756 (patch)
tree2fa23ab385cb629fed263dd69c37fdb1df12b622
parent04aa44b4dfa3ee7a299240794f77c2ef2d55e6f3 (diff)
xdg-toplevel: don't schedule configures on state requests
-rw-r--r--include/wlr/types/wlr_xdg_shell.h8
-rw-r--r--tinywl/tinywl.c30
-rw-r--r--types/xdg_shell/wlr_xdg_toplevel.c4
3 files changed, 38 insertions, 4 deletions
diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h
index 48bfbb97..95c6ee6c 100644
--- a/include/wlr/types/wlr_xdg_shell.h
+++ b/include/wlr/types/wlr_xdg_shell.h
@@ -147,8 +147,16 @@ struct wlr_xdg_toplevel {
char *app_id;
struct {
+ // Note: as per xdg-shell protocol, the compositor has to
+ // handle state requests by sending a configure event,
+ // even if it didn't actually change the state. Therefore,
+ // every compositor implementing xdg-shell support *must*
+ // listen to these signals and schedule a configure event
+ // immediately or at some time in the future; not doing so
+ // is a protocol violation.
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;
diff --git a/tinywl/tinywl.c b/tinywl/tinywl.c
index 290dd094..2ab0bcc0 100644
--- a/tinywl/tinywl.c
+++ b/tinywl/tinywl.c
@@ -85,6 +85,8 @@ struct tinywl_view {
struct wl_listener destroy;
struct wl_listener request_move;
struct wl_listener request_resize;
+ struct wl_listener request_maximize;
+ struct wl_listener request_fullscreen;
int x, y;
};
@@ -619,6 +621,8 @@ static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) {
wl_list_remove(&view->destroy.link);
wl_list_remove(&view->request_move.link);
wl_list_remove(&view->request_resize.link);
+ wl_list_remove(&view->request_maximize.link);
+ wl_list_remove(&view->request_fullscreen.link);
free(view);
}
@@ -684,6 +688,26 @@ static void xdg_toplevel_request_resize(
begin_interactive(view, TINYWL_CURSOR_RESIZE, event->edges);
}
+static void xdg_toplevel_request_maximize(
+ struct wl_listener *listener, void *data) {
+ /* This event is raised when a client would like to maximize itself,
+ * typically because the user clicked on the maximize button on
+ * client-side decorations. tinywl doesn't support maximization, but
+ * to conform to xdg-shell protocol we still must send a configure.
+ * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */
+ struct tinywl_view *view =
+ wl_container_of(listener, view, request_maximize);
+ wlr_xdg_surface_schedule_configure(view->xdg_toplevel->base);
+}
+
+static void xdg_toplevel_request_fullscreen(
+ struct wl_listener *listener, void *data) {
+ /* Just as with request_maximize, we must send a configure here. */
+ struct tinywl_view *view =
+ wl_container_of(listener, view, request_fullscreen);
+ wlr_xdg_surface_schedule_configure(view->xdg_toplevel->base);
+}
+
static void server_new_xdg_surface(struct wl_listener *listener, void *data) {
/* This event is raised when wlr_xdg_shell receives a new xdg surface from a
* client, either a toplevel (application window) or popup. */
@@ -730,6 +754,12 @@ static void server_new_xdg_surface(struct wl_listener *listener, void *data) {
wl_signal_add(&toplevel->events.request_move, &view->request_move);
view->request_resize.notify = xdg_toplevel_request_resize;
wl_signal_add(&toplevel->events.request_resize, &view->request_resize);
+ view->request_maximize.notify = xdg_toplevel_request_maximize;
+ wl_signal_add(&toplevel->events.request_maximize,
+ &view->request_maximize);
+ view->request_fullscreen.notify = xdg_toplevel_request_fullscreen;
+ wl_signal_add(&toplevel->events.request_fullscreen,
+ &view->request_fullscreen);
}
int main(int argc, char *argv[]) {
diff --git a/types/xdg_shell/wlr_xdg_toplevel.c b/types/xdg_shell/wlr_xdg_toplevel.c
index a78a4e89..786cfdad 100644
--- a/types/xdg_shell/wlr_xdg_toplevel.c
+++ b/types/xdg_shell/wlr_xdg_toplevel.c
@@ -320,7 +320,6 @@ static void xdg_toplevel_handle_set_maximized(struct wl_client *client,
wlr_xdg_toplevel_from_resource(resource);
toplevel->requested.maximized = true;
wlr_signal_emit_safe(&toplevel->events.request_maximize, NULL);
- wlr_xdg_surface_schedule_configure(toplevel->base);
}
static void xdg_toplevel_handle_unset_maximized(struct wl_client *client,
@@ -329,7 +328,6 @@ static void xdg_toplevel_handle_unset_maximized(struct wl_client *client,
wlr_xdg_toplevel_from_resource(resource);
toplevel->requested.maximized = false;
wlr_signal_emit_safe(&toplevel->events.request_maximize, NULL);
- wlr_xdg_surface_schedule_configure(toplevel->base);
}
static void handle_fullscreen_output_destroy(struct wl_listener *listener,
@@ -369,7 +367,6 @@ static void xdg_toplevel_handle_set_fullscreen(struct wl_client *client,
store_fullscreen_requested(toplevel, true, output);
wlr_signal_emit_safe(&toplevel->events.request_fullscreen, NULL);
- wlr_xdg_surface_schedule_configure(toplevel->base);
}
static void xdg_toplevel_handle_unset_fullscreen(struct wl_client *client,
@@ -380,7 +377,6 @@ static void xdg_toplevel_handle_unset_fullscreen(struct wl_client *client,
store_fullscreen_requested(toplevel, false, NULL);
wlr_signal_emit_safe(&toplevel->events.request_fullscreen, NULL);
- wlr_xdg_surface_schedule_configure(toplevel->base);
}
static void xdg_toplevel_handle_set_minimized(struct wl_client *client,