1

I have an application that utilizes ALT_R+ENTER to perform a function. When using this application in Xmonad, the combination Mod1+ENTER triggers the function "swap the current window with the master window". By default, ALT_L and ALT_R are mapped to Mod1.

In my .xinitrc, before I start Xmonad, I've altered my key map with xmodmap such that ALT_R is not part of the Mod1 definition. Despite this, Xmonad still performs the window swapping behavior when entering ALT_R+ENTER. Xmonad seems to be unaware that Mod1 no longer includes ALT_R.

Here is my .xinitrc

# Java's GUI can't handle some non-reparenting window managers like
# Xmonad without being told how to behave
export _JAVA_AWT_WM_NONREPARENTING=1

# The right Alt key is useful in IntelliJ, tell Xmonad to ignore it
xmodmap ~/.Xmodmap

# Start Xmonad
xmonad

Here is the output of xmodmap after Xmonad starts.

xmodmap:  up to 4 keys per modifier, (keycodes in parentheses):

shift       Shift_L (0x32),  Shift_R (0x3e)
lock        Caps_Lock (0x42)
control     Control_L (0x25),  Control_R (0x69)
mod1        Alt_L (0x40),  Meta_L (0xcd)
mod2        Num_Lock (0x4d)
mod3      
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf)
mod5        ISO_Level3_Shift (0x5c),  Mode_switch (0xcb)

I've recorded the sequence with xev and confirmed that the ENTER is never registered. Instead, several FocusIn/FocusOut events occur after the ALT_R is recorded.

KeyPress event, serial 32, synthetic NO, window 0x1200001,
    root 0xc0, subw 0x0, time 1432589, (92,374), root:(93,375),
    state 0x0, keycode 108 (keysym 0xffea, Alt_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

FocusOut event, serial 32, synthetic NO, window 0x1200001,
    mode NotifyGrab, detail NotifyAncestor

PropertyNotify event, serial 32, synthetic NO, window 0x1200001,
    atom 0x155 (WM_STATE), time 1433760, state PropertyNewValue

FocusOut event, serial 32, synthetic NO, window 0x1200001,
    mode NotifyUngrab, detail NotifyPointer

FocusIn event, serial 32, synthetic NO, window 0x1200001,
    mode NotifyUngrab, detail NotifyAncestor

KeymapNotify event, serial 32, synthetic NO, window 0x0,
    keys:  0   0   0   0   0   0   0   0   0   0   0   0   0   16  0   0   
           0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   

KeyRelease event, serial 32, synthetic NO, window 0x1200001,
    root 0xc0, subw 0x0, time 1434117, (92,374), root:(93,375),
    state 0x8, keycode 108 (keysym 0xffea, Alt_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

Another interesting observation is that xev reports the state of each key event as 8, regardless of whether ALT_L or ALT_R is being pressed. The constant Mod1Mask in /usr/include/X11/X.h is defined as 8. The following sequence is ALT_L+f followed by ALT_R+f.

KeyPress event, serial 32, synthetic NO, window 0x1000001,
    root 0xc0, subw 0x0, time 4126632, (85,488), root:(86,489),
    state 0x0, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 32, synthetic NO, window 0x1000001,
    root 0xc0, subw 0x0, time 4126850, (85,488), root:(86,489),
    state 0x8, keycode 41 (keysym 0x66, f), same_screen YES,
    XLookupString gives 1 bytes: (66) "f"
    XmbLookupString gives 1 bytes: (66) "f"
    XFilterEvent returns: False

KeyRelease event, serial 32, synthetic NO, window 0x1000001,
    root 0xc0, subw 0x0, time 4126930, (85,488), root:(86,489),
    state 0x8, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 32, synthetic NO, window 0x1000001,
    root 0xc0, subw 0x0, time 4126969, (85,488), root:(86,489),
    state 0x0, keycode 41 (keysym 0x66, f), same_screen YES,
    XLookupString gives 1 bytes: (66) "f"
    XFilterEvent returns: False

KeyPress event, serial 32, synthetic NO, window 0x1000001,
    root 0xc0, subw 0x0, time 4127907, (85,488), root:(86,489),
    state 0x0, keycode 108 (keysym 0xffea, Alt_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 32, synthetic NO, window 0x1000001,
    root 0xc0, subw 0x0, time 4128123, (85,488), root:(86,489),
    state 0x8, keycode 41 (keysym 0x66, f), same_screen YES,
    XLookupString gives 1 bytes: (66) "f"
    XmbLookupString gives 1 bytes: (66) "f"
    XFilterEvent returns: False

KeyRelease event, serial 32, synthetic NO, window 0x1000001,
    root 0xc0, subw 0x0, time 4128164, (85,488), root:(86,489),
    state 0x8, keycode 108 (keysym 0xffea, Alt_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 32, synthetic NO, window 0x1000001,
    root 0xc0, subw 0x0, time 4128203, (85,488), root:(86,489),
    state 0x0, keycode 41 (keysym 0x66, f), same_screen YES,
    XLookupString gives 1 bytes: (66) "f"
    XFilterEvent returns: False

So the question now becomes, if xmodmask says that ALT_R is not mod1, why is X reporting ALT_R+f as if it was?

3

Xmonad can only do this if you use different modifier-masks. In its source code it mentions a special case for example:

-- modMask lets you specify which modkey you want to use. The default
-- is mod1Mask ("left alt").  You may also consider using mod3Mask
-- ("right alt"), which does not conflict with emacs keybindings. The
-- "windows key" is usually mod4Mask.
--
myModMask       = mod1Mask

The suggestion uses two modifier masks because none of the predefined key-modifiers in X include the alt (or meta) key. Those include Shift, Lock, Control — and 5 unspecified modifier keys. Xmonad has no special knowledge of any of these keys other than (reading the source code) Shift and Lock.

So you must assign Alt_L and Alt_R to separate modifier masks if you want them to be used for different purposes in Xmonad.

2
  • You mention that I must assign ALT_R to a separate modifier mask if I want to use it for a different purpose. My question is how can I use it for NO purpose. I don't want Xmonad to interpret it at all. – Huckle Oct 31 '15 at 16:09
  • I've digged into the Xmonad source and the Haskell X11 package source. The Haskell X11 package defines xK_ALT_L and xK_ALT_R, but it doesn't tie their definitions to mod1Mask in any way. Xmonad doesn't import the definition of the Alt keys, so it is not special casing anything either. They should just see whatever flags the X server tells them. I see no reason why Xmonad would interpret ALT_R as Mod1 given the output of xmodmap in the question overview, yet for some reason it does. – Huckle Oct 31 '15 at 17:07
0

The reason Xmonad is treating ALT_R+ENTER as if it was mod1+ENTER is because X is setting the mod1Mask bit in the state field of the KeyEvent, as shown in the xev output in the question. Xmonad is unaware that ALT_R is the key being pressed because X tells it that ENTER was pressed with state = mod1Mask.

Why X is not respecting xmodmap is a separate question, asked here: Why isn't X treating ALT_L and ALT_R differently w/r/t Mod1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.