Browse Source
Changes to be committed: new file: .gitignore new file: README new file: mouse_mute.py new file: requirements.txtmain
commit
d1e8404545
4 changed files with 119 additions and 0 deletions
@ -0,0 +1,2 @@
|
||||
Did you ever need to send a mouse event to a sandboxed X11 program while using |
||||
Wayland? Me neither. But, for the weirdo that wants to, here's this thing. |
||||
@ -0,0 +1,113 @@
|
||||
|
||||
import re |
||||
import select |
||||
import sys |
||||
|
||||
import evdev # https://github.com/gvalkov/python-evdev |
||||
import pulsectl # https://github.com/mk-fg/python-pulse-control |
||||
|
||||
|
||||
# NOTE: adapted from evdev/evtest.py |
||||
def select_mouse(key_code:int = -1) -> evdev.InputDevice: |
||||
def devicenum(device_path): |
||||
digits = re.findall(r"\d+$", device_path) |
||||
return [int(i) for i in digits] |
||||
|
||||
devices = sorted(evdev.list_devices('/dev/input'), key=devicenum) |
||||
devices = [evdev.InputDevice(path) for path in devices] |
||||
if not devices: |
||||
msg = "error: no input devices found (do you have rw permission on %s/*?)" |
||||
print(msg % device_dir, file=sys.stderr) |
||||
return None |
||||
|
||||
for i, dev in enumerate(devices): |
||||
print("{}: {}".format(i, dev.name)) |
||||
|
||||
selection = input("select mouse device: ") |
||||
try: |
||||
if int(selection) > len(devices): |
||||
return None |
||||
except (TypeError, ValueError): |
||||
print("invalid comparison") |
||||
return None |
||||
|
||||
dev_caps = devices[int(selection)].capabilities() |
||||
|
||||
if (evdev.ecodes.EV_KEY not in dev_caps or |
||||
key_code not in dev_caps[evdev.ecodes.EV_KEY]): |
||||
print("this device doesn't have a BTN_SIDE") |
||||
return None |
||||
|
||||
return devices[int(selection)] |
||||
|
||||
def parse_event(e:evdev.InputEvent, listen_key:int) -> int: |
||||
if e.type == evdev.ecodes.EV_KEY: |
||||
if e.code == listen_key: |
||||
return e.value |
||||
|
||||
return -1 |
||||
|
||||
def select_source() -> pulsectl.PulseSourceInfo: |
||||
with pulsectl.Pulse() as pulse: |
||||
source_list = pulse.source_list() |
||||
|
||||
for i, source in enumerate(source_list): |
||||
print("{}: {}".format(i, source.description)) |
||||
|
||||
selection = input("select sount input device: ") |
||||
try: |
||||
if int(selection) > i: |
||||
return None |
||||
except (TypeError, ValueError): |
||||
print("invalid comparison") |
||||
return None |
||||
|
||||
return source_list[int(selection)] |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
# TODO: capture initial mute state |
||||
|
||||
# TODO: select other devices/buttons |
||||
key_code = evdev.ecodes.BTN_SIDE |
||||
device = select_mouse(key_code) |
||||
|
||||
if device == None: |
||||
print("error selecting device") |
||||
# FIXME: restore initial mute state here too |
||||
sys.exit(1) |
||||
|
||||
source = select_source() |
||||
|
||||
if source is None: |
||||
print("error selecting pulse source") |
||||
# FIXME: restore initial mute state here too |
||||
sys.exit(1) |
||||
|
||||
pulse = pulsectl.Pulse() |
||||
|
||||
# NOTE: listen for the BTN_SIDE event |
||||
# TODO: an option to play a sound on mute/unmute here would be nice too: |
||||
# https://github.com/hamiltron/py-simple-audio |
||||
|
||||
try: |
||||
print("Listening for events (press ctrl-c to exit) ...") |
||||
pulse = pulsectl.Pulse() |
||||
pulse.source_list() |
||||
|
||||
while True: |
||||
for event in device.read_loop(): |
||||
ret = parse_event(event, key_code) |
||||
if ret == 0: |
||||
pulse.mute(source, True) |
||||
elif ret == 1: |
||||
pulse.mute(source, False) |
||||
else: |
||||
pass |
||||
except (KeyboardInterrupt, EOFError): |
||||
pass |
||||
|
||||
# TODO: restore initial mute state |
||||
|
||||
|
||||
sys.exit(0) |
||||
Loading…
Reference in new issue