summaryrefslogtreecommitdiff
path: root/patches/xrandrfontsize-0.8.4-20211224-2f6e597.diff
diff options
context:
space:
mode:
Diffstat (limited to 'patches/xrandrfontsize-0.8.4-20211224-2f6e597.diff')
-rw-r--r--patches/xrandrfontsize-0.8.4-20211224-2f6e597.diff288
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);
- }