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);