commit c9268501a2eb120474cebc937439dd4dd6edbf1a
parent c3b838c4f16762953b3bed16da031c88703fe2b1
Author: Louis Burda <quent.burda@gmail.com>
Date: Thu, 16 Mar 2023 03:34:00 +0100
Screen vs monitor semantics + env var checking
Diffstat:
M | loader.c | | | 18 | ++++++++++++------ |
M | winpl.c | | | 126 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
2 files changed, 91 insertions(+), 53 deletions(-)
diff --git a/loader.c b/loader.c
@@ -32,8 +32,10 @@ usage(int rc, bool full)
fprintf(stderr, " [-rw|-rh] SCALE Window size relative to monitor\n");
fprintf(stderr, " -c Center window on monitor\n");
fprintf(stderr, " -f Tag window as dialog (floating)\n");
- fprintf(stderr, " -sn SCREEN Select monitor based on number\n");
- fprintf(stderr, " -sp Select monitor based on cursor\n");
+ fprintf(stderr, " -mn SCREEN Select monitor based on number\n");
+ fprintf(stderr, " -mp Select monitor based on cursor\n");
+ fprintf(stderr, " -mf Select monitor based on focus\n");
+ fprintf(stderr, " -ni Window does not take input (focus)\n");
fprintf(stderr, "\n");
exit(rc);
}
@@ -134,10 +136,14 @@ main(int argc, char *const *argv)
setenv("WINPL_CENTER", "1", true);
} else if (!strcmp(*arg, "-f")) {
setenv("WINPL_FLOAT", "1", true);
- } else if (!strcmp(*arg, "-sn")) {
- setenv("WINPL_SCREEN_NUM", *++arg, true);
- } else if (!strcmp(*arg, "-sp")) {
- setenv("WINPL_SCREEN_PTR", "1", true);
+ } else if (!strcmp(*arg, "-mn")) {
+ setenv("WINPL_MON_NUM", *++arg, true);
+ } else if (!strcmp(*arg, "-mp")) {
+ setenv("WINPL_MON_PTR", "1", true);
+ } else if (!strcmp(*arg, "-mf")) {
+ setenv("WINPL_MON_FOCUS", "1", true);
+ } else if (!strcmp(*arg, "-ni")) {
+ setenv("WINPL_NO_INPUT", "1", true);
} else if (!strcmp(*arg, "--") && *(arg+1)) {
cmd_argv = arg + 1;
break;
diff --git a/winpl.c b/winpl.c
@@ -1,5 +1,6 @@
/* original: https://www.mail-archive.com/devel@xfree86.org/msg05806.html */
+#include <X11/Xutil.h>
#include <X11/Xlib.h>
#include <X11/X.h>
#include <X11/Xatom.h>
@@ -9,19 +10,17 @@
#include <sys/stat.h>
#include <sys/utsname.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdarg.h>
-#include <string.h>
#include <dlfcn.h>
#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
#define MAX(a,b) ((a > b) ? a : b)
#define MIN(a,b) ((a < b) ? a : b)
-#define ERROR(msg) { fprintf(stderr, "winpl: %s\n", msg); exit(1); }
-
extern char **environ;
static const char prefix[] = "WINPL_";
@@ -29,21 +28,33 @@ static const int prefixlen = sizeof(prefix) - 1;
static void *lib_xlib = NULL;
-static char **iter_args(char **env, const char **key, size_t *keylen,
- const char **val);
+static void
+warn(const char *fmt, ...)
+{
+ va_list ap;
-static int intersection_area(XineramaScreenInfo *info, XWindowAttributes *wa);
+ va_start(ap, fmt);
+ fprintf(stderr, "winpl: warn: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+}
+
+static void
+err(const char *fmt, ...)
+{
+ va_list ap;
-static int monitor_from_pointer(XineramaScreenInfo *info, int mcount,
- Display *display, Window window);
-static int monitor_from_focussed(Display *display, XineramaScreenInfo *info,
- int mcount);
+ va_start(ap, fmt);
+ fprintf(stderr, "winpl: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
-static void set_prop(Display *display, Window window, const char *name,
- int type, size_t size, void *val);
-static void set_props(Display *display, Window window);
+ exit(1);
+}
-char **
+static char **
iter_args(char **env, const char **key, size_t *keylen, const char **val)
{
const char *tok;
@@ -62,7 +73,7 @@ iter_args(char **env, const char **key, size_t *keylen, const char **val)
return NULL;
}
-int
+static int
intersection_area(XineramaScreenInfo *info, XWindowAttributes *wa)
{
int dx, dy;
@@ -76,7 +87,7 @@ intersection_area(XineramaScreenInfo *info, XWindowAttributes *wa)
return MAX(0, dx) * MAX(0, dy);
}
-int
+static int
monitor_from_pointer(XineramaScreenInfo *info, int mcount,
Display *display, Window window)
{
@@ -100,7 +111,7 @@ monitor_from_pointer(XineramaScreenInfo *info, int mcount,
return screen;
}
-int
+static int
monitor_from_focussed(Display *display, XineramaScreenInfo *info, int mcount)
{
Window w, root, *dws, dw, pw;
@@ -137,7 +148,7 @@ monitor_from_focussed(Display *display, XineramaScreenInfo *info, int mcount)
return screen;
}
-void
+static void
set_prop(Display *display, Window window, const char *name,
int type, size_t size, void *val)
{
@@ -148,13 +159,14 @@ set_prop(Display *display, Window window, const char *name,
PropModeReplace, val, 1);
}
-void
+static void
set_props(Display *display, Window window)
{
int wx, wy, mx, my;
unsigned int ww, wh, mw, mh;
const char *key, *val;
unsigned int border, depth;
+ XWMHints hints;
size_t keylen;
char **env;
Window root;
@@ -168,48 +180,61 @@ set_props(Display *display, Window window)
if (!XGetGeometry(display, window, &root,
&wx, &wy, &ww, &wh, &border, &depth))
- ERROR("Failed to get window geometry");
+ err("Failed to get window geometry");
if (!XGetGeometry(display, root, &root,
&mx, &my, &mw, &mh, &border, &depth))
- ERROR("Failed to get screen geometry");
+ err("Failed to get screen geometry");
if (XineramaIsActive(display)) {
XineramaScreenInfo *info;
- int mcount, screen;
+ int mcount, mon;
if (!(info = XineramaQueryScreens(display, &mcount)))
- ERROR("Failed to query xinerama");
+ err("Failed to query xinerama");
- screen = -1;
+ mon = -1;
env = environ;
while ((env = iter_args(env, &key, &keylen, &val))) {
- if (!strncmp("SCREEN_NUM", key, keylen)) {
- screen = strtoul(val, NULL, 0);
- if (screen >= mcount || screen < 0)
- ERROR("Screen out-of-bounds");
- } else if (!strncmp("SCREEN_PTR", key, keylen)) {
- screen = monitor_from_pointer(info,
+ if (!strncmp("MON_NUM", key, keylen)) {
+ mon = strtoul(val, NULL, 0);
+ if (mon < 0 || mon >= mcount)
+ err("Monitor number OOB");
+ } else if (!strncmp("MON_PTR", key, keylen)) {
+ mon = monitor_from_pointer(info,
mcount, display, window);
+ } else if (!strncmp("MON_FOCUS", key, keylen)) {
+ mon = monitor_from_focussed(display,
+ info, mcount);
+ } else if (keylen >= 4 && !strncmp(key, "MON_", 4)) {
+ err("Unsupported env var: WINPL_%.*s",
+ (int) keylen, key);
}
}
- if (screen == -1)
- screen = monitor_from_focussed(display,
- info, mcount);
+ if (mon == -1)
+ mon = monitor_from_focussed(display, info, mcount);
- if (screen == -1)
- screen = monitor_from_pointer(info, mcount,
+ if (mon == -1)
+ mon = monitor_from_pointer(info, mcount,
display, window);
- if (screen == -1)
- ERROR("Failed to get screen");
+ if (mon == -1)
+ err("Failed to get monitor");
- mx = info[screen].x_org;
- my = info[screen].y_org;
- mw = info[screen].width;
- mh = info[screen].height;
+ mx = info[mon].x_org;
+ my = info[mon].y_org;
+ mw = info[mon].width;
+ mh = info[mon].height;
+ } else {
+ env = environ;
+ while ((env = iter_args(env, &key, &keylen, &val))) {
+ if (keylen >= 4 && !strncmp(key, "MON_", 4)) {
+ warn("Xinerama is not active");
+ break;
+ }
+ }
}
env = environ;
@@ -254,6 +279,14 @@ set_props(Display *display, Window window)
"_NET_WM_WINDOW_TYPE_DIALOG", False);
set_prop(display, window, "_NET_WM_WINDOW_TYPE",
XA_ATOM, 32, &atom);
+ } else if (!strncmp(key, "NO_INPUT", keylen)) {
+ /* never take input (focus) */
+ hints.flags = InputHint;
+ hints.input = false;
+ XSetWMHints(display, window, &hints);
+ } else if (keylen < 4 || strncmp(key, "MON_", 4)) {
+ err("Unsupported env var: WINPL_%.*s",
+ (int) keylen, key);
}
}
@@ -266,8 +299,7 @@ set_props(Display *display, Window window)
XA_CARDINAL, 32, &ppid);
/* update window pos and geometry */
- XMoveWindow(display, window, wx, wy);
- XResizeWindow(display, window, ww, wh);
+ XMoveResizeWindow(display, window, wx, wy, ww, wh);
}
Window