[PATCH] Prevent unnecessary RandR wmaker restart

2 views
Skip to first unread message

david.m...@gmail.com

unread,
Dec 24, 2025, 6:54:40 AM (yesterday) Dec 24
to Window Maker Development
As reported in bug https://github.com/window-maker/wmaker/issues/34
when RandR is enabled, everytime a monitor is turned on or off wmaker is restarting
(that happens either manually or automatically with DPMS).
This behavior causes issues with xscreensaver.

How to reproduce the issue:
-install xscreensaver and lock the screen
-turn off then on the monitor manually
-you can see that wmaker was restarted and behind the xscreensaver lock window,
the desktop appears, potentially leaking information

Instead of using the RandR event RRScreenChangeNotifyMask which is too generic,
the patch is using RRCrtcChangeNotifyMask defined since RandR 1.2 (released in 2007).
In the recent RandR version, events for output (hardware) changes are propagated via
RROutputChangeNotifyMask while layout changes (like position, size, rotation)
are propagated via RRCrtcChangeNotifyMask.

The patch is purposedly not listening for RROutputChangeNotifyMask,
thus wmaker is not restarting on DPMS events anymore.

Currently, in case a new monitor is added (or removed) wmaker is not discovering it anyway
even after an automatic restart.
Either, wmaker has to be exited and restarted fully or an external tool like arandr
has to be used to configure the new monitor. So after the patch functionality remains unchanged.
---
 src/event.c  | 20 ++++++++++++--------
 src/screen.c | 11 +++++++++--
 2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/src/event.c b/src/event.c
index 67d30098..3b93ffee 100644
--- a/src/event.c
+++ b/src/event.c
@@ -575,14 +575,18 @@ static void handleExtensions(XEvent * event)
  }
 #endif /*KEEP_XKB_LOCK_STATUS */
 #ifdef USE_RANDR
- if (w_global.xext.randr.supported && event->type == (w_global.xext.randr.event_base + RRScreenChangeNotify)) {
- /* From xrandr man page: "Clients must call back into Xlib using
-  * XRRUpdateConfiguration when screen configuration change notify
-  * events are generated */
- XRRUpdateConfiguration(event);
- WCHANGE_STATE(WSTATE_RESTARTING);
- Shutdown(WSRestartPreparationMode);
- Restart(NULL,True);
+ if (w_global.xext.randr.supported) {
+ int base = w_global.xext.randr.event_base;
+ if (event->type == base + RRScreenChangeNotify ||
+    (event->type == base + RRNotify && ((XRRNotifyEvent*)event)->subtype == RRNotify_CrtcChange)) {
+ /* From xrandr man page: "Clients must call back into Xlib using
+ * XRRUpdateConfiguration when screen configuration change notify
+ * events are generated */
+ XRRUpdateConfiguration(event);
+ WCHANGE_STATE(WSTATE_RESTARTING);
+ Shutdown(WSRestartPreparationMode);
+ Restart(NULL,True);
+ }
  }
 #endif
 }
diff --git a/src/screen.c b/src/screen.c
index 3a2fd3b7..59fc8aa9 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -669,8 +669,15 @@ WScreen *wScreenInit(int screen_number)
 #endif /* KEEP_XKB_LOCK_STATUS */
 
 #ifdef USE_RANDR
- if (w_global.xext.randr.supported)
- XRRSelectInput(dpy, scr->root_win, RRScreenChangeNotifyMask);
+ if (w_global.xext.randr.supported) {
+ int major, minor;
+ if (XRRQueryVersion(dpy, &major, &minor)) {
+ if (major >= 1 && minor >= 2)
+ XRRSelectInput(dpy, scr->root_win, RRCrtcChangeNotifyMask);
+ else
+ XRRSelectInput(dpy, scr->root_win, RRScreenChangeNotifyMask);
+ }
+ }
 #endif
 
  XSync(dpy, False);
--
2.43.0

0001-Prevent-unnecessary-RandR-wmaker-restart.patch
Reply all
Reply to author
Forward
0 new messages