Skip to content

Commit d2bf3e1

Browse files
committed
#1171: try to detect the keyboard layout
git-svn-id: https://xpra.org/svn/Xpra/trunk@15092 3bb7dfac-3a0b-4e04-842a-767bc560f471
1 parent 4bd63d7 commit d2bf3e1

File tree

2 files changed

+107
-1
lines changed

2 files changed

+107
-1
lines changed

src/xpra/platform/darwin/keyboard.py

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This file is part of Xpra.
22
# Copyright (C) 2010 Nathaniel Smith <[email protected]>
3-
# Copyright (C) 2011-2014 Antoine Martin <[email protected]>
3+
# Copyright (C) 2011-2017 Antoine Martin <[email protected]>
44
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
55
# later version. See the file COPYING for details.
66

@@ -34,6 +34,27 @@ def __init__(self):
3434
self.num_lock_keycode = NUM_LOCK_KEYCODE
3535
self.key_translations = {}
3636

37+
38+
def get_layout_spec(self):
39+
layout = "us"
40+
layouts = ["us"]
41+
variant = ""
42+
variants = []
43+
try:
44+
from xpra.platform.darwin.keyboard_layout import get_keyboard_layout
45+
i = get_keyboard_layout()
46+
log("get_keyboard_layout()=%s", i)
47+
locale = i["locale"] #ie: "en_GB"
48+
parts = locale.split("_")
49+
if len(parts)==2:
50+
layout = parts[1].lower()
51+
layouts = [layout, 'us']
52+
except Exception as e:
53+
log("get_layout_spec()", exc_info=True)
54+
log.error("Error querying keyboard layout:")
55+
log.error(" %s", e)
56+
return layout, layouts, variant, variants
57+
3758
def get_keymap_modifiers(self):
3859
"""
3960
Override superclass so we can tell the server
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# coding=utf8
2+
# @PydevCodeAnalysisIgnore
3+
# This file is part of Xpra.
4+
# Copyright (C) 2017 Antoine Martin <[email protected]>
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+
8+
# This file is based on this gist:
9+
# https://gist.github.com/pudquick/cff1ecdc02b4cabe5aa0dc6919d97c6d
10+
11+
12+
from Foundation import NSBundle
13+
import objc
14+
15+
def _get_keyboard_layouts():
16+
HIToolbox_bundle = NSBundle.bundleWithIdentifier_("com.apple.HIToolbox")
17+
HIT_functions = [
18+
('TISCreateInputSourceList','@@B'),
19+
('TISGetInputSourceProperty', '@@@'),
20+
]
21+
22+
HIT_constants = [
23+
('kTISPropertyInputSourceType', '@'),
24+
('kTISTypeKeyboardLayout', '@'),
25+
('kTISTypeKeyboardInputMode', '@'),
26+
('kTISPropertyLocalizedName', '@'),
27+
('kTISPropertyBundleID', '@'),
28+
('kTISPropertyInputModeID', '@'),
29+
('kTISPropertyInputSourceID', '@'),
30+
('kTISPropertyLocale', '@'),
31+
('kTISPropertyKeyLayoutNumber', '@'),
32+
('kTISPropertyScriptCode', '@'),
33+
]
34+
35+
objc.loadBundleFunctions(HIToolbox_bundle, globals(), HIT_functions)
36+
# Yes, I know it's amusing that loadBundleVariables is loading constants - ... oh, so it's just me then? k
37+
objc.loadBundleVariables(HIToolbox_bundle, globals(), HIT_constants)
38+
#silence pydev:
39+
40+
# get the list of keyboard layouts
41+
keyboard_layouts = TISCreateInputSourceList({kTISPropertyInputSourceType: kTISTypeKeyboardLayout}, True)
42+
# (
43+
# "<TSMInputSource 0x7ff8e9f2cc00> KB Layout: U.S. (id=0)",
44+
# "<TSMInputSource 0x7ff8e9f2c5f0> KB Layout: Czech - QWERTY (id=30778)",
45+
# "<TSMInputSource 0x7ff8e9f2b8c0> KB Layout: Czech (id=30776)",
46+
# [...]
47+
print("TISCreateInputSourceList keyboard_layouts=%s", keyboard_layouts)
48+
return keyboard_layouts
49+
50+
def _get_keyboard_layout_dict(layout):
51+
def getprop(k):
52+
return TISGetInputSourceProperty(layout, k)
53+
# Can't figure out the constant names for these ones, so we'll make 'em up
54+
kTISPropertyKind = u'TSMInputSourcePropertyKind'
55+
# <TSMInputSource 0x7ff8e9f2c5f0> KB Layout: Czech - QWERTY (id=30778)
56+
kind = getprop(kTISPropertyKind)
57+
# u'TSMInputSourceKindKeyboardLayout'
58+
name = getprop(kTISPropertyLocalizedName)
59+
# u'Czech - QWERTY'
60+
kid = getprop(kTISPropertyKeyLayoutNumber)
61+
# 30778
62+
script = getprop(kTISPropertyScriptCode)
63+
# 29
64+
sid = getprop(kTISPropertyInputSourceID)
65+
# u'com.apple.keylayout.Czech-QWERTY'
66+
locale = getprop(kTISPropertyLocale)
67+
# u'cs'
68+
return {
69+
"kind" : kind,
70+
"name" : name,
71+
"id" : kid,
72+
"script" : script,
73+
"sid" : sid,
74+
"locale" : locale,
75+
}
76+
77+
def get_keyboard_layout():
78+
layouts = _get_keyboard_layouts()
79+
if not layouts:
80+
return {}
81+
#assume the first layout is the active one...
82+
return _get_keyboard_layout_dict(layouts[0])
83+
84+
def get_keyboard_layouts():
85+
return [_get_keyboard_layout_dict(layout) for layout in _get_keyboard_layouts()]

0 commit comments

Comments
 (0)