tRely on libwm for multi-monitor support - glazier - window management experiments
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 44ce23c88b52d3cfb89f90a77c46caf954e45fdc
 (DIR) parent 800aa0ad995b43ee6a0af0bb7c5e7a577f0c387a
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Wed, 17 Jun 2020 11:40:40 +0200
       
       Rely on libwm for multi-monitor support
       
       Diffstat:
         M ewmh.c                              |      14 ++++++++++----
         M glazier.c                           |      71 +++++++++++++++++--------------
         M makefile                            |       4 ++--
         M mkfile                              |       4 ++--
         D randr.c                             |      39 -------------------------------
         D randr.h                             |       5 -----
       
       6 files changed, 53 insertions(+), 84 deletions(-)
       ---
 (DIR) diff --git a/ewmh.c b/ewmh.c
       t@@ -7,7 +7,6 @@
        #include <xcb/randr.h>
        
        #include "arg.h"
       -#include "randr.h"
        #include "wm.h"
        
        #define LEN(x) (sizeof(x)/sizeof(x[0]))
       t@@ -17,6 +16,10 @@ struct xatom {
                xcb_atom_t atom;
        };
        
       +struct xgeom {
       +        int x, y, w, h, b;
       +};
       +
        enum EWMH_TYPES {
                IGNORE,
                NORMAL,
       t@@ -275,7 +278,8 @@ ewmh_fullscreen(xcb_window_t wid, int state)
                size_t n;
                int isfullscreen;
                xcb_atom_t *atom, original_size;
       -        struct geometry_t g, *origin;
       +        xcb_randr_monitor_info_t *m;
       +        struct xgeom g, *origin;
        
                atom = wm_get_atom(wid, ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, &n);
                original_size = wm_add_atom("ORIGINAL_SIZE", strlen("ORIGINAL_SIZE"));
       t@@ -307,13 +311,15 @@ ewmh_fullscreen(xcb_window_t wid, int state)
                        g.b = wm_get_attribute(wid, ATTR_B);
                        wm_set_atom(wid, original_size, XCB_ATOM_CARDINAL, 5, &g);
        
       -                if (randr_geometry(g.x, g.y, &g) < 0)
       +                m = wm_get_monitor(wm_find_monitor(g.x, g.y));
       +                if (!m)
                                return -1;
        
                        /* move window fullscreen */
                        wm_set_border(0, -1, wid);
       -                wm_teleport(wid, g.x, g.y, g.w, g.h);
       +                wm_teleport(wid, m->x, m->y, m->width, m->height);
                        wm_set_atom(wid, ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, 1, &ewmh[_NET_WM_STATE_FULLSCREEN].atom);
       +                free(m);
                        break;
        
                case 2: /* _NET_WM_STATE_TOGGLE */
 (DIR) diff --git a/glazier.c b/glazier.c
       t@@ -5,7 +5,6 @@
        #include <xcb/randr.h>
        
        #include "arg.h"
       -#include "randr.h"
        #include "wm.h"
        
        #define LEN(x) (sizeof(x)/sizeof(x[0]))
       t@@ -263,7 +262,7 @@ int
        cb_create(xcb_generic_event_t *ev)
        {
                int x, y, w, h;
       -        struct geometry_t m;
       +        xcb_randr_monitor_info_t *m;
                xcb_create_notify_event_t *e;
        
                e = (xcb_create_notify_event_t *)ev;
       t@@ -281,13 +280,13 @@ cb_create(xcb_generic_event_t *ev)
                        wm_get_cursor(0, scrn->root, &x, &y);
        
                        /* move window under the cursor */
       -                if (!randr_geometry(x, y, &m)) {
       +                if ((m = wm_get_monitor(wm_find_monitor(x, y)))) {
                                w = wm_get_attribute(e->window, ATTR_W);
                                h = wm_get_attribute(e->window, ATTR_H);
       -                        x = MAX(m.x, x - w/2);
       -                        y = MAX(m.y, y - h/2);
       +                        x = MAX(m->x, x - w/2);
       +                        y = MAX(m->y, y - h/2);
        
       -                        wm_teleport(e->window, MAX(m.x, x), MAX(m.y, y), w, h);
       +                        wm_teleport(e->window, x, y, w, h);
                        }
                }
        
       t@@ -676,21 +675,27 @@ ev_callback(xcb_generic_event_t *ev)
        int
        crossedge(xcb_window_t wid)
        {
       -        struct geometry_t m, w;
       -
       -        w.b = wm_get_attribute(wid, ATTR_B);
       -        w.x = wm_get_attribute(wid, ATTR_X);
       -        w.y = wm_get_attribute(wid, ATTR_Y);
       -        w.w = wm_get_attribute(wid, ATTR_W);
       -        w.h = wm_get_attribute(wid, ATTR_H);
       -        if (randr_geometry(w.x, w.y, &m) < 0)
       +        int r = 0;
       +        int x, y, w, h, b;
       +        xcb_randr_monitor_info_t *m;
       +
       +        b = wm_get_attribute(wid, ATTR_B);
       +        x = wm_get_attribute(wid, ATTR_X);
       +        y = wm_get_attribute(wid, ATTR_Y);
       +        w = wm_get_attribute(wid, ATTR_W);
       +        h = wm_get_attribute(wid, ATTR_H);
       +        m = wm_get_monitor(wm_find_monitor(x, y));
       +
       +        if (!m)
                        return -1;
        
       -        if ((w.x + w.w + 2*w.b > m.x + m.w)
       -         || (w.y + w.h + 2*w.b > m.y + m.h))
       -                return -1;
       +        if ((x + w + 2*b > m->x + m->width)
       +         || (y + h + 2*b > m->y + m->height))
       +                r = 1;
       +
       +        free(m);
                
       -        return 0;
       +        return r;
        }
        
        /*
       t@@ -699,24 +704,26 @@ crossedge(xcb_window_t wid)
        int
        snaptoedge(xcb_window_t wid)
        {
       -        int b;
       -        struct geometry_t m, w;
       -
       -        b   = wm_get_attribute(wid, ATTR_B);
       -        w.x = wm_get_attribute(wid, ATTR_X);
       -        w.y = wm_get_attribute(wid, ATTR_Y);
       -        w.w = wm_get_attribute(wid, ATTR_W);
       -        w.h = wm_get_attribute(wid, ATTR_H);
       -        if (randr_geometry(w.x, w.y, &m) < 0)
       +        int x, y, w, h, b;
       +        xcb_randr_monitor_info_t *m;
       +
       +        b = wm_get_attribute(wid, ATTR_B);
       +        x = wm_get_attribute(wid, ATTR_X);
       +        y = wm_get_attribute(wid, ATTR_Y);
       +        w = wm_get_attribute(wid, ATTR_W);
       +        h = wm_get_attribute(wid, ATTR_H);
       +        m = wm_get_monitor(wm_find_monitor(x, y));
       +
       +        if (!m)
                        return -1;
        
       -        if (w.w + 2*b > m.w) w.w = m.w - 2*b;
       -        if (w.h + 2*b > m.h) w.h = m.h - 2*b;
       +        if (w + 2*b > m->width)  w = m->width - 2*b;
       +        if (h + 2*b > m->height) h = m->height - 2*b;
        
       -        if (w.x + w.w + 2*b > m.x + m.w) w.x = MAX(m.x + b, m.x + m.w - w.w - 2*b);
       -        if (w.y + w.h + 2*b > m.y + m.h) w.y = MAX(m.y + b, m.y + m.h - w.h - 2*b);
       +        if (x + w + 2*b > m->x + m->width) x = MAX(m->x + b, m->x + m->width - w - 2*b);
       +        if (y + h + 2*b > m->y + m->height) y = MAX(m->y + b, m->y + m->height - h - 2*b);
        
       -        wm_teleport(wid, w.x, w.y, w.w, w.h);
       +        wm_teleport(wid, x, y, w, h);
                
                return 0;
        }
 (DIR) diff --git a/makefile b/makefile
       t@@ -2,8 +2,8 @@ include config.mk
        
        all: glazier ewmh
        
       -glazier: glazier.o randr.o libwm/libwm.a
       -ewmh: ewmh.o randr.o libwm/libwm.a
       +glazier: glazier.o libwm/libwm.a
       +ewmh: ewmh.o libwm/libwm.a
        
        glazier.o: glazier.c config.h
        
 (DIR) diff --git a/mkfile b/mkfile
       t@@ -2,10 +2,10 @@
        
        all:V: glazier ewmh
        
       -glazier: glazier.o randr.o libwm/libwm.a
       +glazier: glazier.o libwm/libwm.a
                ${LD} ${LDFLAGS} $prereq ${LIBS} -o $target
        
       -ewmh: ewmh.o randr.o libwm/libwm.a
       +ewmh: ewmh.o libwm/libwm.a
                ${LD} ${LDFLAGS} $prereq ${LIBS} -o $target
        
        glazier.o: glazier.c config.h
 (DIR) diff --git a/randr.c b/randr.c
       t@@ -1,39 +0,0 @@
       -#include <xcb/xcb.h>
       -#include <xcb/randr.h>
       -
       -#include "randr.h"
       -
       -extern xcb_connection_t *conn;
       -extern xcb_screen_t *scrn;
       -
       -/*
       - * Return the geometry of the monitor at the given coordinates
       - */
       -int
       -randr_geometry(int x, int y, struct geometry_t *g)
       -{
       -        xcb_randr_get_monitors_cookie_t c;
       -        xcb_randr_get_monitors_reply_t *r;
       -        xcb_randr_monitor_info_iterator_t i;
       -
       -        /* get_active: ignore inactive monitors */
       -        c = xcb_randr_get_monitors(conn, scrn->root, 1);
       -        r = xcb_randr_get_monitors_reply(conn, c, NULL);
       -        i = xcb_randr_get_monitors_monitors_iterator(r);
       -
       -        while (g && i.rem > 0) {
       -                if (x >= i.data->x
       -                 && y >= i.data->y
       -                 && x <= i.data->width + i.data->x
       -                 && y <= i.data->height + i.data->y) {
       -                        g->x = i.data->x;
       -                        g->y = i.data->y;
       -                        g->w = i.data->width;
       -                        g->h = i.data->height;
       -                        return 0;
       -                }
       -                xcb_randr_monitor_info_next(&i);
       -        }
       -
       -        return -1;
       -}
 (DIR) diff --git a/randr.h b/randr.h
       t@@ -1,5 +0,0 @@
       -struct geometry_t {
       -        int x, y, w, h, b;
       -};
       -
       -int randr_geometry(int, int, struct geometry_t *);