-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathapply-binding.py
More file actions
117 lines (94 loc) · 3.68 KB
/
Copy pathapply-binding.py
File metadata and controls
117 lines (94 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import os
import sys
import argparse
import subprocess
BINDING_NAME = "textual-switcher"
CUSTOM_KEYB_PATH = ""
BINDING_LIST_PATH = ""
DEFAULT_DESKTOP = "gnome"
SUPPORTED_WINDOW_MANAGERS = ['unity', 'gnome', 'cinnamon']
def set_paths(window_manager):
global BINDING_LIST_PATH
global CUSTOM_KEYB_PATH
if window_manager == 'cinnamon':
BINDING_LIST_PATH = "/org/cinnamon/desktop/keybindings/custom-list"
CUSTOM_KEYB_PATH = "/org/cinnamon/desktop/keybindings/custom-keybindings"
if window_manager in ('gnome', 'unity'):
BINDING_LIST_PATH = "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings"
CUSTOM_KEYB_PATH = BINDING_LIST_PATH
def dconf_write(path, value):
if isinstance(value, str):
value = "'{}'".format(value)
elif isinstance(value, list):
value = str(value)
cmd = ["dconf", "write", path, value]
subprocess.check_output(cmd)
def dconf_read(path):
cmd = ["dconf", "read", path]
output = subprocess.check_output(cmd)
return output
def get_binding_list():
bindings = dconf_read(BINDING_LIST_PATH)
bindings = bindings.decode('utf-8')
bindings = bindings.strip().strip("'")
if not bindings:
return []
bindings = bindings[bindings.index("["):] # Deal with '@as'
bindings = bindings[1:-1]
bindings = bindings.replace("'", "")
bindings = bindings.split(",")
bindings = [binding.strip() for binding in bindings if binding.strip()]
return bindings
def add_binding_to_list_entry(new_binding_path, window_manager):
if window_manager in ('gnome', 'unity'):
entry_value = "{}/".format(new_binding_path)
elif window_manager == 'cinnamon':
entry_value = os.path.basename(new_binding_path)
else:
assert False, "invalid window manager"
bindings = get_binding_list()
if entry_value not in bindings:
bindings.append(entry_value)
dconf_write(BINDING_LIST_PATH, bindings)
def set_binding_entry(binding_values, entry_path, window_manager):
for name, value in binding_values.items():
binding_path = "{}/{}".format(entry_path, name)
dconf_write(binding_path, value)
def set_binding(cmd, key_combination, window_manager):
entry_path = "{}/{}".format(CUSTOM_KEYB_PATH, BINDING_NAME)
add_binding_to_list_entry(entry_path, window_manager)
binding_values = dict(name=BINDING_NAME,
binding=key_combination,
command=cmd)
set_binding_entry(binding_values, entry_path, window_manager)
def detect_window_manager():
window_manager = os.getenv("XDG_CURRENT_DESKTOP", None)
if window_manager is None:
return None
window_manager = window_manager.lower()
if 'cinnamon' in window_manager:
window_manager = 'cinnamon'
if window_manager == 'ubuntu:gnome':
window_manager = 'gnome'
if window_manager not in SUPPORTED_WINDOW_MANAGERS:
return None
return window_manager
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("command")
parser.add_argument("key_combination")
return parser.parse_args()
def canonize_binding(binding, window_manager):
if window_manager in ('cinnamon',):
binding = binding.replace('<Control>', '<Primary>')
binding = [binding]
return binding
if __name__ == "__main__":
args = parse_args()
window_manager = detect_window_manager()
if window_manager is None:
print("Unsupported desktop environment: {}".format(window_manager))
sys.exit(1)
key_combination = canonize_binding(args.key_combination, window_manager)
set_paths(window_manager)
set_binding(args.command, key_combination, window_manager)