aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_xdg_shell.h9
-rw-r--r--types/xdg_shell/wlr_xdg_shell.c2
-rw-r--r--types/xdg_shell/wlr_xdg_toplevel.c62
3 files changed, 67 insertions, 6 deletions
diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h
index 22008563..11709c75 100644
--- a/include/wlr/types/wlr_xdg_shell.h
+++ b/include/wlr/types/wlr_xdg_shell.h
@@ -86,6 +86,7 @@ enum wlr_xdg_surface_role {
struct wlr_xdg_toplevel_state {
bool maximized, fullscreen, resizing, activated;
+ uint32_t tiled; // enum wlr_edges
uint32_t width, height;
uint32_t max_width, max_height;
uint32_t min_width, min_height;
@@ -247,6 +248,14 @@ uint32_t wlr_xdg_toplevel_set_resizing(struct wlr_xdg_surface *surface,
bool resizing);
/**
+ * Request that this toplevel surface consider itself in a tiled layout and some
+ * edges are adjacent to another part of the tiling grid. `tiled_edges` is a
+ * bitfield of `enum wlr_edges`. Returns the associated configure serial.
+ */
+uint32_t wlr_xdg_toplevel_set_tiled(struct wlr_xdg_surface *surface,
+ uint32_t tiled_edges);
+
+/**
* Request that this xdg surface closes.
*/
void wlr_xdg_surface_send_close(struct wlr_xdg_surface *surface);
diff --git a/types/xdg_shell/wlr_xdg_shell.c b/types/xdg_shell/wlr_xdg_shell.c
index 9d171746..43b28ff0 100644
--- a/types/xdg_shell/wlr_xdg_shell.c
+++ b/types/xdg_shell/wlr_xdg_shell.c
@@ -3,7 +3,7 @@
#include "types/wlr_xdg_shell.h"
#include "util/signal.h"
-#define WM_BASE_VERSION 1
+#define WM_BASE_VERSION 2
static const struct xdg_wm_base_interface xdg_shell_impl;
diff --git a/types/xdg_shell/wlr_xdg_toplevel.c b/types/xdg_shell/wlr_xdg_toplevel.c
index 387897d9..5968c835 100644
--- a/types/xdg_shell/wlr_xdg_toplevel.c
+++ b/types/xdg_shell/wlr_xdg_toplevel.c
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <wlr/util/log.h>
+#include <wlr/util/edges.h>
#include "types/wlr_xdg_shell.h"
#include "util/signal.h"
@@ -20,6 +21,8 @@ void handle_xdg_toplevel_ack_configure(
configure->toplevel_state->resizing;
surface->toplevel->current.activated =
configure->toplevel_state->activated;
+ surface->toplevel->current.tiled =
+ configure->toplevel_state->tiled;
}
bool compare_xdg_surface_toplevel_state(struct wlr_xdg_toplevel *state) {
@@ -58,6 +61,9 @@ bool compare_xdg_surface_toplevel_state(struct wlr_xdg_toplevel *state) {
if (state->server_pending.resizing != configured.state.resizing) {
return false;
}
+ if (state->server_pending.tiled != configured.state.tiled) {
+ return false;
+ }
if (state->server_pending.width == configured.width &&
state->server_pending.height == configured.height) {
@@ -83,11 +89,10 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
}
*configure->toplevel_state = surface->toplevel->server_pending;
- uint32_t *s;
struct wl_array states;
wl_array_init(&states);
if (surface->toplevel->server_pending.maximized) {
- s = wl_array_add(&states, sizeof(uint32_t));
+ uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
if (!s) {
wlr_log(L_ERROR, "Could not allocate state for maximized xdg_toplevel");
goto error_out;
@@ -95,7 +100,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
*s = XDG_TOPLEVEL_STATE_MAXIMIZED;
}
if (surface->toplevel->server_pending.fullscreen) {
- s = wl_array_add(&states, sizeof(uint32_t));
+ uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
if (!s) {
wlr_log(L_ERROR, "Could not allocate state for fullscreen xdg_toplevel");
goto error_out;
@@ -103,7 +108,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
*s = XDG_TOPLEVEL_STATE_FULLSCREEN;
}
if (surface->toplevel->server_pending.resizing) {
- s = wl_array_add(&states, sizeof(uint32_t));
+ uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
if (!s) {
wlr_log(L_ERROR, "Could not allocate state for resizing xdg_toplevel");
goto error_out;
@@ -111,13 +116,52 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
*s = XDG_TOPLEVEL_STATE_RESIZING;
}
if (surface->toplevel->server_pending.activated) {
- s = wl_array_add(&states, sizeof(uint32_t));
+ uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
if (!s) {
wlr_log(L_ERROR, "Could not allocate state for activated xdg_toplevel");
goto error_out;
}
*s = XDG_TOPLEVEL_STATE_ACTIVATED;
}
+ if (surface->toplevel->server_pending.tiled) {
+ if (wl_resource_get_version(surface->resource) >=
+ XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION) {
+ const struct {
+ enum wlr_edges edge;
+ enum xdg_toplevel_state state;
+ } tiled[] = {
+ { WLR_EDGE_LEFT, XDG_TOPLEVEL_STATE_TILED_LEFT },
+ { WLR_EDGE_RIGHT, XDG_TOPLEVEL_STATE_TILED_RIGHT },
+ { WLR_EDGE_TOP, XDG_TOPLEVEL_STATE_TILED_TOP },
+ { WLR_EDGE_BOTTOM, XDG_TOPLEVEL_STATE_TILED_BOTTOM },
+ };
+
+ for (size_t i = 0; i < sizeof(tiled)/sizeof(tiled[0]); ++i) {
+ if ((surface->toplevel->server_pending.tiled &
+ tiled[i].edge) == 0) {
+ continue;
+ }
+
+ uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
+ if (!s) {
+ wlr_log(L_ERROR,
+ "Could not allocate state for tiled xdg_toplevel");
+ goto error_out;
+ }
+ *s = tiled[i].state;
+ }
+ } else if (!surface->toplevel->server_pending.maximized) {
+ // This version doesn't support tiling, best we can do is make the
+ // toplevel maximized
+ uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
+ if (!s) {
+ wlr_log(L_ERROR,
+ "Could not allocate state for maximized xdg_toplevel");
+ goto error_out;
+ }
+ *s = XDG_TOPLEVEL_STATE_MAXIMIZED;
+ }
+ }
uint32_t width = surface->toplevel->server_pending.width;
uint32_t height = surface->toplevel->server_pending.height;
@@ -479,3 +523,11 @@ uint32_t wlr_xdg_toplevel_set_resizing(struct wlr_xdg_surface *surface,
return schedule_xdg_surface_configure(surface);
}
+
+uint32_t wlr_xdg_toplevel_set_tiled(struct wlr_xdg_surface *surface,
+ uint32_t tiled) {
+ assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
+ surface->toplevel->server_pending.tiled = tiled;
+
+ return schedule_xdg_surface_configure(surface);
+}