mirror of
https://github.com/KevinMidboe/keyboard-dashboard-autostart.git
synced 2025-10-28 17:20:18 +00:00
listens for keyboard input on function keys and runs functions mapped to certain keys
148 lines
3.9 KiB
Python
148 lines
3.9 KiB
Python
#!/usr/bin/python3
|
|
import struct, os, sys, subprocess, threading
|
|
from time import sleep, time
|
|
from evdev import InputDevice, categorize, ecodes, list_devices
|
|
from functools import partial
|
|
|
|
USER='kevin'
|
|
chromeBin = '/usr/bin/chromium-browser'
|
|
BOOKMARK_DIR = f'/home/{USER}/.config/chromium/Default'
|
|
|
|
def findKeyboard():
|
|
devices = [InputDevice(path) for path in list_devices()]
|
|
for device in devices:
|
|
if 'keyboard' in device.name.lower() or 'kbd' in device.name.lower():
|
|
return device
|
|
|
|
raise Exception('Keyboard device not found. You may need to run as root.')
|
|
|
|
def getBookmarks():
|
|
cmd = f"cat {BOOKMARK_DIR}/Bookmarks | jq '.roots.bookmark_bar.children[0].children[] | .url' | tr '\\n' ' '"
|
|
|
|
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=isinstance(cmd, str), text=True, check=True)
|
|
return result.stdout.strip()
|
|
|
|
def programRunning(cmd, onlyPrefix=False):
|
|
if onlyPrefix:
|
|
cmd = cmd.split(' ')[0]
|
|
|
|
try:
|
|
subprocess.run(["pgrep", "-f", cmd], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
|
|
return True
|
|
except subprocess.CalledProcessError:
|
|
return False
|
|
|
|
def buildUserCommand(cmd):
|
|
userSpaceCmd = f'su - {USER} -c'
|
|
userDisplayCmd = 'export DISPLAY=:0; '
|
|
cmdList = userSpaceCmd.split(' ')
|
|
cmdList.append(userDisplayCmd + cmd)
|
|
return cmdList
|
|
|
|
def openBrowser():
|
|
bookmarks = getBookmarks()
|
|
browserCmd = chromeBin + ' \
|
|
--no-first-run \
|
|
--disable \
|
|
--hide-crash-restore-bubble \
|
|
--disable-translate \
|
|
--disable-infobars \
|
|
--disable-suggestions-service \
|
|
--disable-save-password-bubble \
|
|
--kiosk ' \
|
|
+ bookmarks
|
|
|
|
if programRunning(browserCmd, True):
|
|
print('browser already running, exiting')
|
|
return
|
|
|
|
print('launching browser')
|
|
runUnclutter()
|
|
cmd = buildUserCommand(browserCmd)
|
|
subprocess.Popen(cmd)
|
|
|
|
def openTerminal(cmd, windowHeight=None, windowY=None):
|
|
if programRunning(cmd):
|
|
print('terminal already running w/ this command, exiting')
|
|
return
|
|
|
|
print('launching terminal w/ command:', cmd)
|
|
cmd = f'lxterminal -e "{cmd}"'
|
|
|
|
cmd = buildUserCommand(cmd)
|
|
subprocess.Popen(cmd)
|
|
|
|
def runUnclutter():
|
|
program = 'unclutter'
|
|
if programRunning(program):
|
|
print(f"{program} already running")
|
|
return
|
|
|
|
print(f"starting {program}")
|
|
cmd = buildUserCommand(f'{program} &')
|
|
subprocess.run(cmd)
|
|
|
|
def startup():
|
|
timeout = 1
|
|
print("waiting {} seconds, then launching chrome".format(timeout))
|
|
sleep(timeout)
|
|
openBrowser()
|
|
|
|
def listenForInput():
|
|
print("listening for keyboard input")
|
|
|
|
try:
|
|
dev = findKeyboard()
|
|
print(f'Listening to: {dev.name} ({dev.path})')
|
|
|
|
for event in dev.read_loop():
|
|
if event.type != ecodes.EV_KEY:
|
|
continue
|
|
|
|
key_event = categorize(event)
|
|
if key_event.keystate != key_event.key_down:
|
|
continue
|
|
|
|
print(f'Keycode: {key_event.keycode}')
|
|
if key_event.keycode not in KEY_EVENT_PROGRAM_MAP:
|
|
continue
|
|
|
|
KEY_EVENT_PROGRAM_MAP[key_event.keycode]()
|
|
|
|
except PermissionError:
|
|
print('Permission denied. Try running with sudo or check device permissions.')
|
|
except Exception as e:
|
|
print(f'Error: {e}')
|
|
|
|
KEY_EVENT_PROGRAM_MAP = {
|
|
'KEY_F16': openBrowser,
|
|
'KEY_F17': partial(openTerminal, 'watch -n 1 "sensors | grep temp1"')
|
|
}
|
|
|
|
def printHelp():
|
|
print("Available key bindings:\n")
|
|
for key, func in KEY_EVENT_PROGRAM_MAP.items():
|
|
key = key.replace('KEY_', '')
|
|
|
|
if isinstance(func, partial):
|
|
func_name = func.func.__name__
|
|
args = ", ".join(repr(arg) for arg in func.args)
|
|
print(f"{key}: {func_name}({args})")
|
|
else:
|
|
func_name = func.__name__ if hasattr(func, '__name__') else str(func)
|
|
print(f"{key}: {func_name}()")
|
|
|
|
def main():
|
|
backgroundStartupThread = threading.Thread(target=startup)
|
|
backgroundStartupThread.start()
|
|
|
|
listenForInput()
|
|
|
|
if __name__ == '__main__':
|
|
if '-h' in sys.argv or '--help' in sys.argv:
|
|
printHelp()
|
|
sys.exit(0)
|
|
else:
|
|
main()
|
|
|