diff options
Diffstat (limited to 'patches/xrandrfontsize-0.8.4-20211224-2f6e597.diff')
-rw-r--r-- | patches/xrandrfontsize-0.8.4-20211224-2f6e597.diff | 288 |
1 files changed, 0 insertions, 288 deletions
diff --git a/patches/xrandrfontsize-0.8.4-20211224-2f6e597.diff b/patches/xrandrfontsize-0.8.4-20211224-2f6e597.diff deleted file mode 100644 index d7817a0..0000000 --- a/patches/xrandrfontsize-0.8.4-20211224-2f6e597.diff +++ /dev/null @@ -1,288 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index f92798a..517abbb 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -9,5 +9,19 @@ - static int borderpx = 2; - -+/* -+ * Override/adjust fontsize of choosen monitors: -+ */ -+MonitorConfig monitors_config[] = { -+ // skip = fixed relative points size (monitor dpi) -+ // =0 : fixed absolute pixel size (default screen dpi) -+ // >0 : auto absolute pixel size (monitor dpi) -+ // <0 : auto relative points size (monitor dpi) -+ // {"DP-1", 0}, // BUG:(size=0): not restored to default after back'n'forth -+ {"HDMI-0~1", -20}, // BUG:(ignored DPI=220): = 20 is eqv to 10pt (DPI=110) -+ {"HDMI-0~2", -14}, -+}; -+float winmovethreshold = 0.6; -+ - /* - * What program is execed by st depends of these precedence rules: - * 1: program passed with -e -@@ -272,6 +272,7 @@ static Shortcut shortcuts[] = { - { TERMMOD, XK_Prior, zoom, {.f = +1} }, - { TERMMOD, XK_Next, zoom, {.f = -1} }, - { TERMMOD, XK_Home, zoomreset, {.f = 0} }, -+ { TERMMOD, XK_End, refreshxrandr, {.i = 0} }, - { TERMMOD, XK_C, clipcopy, {.i = 0} }, - { TERMMOD, XK_V, clippaste, {.i = 0} }, - { TERMMOD, XK_Y, selpaste, {.i = 0} }, -diff --git a/config.mk b/config.mk -index aaa54ff..2d28597 100644 ---- a/config.mk -+++ b/config.mk -@@ -24,5 +24,7 @@ LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\ - -+LIBS += -lXrandr -+ - # flags - STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 - STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS) - STLDFLAGS = $(LIBS) $(LDFLAGS) -diff --git a/x.c b/x.c -index 684311c..ce1c418 100644 ---- a/x.c -+++ b/x.c -@@ -14,6 +14,7 @@ - #include <X11/keysym.h> - #include <X11/Xft/Xft.h> - #include <X11/XKBlib.h> -+#include <X11/extensions/Xrandr.h> - - char *argv0; - #include "arg.h" -@@ -45,5 +46,18 @@ typedef struct { - signed char appcursor; /* application cursor */ - } Key; - -+typedef struct { -+ const char *name; -+ float defaultfontsize; -+} MonitorConfig; -+ -+typedef struct { -+ Atom name; -+ int x, y, w, h; -+ float defaultfontsize, usedfontsize; -+} MonitorInfo; -+ -+static void refreshxrandr(const Arg *dummy); -+ - /* X modifiers */ - #define XK_ANY_MOD UINT_MAX -@@ -233,7 +233,12 @@ static XWindow xw; - [PropertyNotify] = propnotify, - [SelectionRequest] = selrequest, - }; - -+static double defaultrelfontsize = 0; -+static MonitorInfo *monitors_info = NULL; -+static int monitors_num = 0; -+static int prev_mindex = -1; -+ - /* Globals */ - static DC dc; - static XWindow xw; -@@ -2280,6 +2280,144 @@ xseturgency(int add) - XFree(h); - } - -+static void -+cachemonitorinfo() -+{ -+ int prev_num = monitors_num; -+ MonitorInfo *prev_info = monitors_info; -+ XRRMonitorInfo *xmonitors = XRRGetMonitors(xw.dpy, XRootWindow(xw.dpy, xw.scr), 1, &monitors_num); -+ if (!monitors_num) -+ die("xrandr found no monitors"); -+ -+ monitors_info = xmalloc(monitors_num * sizeof(MonitorInfo)); -+ -+ for (int i = 0; i < monitors_num; ++i) { -+ XRRMonitorInfo *xm = &xmonitors[i]; -+ MonitorInfo *m = &monitors_info[i]; -+ -+ m->name = xm->name; -+ m->x = xm->x; -+ m->y = xm->y; -+ m->w = xm->width; -+ m->h = xm->height; -+ -+ float px_mm = ((float)m->w / xm->mwidth + (float)m->h / xm->mheight) / 2; -+ float px_pt = 25.4 * px_mm / 72; -+ m->defaultfontsize = defaultrelfontsize * px_pt; -+ -+ // Override defaultfontsize (dpi) by user config -+ char *name = XGetAtomName(xw.dpy, xm->name); -+ for (int j = 0; j < LEN(monitors_config); ++j) -+ if (!strcmp(name, monitors_config[j].name)) { -+ m->defaultfontsize = monitors_config[j].defaultfontsize; -+ if (m->defaultfontsize < 0) -+ m->defaultfontsize *= -px_pt; -+ break; -+ } -+ // fprintf(stderr, "%s: %fpx, %f\n", name, m->defaultfontsize, m->usedfontsize); -+ XFree(name); -+ -+ // Restore usedfontsize (zoom) after re-cache for monitors with the same name -+ m->usedfontsize = m->defaultfontsize; -+ for (int j = 0; j < prev_num; ++j) -+ if (prev_info[j].name == m->name) { -+ m->usedfontsize = prev_info[j].usedfontsize; -+ break; -+ } -+ } -+ -+ XRRFreeMonitors(xmonitors); -+ free(prev_info); -+} -+ -+static int -+getmonitorindex_threshold(int w, int h, int x, int y) -+{ -+ int mindex = -1; -+ float fontsize = 0; -+ int thresholdarea = winmovethreshold * w * h; -+ -+ for (int i = 0; i < monitors_num; ++i) { -+ MonitorInfo *m = &monitors_info[i]; -+ int overlap_w = MAX(0, MIN(x + w, m->x + m->w) - MAX(x, m->x)); -+ int overlap_h = MAX(0, MIN(y + h, m->y + m->h) - MAX(y, m->y)); -+ int area = overlap_w * overlap_h; -+ // Choose monitor with largest dpi (defaultfontsize) -+ // from all "mirrored"/overlapped (e.g. projector) -+ if (area >= thresholdarea && fontsize < m->defaultfontsize) { -+ fontsize = m->defaultfontsize; -+ mindex = i; -+ } -+ } -+ return mindex; -+} -+ -+static int -+getmonitorindex_nearest(int w, int h, int x, int y) -+{ -+ int mindex = -1; -+ float fontsize = 0; -+ int overlaparea = 0; -+ -+ for (int i = 0; i < monitors_num; ++i) { -+ MonitorInfo *m = &monitors_info[i]; -+ int overlap_w = MAX(0, MIN(x + w, m->x + m->w) - MAX(x, m->x)); -+ int overlap_h = MAX(0, MIN(y + h, m->y + m->h) - MAX(y, m->y)); -+ int area = overlap_w * overlap_h; -+ // Choose monitor with largest overlapping area -+ // e.g. when "st" is initially spawned in-between monitors -+ if (area > overlaparea) { -+ overlaparea = area; -+ mindex = i; -+ } -+ } -+ return mindex; -+} -+ -+static void -+adjustmonitorfontsize(int mindex) -+{ -+ if (mindex < 0 || prev_mindex == mindex) -+ return; -+ // Save zoom of current monitor before switching -+ if (prev_mindex >= 0) -+ monitors_info[prev_mindex].usedfontsize = usedfontsize; -+ -+ defaultfontsize = monitors_info[mindex].defaultfontsize; -+ // fprintf(stderr, "Crossing: %fpx\n", defaultfontsize); -+ -+ // NOTE: do nothing if font size differs by less than 1% -+ double fontsize = monitors_info[mindex].usedfontsize; -+ double delta = 0.01 * usedfontsize; -+ if (!BETWEEN(fontsize - usedfontsize, -delta, delta)) { -+ // fprintf(stderr, "Adjusted: %fpx\n", fontsize); -+ xunloadfonts(); -+ xloadfonts(usedfont, fontsize); -+ } -+ prev_mindex = mindex; -+} -+ -+void -+refreshxrandr(const Arg *dummy) -+{ -+ // Reset index to detect change of window association on "xrandr ... --primary" -+ // otherwise: zoom won't be saved on switching and new font size won't be loaded -+ // CRIT!!! event from xrandr may place another monitor into same index -+ if (prev_mindex >= 0) -+ monitors_info[prev_mindex].usedfontsize = usedfontsize; -+ prev_mindex = -1; -+ -+ XWindowAttributes xattr = {0}; -+ cachemonitorinfo(); -+ XGetWindowAttributes(xw.dpy, xw.win, &xattr); -+ -+ int mindex = getmonitorindex_threshold(xattr.width, xattr.height, xattr.x, xattr.y); -+ if (mindex < 0) -+ mindex = getmonitorindex_nearest(xattr.width, xattr.height, xattr.x, xattr.y); -+ adjustmonitorfontsize(mindex); -+} -+ -+ - void - xbell(void) - { -@@ -2437,6 +2437,14 @@ cmessage(XEvent *e) - void - resize(XEvent *e) - { -+ // BAD: no resize on monitor plug/unplug/reconfigure -- until window itself is kept in the same place -+ // NOTE: no resize event on zoomabs() -+ // fprintf(stderr, "Resize: %dx%d+%d+%d\n", -+ // e->xconfigure.width, e->xconfigure.height, e->xconfigure.x, e->xconfigure.y); -+ -+ adjustmonitorfontsize(getmonitorindex_threshold( -+ e->xconfigure.width, e->xconfigure.height, e->xconfigure.x, e->xconfigure.y)); -+ - if (e->xconfigure.width == win.w && e->xconfigure.height == win.h) - return; - -@@ -2469,6 +2469,22 @@ run(void) - } - } while (ev.type != MapNotify); - -+ int rr_event_base, rr_error_base, rr_major, rr_minor; -+ if (!XRRQueryExtension (xw.dpy, &rr_event_base, &rr_error_base) || -+ !XRRQueryVersion (xw.dpy, &rr_major, &rr_minor) || -+ rr_major < 1 || (rr_major == 1 && rr_minor < 5)) -+ { -+ die("RandR 1.5 extension isn't available\n"); -+ } -+ XRRSelectInput(xw.dpy, xw.win, RRCrtcChangeNotifyMask); -+ -+ // WARN: can query actual window size/pos only after window is mapped and its width/height are adjusted by WM -+ // * x/y are WM-dependent and can't be determined beforehand anyway -+ // * defaultfontsize isn't available until font is loaded and actual Fc*() size queried -+ // BAD: fonts on startup are always reloaded -- how to specify their size beforehand ? -+ FcPatternGetDouble(dc.font.match->pattern, FC_SIZE, 0, &defaultrelfontsize); -+ refreshxrandr(0); -+ - ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd); - cresize(w, h); - -@@ -2500,6 +2500,16 @@ run(void) - XNextEvent(xw.dpy, &ev); - if (XFilterEvent(&ev, None)) - continue; -+ if (LASTEvent <= ev.type) { -+ if (rr_event_base + RRNotify == ev.type && -+ RRNotify_CrtcChange == ((XRRNotifyEvent *)&ev)->subtype) -+ { -+ XRRUpdateConfiguration(&ev); -+ // fprintf(stderr, "Monitor change: %d > %d\n", rr_event_base, LASTEvent); -+ refreshxrandr(0); -+ } -+ continue; -+ } - if (handler[ev.type]) - (handler[ev.type])(&ev); - } |