Coverage for /home/antoine/projects/xpra-git/dist/python3/lib64/python/xpra/client/gtk_base/gtk_keyboard_helper.py : 49%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of Xpra.
2# Copyright (C) 2011 Serviware (Arthur Huillet, <ahuillet@serviware.com>)
3# Copyright (C) 2010-2019 Antoine Martin <antoine@xpra.org>
4# Copyright (C) 2008, 2010 Nathaniel Smith <njs@pobox.com>
5# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
6# later version. See the file COPYING for details.
8from gi.repository import GLib, Gdk
10from xpra.client.keyboard_helper import KeyboardHelper, log
11from xpra.gtk_common.keymap import get_gtk_keymap
12from xpra.os_util import is_X11
15class GTKKeyboardHelper(KeyboardHelper):
17 def __init__(self, *args):
18 KeyboardHelper.__init__(self, *args)
19 #used for delaying the sending of keymap changes
20 #(as we may be getting dozens of such events at a time)
21 self._keymap_changing = False
22 self._keymap_change_handler_id = None
23 self._keymap = None
24 display = Gdk.Display.get_default()
25 if display:
26 self._keymap = Gdk.Keymap.get_for_display(display)
27 self.update()
28 if self._keymap:
29 self._keymap_change_handler_id = self._keymap.connect("keys-changed", self.keymap_changed)
31 def keymap_changed(self, *args):
32 log("keymap_changed%s", args)
33 if self._keymap_change_handler_id:
34 self._keymap.disconnect(self._keymap_change_handler_id)
35 self._keymap_change_handler_id = None
36 display = Gdk.Display.get_default()
37 self._keymap = Gdk.Keymap.get_for_display(display)
38 if self._keymap_changing:
39 #timer due already
40 return
41 self._keymap_changing = True
42 def do_keys_changed():
43 #re-register the change handler:
44 self._keymap_change_handler_id = self._keymap.connect("keys-changed", self.keymap_changed)
45 self._keymap_changing = False
46 if self.locked:
47 #automatic changes not allowed!
48 log.info("ignoring keymap change: layout is locked to '%s'", self.layout_str())
49 return
50 if self.update() and self.xkbmap_layout:
51 log.info("keymap has been changed to '%s'", self.layout_str())
52 log.info(" sending updated mappings to the server")
53 if self.xkbmap_layout:
54 self.send_layout()
55 self.send_keymap()
56 GLib.timeout_add(500, do_keys_changed)
58 def update(self):
59 old_hash = self.hash
60 super().update()
61 if is_X11():
62 try:
63 self.keyboard.update_modifier_map(Gdk.Display.get_default(), self.xkbmap_mod_meanings)
64 except Exception:
65 log.error("error querying modifier map", exc_info=True)
66 log("update() modifier_map=%s, old hash=%s, new hash=%s", self.keyboard.modifier_map, old_hash, self.hash)
67 return old_hash!=self.hash
69 def get_full_keymap(self):
70 return get_gtk_keymap()
72 def cleanup(self):
73 KeyboardHelper.cleanup(self)
74 if self._keymap_change_handler_id:
75 try:
76 self._keymap.disconnect(self._keymap_change_handler_id)
77 self._keymap_change_handler_id = None
78 except Exception as e:
79 log.warn("failed to disconnect keymap change handler: %s", e)
82def main():
83 #use gtk as display source:
84 from xpra.os_util import POSIX, OSX
85 if POSIX and not OSX:
86 from xpra.x11.gtk_x11.gdk_display_source import init_gdk_display_source
87 init_gdk_display_source()
88 from xpra.util import print_nested_dict
89 from xpra.platform import program_context
90 with program_context("GTK-Keyboard", "GTK Keyboard"):
91 x = GTKKeyboardHelper(None, True, "")
92 x.query_xkbmap()
93 print_nested_dict(x.get_keymap_properties())
95if __name__ == "__main__":
96 main()