Xpra: Ticket #570: Cmd key buggy from Mac to Linux

Hi, there, Thanks for the Xpra, it's an awesome product to use. I have some troubles with setting my keyboard to work when I connect from Mac to my Linux machine.

I want to be able to remap my control and Cmd keys to Control_L and option to Alt_L. Looks like it's impossible right now.

On mac I use Xpra.dmg from wineswitch and default server for Trusty:

xpra client version 0.12.4
** Message: pygobject_register_sinkfunc is deprecated (GstObject)
** (Xpra:25450): WARNING **: Trying to register gtype '(null)' as flags when in fact it is of type '(null)'
** (Xpra:25450): WARNING **: Trying to register gtype 'glong' as enum when in fact it is of type 'glong'
** (Xpra:25450): WARNING **: Trying to register gtype '(null)' as flags when in fact it is of type '(null)'
** (Xpra:25450): WARNING **: Trying to register gtype '(null)' as enum when in fact it is of type '(null)'
2014-05-13 12:33:45,549 Unable to load ArrayDatatype accelerator from OpenGL_accelerate
2014-05-13 12:33:45,575 Unable to load converters accelerators (wrapper, arraydatatype) from OpenGL_accelerate
2014-05-13 12:33:45,578 Unable to load arrayhelpers accelerator from OpenGL_accelerate
2014-05-13 12:33:45,834 Unable to load VBO accelerator from OpenGL_accelerate
2014-05-13 12:33:45,893 Unable to load numpy_formathandler accelerator from OpenGL_accelerate
2014-05-13 12:33:45,894 PyOpenGL warning: OpenGL_accelerate module loaded
2014-05-13 12:33:45,951 using default keyboard settings
2014-05-13 12:33:45,956 desktop size is 2560x1600 with 1 screen(s):
2014-05-13 12:33:45,956   'dhcp-172-19-72-138.mtv.corp.google.com' (903x564 mm)
2014-05-13 12:33:45,956     monitor 1
2014-05-13 12:33:46,333 server: Linux Ubuntu 14.04 trusty, Xpra version 0.12.3 (r6075)
2014-05-13 12:33:46,345 Attached to ssh:timothy:100 (press Control-C to detach)
2014-05-13 12:33:46,410 Unable to load nones_formathandler accelerator from OpenGL_accelerate

I'm using Kinese Freestyle 2 for Mac keyboard, if this is important. Here is output for xev on XQuartz local Mac , Normal X from Mac to Linux, Xpra from Mac to Linux, Xpra from Mac to Linux (no key swap), xpra from Linux to Linux, X local Linux.

OS / key code (keysym) left control left option left command right command right option
Local Mac XQuarz 67 (Control_L) 66 (Alt_L) 63 (Meta_L) 71 (Meta_R) 69 (Alt_R)
X From Mac to Linux 67 (Control_L) 66 (Alt_L) 63 (Meta_L) 71 (Meta_R) 69 (Alt_R)
Xpra from Mac to Linux 64 (Alt_L) 101 (Alt_L) 37 (Control_L) 37 (Control_L) 114 (Alt_R)
Xpra from Mac to Linux (no key swap) 37 (Control_L) 101 (Alt_L) 64 (Alt_L) 113 (Alt_R) 114 (Alt_R)
xpra from Linux to Linux 37 (Control_L) 64 (Alt_L) + 108 KeyRelease? 133 (Super_L) + 134 KeyRelease? 134 (Super_R) (only KeyRelease?) 108 (Alt_R) (only KeyRelease?)
X local Linux 37 (Control_L) 64 (Alt_L) 133 (Super_L) 134 (Super_R) 108 (Alt_R)

There are several problems here: 1) Xpra from Mac uses code 64 for either control or command, but xpra from linux uses code 64 for option 2) KeyRelease? Events are messed up when xpra connects from Linux 3) Xpra mapping for Mac are significantly different from both ssh -X and local X mappings, which is confusing

Can you help me to grasp how Xpra selects key codes for key presses and how does it maps it into keysyms? And is this configurable in any way? Could it be that Xpra X server uses its own configuration?

Thank you.



Wed, 14 May 2014 01:55:52 GMT - Timothy Basanov:

More info: Mac 10.9.2

Inside xpra session on Linux:

$ setxkbmap -print
xkb_keymap {
        xkb_keycodes  { include "xfree86+aliases(qwerty)"       };
        xkb_types     { include "complete"      };
        xkb_compat    { include "complete"      };
        xkb_symbols   { include "pc+us+inet(pc105)"     };
        xkb_geometry  { include "pc(pc105)"     };
};
$ setxkbmap -query
rules:      base
model:      pc105
layout:     us
$ xmodmap -pm
xmodmap:  up to 6 keys per modifier, (keycodes in parentheses):
shift       Shift_L (0x32),  Shift_R (0x3e)
lock        Caps_Lock (0x42)
control     Control_L (0x25),  Control_R (0x6d)
mod1        Alt_L (0x40),  Alt_L (0x65),  Alt_R (0x71),  Alt_R (0x72),  Alt_L (0x7d),  Meta_L (0x9c)
mod2        Num_Lock (0x4d)
mod3        Super_L (0x73),  Super_R (0x74),  Super_L (0x7f)
mod4        Hyper_L (0x80),  Hyper_R (0x88)
mod5        Mode_switch (0x8),  ISO_Level3_Shift (0x7c)
$ xmodmap -pke
keycode   8 = Mode_switch NoSymbol Mode_switch NoSymbol Mode_switch
keycode   9 = Escape NoSymbol Escape NoSymbol Escape
keycode  10 = 1 exclam exclamdown
keycode  11 = 2 at trademark EuroSign
keycode  12 = 3 numbersign sterling
keycode  13 = 4 dollar cent
keycode  14 = 5 percent infinity
keycode  15 = 6 asciicircum section
keycode  16 = 7 ampersand paragraph doubledagger
keycode  17 = 8 asterisk enfilledcircbullet degree
keycode  18 = 9 parenleft ordfeminine periodcentered
keycode  19 = 0 parenright masculine singlelowquotemark
keycode  20 = minus underscore endash emdash
keycode  21 = equal plus notequal plusminus
keycode  22 = BackSpace BackSpace BackSpace BackSpace BackSpace BackSpace
keycode  23 = Tab ISO_Left_Tab Tab ISO_Left_Tab Tab ISO_Left_Tab
keycode  24 = q Q oe OE
keycode  25 = w W NoSymbol doublelowquotemark
keycode  26 = e E dead_acute acute
keycode  27 = r R registered
keycode  28 = t T dagger caron
keycode  29 = y Y yen Aacute
keycode  30 = u U dead_diaeresis diaeresis
keycode  31 = i I dead_circumflex
keycode  32 = o O oslash Oslash
keycode  33 = p P Greek_pi Greek_PI
keycode  34 = bracketleft braceleft leftdoublequotemark rightdoublequotemark
keycode  35 = bracketright braceright leftsinglequotemark rightsinglequotemark
keycode  36 = Return NoSymbol Return NoSymbol Return
keycode  37 = Control_L NoSymbol Control_L NoSymbol Control_L
keycode  38 = a A aring Aring
keycode  39 = s S ssharp Iacute
keycode  40 = d D partialderivative Icircumflex
keycode  41 = f F function Idiaeresis
keycode  42 = g G copyright doubleacute
keycode  43 = h H abovedot Oacute
keycode  44 = j J NoSymbol Ocircumflex
keycode  45 = k K k K k K
keycode  46 = l L notsign Ograve
keycode  47 = semicolon colon ellipsis Uacute
keycode  48 = apostrophe quotedbl ae AE
keycode  49 = grave asciitilde dead_grave grave
keycode  50 = Shift_L NoSymbol Shift_L NoSymbol Shift_L
keycode  51 = backslash bar guillemotleft guillemotright
keycode  52 = z Z Greek_OMEGA cedilla
keycode  53 = x X NoSymbol ogonek
keycode  54 = c C ccedilla Ccedilla
keycode  55 = v V radical
keycode  56 = b B integral idotless
keycode  57 = n N dead_tilde
keycode  58 = m M mu Acircumflex
keycode  59 = comma less lessthanequal macron
keycode  60 = period greater greaterthanequal breve
keycode  61 = slash question division questiondown
keycode  62 = Shift_R NoSymbol Shift_R NoSymbol Shift_R
keycode  63 = KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply XF86ClearGrab
keycode  64 = Alt_L Meta_L Alt_L Meta_L Alt_L Meta_L
keycode  65 = space NoSymbol nobreakspace
keycode  66 = Caps_Lock NoSymbol Caps_Lock NoSymbol Caps_Lock
keycode  67 = F1 F1 F1 F1 F1 F1 XF86Switch_VT_1
keycode  68 = F2 F2 F2 F2 F2 F2 XF86Switch_VT_2
keycode  69 = F3 F3 F3 F3 F3 F3 XF86Switch_VT_3
keycode  70 = F4 F4 F4 F4 F4 F4 XF86Switch_VT_4
keycode  71 = F5 F5 F5 F5 F5 F5 XF86Switch_VT_5
keycode  72 = F6 F6 F6 F6 F6 F6 XF86Switch_VT_6
keycode  73 = F7 F7 F7 F7 F7 F7 XF86Switch_VT_7
keycode  74 = F8 F8 F8 F8 F8 F8 XF86Switch_VT_8
keycode  75 = F9 F9 F9 F9 F9 F9 XF86Switch_VT_9
keycode  76 = F10 F10 F10 F10 F10 F10 XF86Switch_VT_10
keycode  77 = Num_Lock NoSymbol Num_Lock NoSymbol Num_Lock
keycode  78 = Scroll_Lock NoSymbol Scroll_Lock NoSymbol Scroll_Lock
keycode  79 = KP_Home KP_7 KP_Home KP_7 KP_Home KP_7
keycode  80 = KP_Up KP_8 KP_Up KP_8 KP_Up KP_8
keycode  81 = KP_Prior KP_9 KP_Prior KP_9 KP_Prior KP_9
keycode  82 = KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract XF86Prev_VMode
keycode  83 = KP_Left KP_4 KP_Left KP_4 KP_Left KP_4
keycode  84 = KP_Begin KP_5 KP_Begin KP_5 KP_Begin KP_5
keycode  85 = KP_Right KP_6 KP_Right KP_6 KP_Right KP_6
keycode  86 = KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add XF86Next_VMode
keycode  87 = KP_End KP_1 KP_End KP_1 KP_End KP_1
keycode  88 = KP_Down KP_2 KP_Down KP_2 KP_Down KP_2
keycode  89 = KP_Next KP_3 KP_Next KP_3 KP_Next KP_3
keycode  90 = KP_Insert KP_0 KP_Insert KP_0 KP_Insert KP_0
keycode  91 = KP_Delete KP_Decimal KP_Delete KP_Decimal KP_Delete KP_Decimal
keycode  92 = section plusminus section plusminus section plusminus
keycode  93 = Return NoSymbol Return NoSymbol Return
keycode  94 = less greater less greater bar brokenbar bar
keycode  95 = F11 F11 F11 F11 F11 F11 XF86Switch_VT_11
keycode  96 = F12 F12 F12 F12 F12 F12 XF86Switch_VT_12
keycode  97 = Home NoSymbol Home NoSymbol Home
keycode  98 = Up slash Up slash Up slash
keycode  99 = Prior NoSymbol Prior NoSymbol Prior
keycode 100 = Left plus Left plus Left plus
keycode 101 = Alt_L Meta_L Alt_L Meta_L Alt_L Meta_L
keycode 102 = Right asterisk Right asterisk Right asterisk
keycode 103 = End NoSymbol End NoSymbol End
keycode 104 = Down equal Down equal Down equal
keycode 105 = Next NoSymbol Next NoSymbol Next
keycode 106 = Insert NoSymbol Insert NoSymbol Insert
keycode 107 = Delete NoSymbol Delete NoSymbol Delete
keycode 108 = KP_Enter NoSymbol KP_Enter NoSymbol KP_Enter
keycode 109 = Control_R NoSymbol Control_R NoSymbol Control_R
keycode 110 = Pause Break Pause Break Pause Break
keycode 111 = Print Sys_Req Print Sys_Req Print Sys_Req
keycode 112 = KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide XF86Ungrab
keycode 113 = Alt_R Meta_R Alt_R Meta_R Alt_R Meta_R
keycode 114 = Alt_R Meta_R Alt_R Meta_R Alt_R Meta_R
keycode 115 = Super_L NoSymbol Super_L NoSymbol Super_L
keycode 116 = Super_R NoSymbol Super_R NoSymbol Super_R
keycode 117 = Menu NoSymbol Menu NoSymbol Menu
keycode 118 = Escape NoSymbol Escape NoSymbol Escape
keycode 119 = F13 NoSymbol F13 NoSymbol F13
keycode 120 = F16 NoSymbol F16 NoSymbol F16
keycode 121 = F14 NoSymbol F14 NoSymbol F14
keycode 122 = F15 NoSymbol F15 NoSymbol F15
keycode 123 = Prior NoSymbol Prior NoSymbol Prior
keycode 124 = ISO_Level3_Shift NoSymbol ISO_Level3_Shift NoSymbol ISO_Level3_Shift
keycode 125 = Alt_L NoSymbol Alt_L NoSymbol Alt_L
keycode 126 = KP_Equal NoSymbol KP_Equal NoSymbol KP_Equal
keycode 127 = Super_L NoSymbol Super_L NoSymbol Super_L
keycode 128 = Hyper_L NoSymbol Hyper_L NoSymbol Hyper_L
keycode 129 = XF86AudioMedia NoSymbol XF86AudioMedia NoSymbol XF86AudioMedia
keycode 130 = Next NoSymbol Next NoSymbol Next
keycode 131 = Left NoSymbol Left NoSymbol Left
keycode 132 = Right NoSymbol Right NoSymbol Right
keycode 133 = Down NoSymbol Down NoSymbol Down
keycode 134 = KP_Decimal KP_Decimal KP_Decimal KP_Decimal KP_Decimal KP_Decimal
keycode 135 = Up NoSymbol Up NoSymbol Up
keycode 136 = Hyper_R NoSymbol Hyper_R NoSymbol Hyper_R
keycode 137 =
keycode 138 =
keycode 139 =
keycode 140 =
keycode 141 =
keycode 142 =
keycode 143 =
keycode 144 = XF86AudioPrev NoSymbol XF86AudioPrev NoSymbol XF86AudioPrev
keycode 145 =
keycode 146 =
keycode 147 =
keycode 148 =
keycode 149 =
keycode 150 = XF86Sleep NoSymbol XF86Sleep NoSymbol XF86Sleep
keycode 151 =
keycode 152 =
keycode 153 = XF86AudioNext NoSymbol XF86AudioNext NoSymbol XF86AudioNext
keycode 154 =
keycode 155 =
keycode 156 = Meta_L NoSymbol Meta_L NoSymbol Meta_L
keycode 157 =
keycode 158 =
keycode 159 =
keycode 160 = XF86AudioMute NoSymbol XF86AudioMute NoSymbol XF86AudioMute
keycode 161 = XF86Calculator NoSymbol XF86Calculator NoSymbol XF86Calculator
keycode 162 = XF86AudioPlay XF86AudioPause XF86AudioPlay XF86AudioPause XF86AudioPlay XF86AudioPause
keycode 163 =
keycode 164 = XF86AudioStop XF86Eject XF86AudioStop XF86Eject XF86AudioStop XF86Eject
keycode 165 =
keycode 166 =
keycode 167 =
keycode 168 =
keycode 169 =
keycode 170 = XF86Eject NoSymbol XF86Eject NoSymbol XF86Eject
keycode 171 =
keycode 172 =
keycode 173 =
keycode 174 = XF86AudioLowerVolume NoSymbol XF86AudioLowerVolume NoSymbol XF86AudioLowerVolume
keycode 175 =
keycode 176 = XF86AudioRaiseVolume NoSymbol XF86AudioRaiseVolume NoSymbol XF86AudioRaiseVolume
keycode 177 =
keycode 178 = XF86WWW NoSymbol XF86WWW NoSymbol XF86WWW
keycode 179 =
keycode 180 =
keycode 181 =
keycode 182 =
keycode 183 =
keycode 184 =
keycode 185 =
keycode 186 =
keycode 187 =
keycode 188 =
keycode 189 =
keycode 190 =
keycode 191 =
keycode 192 =
keycode 193 =
keycode 194 =
keycode 195 =
keycode 196 =
keycode 197 =
keycode 198 =
keycode 199 =
keycode 200 =
keycode 201 =
keycode 202 =
keycode 203 =
keycode 204 = XF86Eject NoSymbol XF86Eject NoSymbol XF86Eject
keycode 205 =
keycode 206 =
keycode 207 =
keycode 208 =
keycode 209 =
keycode 210 =
keycode 211 =
keycode 212 =
keycode 213 =
keycode 214 = XF86Display NoSymbol XF86Display NoSymbol XF86Display
keycode 215 = XF86KbdLightOnOff NoSymbol XF86KbdLightOnOff NoSymbol XF86KbdLightOnOff
keycode 216 = XF86KbdBrightnessDown NoSymbol XF86KbdBrightnessDown NoSymbol XF86KbdBrightnessDown
keycode 217 = XF86KbdBrightnessUp NoSymbol XF86KbdBrightnessUp NoSymbol XF86KbdBrightnessUp
keycode 218 =
keycode 219 =
keycode 220 =
keycode 221 =
keycode 222 = XF86PowerOff NoSymbol XF86PowerOff NoSymbol XF86PowerOff
keycode 223 = XF86Standby NoSymbol XF86Standby NoSymbol XF86Standby
keycode 224 =
keycode 225 =
keycode 226 =
keycode 227 = XF86WakeUp NoSymbol XF86WakeUp NoSymbol XF86WakeUp
keycode 228 =
keycode 229 = XF86Search NoSymbol XF86Search NoSymbol XF86Search
keycode 230 = XF86Favorites NoSymbol XF86Favorites NoSymbol XF86Favorites
keycode 231 = XF86Reload NoSymbol XF86Reload NoSymbol XF86Reload
keycode 232 = XF86Stop NoSymbol XF86Stop NoSymbol XF86Stop
keycode 233 = XF86Forward NoSymbol XF86Forward NoSymbol XF86Forward
keycode 234 = XF86Back NoSymbol XF86Back NoSymbol XF86Back
keycode 235 = XF86MyComputer NoSymbol XF86MyComputer NoSymbol XF86MyComputer
keycode 236 = XF86Mail NoSymbol XF86Mail NoSymbol XF86Mail
keycode 237 = XF86AudioMedia NoSymbol XF86AudioMedia NoSymbol XF86AudioMedia
keycode 238 =
keycode 239 =
keycode 240 =
keycode 241 =
keycode 242 =
keycode 243 =
keycode 244 = XF86Battery NoSymbol XF86Battery NoSymbol XF86Battery
keycode 245 =
keycode 246 = XF86WLAN NoSymbol XF86WLAN NoSymbol XF86WLAN
keycode 247 =
keycode 248 =
keycode 249 =
keycode 250 =
keycode 251 =
keycode 252 =
keycode 253 =
keycode 254 =
keycode 255 =
$ python /usr/lib/python2.7/dist-packages/xpra/gtk_common/keymap.py
gtk_keymap: (keyval, name, keycode, group, level)
(65406, 'Mode_switch', 8, 0, 0)
(65307, 'Escape', 9, 0, 0)
(49, '1', 10, 0, 0)
(33, 'exclam', 10, 0, 1)
(161, 'exclamdown', 10, 1, 0)
(50, '2', 11, 0, 0)
(64, 'at', 11, 0, 1)
(2761, 'trademark', 11, 1, 0)
(8364, 'EuroSign', 11, 1, 1)
(51, '3', 12, 0, 0)
(35, 'numbersign', 12, 0, 1)
(163, 'sterling', 12, 1, 0)
(52, '4', 13, 0, 0)
(36, 'dollar', 13, 0, 1)
(162, 'cent', 13, 1, 0)
(53, '5', 14, 0, 0)
(37, 'percent', 14, 0, 1)
(2242, 'infinity', 14, 1, 0)
(54, '6', 15, 0, 0)
(94, 'asciicircum', 15, 0, 1)
(167, 'section', 15, 1, 0)
(55, '7', 16, 0, 0)
(38, 'ampersand', 16, 0, 1)
(182, 'paragraph', 16, 1, 0)
(2802, 'doubledagger', 16, 1, 1)
(56, '8', 17, 0, 0)
(42, 'asterisk', 17, 0, 1)
(2790, 'enfilledcircbullet', 17, 1, 0)
(176, 'degree', 17, 1, 1)
(57, '9', 18, 0, 0)
(40, 'parenleft', 18, 0, 1)
(170, 'ordfeminine', 18, 1, 0)
(183, 'periodcentered', 18, 1, 1)
(48, '0', 19, 0, 0)
(41, 'parenright', 19, 0, 1)
(186, 'masculine', 19, 1, 0)
(2813, 'singlelowquotemark', 19, 1, 1)
(45, 'minus', 20, 0, 0)
(95, 'underscore', 20, 0, 1)
(2730, 'endash', 20, 1, 0)
(2729, 'emdash', 20, 1, 1)
(61, 'equal', 21, 0, 0)
(43, 'plus', 21, 0, 1)
(2237, 'notequal', 21, 1, 0)
(177, 'plusminus', 21, 1, 1)
(65288, 'BackSpace', 22, 0, 0)
(65288, 'BackSpace', 22, 0, 1)
(65289, 'Tab', 23, 0, 0)
(65056, 'ISO_Left_Tab', 23, 0, 1)
(113, 'q', 24, 0, 0)
(81, 'Q', 24, 0, 1)
(5053, 'oe', 24, 1, 0)
(5052, 'OE', 24, 1, 1)
(119, 'w', 25, 0, 0)
(87, 'W', 25, 0, 1)
(2814, 'doublelowquotemark', 25, 1, 1)
(101, 'e', 26, 0, 0)
(69, 'E', 26, 0, 1)
(65105, 'dead_acute', 26, 1, 0)
(180, 'acute', 26, 1, 1)
(114, 'r', 27, 0, 0)
(82, 'R', 27, 0, 1)
(174, 'registered', 27, 1, 0)
(116, 't', 28, 0, 0)
(84, 'T', 28, 0, 1)
(2801, 'dagger', 28, 1, 0)
(439, 'caron', 28, 1, 1)
(121, 'y', 29, 0, 0)
(89, 'Y', 29, 0, 1)
(165, 'yen', 29, 1, 0)
(193, 'Aacute', 29, 1, 1)
(117, 'u', 30, 0, 0)
(85, 'U', 30, 0, 1)
(65111, 'dead_diaeresis', 30, 1, 0)
(168, 'diaeresis', 30, 1, 1)
(105, 'i', 31, 0, 0)
(73, 'I', 31, 0, 1)
(65106, 'dead_circumflex', 31, 1, 0)
(111, 'o', 32, 0, 0)
(79, 'O', 32, 0, 1)
(248, 'oslash', 32, 1, 0)
(216, 'Oslash', 32, 1, 1)
(112, 'p', 33, 0, 0)
(80, 'P', 33, 0, 1)
(2032, 'Greek_pi', 33, 1, 0)
(2000, 'Greek_PI', 33, 1, 1)
(91, 'bracketleft', 34, 0, 0)
(123, 'braceleft', 34, 0, 1)
(2770, 'leftdoublequotemark', 34, 1, 0)
(2771, 'rightdoublequotemark', 34, 1, 1)
(93, 'bracketright', 35, 0, 0)
(125, 'braceright', 35, 0, 1)
(2768, 'leftsinglequotemark', 35, 1, 0)
(2769, 'rightsinglequotemark', 35, 1, 1)
(65293, 'Return', 36, 0, 0)
(65507, 'Control_L', 37, 0, 0)
(97, 'a', 38, 0, 0)
(65, 'A', 38, 0, 1)
(229, 'aring', 38, 1, 0)
(197, 'Aring', 38, 1, 1)
(115, 's', 39, 0, 0)
(83, 'S', 39, 0, 1)
(223, 'ssharp', 39, 1, 0)
(205, 'Iacute', 39, 1, 1)
(100, 'd', 40, 0, 0)
(68, 'D', 40, 0, 1)
(2287, 'partialderivative', 40, 1, 0)
(206, 'Icircumflex', 40, 1, 1)
(102, 'f', 41, 0, 0)
(70, 'F', 41, 0, 1)
(2294, 'function', 41, 1, 0)
(207, 'Idiaeresis', 41, 1, 1)
(103, 'g', 42, 0, 0)
(71, 'G', 42, 0, 1)
(169, 'copyright', 42, 1, 0)
(445, 'doubleacute', 42, 1, 1)
(104, 'h', 43, 0, 0)
(72, 'H', 43, 0, 1)
(511, 'abovedot', 43, 1, 0)
(211, 'Oacute', 43, 1, 1)
(106, 'j', 44, 0, 0)
(74, 'J', 44, 0, 1)
(212, 'Ocircumflex', 44, 1, 1)
(107, 'k', 45, 0, 0)
(75, 'K', 45, 0, 1)
(108, 'l', 46, 0, 0)
(76, 'L', 46, 0, 1)
(172, 'notsign', 46, 1, 0)
(210, 'Ograve', 46, 1, 1)
(59, 'semicolon', 47, 0, 0)
(58, 'colon', 47, 0, 1)
(2734, 'ellipsis', 47, 1, 0)
(218, 'Uacute', 47, 1, 1)
(39, 'apostrophe', 48, 0, 0)
(34, 'quotedbl', 48, 0, 1)
(230, 'ae', 48, 1, 0)
(198, 'AE', 48, 1, 1)
(96, 'grave', 49, 0, 0)
(126, 'asciitilde', 49, 0, 1)
(65104, 'dead_grave', 49, 1, 0)
(96, 'grave', 49, 1, 1)
(65505, 'Shift_L', 50, 0, 0)
(92, 'backslash', 51, 0, 0)
(124, 'bar', 51, 0, 1)
(171, 'guillemotleft', 51, 1, 0)
(187, 'guillemotright', 51, 1, 1)
(122, 'z', 52, 0, 0)
(90, 'Z', 52, 0, 1)
(2009, 'Greek_OMEGA', 52, 1, 0)
(184, 'cedilla', 52, 1, 1)
(120, 'x', 53, 0, 0)
(88, 'X', 53, 0, 1)
(434, 'ogonek', 53, 1, 1)
(99, 'c', 54, 0, 0)
(67, 'C', 54, 0, 1)
(231, 'ccedilla', 54, 1, 0)
(199, 'Ccedilla', 54, 1, 1)
(118, 'v', 55, 0, 0)
(86, 'V', 55, 0, 1)
(2262, 'radical', 55, 1, 0)
(98, 'b', 56, 0, 0)
(66, 'B', 56, 0, 1)
(2239, 'integral', 56, 1, 0)
(697, 'idotless', 56, 1, 1)
(110, 'n', 57, 0, 0)
(78, 'N', 57, 0, 1)
(65107, 'dead_tilde', 57, 1, 0)
(109, 'm', 58, 0, 0)
(77, 'M', 58, 0, 1)
(181, 'mu', 58, 1, 0)
(194, 'Acircumflex', 58, 1, 1)
(44, 'comma', 59, 0, 0)
(60, 'less', 59, 0, 1)
(2236, 'lessthanequal', 59, 1, 0)
(175, 'macron', 59, 1, 1)
(46, 'period', 60, 0, 0)
(62, 'greater', 60, 0, 1)
(2238, 'greaterthanequal', 60, 1, 0)
(418, 'breve', 60, 1, 1)
(47, 'slash', 61, 0, 0)
(63, 'question', 61, 0, 1)
(247, 'division', 61, 1, 0)
(191, 'questiondown', 61, 1, 1)
(65506, 'Shift_R', 62, 0, 0)
(65450, 'KP_Multiply', 63, 0, 0)
(65450, 'KP_Multiply', 63, 0, 1)
(65450, 'KP_Multiply', 63, 0, 2)
(65450, 'KP_Multiply', 63, 0, 3)
(269024801, 'XF86ClearGrab', 63, 0, 4)
(65450, 'KP_Multiply', 63, 1, 0)
(65450, 'KP_Multiply', 63, 1, 1)
(65513, 'Alt_L', 64, 0, 0)
(65511, 'Meta_L', 64, 0, 1)
(32, 'space', 65, 0, 0)
(160, 'nobreakspace', 65, 1, 0)
(65509, 'Caps_Lock', 66, 0, 0)
(65470, 'F1', 67, 0, 0)
(65470, 'F1', 67, 0, 1)
(65470, 'F1', 67, 0, 2)
(65470, 'F1', 67, 0, 3)
(269024769, 'XF86Switch_VT_1', 67, 0, 4)
(65470, 'F1', 67, 1, 0)
(65470, 'F1', 67, 1, 1)
(65471, 'F2', 68, 0, 0)
(65471, 'F2', 68, 0, 1)
(65471, 'F2', 68, 0, 2)
(65471, 'F2', 68, 0, 3)
(269024770, 'XF86Switch_VT_2', 68, 0, 4)
(65471, 'F2', 68, 1, 0)
(65471, 'F2', 68, 1, 1)
(65472, 'F3', 69, 0, 0)
(65472, 'F3', 69, 0, 1)
(65472, 'F3', 69, 0, 2)
(65472, 'F3', 69, 0, 3)
(269024771, 'XF86Switch_VT_3', 69, 0, 4)
(65472, 'F3', 69, 1, 0)
(65472, 'F3', 69, 1, 1)
(65473, 'F4', 70, 0, 0)
(65473, 'F4', 70, 0, 1)
(65473, 'F4', 70, 0, 2)
(65473, 'F4', 70, 0, 3)
(269024772, 'XF86Switch_VT_4', 70, 0, 4)
(65473, 'F4', 70, 1, 0)
(65473, 'F4', 70, 1, 1)
(65474, 'F5', 71, 0, 0)
(65474, 'F5', 71, 0, 1)
(65474, 'F5', 71, 0, 2)
(65474, 'F5', 71, 0, 3)
(269024773, 'XF86Switch_VT_5', 71, 0, 4)
(65474, 'F5', 71, 1, 0)
(65474, 'F5', 71, 1, 1)
(65475, 'F6', 72, 0, 0)
(65475, 'F6', 72, 0, 1)
(65475, 'F6', 72, 0, 2)
(65475, 'F6', 72, 0, 3)
(269024774, 'XF86Switch_VT_6', 72, 0, 4)
(65475, 'F6', 72, 1, 0)
(65475, 'F6', 72, 1, 1)
(65476, 'F7', 73, 0, 0)
(65476, 'F7', 73, 0, 1)
(65476, 'F7', 73, 0, 2)
(65476, 'F7', 73, 0, 3)
(269024775, 'XF86Switch_VT_7', 73, 0, 4)
(65476, 'F7', 73, 1, 0)
(65476, 'F7', 73, 1, 1)
(65477, 'F8', 74, 0, 0)
(65477, 'F8', 74, 0, 1)
(65477, 'F8', 74, 0, 2)
(65477, 'F8', 74, 0, 3)
(269024776, 'XF86Switch_VT_8', 74, 0, 4)
(65477, 'F8', 74, 1, 0)
(65477, 'F8', 74, 1, 1)
(65478, 'F9', 75, 0, 0)
(65478, 'F9', 75, 0, 1)
(65478, 'F9', 75, 0, 2)
(65478, 'F9', 75, 0, 3)
(269024777, 'XF86Switch_VT_9', 75, 0, 4)
(65478, 'F9', 75, 1, 0)
(65478, 'F9', 75, 1, 1)
(65479, 'F10', 76, 0, 0)
(65479, 'F10', 76, 0, 1)
(65479, 'F10', 76, 0, 2)
(65479, 'F10', 76, 0, 3)
(269024778, 'XF86Switch_VT_10', 76, 0, 4)
(65479, 'F10', 76, 1, 0)
(65479, 'F10', 76, 1, 1)
(65407, 'Num_Lock', 77, 0, 0)
(65300, 'Scroll_Lock', 78, 0, 0)
(65429, 'KP_Home', 79, 0, 0)
(65463, 'KP_7', 79, 0, 1)
(65431, 'KP_Up', 80, 0, 0)
(65464, 'KP_8', 80, 0, 1)
(65434, 'KP_Page_Up', 81, 0, 0)
(65465, 'KP_9', 81, 0, 1)
(65453, 'KP_Subtract', 82, 0, 0)
(65453, 'KP_Subtract', 82, 0, 1)
(65453, 'KP_Subtract', 82, 0, 2)
(65453, 'KP_Subtract', 82, 0, 3)
(269024803, 'XF86Prev_VMode', 82, 0, 4)
(65453, 'KP_Subtract', 82, 1, 0)
(65453, 'KP_Subtract', 82, 1, 1)
(65430, 'KP_Left', 83, 0, 0)
(65460, 'KP_4', 83, 0, 1)
(65437, 'KP_Begin', 84, 0, 0)
(65461, 'KP_5', 84, 0, 1)
(65432, 'KP_Right', 85, 0, 0)
(65462, 'KP_6', 85, 0, 1)
(65451, 'KP_Add', 86, 0, 0)
(65451, 'KP_Add', 86, 0, 1)
(65451, 'KP_Add', 86, 0, 2)
(65451, 'KP_Add', 86, 0, 3)
(269024802, 'XF86Next_VMode', 86, 0, 4)
(65451, 'KP_Add', 86, 1, 0)
(65451, 'KP_Add', 86, 1, 1)
(65436, 'KP_End', 87, 0, 0)
(65457, 'KP_1', 87, 0, 1)
(65433, 'KP_Down', 88, 0, 0)
(65458, 'KP_2', 88, 0, 1)
(65435, 'KP_Page_Down', 89, 0, 0)
(65459, 'KP_3', 89, 0, 1)
(65438, 'KP_Insert', 90, 0, 0)
(65456, 'KP_0', 90, 0, 1)
(65439, 'KP_Delete', 91, 0, 0)
(65454, 'KP_Decimal', 91, 0, 1)
(167, 'section', 92, 0, 0)
(177, 'plusminus', 92, 0, 1)
(65293, 'Return', 93, 0, 0)
(60, 'less', 94, 0, 0)
(62, 'greater', 94, 0, 1)
(124, 'bar', 94, 0, 2)
(166, 'brokenbar', 94, 0, 3)
(60, 'less', 94, 1, 0)
(62, 'greater', 94, 1, 1)
(124, 'bar', 94, 2, 0)
(32, 'space', 94, 2, 2)
(65480, 'F11', 95, 0, 0)
(65480, 'F11', 95, 0, 1)
(65480, 'F11', 95, 0, 2)
(65480, 'F11', 95, 0, 3)
(269024779, 'XF86Switch_VT_11', 95, 0, 4)
(65480, 'F11', 95, 1, 0)
(65480, 'F11', 95, 1, 1)
(124, 'bar', 95, 1, 3)
(65481, 'F12', 96, 0, 0)
(65481, 'F12', 96, 0, 1)
(65481, 'F12', 96, 0, 2)
(65481, 'F12', 96, 0, 3)
(269024780, 'XF86Switch_VT_12', 96, 0, 4)
(65481, 'F12', 96, 1, 0)
(65481, 'F12', 96, 1, 1)
(124, 'bar', 96, 1, 3)
(65360, 'Home', 97, 0, 0)
(65362, 'Up', 98, 0, 0)
(47, 'slash', 98, 0, 1)
(65365, 'Page_Up', 99, 0, 0)
(65361, 'Left', 100, 0, 0)
(43, 'plus', 100, 0, 1)
(65513, 'Alt_L', 101, 0, 0)
(65511, 'Meta_L', 101, 0, 1)
(65363, 'Right', 102, 0, 0)
(42, 'asterisk', 102, 0, 1)
(65367, 'End', 103, 0, 0)
(65364, 'Down', 104, 0, 0)
(61, 'equal', 104, 0, 1)
(65366, 'Page_Down', 105, 0, 0)
(65379, 'Insert', 106, 0, 0)
(65535, 'Delete', 107, 0, 0)
(65421, 'KP_Enter', 108, 0, 0)
(65508, 'Control_R', 109, 0, 0)
(65299, 'Pause', 110, 0, 0)
(65387, 'Break', 110, 0, 1)
(65377, 'Print', 111, 0, 0)
(65301, 'Sys_Req', 111, 0, 1)
(65455, 'KP_Divide', 112, 0, 0)
(65455, 'KP_Divide', 112, 0, 1)
(65455, 'KP_Divide', 112, 0, 2)
(65455, 'KP_Divide', 112, 0, 3)
(269024800, 'XF86Ungrab', 112, 0, 4)
(65455, 'KP_Divide', 112, 1, 0)
(65455, 'KP_Divide', 112, 1, 1)
(124, 'bar', 112, 1, 3)
(65514, 'Alt_R', 113, 0, 0)
(65512, 'Meta_R', 113, 0, 1)
(65514, 'Alt_R', 114, 0, 0)
(65512, 'Meta_R', 114, 0, 1)
(65515, 'Super_L', 115, 0, 0)
(65516, 'Super_R', 116, 0, 0)
(65383, 'Menu', 117, 0, 0)
(65307, 'Escape', 118, 0, 0)
(65482, 'F13', 119, 0, 0)
(65485, 'F16', 120, 0, 0)
(65483, 'F14', 121, 0, 0)
(65484, 'F15', 122, 0, 0)
(65365, 'Page_Up', 123, 0, 0)
(65027, 'ISO_Level3_Shift', 124, 0, 0)
(65513, 'Alt_L', 125, 0, 0)
(65469, 'KP_Equal', 126, 0, 0)
(65515, 'Super_L', 127, 0, 0)
(65517, 'Hyper_L', 128, 0, 0)
(269025074, 'XF86AudioMedia', 129, 0, 0)
(65366, 'Page_Down', 130, 0, 0)
(65361, 'Left', 131, 0, 0)
(65363, 'Right', 132, 0, 0)
(65364, 'Down', 133, 0, 0)
(65454, 'KP_Decimal', 134, 0, 0)
(65454, 'KP_Decimal', 134, 0, 1)
(65362, 'Up', 135, 0, 0)
(65518, 'Hyper_R', 136, 0, 0)
(269025046, 'XF86AudioPrev', 144, 0, 0)
(269025071, 'XF86Sleep', 150, 0, 0)
(269025047, 'XF86AudioNext', 153, 0, 0)
(65511, 'Meta_L', 156, 0, 0)
(269025042, 'XF86AudioMute', 160, 0, 0)
(269025053, 'XF86Calculator', 161, 0, 0)
(269025044, 'XF86AudioPlay', 162, 0, 0)
(269025073, 'XF86AudioPause', 162, 0, 1)
(269025045, 'XF86AudioStop', 164, 0, 0)
(269025068, 'XF86Eject', 164, 0, 1)
(269025068, 'XF86Eject', 170, 0, 0)
(269025041, 'XF86AudioLowerVolume', 174, 0, 0)
(269025043, 'XF86AudioRaiseVolume', 176, 0, 0)
(269025070, 'XF86WWW', 178, 0, 0)
(269025068, 'XF86Eject', 204, 0, 0)
(269025113, 'XF86Display', 214, 0, 0)
(269025028, 'XF86KbdLightOnOff', 215, 0, 0)
(269025030, 'XF86KbdBrightnessDown', 216, 0, 0)
(269025029, 'XF86KbdBrightnessUp', 217, 0, 0)
(269025066, 'XF86PowerOff', 222, 0, 0)
(269025040, 'XF86Standby', 223, 0, 0)
(269025067, 'XF86WakeUp', 227, 0, 0)
(269025051, 'XF86Search', 229, 0, 0)
(269025072, 'XF86Favorites', 230, 0, 0)
(269025139, 'XF86Reload', 231, 0, 0)
(269025064, 'XF86Stop', 232, 0, 0)
(269025063, 'XF86Forward', 233, 0, 0)
(269025062, 'XF86Back', 234, 0, 0)
(269025075, 'XF86MyComputer', 235, 0, 0)
(269025049, 'XF86Mail', 236, 0, 0)
(269025074, 'XF86AudioMedia', 237, 0, 0)
(269025171, 'XF86Battery', 244, 0, 0)
(269025173, 'XF86WLAN', 246, 0, 0)

Wed, 14 May 2014 15:06:35 GMT - Antoine Martin: owner changed

Debugging keyboard bugs takes a crazy amount of effort, I am not saying this to discourage you, just so that you are aware of the task ahead. The main problem on my side, apart from the lack of time, is that I use OSX in virtualbox only, and the virtualization already does some keyboard remapping, and the client OS also intercepts certain keys (though that can probably be configured). I guess I could try a USB keyboard pass-through, maybe that would work.

Judging by the amount of debugging information you have provided, you may have already found wiki/Keyboard?


Xpra from Mac uses code 64 for either control or command, but xpra from linux uses code 64 for option


I haven't looked at the details yet, just bear in mind that we map the mac keycodes to the server keymap.. so things can quickly get confusing.

KeyRelease Events are messed up when xpra connects from Linux


That would be bug and an unusual one, Linux to Linux works pretty well, usually.

Xpra mapping for Mac are significantly different from both ssh -X and local X mappings, which is confusing


Yes, they would be: the xpra client on OSX does not use X11 at all, it is a native application and therefore does not have access to the X11 keyboard information.


Can you help me to grasp how Xpra selects key codes for key presses and how does it maps it into keysyms?


Yes, it's ugly but you should get debug information by running the server or the client with:

xpra -d keyboard

or even:

xpra -d keyboard,verbose

A brief explanation for the macosx case: we set a default keymap on the server then try to map the macosx keyboard definition (the keysyms definitions for each key), minimizing the amount of remapping from client keycodes to server keycodes. (we generate a translation table as we remap keys). When the osx client sends the server a keycode (and modifier state, keysym, etc..), we look up the real keycode (for the actual server keymap in use) and press/unpress it.

And is this configurable in any way?


Unfortunately not, yet.


Wed, 14 May 2014 21:13:33 GMT - Timothy Basanov: attachment set


Wed, 14 May 2014 21:13:45 GMT - Timothy Basanov: attachment set


Wed, 14 May 2014 21:19:32 GMT - Timothy Basanov:

Looks like Xpra key mappings on a Mac is a mystery for me. I want to make it behave as close to a normal X app as possible, for me Xpra is a drop-in replacement. I'm totally comfortable with having XQuarz running or running xmodmap once to save configuration for Xpra to read.

I'll try to spend more time to understand how this works. Meanwhile here are logs for left control key pressed.

Logs on the client:

2014-05-14 14:15:29,792 mask_to_names(<flags 8192 of type GdkModifierType>)=['mod2']
2014-05-14 14:15:34,127 mask_to_names(<flags 0 of type GdkModifierType>)=['mod2']
2014-05-14 14:15:34,127 parse_key_event(<gtk.gdk.Event at 0xd0c5530: GDK_KEY_PRESS keyval=Control_L>, True)=<GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '', 'keyname': 'Control_L', 'pressed': True, 'keyval': 65507, 'keycode': 59}>
2014-05-14 14:15:34,127 handle_key_action(GLClientWindow(1 : GLPixmapBacking(1, (178, 178), None)), <GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '', 'keyname': 'Control_L', 'pressed': True, 'keyval': 65507, 'keycode': 59}>) wid=1
2014-05-14 14:15:34,127 swap keys: translating key '<GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '', 'keyname': 'Control_L', 'pressed': True, 'keyval': 65507, 'keycode': 59}>' to (55, 'Alt_L')
2014-05-14 14:15:34,128 send_key_action(1, <GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '', 'keyname': 'Alt_L', 'pressed': True, 'keyval': 65507, 'keycode': 55}>)
2014-05-14 14:15:36,245 mask_to_names swapping control for meta: control for mod1
2014-05-14 14:15:36,245 mask_to_names(<flags GDK_CONTROL_MASK | GDK_MOD1_MASK of type GdkModifierType>)=['mod1', 'mod2']

And on the server:

2014-05-14 14:17:21,816 make_keymask_match(('mod1', 'mod2')) current mask: set(['mod2']), wanted: set(['mod1', 'mod2']), ignoring=None/['lock'], keys_pressed={}
2014-05-14 14:17:21,817 keynames(mod1)=set(['Meta_R', 'Alt_R', 'Meta_L', 'Alt_L']), keycodes=[113, 114, 64, 156, 101, 125], nuisance=False
2014-05-14 14:17:21,817 make_keymask_match(add) ('mod1', 'mod2') modifier mod1 using 113, success: True
2014-05-14 14:17:21,818 make_keymask_match(('mod2',)) current mask: set(['mod1', 'mod2']), wanted: set(['mod2']), ignoring=64/['Alt_L'], keys_pressed={}
2014-05-14 14:17:21,818 modifier ignored (ignored keyname=Alt_L)
2014-05-14 14:17:21,818 modifier mod1 ignored (in ignored keynames=set(['Meta_R', 'Alt_R', 'Meta_L', 'Alt_L']))
2014-05-14 14:17:21,818 handle_key(2,True,Alt_L,65507,64,('mod2',)) keyboard_sync=False
2014-05-14 14:17:21,818 handle keycode pressing 64: key Alt_L
2014-05-14 14:17:21,818 fake_key(64, True)
2014-05-14 14:17:21,819 handle keycode unpressing 64: key Alt_L
2014-05-14 14:17:21,819 fake_key(64, False)
2014-05-14 14:17:23,924 _clear_keys_pressed()

Additionally I've attached logs from server and a client startup. They output Tons of information. Hope that this can help us to resolve a problem. =)


Thu, 15 May 2014 04:50:02 GMT - Antoine Martin:

I want to make it behave as close to a normal X app as possible


Then you may be better off compiling xpra against the X11 headers as we do on other X11 based platforms (Linux, BSD, ..). The problem is that there are still dozens of special cases for macs sprinkled throughout the code (checks for sys.platform.startswith("darwin") usually), and decide which ones can be kept and which ones should fall through..

I'm totally comfortable with having XQuarz running or running xmodmap once to save configuration for Xpra to read.


That's assuming that the XQuartz keyboard configuration is related to the one we get from GTK. It should be... but the devil is in the details.

I think you may well be interested in reading: ticket:567#comment:12 which is about "swap_keys" and keyboard sync and explains why we unpress the Alt_L key (just updated earlier today)


Tue, 29 Jul 2014 10:45:18 GMT - Antoine Martin:

Can I close this?


Fri, 01 Aug 2014 13:10:12 GMT - Antoine Martin: status changed; resolution set


Sat, 02 Aug 2014 01:12:09 GMT - Timothy Basanov:

That's ok to close this ticket.

I've invested a dozen hours into this issue, no success. These issues are definitely tricky.


Sat, 23 Jan 2021 04:59:40 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/570