1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-03-19 17:23:33 +01:00

wmaker: handle keybinding change notifications

This patch is to fix an issue seen on FreeBSD 15 where
keybinding are mixed up at the cold start of wmaker.
It is mentioned at https://github.com/window-maker/wmaker/issues/43
Seems that issue is not happening on Linux.
A warm restart ("restart window maker") from the root menu
is getting rid of that issue temporarily.

To solve that issue, now wmaker is reloading the keyboard mapping
via the new wReadKeybindings function when a XkbNewKeyboardNotifyMask
event is received.
It means xkb, which is part of X11 core,
is now used by default and not conditionally with modelock.
I tried to delay reading the keybinding as late as possible but
it did not solve the issue as seems X is started with a improper
keyboard by default.

Here some debug trace when the bindings are loaded by wmaker on FreeBSD:

Keybind F12: keycode=96 modifier=0x0   <--- cold starting wmaker
Keybind F11: keycode=95 modifier=0x0
Keybind Escape: keycode=9 modifier=0x4
Keybind M: keycode=58 modifier=0x8
Keybind H: keycode=43 modifier=0x8
Keybind Up: keycode=98 modifier=0x8   <--- keycode is wrong, provided by X11
Keybind Down: keycode=104 modifier=0x8
Keybind Tab: keycode=23 modifier=0x8
Keybind Tab: keycode=23 modifier=0x9
Keybind Right: keycode=102 modifier=0xc
Keybind Left: keycode=100 modifier=0xc
Keybind 1: keycode=10 modifier=0x8
Keybind 2: keycode=11 modifier=0x8
Keybind 3: keycode=12 modifier=0x8
Keybind 4: keycode=13 modifier=0x8
Keybind 5: keycode=14 modifier=0x8
Keybind 6: keycode=15 modifier=0x8
Keybind 7: keycode=16 modifier=0x8
Keybind 8: keycode=17 modifier=0x8
Keybind 9: keycode=18 modifier=0x8
Keybind 0: keycode=19 modifier=0x8
Keybind Print: keycode=111 modifier=0x0   <--- keycode is wrong, 111 is UP key

/usr/ports/x11-wm/windowmaker/work/WindowMaker-0.96.0/src/.libs/wmaker(execInitScript(main.c:531)):
error: /root/GNUstep/Library/WindowMaker/autostart:could not execute initialization script   <--- warm restart from wmaker
Keybind F12: keycode=96 modifier=0x0
Keybind F11: keycode=95 modifier=0x0
Keybind Escape: keycode=9 modifier=0x4
Keybind M: keycode=58 modifier=0x8
Keybind H: keycode=43 modifier=0x8
Keybind Up: keycode=111 modifier=0x8   <--- UP key keycode is correct
Keybind Down: keycode=116 modifier=0x8
Keybind Tab: keycode=23 modifier=0x8
Keybind Tab: keycode=23 modifier=0x9
Keybind Right: keycode=114 modifier=0xc
Keybind Left: keycode=113 modifier=0xc
Keybind 1: keycode=10 modifier=0x8
Keybind 2: keycode=11 modifier=0x8
Keybind 3: keycode=12 modifier=0x8
Keybind 4: keycode=13 modifier=0x8
Keybind 5: keycode=14 modifier=0x8
Keybind 6: keycode=15 modifier=0x8
Keybind 7: keycode=16 modifier=0x8
Keybind 8: keycode=17 modifier=0x8
Keybind 9: keycode=18 modifier=0x8
Keybind 0: keycode=19 modifier=0x8
Keybind Print: keycode=107 modifier=0x0   <--- Print keycode is correct

Alternatively, to mitigate the issue, .xinitrc can be set to:

setxkbmap -layout us
exec wmaker

or whatever layout you are using.
This commit is contained in:
David Maciejak
2026-02-04 19:16:58 -05:00
committed by Carlos R. Mafra
parent c620b354b5
commit d303317a31
6 changed files with 54 additions and 15 deletions

View File

@@ -619,12 +619,10 @@ extern struct wmaker_global_variables {
} shape;
#endif
#ifdef KEEP_XKB_LOCK_STATUS
struct {
Bool supported;
int event_base;
} xkb;
#endif
#ifdef USE_RANDR
struct {

View File

@@ -1303,6 +1303,29 @@ void wReadDefaults(WScreen * scr, WMPropList * new_dict)
}
}
void wReadKeybindings(WScreen *scr, WMPropList *dict)
{
WDefaultEntry *entry;
unsigned int i;
void *tdata;
for (i = 0; i < wlengthof(optionList); i++) {
entry = &optionList[i];
if (entry->convert == getKeybind) {
WMPropList *plvalue = NULL;
if (dict)
plvalue = WMGetFromPLDictionary(dict, entry->plkey);
if (!plvalue)
plvalue = entry->plvalue;
if (plvalue) {
int ok = (*entry->convert)(scr, entry, plvalue, entry->addr, &tdata);
if (ok && entry->update)
(*entry->update)(scr, entry, tdata, entry->extra_data);
}
}
}
}
void wDefaultUpdateIcons(WScreen *scr)
{
WAppIcon *aicon = scr->app_icon_list;

View File

@@ -33,6 +33,7 @@ WDDomain * wDefaultsInitDomain(const char *domain, Bool requireDictionary);
void wDefaultsMergeGlobalMenus(WDDomain *menuDomain);
void wReadDefaults(WScreen *scr, WMPropList *new_dict);
void wReadKeybindings(WScreen *scr, WMPropList *dict);
void wDefaultUpdateIcons(WScreen *scr);
void wReadStaticDefaults(WMPropList *dict);
void wDefaultsCheckDomains(void *arg);

View File

@@ -49,9 +49,7 @@
#include <X11/extensions/Xrandr.h>
#endif
#ifdef KEEP_XKB_LOCK_STATUS
#include <X11/XKBlib.h>
#endif /* KEEP_XKB_LOCK_STATUS */
#include "WindowMaker.h"
#include "window.h"
@@ -103,7 +101,9 @@ static void handleKeyPress(XEvent *event);
static void handleFocusIn(XEvent *event);
static void handleMotionNotify(XEvent *event);
static void handleVisibilityNotify(XEvent *event);
#ifdef HAVE_INOTIFY
static void handle_inotify_events(void);
#endif
static void handle_selection_request(XSelectionRequestEvent *event);
static void handle_selection_clear(XSelectionClearEvent *event);
static void wdelete_death_handler(WMagicNumber id);
@@ -569,11 +569,26 @@ static void handleExtensions(XEvent * event)
handleShapeNotify(event);
}
#endif
if (w_global.xext.xkb.supported && event->type == w_global.xext.xkb.event_base) {
XkbEvent *xkbevent = (XkbEvent *) event;
if (xkbevent->any.xkb_type == XkbNewKeyboardNotify) {
int j;
WScreen *scr;
for (j = 0; j < w_global.screen_count; j++) {
scr = wScreenWithNumber(j);
wReadKeybindings(scr, w_global.domain.wmaker->dictionary);
}
}
#ifdef KEEP_XKB_LOCK_STATUS
if (wPreferences.modelock && (event->type == w_global.xext.xkb.event_base)) {
handleXkbIndicatorStateNotify((XkbEvent *) event);
else {
if (wPreferences.modelock && (xkbevent->any.xkb_type == XkbIndicatorStateNotify)) {
handleXkbIndicatorStateNotify((XkbEvent *) event);
}
}
#endif /*KEEP_XKB_LOCK_STATUS */
}
#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
@@ -1275,6 +1290,7 @@ static void handleXkbIndicatorStateNotify(XkbEvent *event)
WScreen *scr;
XkbStateRec staterec;
int i;
(void) event;
for (i = 0; i < w_global.screen_count; i++) {
scr = wScreenWithNumber(i);

View File

@@ -32,9 +32,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#ifdef KEEP_XKB_LOCK_STATUS
#include <X11/XKBlib.h>
#endif /* KEEP_XKB_LOCK_STATUS */
#ifdef USE_RANDR
#include <X11/extensions/Xrandr.h>
#endif
@@ -663,9 +661,11 @@ WScreen *wScreenInit(int screen_number)
/* Only GroupLock doesn't work correctly in my system since right-alt
* can change mode while holding it too - ]d
*/
if (w_global.xext.xkb.supported) {
XkbSelectEvents(dpy, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask);
}
if (w_global.xext.xkb.supported)
XkbSelectEvents(dpy, XkbUseCoreKbd, XkbIndicatorStateNotifyMask|XkbNewKeyboardNotifyMask, XkbIndicatorStateNotifyMask|XkbNewKeyboardNotifyMask);
#else
if (w_global.xext.xkb.supported)
XkbSelectEvents(dpy, XkbUseCoreKbd, XkbNewKeyboardNotifyMask, XkbNewKeyboardNotifyMask);
#endif /* KEEP_XKB_LOCK_STATUS */
#ifdef USE_RANDR

View File

@@ -41,9 +41,7 @@
#ifdef USE_XSHAPE
#include <X11/extensions/shape.h>
#endif
#ifdef KEEP_XKB_LOCK_STATUS
#include <X11/XKBlib.h>
#endif
#ifdef USE_RANDR
#include <X11/extensions/Xrandr.h>
#endif
@@ -601,12 +599,15 @@ void StartUp(Bool defaultScreenOnly)
w_global.xext.randr.supported = XRRQueryExtension(dpy, &w_global.xext.randr.event_base, &j);
#endif
#ifdef KEEP_XKB_LOCK_STATUS
w_global.xext.xkb.supported = XkbQueryExtension(dpy, NULL, &w_global.xext.xkb.event_base, NULL, NULL, NULL);
#ifdef KEEP_XKB_LOCK_STATUS
if (wPreferences.modelock && !w_global.xext.xkb.supported) {
wwarning(_("XKB is not supported. KbdModeLock is automatically disabled."));
wPreferences.modelock = 0;
}
#else
if (!w_global.xext.xkb.supported)
wwarning(_("XKB is not supported."));
#endif
if (defaultScreenOnly)