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:
committed by
Carlos R. Mafra
parent
c620b354b5
commit
d303317a31
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
26
src/event.c
26
src/event.c
@@ -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);
|
||||
|
||||
10
src/screen.c
10
src/screen.c
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user