#pylint: disable=C0111,R0903,W0212 """Enable/disable automatic screen locking. Requires the following executables: * xdg-screensaver * xdotool * xprop (as dependency for xdotool) * notify-send """ import logging import os import psutil import bumblebee.input import bumblebee.output import bumblebee.engine class Module(bumblebee.engine.Module): def __init__(self, engine, config): super(Module, self).__init__(engine, config, bumblebee.output.Widget(full_text='') ) self._active = False self._xid = None engine.input.register_callback(self, button=bumblebee.input.LEFT_MOUSE, cmd=self._toggle ) def _check_requirements(self): requirements = ['xdotool', 'xprop', 'xdg-screensaver'] missing = [] for tool in requirements: if not bumblebee.util.which(tool): missing.append(tool) return missing def _get_i3bar_xid(self): xid = bumblebee.util.execute('xdotool search --class \'i3bar\'').partition('\n')[0].strip() if xid.isdigit(): return xid logging.warning('Module caffeine: xdotool couldn't get X window ID of \'i3bar\'.') return None def _notify(self): if not bumblebee.util.which('notify-send'): return if self._active: bumblebee.util.execute('notify-send \'Consuming caffeine\'') else: bumblebee.util.execute('notify-send \'Out of coffee\'') def _suspend_screensaver(self): self._xid = self._get_i3bar_xid() if self._xid is None: return False pid = os.fork() if pid == 0: os.setsid() bumblebee.util.execute('xdg-screensaver suspend {}'.format(self._xid)) os._exit(0) else: os.waitpid(pid, 0) return True def _resume_screensaver(self): success = True xprop_path = bumblebee.util.which('xprop') pids = [ p.pid for p in psutil.process_iter() if p.cmdline() == [xprop_path, '-id', str(self._xid), '-spy'] ] for pid in pids: try: os.kill(pid, 9) except OSError: success = False return success def state(self, _): if self._active: return 'activated' return 'deactivated' def _toggle(self, _): missing = self._check_requirements() if missing: logging.warning('Could not run caffeine - missing %s!', ', '.join(missing)) return self._active = not self._active if self._active: success = self._suspend_screensaver() else: success = self._resume_screensaver() if success: self._notify() else: self._active = not self._active # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4