forked from BurntSushi/pager-multihead
-
Notifications
You must be signed in to change notification settings - Fork 0
/
keymousebind.py
181 lines (135 loc) · 6.09 KB
/
keymousebind.py
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
from functools import partial
import xpybutil.ewmh as ewmh
import prompt
keybinds = {}
# KEY BINDING CONFIGURATION
##########################
# Here's where using Python for configuration really shines. You can
# completely control the way desktops are switched. For example, the current
# 'set_desktop' function takes either a desktop index or a prefix of a desktop
# name. One can use the keybindings '<Control><Alt>a' - '<Control><Alt>z'
# to switch between desktops starting with the corresponding letter.
# Also, I've stolen the "prompt" concept from Xmonad. If you know Python,
# check out 'prompt.py'; it should be fairly straight-forward to create your
# own prompts. If you want to modify it further (i.e., its appearance), you'll
# need to have some experiece with pygtk.
# There really aren't any docs, so please feel free to email me
# jamslam@gmail.com, or use https://bbs.archlinux.org/viewtopic.php?id=124331
def init():
shifts = ['exclam', 'at', 'numbersign', 'dollar', 'percent', 'asciicircum',
'ampersand', 'asterisk', 'parenleft']
for i in xrange(1, 10):
keybinds['<Alt>%d' % i] = mk_set_desktop(str(i))
keybinds['<Alt>%s' % shifts[i - 1]] = mk_set_activewin_desktop(str(i))
for c in xrange(ord('a'), ord('z') + 1):
keybinds['<Control><Alt>%s' % chr(c)] = mk_set_desktop(chr(c))
keybinds['<Super><Alt>%s' % chr(c)] = mk_set_activewin_desktop(chr(c))
keybinds['<Super>BackSpace'] = remove_empty_current_desktop
keybinds['<Super>Return'] = mk_prompt_desktop()
keybinds['<Super><Shift>Return'] = prompt_set_activewin_desktop
keybinds['<Super><Alt>space'] = mk_prompt_all_windows()
keybinds['<Super>space'] = mk_prompt_windows()
# MOUSE BINDING CONFIGURATION
#############################
# There isn't much here yet, other than when one clicks on mini-desktop picture.
def desktop_clicked(desktop):
ewmh.request_current_desktop_checked(desktop.desk).check()
# HELPER FUNCTIONS
##################
def mk_set_desktop(i_or_name):
return partial(set_desktop, str(i_or_name))
def mk_set_activewin_desktop(i_or_name):
return partial(set_activewin_desktop, str(i_or_name))
def mk_prompt_desktop():
return partial(prompt.desktops, set_or_add_desktop)
def mk_prompt_windows():
return partial(prompt.windows, goto_window, prefix_complete=False,
homogenous=False, current_desk=True)
def mk_prompt_all_windows():
return partial(prompt.windows, goto_window)
def set_desktop(i_or_name):
nextdesk = get_desk(i_or_name)
if nextdesk is not None:
ewmh.request_current_desktop_checked(nextdesk).check()
def set_activewin_desktop(i_or_name):
awin = ewmh.get_active_window().reply()
set_win_desktop(i_or_name, awin)
def set_win_desktop(i_or_name, win):
nextdesk = get_desk(i_or_name)
if None not in (nextdesk, win):
ewmh.request_wm_desktop_checked(win, nextdesk, 2).check()
def set_or_add_desktop(name):
names = ewmh.get_desktop_names().reply()
if name not in names:
names.append(name)
ewmh.set_desktop_names_checked(names).check()
num_desks = ewmh.get_number_of_desktops().reply()
ewmh.request_number_of_desktops_checked(num_desks + 1).check()
ewmh.request_current_desktop_checked(names.index(name)).check()
def prompt_set_activewin_desktop():
activewin = ewmh.get_active_window().reply()
def fun(name):
names = ewmh.get_desktop_names().reply()
if name not in names:
names.append(name)
ewmh.set_desktop_names_checked(names).check()
num_desks = ewmh.get_number_of_desktops().reply()
ewmh.request_number_of_desktops_checked(num_desks + 1).check()
ewmh.request_wm_desktop_checked(activewin,
names.index(name), 2).check()
prompt.desktops(fun)
def remove_empty_current_desktop():
# This isn't as straight-forward as decrementing _NET_NUMBER_OF_DESKTOPS.
# We need to make sure we remove the right name, too.
# AND only do it if there are no clients on this desktop.
clients = ewmh.get_client_list().reply()
cur = ewmh.get_current_desktop().reply()
for c in clients:
if ewmh.get_wm_desktop(c).reply() == cur:
return
names = ewmh.get_desktop_names().reply()
if cur < len(names):
names.pop(cur)
ewmh.set_desktop_names_checked(names).check()
# Subtract one from every client's desktop above the current one
for c in clients:
cdesk = ewmh.get_wm_desktop(c).reply()
if cdesk > cur and cdesk != 0xffffffff:
ewmh.set_wm_desktop_checked(c, cdesk - 1).check()
ndesks = ewmh.get_number_of_desktops().reply()
ewmh.request_number_of_desktops_checked(ndesks - 1).check()
def goto_window(win_name_or_id):
wid = win_name_or_id
if isinstance(wid, basestring):
clients = ewmh.get_client_list().reply()
for c in clients:
if wid == ewmh.get_wm_name(c).reply():
wid = c
break
if isinstance(wid, int):
wdesk = ewmh.get_wm_desktop(wid).reply()
if wdesk not in ewmh.get_visible_desktops().reply():
ewmh.request_current_desktop_checked(wdesk).check()
ewmh.request_active_window_checked(wid, source=2).check()
def get_desk(i_or_name):
if isinstance(i_or_name, int):
return i_or_name
assert isinstance(i_or_name, basestring)
nextdesk = None
names = ewmh.get_desktop_names().reply()
ci = ewmh.get_current_desktop().reply()
visibles = ewmh.get_visible_desktops().reply()
cname = names[ci] if ci < len(names) else ''
fnames = names[:]
if visibles:
not_cur_or_vis = lambda (i, nm): i not in visibles or i == ci
fnames = [nm for i, nm in filter(not_cur_or_vis, enumerate(fnames))]
fnames = filter(lambda n: n.lower().startswith(i_or_name.lower()), fnames)
fnames = sorted(fnames)
if cname in fnames:
posInPrefix = (fnames.index(cname) + 1) % len(fnames)
nextdesk = names.index(fnames[posInPrefix])
elif len(fnames):
nextdesk = names.index(fnames[0])
return nextdesk
init()