PK!4u} linux-touchpad/__init__.pyimport uvloop uvloop.install() PK!~~linux-touchpad/__main__.pyimport os import asyncio as aio import signal import argparse from .lock import Lock, LockExistsError from .touchpad import SIGTOGGLE, watch_devices from .process import handler def start(): try: with Lock(): signal.signal(signal.SIGTERM, handler) signal.signal(SIGTOGGLE, handler) aio.run(watch_devices()) except LockExistsError: pass def signal_toggle(): pid = Lock.getpid() os.kill(pid, SIGTOGGLE) def signal_kill(): pid = Lock.getpid() os.kill(pid, signal.SIGTERM) parser = argparse.ArgumentParser() options = { 'start': start, 'toggle': signal_toggle, 'kill': signal_kill } parser.add_argument('command') if __name__ == '__main__': args = parser.parse_args() command = options.get(args.command) if command is not None: command() else: parser.print_help() PK!ttlinux-touchpad/lock.pyimport os from contextlib import suppress from .process import kill class LockExistsError(Exception): pass class Lock: path, _ = os.path.split(__file__) _lock = os.path.join(path, '.lock') def __init__(self): if self.islocked(): lockpid = self.getpid() kill(lockpid) self.cleanup() def __enter__(self): self.create_lock() return self def __exit__(self, *args): self.cleanup() def create_lock(self): with open(Lock._lock, 'w+') as fp: fp.write(str(os.getpid())) def cleanup(self): with suppress(FileNotFoundError): os.remove(self._lock) @staticmethod def islocked() -> bool: return os.path.exists(Lock._lock) @staticmethod def getpid(): with open(Lock._lock) as fp: return int(fp.read()) PK!vlinux-touchpad/process.pyimport os from contextlib import suppress from . import touchpad as tp def handler(signum, frame): if signum == tp.SIGTOGGLE: tp.toggle() else: tp.kill() def kill(ps): with suppress(ProcessLookupError): os.kill(ps, 9) PK!Za))linux-touchpad/touchpad.pyimport re import subprocess as subp import signal import asyncio as aio from operator import itemgetter from typing import Coroutine SIGTOGGLE = signal.SIGUSR1 DEVICE_RE = re.compile(r'(\w.+\b(?=\W.+id))(?:.+id=)(\d+)') ENABLED_RE = re.compile(r'(?:Device Enabled.*\t)(1)') toggled = False running = True def toggle(): global toggled toggled = not toggled def kill(): global running running = False async def run(command: list) -> str: ps = await aio.create_subprocess_exec(*command, stdout=subp.PIPE) raw = await ps.stdout.read() return raw.decode() async def get_devices() -> dict: rawout = await run(['xinput', 'list']) out = re.findall(DEVICE_RE, rawout) props = await aio.gather(*(parse_props(name, id) for name, id in out)) mice = filter(itemgetter('is_mouse'), props) return {mouse.pop('name'): mouse for mouse in mice} async def parse_props(device: str, device_id: str) -> bool: rawout = await run(['xinput', 'list-props', device_id]) props = { 'name': device if 'touchpad' not in device.casefold() else 'touchpad', 'id': device_id, 'is_enabled': bool(re.search(ENABLED_RE, rawout)), 'is_mouse': bool(re.search('Accel Speed', rawout)), } return props async def disable_device(device_id): await run(['xinput', 'disable', device_id]) async def enable_device(device_id): await run(['xinput', 'enable', device_id]) async def get_action() -> Coroutine: global toggled devices = await get_devices() touchpad = devices.pop('touchpad') mouse_exists = len(devices) > 1 touchpad_enabled = touchpad['is_enabled'] touchpad_id = touchpad['id'] if (toggled or not mouse_exists) and not touchpad_enabled: return enable_device(touchpad_id) elif mouse_exists and touchpad_enabled and not toggled: return disable_device(touchpad_id) else: return aio.sleep(0) async def watch_devices(): global running while running: action = await get_action() await aio.gather(action, aio.sleep(1)) PK!HڽTU$linux_touchpad-0.1.2.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]\fi4WZ^EgM_-]#0(q7PK!H~7Z'linux_touchpad-0.1.2.dist-info/METADATARMO0WK+%β+*E](Z=M4%Ğd_y+dXLQ00Gz4л0WƐruV_qRj^i1 +oi%";JvM޺@5% 6omB .a.oFKߧ' ^6gwP^c%Ř^N/(7dw ?+[-^??.\fCOqw'zNsbY}4H1xk"Kzs FG$Fȗ S; (cR( =9xҩ80CۊO.hPK!HF'܃w%linux_touchpad-0.1.2.dist-info/RECORD̹@|h`NEEI(ni9Я`* &{C5Jƴj=j\_hި [̒!o7%ML˼JO[9,5xCass3aOtڞ9CE׳Doh>R"ܼ?O&5b$2[[ ͉R8ZdK[ۓ4ʈbב`r1\S+ڋڮS.385|im T "?RC$WW+(o=&Y+J׸ N>;qT5"t|RM3(%rՖKK&vuP Jr³\U ˑӦ zOSO?PK!4u} linux-touchpad/__init__.pyPK!~~Xlinux-touchpad/__main__.pyPK!ttlinux-touchpad/lock.pyPK!vlinux-touchpad/process.pyPK!Za))linux-touchpad/touchpad.pyPK!HڽTU$Plinux_touchpad-0.1.2.dist-info/WHEELPK!H~7Z'linux_touchpad-0.1.2.dist-info/METADATAPK!HF'܃w%linux_touchpad-0.1.2.dist-info/RECORDPK]