Hide keyboard shortcuts

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. 

7 

8from gi.repository import GLib, Gdk 

9 

10from xpra.client.keyboard_helper import KeyboardHelper, log 

11from xpra.gtk_common.keymap import get_gtk_keymap 

12from xpra.os_util import is_X11 

13 

14 

15class GTKKeyboardHelper(KeyboardHelper): 

16 

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) 

30 

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) 

57 

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 

68 

69 def get_full_keymap(self): 

70 return get_gtk_keymap() 

71 

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) 

80 

81 

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()) 

94 

95if __name__ == "__main__": 

96 main()