forked from dogeystamp/inkscape-shortcut-manager
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
110 lines (89 loc) · 3.54 KB
/
main.py
File metadata and controls
110 lines (89 loc) · 3.54 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
import threading
import Xlib
from Xlib.display import Display
from Xlib import X, XK
from Xlib.protocol import event
from normal import normal_mode
class Manager():
def __init__(self, inkscape_id):
self.id = inkscape_id
self.disp = Display()
self.screen = self.disp.screen()
self.root = self.screen.root
self.inkscape = self.disp.create_resource_object('window', inkscape_id)
self.mode = normal_mode
def event(self, name, detail, state):
return name(
time=X.CurrentTime,
root=self.root,
window=self.inkscape,
same_screen=0, child=Xlib.X.NONE,
root_x=0, root_y=0, event_x=0, event_y=0,
state=state,
detail=detail
)
def string_to_keycode(self, key):
keysym = XK.string_to_keysym(key)
keycode = self.disp.keysym_to_keycode(keysym)
return keycode
def press(self, key, mask=X.NONE):
keycode = self.string_to_keycode(key)
self.inkscape.send_event(self.event(event.KeyPress, keycode, mask), propagate=True)
self.inkscape.send_event(self.event(event.KeyRelease, keycode, mask), propagate=True)
self.disp.flush()
self.disp.sync()
def grab(self):
for mask in 0, X.ControlMask, X.ShiftMask:
self.inkscape.grab_key(X.AnyKey, mask, True, X.GrabModeAsync, X.GrabModeAsync)
# works with numlock too
self.inkscape.grab_key(X.AnyKey, mask | X.Mod2Mask, True, X.GrabModeAsync, X.GrabModeAsync)
# Ungrab window manager shortcuts (Super + ...)
self.inkscape.ungrab_key(self.string_to_keycode('Super_L'), X.AnyModifier, True)
self.inkscape.ungrab_key(self.string_to_keycode('Alt_L'), X.AnyModifier, True)
self.inkscape.change_attributes(event_mask=X.KeyReleaseMask | X.KeyPressMask | X.StructureNotifyMask)
def ungrab(self):
self.inkscape.ungrab_key(X.AnyKey, X.AnyModifier, True)
def listen(self):
self.grab()
while True:
evt = self.disp.next_event()
if evt.type in [X.KeyPress, X.KeyRelease]:
keycode = evt.detail
keysym = self.disp.keycode_to_keysym(keycode, 0)
char = XK.keysym_to_string(keysym)
self.disp.allow_events(X.ReplayKeyboard, X.CurrentTime)
self.mode(self, evt, char)
if evt.type == X.DestroyNotify:
if evt.window.id == self.id:
self.ungrab()
return
def create(inkscape_id):
m = Manager(inkscape_id)
m.listen()
def is_inkscape(window):
return (window.get_wm_class() and 'inkscape' in window. get_wm_class()[0])
def main():
disp = Display()
screen = disp.screen()
root = screen.root
# First listen for existing windows
for window in root.query_tree().children:
if is_inkscape(window):
print('Found existing window')
listen = threading.Thread(target=create, args=[window.id])
listen.start()
# New windows
root.change_attributes(event_mask=X.SubstructureNotifyMask)
while True:
evt = disp.next_event()
if evt.type == X.CreateNotify:
window = evt.window
try:
if is_inkscape(window):
print('New window!')
listen = threading.Thread(target=create, args=[window.id])
listen.start()
except Xlib.error.BadWindow:
pass
if __name__ == '__main__':
main()