PK!4u} linux-touchpad/__init__.pyimport uvloop uvloop.install() PK!S>>linux-touchpad/__main__.pyfrom .main import main if __name__ == '__main__': main() PK!.linux-touchpad/lock.pyimport os from contextlib import suppress from pathlib import Path class Lock: _lock: Path = Path(__file__).with_name('.lock') def __init__(self): if self.islocked(): lockpid = self.getpid() with suppress(ProcessLookupError): os.kill(lockpid, 9) self.cleanup() def __enter__(self): self.create_lock() return self def __exit__(self, *args): self.cleanup() def create_lock(self): self._lock.write_text(str(os.getpid())) def cleanup(self): with suppress(FileNotFoundError): self._lock.unlink() @staticmethod def islocked() -> bool: return Lock._lock.exists() @staticmethod def getpid(): return int(Lock._lock.read_text()) PK!Hilinux-touchpad/main.pyimport os import signal import argparse from .lock import Lock from .touchpad import SIGTOGGLE from .watchdog import WatchDog def start(): with Lock(): watchdog = WatchDog() signal.signal(signal.SIGTERM, watchdog.sig_handler) signal.signal(SIGTOGGLE, watchdog.sig_handler) watchdog.start() def signal_toggle(): pid = Lock.getpid() os.kill(pid, SIGTOGGLE) def signal_kill(): if Lock.islocked(): 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) args = parser.parse_args() command = choices[args.command] command() if __name__ == '__main__': main() PK!:Glinux-touchpad/touchpad.pyimport signal import subprocess as subp SIGTOGGLE = signal.SIGUSR1 class TouchPad: toggled = False def __init__(self, device): self.device = device self.name = self.device.parent.attributes.get('name').decode() def disable(self): subp.run(['xinput', 'disable', self.name]) def enable(self): subp.run(['xinput', 'enable', self.name]) def toggle(self): self.toggled = not self.toggled PK!5= = linux-touchpad/watchdog.pyimport sys from enum import Enum from pyudev import Context, Monitor from collections import defaultdict from .touchpad import TouchPad, SIGTOGGLE class DeviceClass(Enum): TouchPad = 0 Mouse = 1 Other = 2 def identify(device) -> DeviceClass: props = look(device, 'removable', 'phys') def find_in(it, name): return any(name in item.casefold() for item in it) if 'removable' in props['removable']: return DeviceClass.Mouse # USB but not removable probably means it's a controller if find_in(props['phys'], 'usb'): return DeviceClass.Other return DeviceClass.TouchPad def look(device, *names) -> dict: data = defaultdict(list) for dev in [device] + list(device.ancestors): for name in names: prop = dev.attributes.get(name) if prop is not None: data[name].append(prop.decode()) return data class WatchDog: context = Context() devices = set() _touchpad = None def __init__(self): self.monitor = Monitor.from_netlink(self.context) self.monitor.filter_by('input') for dev in self.context.list_devices(subsystem='input', sys_name='mouse*'): cls = identify(dev) if cls is DeviceClass.TouchPad: self._touchpad = TouchPad(dev) elif cls is DeviceClass.Mouse: self.add(dev) self.refresh() def start(self): for device in iter(self.monitor.poll, None): if 'mouse' in device.sys_name: cls = identify(device) if cls is DeviceClass.Mouse and hasattr(self, device.action): action = getattr(self, device.action) action(device) def add(self, device): self.devices.add(device) self.refresh() def remove(self, device): if device in self.devices: self.devices.remove(device) self.refresh() def refresh(self): if not self._touchpad: return if self.devices and not self._touchpad.toggled: self._touchpad.disable() else: self._touchpad.enable() def sig_handler(self, signum, frame): if signum == SIGTOGGLE: self._touchpad.toggle() self.refresh() else: sys.exit() PK!Q77&linux_touchpad-0.2.1.dist-info/LICENSE The MIT License (MIT) Copyright (c) 2019 Noah Corona Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK!HڽTU$linux_touchpad-0.2.1.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]\fi4WZ^EgM_-]#0(q7PK!H!~'linux_touchpad-0.2.1.dist-info/METADATAUnF}߯@@k "$EQF[Xr(9"7Z{M ȷgy^Drr̙ktDcF>Rˢ۫nV8mWtmjDH=хVMEmtx$mk؈(#OXsHiNk 5>u] A,XI/bこUOi xVO{%t۞X UyK]qՖҒt9tKK!UY@$KVuP&сpW 'Бò Ze< >OcS.k\ej78_m7"zuɀ5iQ:4i\5 :v;:wbR`MdvVڻPZ}ZN ]%`7?ps6hw7h>FH>K؍v7I] {T 2p/$i$ l:nTۙ_j Gfu>ߴ'o)fki#|(KDQzt:ϟY4zyXҞm'(bX&& 1$be**E_ 85#*_т@MfO?;黛Ղ]]EklK L *\W$ͧ'-gE\p\bFw^v7$;p /rt6VBE]i]38~;1ȁ%͹{zCaCҖ5u&ję c$!d#~č0{i΀OR`ѯ'? $'ؔ |[ޅS'>ZAiWhP y@R;1EzQ$cz?rf|UW}َmUo߈HSV) t6m#,|=0[y:|PK!4u} linux-touchpad/__init__.pyPK!S>>Xlinux-touchpad/__main__.pyPK!.linux-touchpad/lock.pyPK!Hilinux-touchpad/main.pyPK!:G linux-touchpad/touchpad.pyPK!5= =  linux-touchpad/watchdog.pyPK!Q77&ylinux_touchpad-0.2.1.dist-info/LICENSEPK!HڽTU$linux_touchpad-0.2.1.dist-info/WHEELPK!H!~'linux_touchpad-0.2.1.dist-info/METADATAPK!HmPɠ%%linux_touchpad-0.2.1.dist-info/RECORDPK