commit 38bb70b47cbceaba2a2ce515edbb4251f8ed4841
parent 9db814afb5690daef79b7494625dd12165ccc786
Author: Louis Burda <quent.burda@gmail.com>
Date: Sat, 3 Oct 2020 12:19:12 +0200
Fix WINPRELOAD_POS_CENTER for single monitor
Diffstat:
M | README | | | 2 | +- |
D | dwm-scraps.c | | | 74 | -------------------------------------------------------------------------- |
M | makefile | | | 2 | +- |
M | winpreload.c | | | 53 | +++++++++++++++++++++++++++++++++++++++-------------- |
4 files changed, 41 insertions(+), 90 deletions(-)
diff --git a/README b/README
@@ -10,4 +10,4 @@ windows created by a program through the use of LD_PRELOAD. This
enables the user to set properties such as _NET_WM_WINDOW_TYPE to
start the window as floating and adjust its position. Parameters
are passed to winpreload via environment variables, which are
-prefixed with 'WINPRELOAD+'.
+prefixed with 'WINPRELOAD_'.
diff --git a/dwm-scraps.c b/dwm-scraps.c
@@ -1,74 +0,0 @@
-#ifdef XINERAMA
- if (XineramaIsActive(dpy)) {
- int i, j, n, nn;
- Client *c;
- Monitor *m;
- XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
- XineramaScreenInfo *unique = NULL;
-
- for (n = 0, m = mons; m; m = m->next, n++);
- /* only consider unique geometries as separate screens */
- unique = ecalloc(nn, sizeof(XineramaScreenInfo));
- for (i = 0, j = 0; i < nn; i++)
- if (isuniquegeom(unique, j, &info[i]))
- memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
- XFree(info);
- nn = j;
- if (n <= nn) { /* new monitors available */
- for (i = 0; i < (nn - n); i++) {
- for (m = mons; m && m->next; m = m->next);
- if (m)
- m->next = createmon();
- else
- mons = createmon();
- }
- for (i = 0, m = mons; i < nn && m; m = m->next, i++)
- if (i >= n
- || unique[i].x_org != m->mx || unique[i].y_org != m->my
- || unique[i].width != m->mw || unique[i].height != m->mh)
- {
- dirty = 1;
- m->num = i;
- m->mx = m->wx = unique[i].x_org;
- m->my = m->wy = unique[i].y_org;
- m->mw = m->ww = unique[i].width;
- m->mh = m->wh = unique[i].height;
- updatebarpos(m);
- }
- } else { /* less monitors available nn < n */
- for (i = nn; i < n; i++) {
- for (m = mons; m && m->next; m = m->next);
- while ((c = m->clients)) {
- dirty = 1;
- m->clients = c->next;
- detachstack(c);
- c->mon = mons;
- attach(c);
- attachstack(c);
- }
- if (m == selmon)
- selmon = mons;
- cleanupmon(m);
- }
- }
- free(unique);
- } else
-#endif /* XINERAMA */
- { /* default monitor setup */
- if (!mons)
- mons = createmon();
- if (mons->mw != sw || mons->mh != sh) {
- dirty = 1;
- mons->mw = mons->ww = sw;
- mons->mh = mons->wh = sh;
- updatebarpos(mons);
- }
- }
- if (dirty) {
- selmon = mons;
- selmon = wintomon(root);
- }
- return dirty;
-
-could use intersection of window rectangle and monitor to get which.
-for new windows is probably always the first monitor.
diff --git a/makefile b/makefile
@@ -1,5 +1,5 @@
CFLAGS = -nostartfiles -fPIC -shared -Wl,-soname,xwrap.so
-LDLIBS = -ldl -lX11
+LDLIBS = -ldl -lX11 -lXinerama
winpreload.so: winpreload.c
$(CC) -o $@ $< $(CFLAGS) $(LDLIBS)
diff --git a/winpreload.c b/winpreload.c
@@ -12,6 +12,7 @@
#include <X11/Xlib.h>
#include <X11/X.h>
#include <X11/Xatom.h>
+#include <X11/extensions/Xinerama.h>
extern char **environ;
@@ -41,25 +42,45 @@ static void set_properties(Display *display, Window window);
void
set_properties(Display *display, Window window)
{
- int wx, wy, dx, dy, atom = 0;
- unsigned int ww, wh, dw, dh;
+ int wx, wy, mx, my, atom = 0;
+ unsigned int ww, wh, mw, mh;
char *env = NULL;
{
Window root;
unsigned int width, height, border, depth;
- Screen *screen = XDefaultScreenOfDisplay(display);
- dw = screen->width;
- dh = screen->height;
-
- XGetGeometry(display, screen->root,
- &root, &dx, &dy, &width, &height, &border, &depth);
XGetGeometry(display, window,
&root, &wx, &wy, &ww, &wh, &border, &depth);
- }
- printf("%i %i %i %i\n", dx, dy, dw, dh);
+ /* get monitor that intersects window rect */
+ if (XineramaIsActive(display)) {
+ int mcount, i;
+ XineramaScreenInfo *info, target;
+
+ info = XineramaQueryScreens(display, &mcount);
+
+ for (i = 0; i < mcount; i++) {
+ if ((target.x_org != info[i].x_org
+ || target.y_org != info[i].y_org)
+ && wx >= info[i].x_org && wy >= info[i].y_org
+ && wx < info[i].x_org + info[i].width
+ && wy < info[i].y_org + info[i].height) {
+ target = info[i];
+ }
+ }
+
+ mx = target.x_org;
+ my = target.y_org;
+ mw = target.width;
+ mh = target.height;
+
+ XFree(info);
+ } else {
+ XGetGeometry(display, root, &root, &mx, &my,
+ &mw, &mh, &border, &depth);
+ }
+ }
char **s, *iter, *key, *value;
for (s = environ; *s; s++) {
@@ -77,12 +98,16 @@ set_properties(Display *display, Window window)
key = &key[env_prefixlen];
if (!strcmp(key, "POS_X")) {
- wx = dx + atoi(value);
+ wx = mx + atoi(value);
} else if (!strcmp(key, "POS_Y")) {
- wy = dy + atoi(value);
+ wy = my + atoi(value);
+ } else if (!strcmp(key, "RPOS_X")) {
+ wx = atoi(value);
+ } else if (!strcmp(key, "RPOS_Y")) {
+ wy = atoi(value);
} else if (!strcmp(key, "POS_CENTER")) {
- wx = dx + dw / 2.f;
- wy = dy + dh / 2.f;
+ wx = mx + (mw - ww) / 2.f;
+ wy = my + (mh - ww) / 2.f;
} else if (!strcmp(key, "DIALOG")) {
Atom a;