Files
wayland_key_mapper/volume_remapper.py

82 lines
3.0 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
volume_remapper.py
------------------
Listen for VolumeUp key events and emit a different key code
(“Ctrl+Shift+M” by default) so the focused application receives it.
Dependencies: pythonevdev (pip install evdev)
"""
import sys
import os
import argparse
from evdev import InputDevice, categorize, ecodes, UInput, list_devices
import time
# ------------------------------------------------------------------ #
# Helpers
# ------------------------------------------------------------------ #
def find_device(name_substr="volume"):
"""Return the first InputDevice that contains a KEY_VOLUMEUP event."""
for dev_path in [d.path for d in list_devices()]:
dev = InputDevice(dev_path)
caps = dev.capabilities()
if ecodes.EV_KEY in caps and ecodes.KEY_VOLUMEUP in caps[ecodes.EV_KEY]:
if name_substr.lower() in dev.name.lower():
return dev
return None
# ------------------------------------------------------------------ #
# Core logic
# ------------------------------------------------------------------ #
def main(remap_keys, device=None):
"""
:param remap_keys: tuple of ecodes.KEY_* codes to emit (e.g. (ecodes.KEY_LCTRL, ecodes.KEY_LSHIFT, ecodes.KEY_M))
:param device: path to /dev/input/eventX or None to autodetect
"""
if device is None:
dev = find_device()
if dev is None:
print("⚠️ No device with a VolumeUp key found.", file=sys.stderr)
sys.exit(1)
else:
dev = InputDevice(device)
print(f"[INFO] Listening on {dev.path} ({dev.name}) ...")
print(f"[INFO] Remapping to: {', '.join(ecodes.KEY.get(k) for k in remap_keys)}")
# Create a virtual keyboard (uinput)
ui = UInput(events=[
ecodes.EV_KEY, # only key events
ecodes.EV_SYN
], name='volumeremapper')
try:
for event in dev.read_loop():
if event.type == ecodes.EV_KEY:
if event.code == ecodes.KEY_VOLUMEUP and event.value == 1: # key_down
# Emit the mapped key sequence
for key in remap_keys:
ui.write(ecodes.EV_KEY, key, 1) # key down
ui.write(ecodes.EV_KEY, key, 0) # key up
ui.syn()
print(f"✅ Mapped VolumeUp → {', '.join(ecodes.KEY.get(k) for k in remap_keys)}")
except KeyboardInterrupt:
print("\n[INFO] Stopping …")
finally:
ui.close()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Remap VolumeUp to any key combo.")
parser.add_argument("--device", help="Optional /dev/input/eventX path to listen on.")
parser.add_argument("--to", nargs="+", default=["KEY_LCTRL", "KEY_LSHIFT", "KEY_M"],
help="Spaceseparated key names to emit. Default: Ctrl+Shift+M")
args = parser.parse_args()
# Convert key names to ecodes
remap = [ecodes.KEY[code.upper()] for code in args.to]
main(remap_keys=remap, device=args.device)