mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-12 16:35:58 +01:00
xdg-shell: add wlr_xdg_toplevel_set_tiled
This commit is contained in:
parent
b597f5e380
commit
47f097e09b
3 changed files with 67 additions and 6 deletions
|
@ -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;
|
||||
|
@ -246,6 +247,14 @@ uint32_t wlr_xdg_toplevel_set_fullscreen(struct wlr_xdg_surface *surface,
|
|||
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.
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue