Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow the user to switch keyboard layout manually at runtime #230

Closed
totaam opened this issue Jan 3, 2013 · 21 comments
Closed

allow the user to switch keyboard layout manually at runtime #230

totaam opened this issue Jan 3, 2013 · 21 comments

Comments

@totaam
Copy link
Collaborator

totaam commented Jan 3, 2013

Issue migrated from trac ticket # 230

component: core | priority: major | resolution: duplicate

2013-01-03 14:30:16: onlyjob created the issue


Here is a very strange problem:

When I connect to xpra session from local machine (the very one where xpra server is started) sometimes keyboard accidentally switches to national layout in a way that it is impossible to switch keyboard back to English. For example I was typing an email in English when suddenly without pressing modifier combination (Alt+Shift) keyboard switched to national layout for all applications in session. I couldn't switch back to English at all. I tried re-connecting and "xpra upgrade" but nothing helped. The following error was logged:

2013-01-04 01:05:11,801 setting key repeat rate from client: 492ms delay / 50ms interval
2013-01-04 01:05:11,803 setting keymap: {'rules': 'evdev', 'model': 'pc105', 'layout': 'us'}
2013-01-04 01:05:11,838 setting full keymap definition from client via xkbcomp
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/xpra/server.py", line 1172, in _process_server_settings
    self.update_server_settings(packet[1])
  File "/usr/lib/python2.7/dist-packages/xpra/server.py", line 1209, in update_server_settings
    self._xsettings_manager = XSettingsManager(v)
  File "/usr/lib/python2.7/dist-packages/xpra/xposix/xsettings.py", line 34, in __init__
    self._set_blob_in_place(settings_blob)
  File "/usr/lib/python2.7/dist-packages/xpra/xposix/xsettings.py", line 40, in _set_blob_in_place
    settings_blob)
  File "/usr/lib/python2.7/dist-packages/wimpiggy/prop.py", line 293, in prop_set
    _prop_encode(target, etype, value))
  File "/usr/lib/python2.7/dist-packages/wimpiggy/prop.py", line 274, in _prop_encode
    return _prop_encode_scalar(disp, etype, value)
  File "/usr/lib/python2.7/dist-packages/wimpiggy/prop.py", line 279, in _prop_encode_scalar
    return (atom, formatbits, serialize(disp, value))
  File "/usr/lib/python2.7/dist-packages/wimpiggy/xsettings_prop.py", line 95, in set_settings
    assert type(value)==int
AssertionError

The above is from Xpra 0.7.6.
There were no clipboard manager(s) running and I was typing in kmail when it happened but I have a feeling that application doesn't matter because I remember it happened before in some other apps.

Interestingly enough only local connection is affected. I was able to switch layout back to English when I connected to session from another computer over SSH.

Please advise what kind of debug log may be useful. Thanks.

@totaam
Copy link
Collaborator Author

totaam commented Jan 3, 2013

2013-01-03 16:07:00: antoine changed status from new to accepted

@totaam
Copy link
Collaborator Author

totaam commented Jan 3, 2013

2013-01-03 16:07:00: antoine commented


First, are you sure that the stacktrace above is related to the problem you experienced?
This stacktrace seems to have been recorded during the connection setup, and your problem only occurred afterwards didn't it? XSETTTINGS aren't related to the keyboard state at all.
Second, what version was the client, also 0.7.6? What desktop environment, etc?
I've reviewed the code that prepares the server settings (and it is very easy to read - wasn't easy to write for sure..), and the only way one can get a XSettingsTypeInteger value is from value = struct.unpack("=I", d[pos:pos+4])[0] - I don't see how it is ever possible to get anything but an integer from this call. Nonetheless, I've added much more thorough validation of the data both on the way out (extracting XSETTINGS from the client - see r2444) and on the way in (updating the server - see r2443). Please use trunk or apply to 0.7.6 (it will apply cleanly as this class has not changed much since ~0.4 - the whole thing is just broken in 0.3 and older)
If you can reproduce this, it would really help to get the debug output (xpra -d all) from both the client and server.


Now, the layout issue is probably something else. Are you using keyboard sync mode or not?
Can you reproduce this with debug switched on? I think it is possible that as you move around and focus/unfocus windows, we press modifier keys for you on the server side to make sure the state of the server keyboard matches your client's state... and we may end up triggering this combination accidentally. That's unfortunate, and also hard to fix. I can't think of an easy way around that. A workaround would be to use keys which are not all modifiers for layout switching, as we never press those automagically.

@totaam
Copy link
Collaborator Author

totaam commented Jan 4, 2013

2013-01-04 11:35:02: onlyjob commented


Replying to [comment:1 antoine]:

First, are you sure that the stacktrace above is related to the problem you experienced?

No I'm not sure. However just like the keyboard problem I see this error only with local connection so I thought it might be related.

Second, what version was the client, also 0.7.6? What desktop environment, etc?

Yes 0.7.6 both server and client (remember it's local connection ;)

I've reviewed the code that prepares the server settings (and it is very easy to read - wasn't easy to write for sure..), and the only way one can get a XSettingsTypeInteger value is from value = struct.unpack("=I", d[pos:pos+4])[0] - I don't see how it is ever possible to get anything but an integer from this call. Nonetheless, I've added much more thorough validation of the data both on the way out (extracting XSETTINGS from the client - see r2444) and on the way in (updating the server - see r2443). Please use trunk or apply to 0.7.6 (it will apply cleanly as this class has not changed much since ~0.4 - the whole thing is just broken in 0.3 and older)
If you can reproduce this, it would really help to get the debug output (xpra -d all) from both the client and server.

Understood, will try as soon as I can.


Now, the layout issue is probably something else. Are you using keyboard sync mode or not?

No keyboard synch. (sorry, forgot to mention).

Can you reproduce this with debug switched on? I think it is possible that as you move around and focus/unfocus windows, we press modifier keys for you on the server side to make sure the state of the server keyboard matches your client's state... and we may end up triggering this combination accidentally. That's unfortunate, and also hard to fix. I can't think of an easy way around that. A workaround would be to use keys which are not all modifiers for layout switching, as we never press those automagically.

I see... Also I didn't try with keyboard sync yet... Will post more info. when I have it. Cheers.

@totaam
Copy link
Collaborator Author

totaam commented Jan 6, 2013

2013-01-06 04:45:35: onlyjob commented


Just a little update: I tried r2443 and r2444 changesets applied to 0.7.6 with same effect. Here is log fragment taken with "-d all":

2013-01-06 15:30:29,301   not forwarding to CompositeHelper handler, it has no wimpiggy-property-notify-event signal
2013-01-06 15:30:29,302 grok_modifier_map(<gtk.gdk.Display object at 0x15804b0 (GdkDisplayX11 at 0x1615230)>,{'ISO_Level3_Shift': 'mod5', 'Mode_switch': 'mod5', 'Meta_L': 'mod1', 'Control_R': 'control', 'Super_R': 'mod4', 'Alt_R': 'mod1', 'Hyper_L': 'mod4', 'Caps_Lock': 'lock', 'Alt_L': 'mod1', 'Num_Lock': 'mod2', 'Super_L': 'mod4', 'Shift_R': 'shift', 'Shift_L': 'shift', 'Control_L': 'control'})={'control': 4, 'hyper': 0, 'lock': 2, 'meta': 0, 'alt': 0, 'super': 0, 'nuisance': 2, 'mod1': 8, 'mod2': 16, 'mod3': 32, 'mod4': 64, 'mod5': 128, 'shift': 1, 'num': 0, 'scroll': 0}
2013-01-06 15:30:29,302 modifier_map({'ISO_Level3_Shift': 'mod5', 'Mode_switch': 'mod5', 'Meta_L': 'mod1', 'Control_R': 'control', 'Super_R': 'mod4', 'Alt_R': 'mod1', 'Hyper_L': 'mod4', 'Caps_Lock': 'lock', 'Alt_L': 'mod1', 'Num_Lock': 'mod2', 'Super_L': 'mod4', 'Shift_R': 'shift', 'Shift_L': 'shift', 'Control_L': 'control'})={'control': 4, 'hyper': 0, 'lock': 2, 'meta': 0, 'alt': 0, 'super': 0, 'nuisance': 2, 'mod1': 8, 'mod2': 16, 'mod3': 32, 'mod4': 64, 'mod5': 128, 'shift': 1, 'num': 0, 'scroll': 0}
2013-01-06 15:30:29,302 compute_modifier_keynames: keycodes_for_modifier_keynames={'ISO_Level3_Shift': set([92]), 'Mode_switch': set([203]), 'Meta_L': set([205]), 'Control_R': set([105]), 'Super_R': set([134]), 'Alt_R': set([108]), 'Hyper_L': set([207]), 'Caps_Lock': set([66]), 'Alt_L': set([64, 204]), 'Num_Lock': set([77]), 'Super_L': set([133, 206]), 'Shift_R': set([62]), 'Shift_L': set([50]), 'Control_L': set([37])}
2013-01-06 15:30:29,302 client has requested compression level=1
2013-01-06 15:30:29,303 process clipboard packet type=clipboard-token
2013-01-06 15:30:29,303 process clipboard token selection=CLIPBOARD, local clipboard name=CLIPBOARD
2013-01-06 15:30:29,303 got token, selection=CLIPBOARD
2013-01-06 15:30:29,303 process clipboard packet type=clipboard-token
2013-01-06 15:30:29,303 process clipboard token selection=PRIMARY, local clipboard name=PRIMARY
2013-01-06 15:30:29,303 got token, selection=PRIMARY
2013-01-06 15:30:29,304 process clipboard packet type=clipboard-token
2013-01-06 15:30:29,304 process clipboard token selection=SECONDARY, local clipboard name=SECONDARY
2013-01-06 15:30:29,304 got token, selection=SECONDARY
2013-01-06 15:30:29,304 server_settings: old={'resource-manager': 'Xft.dpi:\t96\n\n'}, updating with={'xsettings-blob': (0, ((0, 'Xft/Hinting', 4294967295L, 0), (1, 'Gtk/ToolbarStyle', 'icons', 0), (0, 'Net/CursorBlinkTime', 1200, 0), (1, 'Gtk/KeyThemeName', *, 0), (1, 'Net/SoundThemeName', 'default', 0), (1, 'Gtk/FontName', 'Sans 10', 0), (0, 'Gtk/ToolbarIconSize', 3, 0), (0, 'Net/EnableInputFeedbackSounds', 0, 0), (0, 'Gtk/ButtonImages', 1, 0), (0, 'Net/EnableEventSounds', 0, 0), (0, 'Net/CursorBlink', 1, 0), (0, 'Net/DoubleClickDistance', 5, 0), (1, 'Net/IconThemeName', 'Tango', 0), (0, 'Gtk/CanChangeAccels', 0, 0), (1, 'Gtk/ColorPalette', 'black:white:gray50:red:purple:blue:light blue:green:yellow:orange:lavender:brown:goldenrod4:dodger blue:pink:light green:gray10:gray30:gray75:gray90', 0), (1, 'Gtk/IMPreeditStyle', *, 0), (0, 'Xft/Antialias', 1, 0), (1, 'Gtk/IMModule', *, 0), (0, 'Net/DoubleClickTime', 250, 0), (1, 'Gtk/IMStatusStyle', *, 0), (0, 'Net/DndDragThreshold', 8, 0), (1, 'Gtk/CursorThemeName', *, 0), (1, 'Gtk/IconSizes', *, 0), (1, 'Net/ThemeName', 'Xfce', 0), (1, 'Xft/HintStyle', 'hintslight', 0), (1, 'Gtk/MenuBarAccel', 'F10', 0), (0, 'Gtk/MenuImages', 1, 0), (0, 'Gtk/CursorThemeSize', 0, 0), (1, 'Xft/RGBA', 'none', 0)))}
2013-01-06 15:30:29,305 sending message to 0x44L
2013-01-06 15:30:29,305 format_xsettings((0, ((0, 'Xft/Hinting', 4294967295L, 0), (1, 'Gtk/ToolbarStyle', 'icons', 0), (0, 'Net/CursorBlinkTime', 1200, 0), (1, 'Gtk/KeyThemeName', *, 0), (1, 'Net/SoundThemeName', 'default', 0), (1, 'Gtk/FontName', 'Sans 10', 0), (0, 'Gtk/ToolbarIconSize', 3, 0), (0, 'Net/EnableInputFeedbackSounds', 0, 0), (0, 'Gtk/ButtonImages', 1, 0), (0, 'Net/EnableEventSounds', 0, 0), (0, 'Net/CursorBlink', 1, 0), (0, 'Net/DoubleClickDistance', 5, 0), (1, 'Net/IconThemeName', 'Tango', 0), (0, 'Gtk/CanChangeAccels', 0, 0), (1, 'Gtk/ColorPalette', 'black:white:gray50:red:purple:blue:light blue:green:yellow:orange:lavender:brown:goldenrod4:dodger blue:pink:light green:gray10:gray30:gray75:gray90', 0), (1, 'Gtk/IMPreeditStyle', *, 0), (0, 'Xft/Antialias', 1, 0), (1, 'Gtk/IMModule', *, 0), (0, 'Net/DoubleClickTime', 250, 0), (1, 'Gtk/IMStatusStyle', *, 0), (0, 'Net/DndDragThreshold', 8, 0), (1, 'Gtk/CursorThemeName', *, 0), (1, 'Gtk/IconSizes', *, 0), (1, 'Net/ThemeName', 'Xfce', 0), (1, 'Xft/HintStyle', 'hintslight', 0), (1, 'Gtk/MenuBarAccel', 'F10', 0), (0, 'Gtk/MenuImages', 1, 0), (0, 'Gtk/CursorThemeSize', 0, 0), (1, 'Xft/RGBA', 'none', 0)))) serial=0, 29 settings
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/xpra/server.py", line 1172, in _process_server_settings
    self.update_server_settings(packet[1])
  File "/usr/lib/python2.7/dist-packages/xpra/server.py", line 1209, in update_server_settings
    self._xsettings_manager = XSettingsManager(v)
  File "/usr/lib/python2.7/dist-packages/xpra/xposix/xsettings.py", line 34, in __init__
    self._set_blob_in_place(settings_blob)
  File "/usr/lib/python2.7/dist-packages/xpra/xposix/xsettings.py", line 40, in _set_blob_in_place
    settings_blob)
  File "/usr/lib/python2.7/dist-packages/wimpiggy/prop.py", line 293, in prop_set
    _prop_encode(target, etype, value))
  File "/usr/lib/python2.7/dist-packages/wimpiggy/prop.py", line 274, in _prop_encode
    return _prop_encode_scalar(disp, etype, value)
  File "/usr/lib/python2.7/dist-packages/wimpiggy/prop.py", line 279, in _prop_encode_scalar
    return (atom, formatbits, serialize(disp, value))
  File "/usr/lib/python2.7/dist-packages/wimpiggy/xsettings_prop.py", line 100, in set_settings
    assert type(value)==int, "invalid value type (int wanted): %s" % type(value)
AssertionError: invalid value type (int wanted): <type 'long'>

This is on Xfce desktop environment (sorry for not mentioning this earlier).

I had few more cases of accidental keyboard switching (with or without keyboard sync). I was only able to recover by attaching from remote computer and switching keyboard back to English. So here is the thought: as a remedy is it possible to reset keyboard layout on attaching?

I'll try to get "-d all" log demonstrating problem with accidental layout switching.

@totaam
Copy link
Collaborator Author

totaam commented Jan 6, 2013

2013-01-06 05:59:57: antoine changed title from only national keyboard layout on local connection to allow the user to switch keyboard layout manually at runtime

@totaam
Copy link
Collaborator Author

totaam commented Jan 6, 2013

2013-01-06 05:59:57: antoine commented


OK, the XSETTINGS problem should be fixed in r2451, please confirm so I can backport to the v0.7.x branch.


As for layout switching, we may be able to do better than just resetting on connect (maybe we can do that too), by allowing the user to select the active layout via the system tray. I have seen Xkb code that does just that. I just hope that getting notifications when the layout is changed from underneath us is as easy so we can keep the tray in sync with the current server keyboard layout state.

@totaam
Copy link
Collaborator Author

totaam commented Jan 6, 2013

2013-01-06 09:02:44: onlyjob commented


Replying to [comment:4 antoine]:

OK, the XSETTINGS problem should be fixed in r2451, please confirm so I can backport to the v0.7.x branch.

I applied r2451 on top of r2443 and r2444 (0.7.6) and hereby confirm that there is no more errors when connecting to local session. Thank you.

I'm looking forward to try your lovely idea to integrate keyboard selection to tray. :)

Cheers.

@totaam
Copy link
Collaborator Author

totaam commented Jan 13, 2013

2013-01-13 23:06:43: onlyjob uploaded file natkeyb.log.xz (10.6 KiB)

local connection, switched to nat layout just before disconnection.

@totaam
Copy link
Collaborator Author

totaam commented Jan 13, 2013

2013-01-13 23:09:26: onlyjob commented


As promised I attached log (-d all) of the situation when in local connection keyboard switches to national layout without user pressing corresponding key combination.
I disconnected the session as soon as I noticed the problem.

@totaam
Copy link
Collaborator Author

totaam commented Mar 20, 2013

2013-03-20 14:18:57: antoine commented


I think this badly needs Xkb, but I will try to expose the layouts thing via the applet in a future release, far too late for 0.9 though.. re-scheduling it.

@totaam
Copy link
Collaborator Author

totaam commented Jul 16, 2013

2013-07-16 07:30:30: antoine changed status from accepted to new

@totaam
Copy link
Collaborator Author

totaam commented Jul 16, 2013

2013-07-16 07:30:30: antoine commented


Re-scheduling, Xkb work is due for 0.11

@totaam
Copy link
Collaborator Author

totaam commented Oct 17, 2013

2013-10-17 08:36:32: totaam changed status from new to assigned

@totaam
Copy link
Collaborator Author

totaam commented Oct 17, 2013

2013-10-17 08:36:32: totaam changed owner from antoine to totaam

@totaam
Copy link
Collaborator Author

totaam commented Oct 17, 2013

2013-10-17 08:36:32: totaam commented


re-scheduling (again)

@totaam
Copy link
Collaborator Author

totaam commented Feb 13, 2014

2014-02-13 14:29:26: antoine changed status from assigned to new

@totaam
Copy link
Collaborator Author

totaam commented Feb 13, 2014

2014-02-13 14:29:26: antoine changed owner from totaam to onlyjob

@totaam
Copy link
Collaborator Author

totaam commented Feb 13, 2014

2014-02-13 14:29:26: antoine commented


In order to allow the client to select a particular keyboard layout at runtime, we must first identify which layouts the client would like to select from...
And I can't see anything in the data above that indicates more than one layout.
Since you seem to be using a dual layout configuration, can you please post more data so we can try to see where the extra layouts can be found? The Keyboard may have some helpful pointers, see also Keyboard Configuration in Xorg

@totaam
Copy link
Collaborator Author

totaam commented Mar 5, 2014

2014-03-05 08:47:06: totaam changed status from new to closed

@totaam
Copy link
Collaborator Author

totaam commented Mar 5, 2014

2014-03-05 08:47:06: totaam changed resolution from ** to duplicate

@totaam
Copy link
Collaborator Author

totaam commented Mar 5, 2014

2014-03-05 08:47:06: totaam commented


Please follow up in #86 which has more information, if a bit dated, and a patch which should allow you to select the layout manually.

@totaam totaam closed this as completed Mar 5, 2014
@totaam totaam added the v0.7.x label Jan 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant