tMap new windows in the middle of the output - spkp - Stacking wayland compositor
(HTM) git clone git://git.z3bra.org/spkp.git
(DIR) Log
(DIR) Files
(DIR) Refs
---
(DIR) commit 3867c8b681c67c614f258aad4dc65fb8f775786f
(DIR) parent 6ab5e13d8e42ac4c6490936970e6ec4085fab45a
(HTM) Author: Willy Goiffon <dev@z3bra.org>
Date: Mon, 16 Nov 2020 11:47:15 +0100
Map new windows in the middle of the output
Diffstat:
M sp:kp.c | 40 +++++++++++++++++++++++++++++--
1 file changed, 38 insertions(+), 2 deletions(-)
---
(DIR) diff --git a/sp:kp.c b/sp:kp.c
t@@ -32,6 +32,7 @@
#include "arg.h"
#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
#define CLEANMASK(mask) (mask & ~(WLR_MODIFIER_CAPS|WLR_MODIFIER_SHIFT))
enum {
t@@ -400,14 +401,19 @@ cb_new_window(struct wl_listener *listener, void *data)
window->server = server;
window->toplevel = surface;
- window->x = 0;
- window->y = 0;
+ window->x = -1;
+ window->y = -1;
window->mapped = 0;
window->map.notify = cb_map_window;
window->unmap.notify = cb_unmap_window;
window->destroy.notify = cb_destroy_window;
+ /* have the client consider itself "tiled", to constrain it */
+ wlr_xdg_toplevel_set_tiled(window->toplevel,
+ WLR_EDGE_LEFT | WLR_EDGE_RIGHT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM);
+
+
wl_signal_add(&surface->events.map, &window->map);
wl_signal_add(&surface->events.unmap, &window->unmap);
wl_signal_add(&surface->events.destroy, &window->destroy);
t@@ -464,9 +470,39 @@ void
cb_map_window(struct wl_listener *listener, void *data)
{
(void)data;
+ int ow, oh;
struct window *w;
+ struct wlr_output *output;
+ struct state *server;
+ struct wlr_output_layout_output *layer;
+ struct wlr_box geom;
w = wl_container_of(listener, w, map);
+ server = w->server;
+
+ /*
+ * New windows are created with no specific position on
+ * screen. In this case, they're put in the middle of the output,
+ * and eventually resized if they're bigger than said output.
+ */
+ if (w->x < 0 || w->y < 0) {
+ output = wlr_output_layout_output_at(server->layout,
+ server->cursor->x, server->cursor->y);
+ layer = wlr_output_layout_get(server->layout, output);
+
+ wlr_output_effective_resolution(output, &ow, &oh);
+ wlr_xdg_surface_get_geometry(w->toplevel, &geom);
+
+ if (geom.width > ow || geom.height > oh) {
+ geom.width = MIN(ow - 2 * bordersize, geom.width);
+ geom.height = MIN(oh - 2 * bordersize, geom.height);
+ wlr_xdg_toplevel_set_size(w->toplevel, geom.width, geom.height);
+ }
+
+ w->x = layer->x + ow/2 - geom.width/2;
+ w->y = layer->y + oh/2 - geom.height/2;
+ }
+
w->mapped = 1;
focus(w);