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
|
#!/usr/bin/env python3
import argparse
device_ids = {
"k:0000:0000", # cros_ec keyboard
"k:0001:0001", # AT keyboard
"k:18d1:503c", # Google Inc. Hammer
"k:18d1:5050", # Google Inc. Hammer
}
vivaldi_keys = {
"90": "previoussong",
"91": "zoom",
"92": "scale",
"93": "print",
"94": "brightnessdown",
"95": "brightnessup",
"97": "kbdillumdown",
"98": "kbdillumup",
"99": "nextsong",
"9A": "playpause",
"9B": "micmute",
"9E": "kbdillumtoggle",
"A0": "mute",
"AE": "volumedown",
"B0": "volumeup",
"E9": "forward",
"EA": "back",
"E7": "refresh",
}
def get_ids_string(device_ids):
return "\n".join(device_ids)
def get_physmap_data():
try:
with open("/sys/bus/platform/devices/i8042/serio0/function_row_physmap", "r") as file:
return file.read().strip().split()
except FileNotFoundError:
return ""
def get_functional_row(physmap, use_vivaldi, super_is_held, super_inverted):
i = 0
result = ""
for scancode in physmap:
i += 1
# Map zoom to f11 since most applications wont listen to zoom
mapping = "f11" if vivaldi_keys[scancode] == "zoom" \
else vivaldi_keys[scancode]
match [super_is_held, use_vivaldi, super_inverted]:
case [True, True, False] | [False, True, True]:
result += f"{vivaldi_keys[scancode]} = f{i}\n"
case [True, False, False] | [False, False, True]:
result += f"f{i} = f{i}\n"
case [False, True, False] | [True, True, True]:
result += f"{vivaldi_keys[scancode]} = {mapping}\n"
case [False, False, False] | [True, False, True]:
result += f"f{i} = {mapping}\n"
return result
def get_keyd_config(physmap, inverted):
config = f"""\
[ids]
{get_ids_string(device_ids)}
[main]
{get_functional_row(physmap, use_vivaldi=False, super_is_held=False, super_inverted=inverted)}
{get_functional_row(physmap, use_vivaldi=True, super_is_held=False, super_inverted=inverted)}
f13=coffee
sleep=coffee
[meta]
{get_functional_row(physmap, use_vivaldi=False, super_is_held=True, super_inverted=inverted)}
{get_functional_row(physmap, use_vivaldi=True, super_is_held=True, super_inverted=inverted)}
[alt]
backspace = delete
brightnessdown = kbdillumdown
brightnessup = kbdillumup
f6 = kbdillumdown
f7 = kbdillumup
[control]
f5 = print
scale = print
[control+alt]
backspace = C-A-delete
"""
return config
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--file", default="cros.conf", help="path to save config (default: cros.conf)")
parser.add_argument("-i", "--inverted", action="store_true",
help="use functional keys by default and media keys when super is held")
args = vars(parser.parse_args())
physmap = get_physmap_data()
if not physmap:
print("no function row mapping found, using default mapping")
physmap = ['EA', 'E9', 'E7', '91', '92', '94', '95', 'A0', 'AE', 'B0']
config = get_keyd_config(physmap, args["inverted"])
with open(args["file"], "w") as conf:
conf.write(config)
if __name__ == "__main__":
main()
|