PK!4u} linux-touchpad/__init__.pyimport uvloop uvloop.install() PK!S>>linux-touchpad/__main__.pyfrom .main import main if __name__ == '__main__': main() 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! @Dlinux-touchpad/main.pyimport os import asyncio as aio import signal import argparse from operator import itemgetter 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) def main(): choices = { 'start': start, 'toggle': signal_toggle, 'kill': signal_kill } parser = argparse.ArgumentParser( prog="linux-touchpad", description="Auto disable touchpad when mouse is detected." ) parser.add_argument('command', choices=choices, type=itemgetter) args = parser.parse_args() command = args.command(choices) command() if __name__ == '__main__': main() 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.4.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]\fi4WZ^EgM_-]#0(q7PK!H~'linux_touchpad-0.1.4.dist-info/METADATAUmOFbH-DiJAFNjU){beK~{g$;/<5:qǣh* %& >-*GMI;eDr p(BSY~%F)Q\e48w4G0a)*K. ZH'ՄIhҦf&͋%’ O?hŭ^:vyaF2NO؅֊@Á$ws8*w8|0:7,ካKN~=Uw)KoRwɏ2 Z^%piLkhS#*G.r\h*j7%m2]+FDyb~eEJsZK)7hYD |ReJ<~ 36nj-{NK\.Y}>(!Jʻ?^꺎K6Ԕ08QhLᖔb 10Wq)[8V0 d jބ9:.T }^D:cXdP ³,ؓgi,up- R"{;U`竸-6FBd%`xw2 bMڵ_A-ʹGW sI;EPs)W"Br+QM`]ju-'Sht4{_F/5J~7mSYZ:l-u,@C)hQwD* ;N3|+anV$ @(,Vf=4F;A.=@KpNJ[6s7A*R/4n:oړm={S]T>%"=L:/,F^siO wm'(bX&& 1$kb(}cJJOimFk)h-E01Ȇt3neចR~bwnXPK!HD{%linux_touchpad-0.1.4.dist-info/RECORDι@|q 6hGQQf@ 9iF~kk* &~i?1]'-NߣSEvm|B. հ;a%e:F>7 1r7S (:$^phd`SZ-I\ex&u9jV-L/n٤E^?sOڴ3f(Q;9F_ꊚ X}nMdm$:TQ:_FYTܹjFOIs=Y:ix{B48N6MY k6tC*:ҎGg/=$]p ac0ͫwPڟUFŤ2AYk%$2cIxSOW?=IlI50k7Z#cDx8}h͍1<' ?{9{PK!4u} linux-touchpad/__init__.pyPK!S>>Xlinux-touchpad/__main__.pyPK!ttlinux-touchpad/lock.pyPK! @Dvlinux-touchpad/main.pyPK!vlinux-touchpad/process.pyPK!Za)) linux-touchpad/touchpad.pyPK!HڽTU$Tlinux_touchpad-0.1.4.dist-info/WHEELPK!H~'linux_touchpad-0.1.4.dist-info/METADATAPK!HD{%!linux_touchpad-0.1.4.dist-info/RECORDPK