-
Notifications
You must be signed in to change notification settings - Fork 0
/
autohidewibox.py
executable file
·182 lines (160 loc) · 6.29 KB
/
autohidewibox.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
181
182
#!/usr/bin/env python3
import configparser
import os.path as path
import re
import subprocess
import sys
import threading
MODE_TRANSIENT = "transient"
MODE_TOGGLE = "toggle"
config = configparser.ConfigParser()
try:
user_awesome_conf = path.join(
path.expanduser("~"), ".config/awesome/autohidewibox.conf"
)
user_conf = path.join(path.expanduser("~"), ".config/autohidewibox.conf")
system_conf = "/etc/autohidewibox.conf"
if len(sys.argv) > 1 and path.isfile(sys.argv[1]):
config.read(sys.argv[1])
elif path.isfile(user_awesome_conf):
config.read(user_awesome_conf)
elif path.isfile(user_conf):
config.read(user_conf)
else:
config.read(system_conf)
except configparser.MissingSectionHeaderError:
pass
awesome_version = config.get("autohidewibox", "awesome_version", fallback=4)
super_keys = config.get("autohidewibox", "super_keys", fallback="133,134").split(",")
wiboxes = config.get("autohidewibox", "wiboxname", fallback="mywibox").split(",")
custom_hide = config.get("autohidewibox", "custom_hide", fallback=None)
custom_show = config.get("autohidewibox", "custom_show", fallback=None)
delay_show = config.getfloat("autohidewibox", "delay_show", fallback=0)
delay_hide = config.getfloat("autohidewibox", "delay_hide", fallback=0)
mode = config.get("autohidewibox", "mode", fallback=MODE_TRANSIENT)
debug = config.getboolean("autohidewibox", "debug", fallback=False)
# (remove the following line if your wibox variables have strange characters)
wiboxes = [w for w in wiboxes if re.match("^[a-zA-Z_][a-zA-Z0-9_]*$", w)]
### python>=3.4:
# wiboxes = [ w for w in wiboxes if re.fullmatch("[a-zA-Z_][a-zA-Z0-9_]*", w) ]
delay = {True: delay_show, False: delay_hide}
delay_thread = None
wibox_is_currently_visible = False
waiting_for = False
non_super_key_was_pressed = False
cancel = threading.Event()
sh_path = ""
sh_potential_paths = ["/usr/bin/sh", "/bin/sh"]
for p in sh_potential_paths:
if path.exists(p):
sh_path = p
break
if sh_path == "":
print("Can't find sh in any of: " + ",".join(sh_potential_paths), file=sys.stderr)
sys.exit(1)
hide_command_v3 = "for k,v in pairs({wibox}) do v.visible = {state} end"
hide_command_v4 = "for s in screen do s.{wibox}.visible = {state} end"
try:
hide_command = hide_command_v4 if int(awesome_version) >= 4 else hide_command_v3
except ValueError:
hide_command = hide_command_v4
def _debug(*args):
if debug:
print(*args)
def set_wibox_state(state=True, immediate=False):
global delay_thread, waiting_for, cancel, wibox_is_currently_visible
wibox_is_currently_visible = state
dbg_pstate = "show" if state else "hide"
if delay[not state] > 0:
_debug(dbg_pstate, "delay other")
if type(delay_thread) == threading.Thread and delay_thread.is_alive():
# two consecutive opposing events cancel out. second event should not be
# called
_debug(dbg_pstate, "delay other, thread alive -> cancel")
cancel.set()
return
if delay[state] > 0 and not immediate:
_debug(dbg_pstate + " delay same")
if not (type(delay_thread) == threading.Thread and delay_thread.is_alive()):
_debug(dbg_pstate, "delay same, thread dead -> start wait")
waiting_for = state
cancel.clear()
delay_thread = threading.Thread(
group=None, target=wait_delay, kwargs={"state": state}
)
delay_thread.daemon = True
delay_thread.start()
# a second event setting the same state is silently discarded
return
_debug("state:", dbg_pstate)
for wibox in wiboxes:
subprocess.call(
sh_path
+ " "
+ "-c \"echo '"
+ hide_command.format(wibox=wibox, state="true" if state else "false")
+ "' | awesome-client\"",
shell=True,
)
customcmd = custom_show if state else custom_hide
if customcmd:
subprocess.call(
sh_path + " " + "-c \"echo '" + customcmd + "' | awesome-client\"",
shell=True,
)
def wait_delay(state=True):
if not cancel.wait(delay[state] / 1000):
set_wibox_state(state=state, immediate=True)
try:
set_wibox_state(False)
proc = subprocess.Popen(
["xinput", "--test-xi2", "--root", "3"], stdout=subprocess.PIPE
)
field = None
key_state = None
for line in proc.stdout:
l = line.decode("utf-8").strip()
event_match = re.match("EVENT type (\\d+) \\(.+\\)", l)
detail_match = re.match("detail: (\\d+)", l)
if event_match:
_debug(event_match)
try:
field = "event"
key_state = event_match.group(1)
_debug("found event, waiting for detail...")
except IndexError:
field = None
key_state = None
if (field == "event") and detail_match:
_debug(detail_match)
try:
if detail_match.group(1) in super_keys:
_debug("is a super key")
if key_state == "13": # press
non_super_key_was_pressed = False
if mode == MODE_TRANSIENT:
_debug("showing wibox")
set_wibox_state(True)
if key_state == "14": # release
if mode == MODE_TRANSIENT:
_debug("hiding wibox")
set_wibox_state(False)
# Avoid toggling the wibox when a super key is used in
# conjunction with another key.
elif mode == MODE_TOGGLE and not non_super_key_was_pressed:
_debug("toggling wibox")
set_wibox_state(not wibox_is_currently_visible)
non_super_key_was_pressed = False
else:
non_super_key_was_pressed = True
except IndexError:
_debug("Couldn't parse key_state number.")
pass
finally:
field = None
key_state = None
except KeyboardInterrupt:
pass
finally:
set_wibox_state(True, True)
_debug("Shutting down")