Skip to content

Instantly share code, notes, and snippets.

@djarum-black
Created May 8, 2024 23:42
Show Gist options
  • Save djarum-black/dc44420385f7d8b9408b007f549dd6d2 to your computer and use it in GitHub Desktop.
Save djarum-black/dc44420385f7d8b9408b007f549dd6d2 to your computer and use it in GitHub Desktop.
External Numpad
import os
import yaml
import logging
import logging.handlers
import subprocess
from evdev import InputDevice, categorize, ecodes
import i3ipc
# Setup logging to syslog
logger = logging.getLogger('WindowLogger')
logger.setLevel(logging.DEBUG) # Set to DEBUG for extensive logging
handler = logging.handlers.SysLogHandler(address='/dev/log')
logger.addHandler(handler)
formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
def load_shortcuts(file_path):
with open(file_path, 'r') as file:
return yaml.safe_load(file)
def execute_command(command):
os.environ['DISPLAY'] = ':0'
subprocess.run(command)
def get_active_window_info():
try:
window_id = subprocess.run(['xdotool', 'getactivewindow'], capture_output=True, text=True).stdout.strip()
window_name = subprocess.run(['xdotool', 'getwindowname', window_id], capture_output=True, text=True).stdout.strip()
logger.debug(f"Active window ID: {window_id}, Name: {window_name}")
return window_id, window_name
except Exception as e:
logger.error(f"Error retrieving window information: {str(e)}")
return None, None
def switch_workspace(workspace):
i3.command(f'workspace {workspace}')
def handle_key_event(event, shortcuts, window_name):
if event.type == ecodes.EV_KEY:
key = categorize(event)
if key.keystate == key.key_down: # Key press
keycode = key.keycode
if keycode in shortcuts:
default_action = None
for shortcut in shortcuts[keycode]:
if 'ifwindow' in shortcut:
match_type = shortcut.get('match_type', 'exact')
if match_type == 'start' and not window_name.startswith(shortcut['ifwindow']):
continue
elif match_type == 'end' and not window_name.endswith(shortcut['ifwindow']):
continue
elif match_type == 'contain' and shortcut['ifwindow'] not in window_name:
continue
elif match_type == 'exact' and shortcut['ifwindow'] != window_name:
continue
logger.debug(f"Selected shortcut: {shortcut}")
if 'function' in shortcut:
globals()[shortcut['function']](shortcut.get('arg'))
elif 'command' in shortcut:
execute_command(shortcut['command'])
return
elif 'ifwindow' not in shortcut:
default_action = shortcut
if default_action:
logger.debug(f"Selected shortcut: {default_action}")
if 'function' in default_action:
globals()[default_action['function']](default_action.get('arg'))
elif 'command' in default_action:
execute_command(default_action['command'])
# Load keyboard shortcuts from YAML file
shortcuts = load_shortcuts('shortcuts.yaml')
# Get the device location
device_location = shortcuts.pop('device', '/dev/input/event2')
# Create the connection to i3
i3 = i3ipc.Connection()
# Specify the device
dev = InputDevice(device_location)
dev.grab()
# Loop to handle key events
for event in dev.read_loop():
window_id, window_name = get_active_window_info()
logger.info(f"Active window ID: {window_id}, Name: {window_name}")
handle_key_event(event, shortcuts, window_name)
certifi==2024.2.2
charset-normalizer==3.3.2
evdev==1.7.1
i3ipc==2.2.1
idna==3.7
python-xlib==0.33
PyYAML==6.0.1
requests==2.31.0
six==1.16.0
urllib3==2.2.1
device: '/dev/input/event2'
KEY_KP1:
- command: ['i3-msg', 'workspace', 'NP1']
KEY_KP2:
- command: ['i3-msg', 'workspace', 'NP2']
KEY_KP3:
- command: ['i3-msg', 'workspace', 'NP3']
KEY_KP4:
- command: ['i3-msg', 'workspace', 'NP4']
KEY_KP5:
- command: ['i3-msg', 'workspace', 'NP5']
KEY_KP6:
- command: ['i3-msg', 'workspace', 'NP6']
KEY_KP7:
- command: ['i3-msg', 'workspace', 'NP7']
KEY_KP8:
- command: ['i3-msg', 'workspace', 'NP8']
KEY_KP9:
- command: ['i3-msg', 'workspace', 'NP9']
KEY_KP0:
- command: ['i3-msg', 'workspace', 'NP10']
KEY_KPMINUS:
- command: ['xdotool', 'key', 'Shift+Ctrl+a']
ifwindow: 'Terminal'
match_type: 'start'
- command: ['xdotool', 'key', 'Shift+a']
ifwindow: 'Firefox'
match_type: 'end'
- command: ['xdotool', 'key', 'Shift+b']
ifwindow: 'Browser'
match_type: 'contain'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment