class FullscreenTrigger(Trigger): def __init__(self): if os.environ.get("WAYLAND_DISPLAY") is None: self._ewmh = EWMH() else: logger.info("Running on Wayland; fullscreen trigger won't work.") self._ewmh = None def run(self) -> DesiredState: """Determine if a fullscreen application is running.""" inhibit = False if self._ewmh: window = self._ewmh.getActiveWindow() # ewmh.getWmState(window) returns None is scenarios where # ewmh.getWmState(window, str=True) throws an exception # (it's a bug in pyewmh): if window and self._ewmh.getWmState(window): wm_state = self._ewmh.getWmState(window, True) inhibit = "_NET_WM_STATE_FULLSCREEN" in wm_state if inhibit: logger.info("Fullscreen window detected.") return DesiredState.INHIBIT_ALL else: return DesiredState.UNINHIBITED
def runner(): parser = argparse.ArgumentParser(description='Move windows around.') parser.add_argument('-d','--double-command', action="store_true", dest='double', help='If this is set the double command mode will activate', ) if sys.argv[1:]: parser.add_argument('direction', type=str, help='direction that you want to move', choices=('bottomright', 'bottomleft', 'topleft', 'topright', 'center', 'top', 'right', 'bottom', 'left',), nargs=1, ) else: parser.add_argument('--direction', default = ['center']) args = parser.parse_args() ewmh = EWMH() main = MainInfo(ewmh) moveWin = DispatchMove(main,args.double) if (DEBUG): import pprint print 'DOUBLE MODE:',args.double pprint.pprint(vars(main)) moveWin.move(ewmh.getActiveWindow(), args.direction[0]) return 0
def runLinuxMinimize(command, args): from ewmh import EWMH ewmh = EWMH() win = ewmh.getActiveWindow() args.insert(0, command) subprocess.call(args) ewmh.setActiveWindow(win) ewmh.display.flush()
def __attempt_autoactivation(self): """Attempts to auto-activate inhibition by verifying if any of the whitelisted processes is running OR if there's a fullscreen app. """ if self.get_activated() and not self.__auto_activated: logging.debug("Inhibition manually activated. Won't attempt to " + "auto-activate") return True process_running = False # Determine if one of the whitelisted processes is running. for proc in self.__process_manager.get_process_list(): if utils.isProcessRunning(proc): process_running = True if self.__auto_activated: logging.info( "Process {} detected but was already ".format(proc) + "auto-activated") elif not self.get_activated(): logging.info( "Process {} detected. Inhibiting.".format(proc)) # Determine if a fullscreen application is running ewmh = EWMH() window = ewmh.getActiveWindow() if window: # ewmh.getWmState(window) returns None is scenarios where # ewmh.getWmState(window, str=True) throws an exception # (it's a bug in pyewmh): fullscreen = ewmh.getWmState(window) and \ "_NET_WM_STATE_FULLSCREEN" in ewmh.getWmState(window, str=True) else: fullscreen = False if fullscreen: if self.__auto_activated: logging.debug("Fullscreen app detected, but was already " + "auto-activated") elif not self.get_activated(): logging.info("Fullscreen app detected. Inhibiting.") # Disable auto-activation? if not process_running and not fullscreen and self.__auto_activated: logging.info("Was auto-inhibited, but there's no fullscreen or " + "whitelisted process now. De-activating.") self.__auto_activated = False self.__set_activated(False) elif process_running or fullscreen and not self.__auto_activated: self.__auto_activated = True self.__set_activated(True) return True
class ActiveWindowMonitor(QThread): output = pyqtSignal(int, int, int, int, int) def __init__(self, parent=None): QThread.__init__(self, parent) self.exiting = False self.ewmh = EWMH() self.active_window_id_tree = [] def run(self): Xroot.change_attributes(event_mask=Xlib.X.PropertyChangeMask | Xlib.X.SubstructureNotifyMask) self.notify_about_active_window() while True: event = disp.next_event() if (event.type == Xlib.X.PropertyNotify and event.atom == NET_ACTIVE_WINDOW): self.notify_about_active_window() elif event.type == Xlib.X.ConfigureNotify: if event.window.id in self.active_window_id_tree: self.notify_about_active_window() def notify_about_active_window(self): # the active window has changed; get it and emit its details cur = self.ewmh.getActiveWindow() # and store its window tree so we can trap ConfigureNotify events # on our window, which might actually be a bunch of X windows # created invisibly by the window manager as a frame pointer = cur self.active_window_id_tree = [] while pointer.id != Xroot.id: self.active_window_id_tree.append(pointer.id) pointer = pointer.query_tree().parent # dsk = self.ewmh.getCurrentDesktop() # wdsk = self.ewmh.getWmDesktop(cur) geo = cur.get_geometry() (x, y) = (geo.x, geo.y) frame = cur while True: parent = frame.query_tree().parent pgeom = parent.get_geometry() x += pgeom.x y += pgeom.y if parent.id == self.ewmh.root.id: break frame = parent #print("------------- Window", cur.get_wm_class()[1], # x, y, geo.width, geo.height, "-------------") self.output.emit(x, y, geo.width, geo.height, cur.id) def __del__(self): self.exiting = True self.wait()
class WindowManager: GOOGLE_CHROME = "google-chrome" def __init__(self): self.window_manager = EWMH() self.dict = dict() self.dict[GesturesEnum.THREE_SWIPE_LEFT] = [e.KEY_LEFTALT, e.KEY_RIGHT] self.dict[GesturesEnum.THREE_SWIPE_RIGHT] = [e.KEY_LEFTALT, e.KEY_LEFT] def get_active_window_class(self): window = self.window_manager.getActiveWindow() window_class = window.get_wm_class()[1] if window_class == self.GOOGLE_CHROME: return self.GOOGLE_CHROME return None def get_ecodes(self, gesture_code): return self.dict.get(gesture_code, None)
class FullscreenTrigger: def __init__(self): self._ewmh = EWMH() def run(self) -> DesiredState: """Determine if a fullscreen application is running.""" inhibit = False window = self._ewmh.getActiveWindow() # ewmh.getWmState(window) returns None is scenarios where # ewmh.getWmState(window, str=True) throws an exception # (it's a bug in pyewmh): if window and self._ewmh.getWmState(window): wm_state = self._ewmh.getWmState(window, True) inhibit = "_NET_WM_STATE_FULLSCREEN" in wm_state if inhibit: logger.info("Fullscreen app detected.") return DesiredState.INHIBIT_ALL return DesiredState.UNINHIBITED
def get_current_window(): wm = EWMH() xlib_win = wm.getActiveWindow() window = Window.from_xlib_window(xlib_win) return window
class Caffeine(GObject.GObject): def __init__(self, process_manager): GObject.GObject.__init__(self) self.__inhibitors = [ GnomeInhibitor(), XdgScreenSaverInhibitor(), XdgPowerManagmentInhibitor(), XssInhibitor(), DpmsInhibitor(), XorgInhibitor(), XautolockInhibitor(), xfceInhibitor() ] self.__process_manager = process_manager # Status string (XXX: Let's double check how well this is working). self.status_string = "Caffeine is starting up..." # Inhibition has been requested (though it may not yet be active). self.__inhibition_manually_requested = False # Inhibition has successfully been activated. self.__inhibition_successful = False self.__auto_activated = False self.timer = None self.notification = None self._ewmh = EWMH() # FIXME: add capability to xdg-screensaver to report timeout. GLib.timeout_add(10000, self.__attempt_autoactivation) logger.info(self.status_string) def __attempt_autoactivation(self): """ Determines if we want to auto-activate inhibition by verifying if any of the whitelisted processes is running OR if there's a fullscreen app. """ # tr.print_diff() if self.get_activated() and not self.__auto_activated: logger.debug("Inhibition manually activated. Won't attempt to " + "auto-activate") return True process_running = False # Determine if one of the whitelisted processes is running. for proc in self.__process_manager.get_process_list(): if utils.isProcessRunning(proc): process_running = True if self.__auto_activated: logger.info("Process %s detected. No change.", proc) elif not self.get_activated(): logger.info("Process %s detected. Inhibiting.", proc) # If none where running, let's look for fullscreen: if not process_running: # Determine if a fullscreen application is running window = self._ewmh.getActiveWindow() # ewmh.getWmState(window) returns None is scenarios where # ewmh.getWmState(window, str=True) throws an exception # (it's a bug in pyewmh): if window and self._ewmh.getWmState(window): fullscreen = "_NET_WM_STATE_FULLSCREEN" in \ self._ewmh.getWmState(window, True) else: fullscreen = False if fullscreen: if self.__auto_activated: logger.debug("Fullscreen app detected. No change.") elif not self.get_activated(): logger.info("Fullscreen app detected. Inhibiting.") if (process_running or fullscreen) and not self.__auto_activated: self.__auto_activated = True # TODO: Check __set_activated self.__set_activated(True) elif not (process_running or fullscreen) and self.__auto_activated: logger.info("Was auto-inhibited, but there's no fullscreen or " + "whitelisted process now. De-activating.") self.__auto_activated = False # TODO: Check __set_activated self.__set_activated(False) return True def quit(self): """ Cancels any timer thread running so the program can quit right away. """ if self.timer: self.timer.cancel() def _notify(self, message, icon, title="Caffeine"): """Easy way to use pynotify.""" # try: Notify.init("Caffeine") if self.notification: self.notification.update(title, message, icon) else: self.notification = Notify.Notification.new(title, message, icon) # XXX: Notify OSD doesn't seem to work when sleep is prevented # if self.screenSaverCookie is not None and \ # self.__inhibition_successful: # self.ssProxy.UnInhibit(self.screenSaverCookie) self.notification.show() # if self.screenSaverCookie is not None and \ # self.__inhibition_successful: # self.screenSaverCookie = \ # self.ssProxy.Inhibit("Caffeine", # "User has requested that Caffeine "+ # "disable the screen saver") # except Exception as e: # logger.error("Exception occurred:\n%s", e) # finally: # return False def timed_activation(self, time, show_notification=True): """Calls toggle_activated after the number of seconds specified by time has passed. """ message = (_("Timed activation set; ") + _("Caffeine will prevent powersaving for the next ") + str(time)) logger.info("Timed activation set for " + str(time)) if self.status_string == "": self.status_string = _("Activated for ") + str(time) self.emit("activation-toggled", self.get_activated(), self.status_string) self.set_activated(True, show_notification) if show_notification: self._notify(message, full_cup_icon) # and deactivate after time has passed. # Stop already running timer if self.timer: logger.info("Previous timed activation cancelled due to a " + "second timed activation request (was set for " + str(self.timer.interval) + " or " + str(time) + " seconds )") self.timer.cancel() self.timer = Timer(time, self._deactivate, args=[show_notification]) self.timer.name = "Active" self.timer.start() def _deactivate(self, show_notification): self.timer.name = "Expired" self.toggle_activated(show_notification) def __set_activated(self, activate): """Enables inhibition, but does not mark is as manually enabled. """ if self.get_activated() != activate: self.__toggle_activated(activate) def get_activated(self): """Returns True if inhibition was manually activated. """ return self.__inhibition_manually_requested def set_activated(self, activate, show_notification=True): """Sets inhibition as manually activated. """ if self.get_activated() != activate: self.toggle_activated(show_notification) def toggle_activated(self, show_notification=True): """ *Manually* toggles inhibition. """ self.__auto_activated = False self.__toggle_activated(note=show_notification) def __toggle_activated(self, note): """ Toggle inhibition. """ if self.__inhibition_manually_requested: # sleep prevention was on now turn it off self.__inhibition_manually_requested = False logger.info("Caffeine is now dormant; powersaving is re-enabled.") self.status_string = \ _("Caffeine is dormant; powersaving is enabled") # If the user clicks on the full coffee-cup to disable # sleep prevention, it should also # cancel the timer for timed activation. if self.timer is not None and self.timer.name != "Expired": message = (_("Timed activation cancelled (was set for ") + str(self.timer.interval) + ")") logger.info("Timed activation cancelled (was set for " + str(self.timer.interval) + ")") if note: self._notify(message, empty_cup_icon) self.timer.cancel() self.timer = None elif self.timer is not None and self.timer.name == "Expired": message = (str(self.timer.interval) + _(" have elapsed; powersaving is re-enabled")) logger.info("Timed activation period (" + str(self.timer.interval) + ") has elapsed") if note: self._notify(message, empty_cup_icon) self.timer = None else: self.__inhibition_manually_requested = True self._performTogglingActions() self.status_string == "Caffeine is preventing powersaving." self.emit("activation-toggled", self.get_activated(), self.status_string) self.status_string = "" def _performTogglingActions(self): """This method performs the actions that affect the screensaver and powersaving.""" for inhibitor in self.__inhibitors: if inhibitor.applicable: logger.info("%s is applicable, running it.", inhibitor) Thread(target=inhibitor.toggle).start() self.__inhibition_successful = not self.__inhibition_successful
.distinct_until_changed() cpu = Observable.interval(6000) \ .map(get_cpu) \ .map(lambda x: cpu_icon+make_bar(x)) mem = Observable.interval(6000) \ .map(get_mem) \ .map(lambda x: mem_icon+make_bar(x)) mail = Observable.interval(6000).map(lambda x, y: mail_icon+str(get_mail(x))) \ .distinct_until_changed() mail_headings = Observable.interval(6000).map(lambda x, y: get_mail_headings(x)) windows = Observable.interval(500) \ .map(lambda x: ewmh.getActiveWindow()) \ .distinct_until_changed() \ .filter(lambda x: x) active = windows.map(decorateWindow) left = combine_frames(time, active) right = combine_frames(cpu, mem, mail, disks) \ .map(lambda x: "^p(_CENTER){}".format(x)) \ header = Observable.combine_latest( left, right, lambda x, y: "{} ^p(_CENTER){}".format(x, y)) body = Observable.merge(
class WindowTracker: is_win = os.name == 'nt' def __init__(self): if self.is_win: import win32api, win32gui self.win32api = win32api self.win32gui = win32gui self.get_win_name = self._win_get_win_name self.get_idle_time = self._win_get_idle_time self._win_last_known_win = 0 self._win_last_known_win_name = "" self._win_last_known_win_class = "" else: from ewmh import EWMH self.ewmh = EWMH() self.get_win_name = self._posix_get_win_name self.get_idle_time = self._posix_get_idle_time def _win_get_win_name(self): cur_window = self.win32gui.GetForegroundWindow() if cur_window == 0: cur_window = self._win_last_known_win cur_name = self._win_last_known_win_name cur_class = self._win_last_known_win_class cur_class = self.win32gui.GetClassName(cur_window) else: cur_name = self.win32gui.GetWindowText(cur_window) cur_class = self.win32gui.GetClassName(cur_window) self._win_last_known_win = cur_window self._win_last_known_win_class = cur_class self._win_last_known_win_name = cur_name return ((cur_class, cur_class), cur_name) def _win_get_idle_time(self): now = self.win32api.GetTickCount() last_activity = self.win32api.GetLastInputInfo() return round((now - last_activity)/1000.0) def _posix_get_win_name(self): cur_window = self.ewmh.getActiveWindow() cur_class = None while cur_class is None: cur_name = cur_window.get_wm_name() cur_class = cur_window.get_wm_class() if cur_class is None: cur_window = cur_window.query_tree().parent return (cur_class, cur_name) def _posix_get_idle_time(self): import ctypes class XScreenSaverInfo( ctypes.Structure): """ typedef struct { ... } XScreenSaverInfo; """ _fields_ = [('window', ctypes.c_ulong), # screen saver window ('state', ctypes.c_int), # off,on,disabled ('kind', ctypes.c_int), # blanked,internal,external ('since', ctypes.c_ulong), # milliseconds ('idle', ctypes.c_ulong), # milliseconds ('event_mask', ctypes.c_ulong)] # events xlib = ctypes.cdll.LoadLibrary('libX11.so.6') display = xlib.XOpenDisplay(os.environ['DISPLAY']) xss = ctypes.cdll.LoadLibrary('libXss.so.1') xss.XScreenSaverAllocInfo.restype = ctypes.POINTER(XScreenSaverInfo) xssinfo = xss.XScreenSaverAllocInfo() xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), xssinfo) idle = int(round(xssinfo.contents.idle / 1000.0)) xlib.XCloseDisplay(display) return idle
class Caffeine(GObject.GObject): def __init__(self, process_manager): GObject.GObject.__init__(self) self.__inhibitors = [ GnomeInhibitor(), XdgPowerManagmentInhibitor(), XssInhibitor(), XorgInhibitor(), XautolockInhibitor(), XidlehookInhibitor(), XdgScreenSaverInhibitor(), DpmsInhibitor() ] self.__process_manager = process_manager # Status string (XXX: Let's double check how well this is working). self.status_string = "Caffeine is starting up..." # Inhibition has been requested (though it may not yet be active). self.__inhibition_manually_requested = False # Number of procs playing audio but nothing visual. This is a special # case where we want the screen to turn off while still preventing # the computer from suspending self.music_procs = 0 # Inhibition has successfully been activated. self.__inhibition_successful = False self.__auto_activated = False self.timer = None self.notification = None self._ewmh = EWMH() # FIXME: add capability to xdg-screensaver to report timeout. GLib.timeout_add(10000, self.__attempt_autoactivation) logger.info(self.status_string) def __attempt_autoactivation(self): """ Determines if we want to auto-activate inhibition by verifying if any of the whitelisted processes is running OR if there's a fullscreen app. """ # tr.print_diff() if self.get_activated() and not self.__auto_activated: logger.debug("Inhibition manually activated. Won't attempt to " + "auto-activate") return True process_running = False # Determine if one of the whitelisted processes is running. for proc in self.__process_manager.get_process_list(): if utils.isProcessRunning(proc): process_running = True if self.__auto_activated: logger.info("Process %s detected. No change.", proc) elif not self.get_activated(): logger.info("Process %s detected. Inhibiting.", proc) # If none where running, let's look for fullscreen: if not process_running: # Determine if a fullscreen application is running window = self._ewmh.getActiveWindow() # ewmh.getWmState(window) returns None is scenarios where # ewmh.getWmState(window, str=True) throws an exception # (it's a bug in pyewmh): if window and self._ewmh.getWmState(window): fullscreen = "_NET_WM_STATE_FULLSCREEN" in \ self._ewmh.getWmState(window, True) else: fullscreen = False if fullscreen: if self.__auto_activated: logger.debug("Fullscreen app detected. No change.") elif not self.get_activated(): logger.info("Fullscreen app detected. Inhibiting.") # Let's look for playing audio: # Number of supposed audio only streams. We can turn the screen off # for those: self.music_procs = 0 # Number of all audio streams including videos. We keep the screen on # here: screen_relevant_procs = 0 if not process_running and not fullscreen: # Get all audio playback streams # Music players seem to use the music role. We can turn the screen # off there. Keep the screen on for audio without music role, # as they might be videos with Pulse() as pulseaudio: for sink in pulseaudio.sink_input_list(): sink_state = pulseaudio.sink_info(sink.sink).state if sink_state is PulseStateEnum.running and \ sink.proplist.get('media.role') == "music": # seems to be audio only self.music_procs += 1 elif sink_state is PulseStateEnum.running: # Video or other audio source screen_relevant_procs += 1 # Get all audio recording streams for source in pulseaudio.source_output_list(): source_state = pulseaudio.source_info(source.source).state if source_state is PulseStateEnum.running: # Treat recordings as video because likely you don't # want to turn the screen of while recording screen_relevant_procs += 1 if self.music_procs > 0 or screen_relevant_procs > 0: if self.__auto_activated: logger.debug("Audio playback detected. No change.") elif not self.get_activated(): logger.info("Audio playback detected. Inhibiting.") if (process_running or fullscreen or self.music_procs > 0 or screen_relevant_procs > 0) and not self.__auto_activated: self.__auto_activated = True # TODO: Check __set_activated self.__set_activated(True) elif not (process_running or fullscreen or self.music_procs > 0 or screen_relevant_procs > 0) and self.__auto_activated: logger.info( "Was auto-inhibited, but there's no fullscreen, whitelisted " "process or audio playback now. De-activating.") # TODO: Check __set_activated self.__set_activated(False) self.__auto_activated = False return True def quit(self): """ Cancels any timer thread running so the program can quit right away. """ if self.timer: self.timer.cancel() def _notify(self, message, icon, title="Caffeine"): """Easy way to use pynotify.""" # try: Notify.init("Caffeine") if self.notification: self.notification.update(title, message, icon) else: self.notification = Notify.Notification.new(title, message, icon) # XXX: Notify OSD doesn't seem to work when sleep is prevented # if self.screenSaverCookie is not None and \ # self.__inhibition_successful: # self.ssProxy.UnInhibit(self.screenSaverCookie) self.notification.show() # if self.screenSaverCookie is not None and \ # self.__inhibition_successful: # self.screenSaverCookie = \ # self.ssProxy.Inhibit("Caffeine", # "User has requested that Caffeine "+ # "disable the screen saver") # except Exception as e: # logger.error("Exception occurred:\n%s", e) # finally: # return False def timed_activation(self, time, show_notification=True): """Calls toggle_activated after the number of seconds specified by time has passed. """ message = (_("Timed activation set; ") + _("Caffeine will prevent powersaving for the next ") + str(time)) logger.info("Timed activation set for " + str(time)) if self.status_string == "": self.status_string = _("Activated for ") + str(time) self.emit("activation-toggled", self.get_activated(), self.status_string) self.set_activated(True, show_notification) if show_notification: self._notify(message, full_cup_icon) # and deactivate after time has passed. # Stop already running timer if self.timer: logger.info("Previous timed activation cancelled due to a " + "second timed activation request (was set for " + str(self.timer.interval) + " or " + str(time) + " seconds )") self.timer.cancel() self.timer = Timer(time, self._deactivate, args=[show_notification]) self.timer.name = "Active" self.timer.start() def _deactivate(self, show_notification): self.timer.name = "Expired" self.toggle_activated(show_notification) def __set_activated(self, activate): """Enables inhibition, but does not mark is as manually enabled. """ if self.get_activated() != activate: self.__toggle_activated(activate) def get_activated(self): """Returns True if inhibition was manually activated. """ return self.__inhibition_manually_requested def set_activated(self, activate, show_notification=True): """Sets inhibition as manually activated. """ if self.get_activated() != activate: self.toggle_activated(show_notification) def toggle_activated(self, show_notification=True): """ *Manually* toggles inhibition. """ self.__auto_activated = False self.__toggle_activated(note=show_notification) def __toggle_activated(self, note): """ Toggle inhibition. """ if self.__inhibition_manually_requested: # sleep prevention was on now turn it off self.__inhibition_manually_requested = False logger.info("Caffeine is now dormant; powersaving is re-enabled.") self.status_string = \ _("Caffeine is dormant; powersaving is enabled") # If the user clicks on the full coffee-cup to disable # sleep prevention, it should also # cancel the timer for timed activation. if self.timer is not None and self.timer.name != "Expired": message = (_("Timed activation cancelled (was set for ") + str(self.timer.interval) + ")") logger.info("Timed activation cancelled (was set for " + str(self.timer.interval) + ")") if note: self._notify(message, empty_cup_icon) self.timer.cancel() self.timer = None elif self.timer is not None and self.timer.name == "Expired": message = (str(self.timer.interval) + _(" have elapsed; powersaving is re-enabled")) logger.info("Timed activation period (" + str(self.timer.interval) + ") has elapsed") if note: self._notify(message, empty_cup_icon) self.timer = None else: self.__inhibition_manually_requested = True # decide, if we allow the screen to sleep if (self.music_procs > 0 or not self.__inhibition_manually_requested): inhibit_screen = False else: inhibit_screen = True self._performTogglingActions(self.__inhibition_manually_requested, inhibit_screen) logger.info("\n\n") self.status_string = "Caffeine is preventing powersaving." self.emit("activation-toggled", self.get_activated(), self.status_string) self.status_string = "" def _performTogglingActions(self, suspend, susp_screen): """This method performs the actions that affect the screensaver and powersaving.""" for inhibitor in self.__inhibitors: if inhibitor.applicable: inhibitor.set(susp_screen) if inhibitor.is_screen_inhibitor() \ else inhibitor.set(suspend) logger.info("%s is applicable, state: %s" % (inhibitor, inhibitor.running)) self.__inhibition_successful = not self.__inhibition_successful
import time from ewmh import EWMH ewmh = EWMH() # get the active window while True: win = ewmh.getActiveWindow() print(ewmh.getWmName(win)) print(win.get_wm_class()) time.sleep(2)
class Caffeine(GObject.GObject): def __init__(self, process_manager): GObject.GObject.__init__(self) self.__inhibitors = [ GnomeInhibitor(), XdgScreenSaverInhibitor(), XdgPowerManagmentInhibitor(), XssInhibitor(), DpmsInhibitor(), XorgInhibitor(), XautolockInhibitor() ] self.__process_manager = process_manager # Status string (XXX: Let's double check how well this is working). self.status_string = "Caffeine is starting up..." # Inhibition has been requested (though it may not yet be active). self.__inhibition_manually_requested = False # Inhibition has successfully been activated. self.__inhibition_successful = False self.__auto_activated = False self.timer = None self.notification = None self._ewmh = EWMH() # FIXME: add capability to xdg-screensaver to report timeout. GLib.timeout_add(10000, self.__attempt_autoactivation) logger.info(self.status_string) def __attempt_autoactivation(self): """ Determines if we want to auto-activate inhibition by verifying if any of the whitelisted processes is running OR if there's a fullscreen app. """ # tr.print_diff() if self.get_activated() and not self.__auto_activated: logger.debug("Inhibition manually activated. Won't attempt to " + "auto-activate") return True process_running = False # Determine if one of the whitelisted processes is running. for proc in self.__process_manager.get_process_list(): if utils.isProcessRunning(proc): process_running = True if self.__auto_activated: logger.info("Process %s detected. No change.", proc) elif not self.get_activated(): logger.info("Process %s detected. Inhibiting.", proc) # If none where running, let's look for fullscreen: if not process_running: # Determine if a fullscreen application is running window = self._ewmh.getActiveWindow() # ewmh.getWmState(window) returns None is scenarios where # ewmh.getWmState(window, str=True) throws an exception # (it's a bug in pyewmh): if window and self._ewmh.getWmState(window): fullscreen = "_NET_WM_STATE_FULLSCREEN" in \ self._ewmh.getWmState(window, True) else: fullscreen = False if fullscreen: if self.__auto_activated: logger.debug("Fullscreen app detected. No change.") elif not self.get_activated(): logger.info("Fullscreen app detected. Inhibiting.") if (process_running or fullscreen) and not self.__auto_activated: self.__auto_activated = True # TODO: Check __set_activated self.__set_activated(True) elif not (process_running or fullscreen) and self.__auto_activated: logger.info("Was auto-inhibited, but there's no fullscreen or " + "whitelisted process now. De-activating.") self.__auto_activated = False # TODO: Check __set_activated self.__set_activated(False) return True def quit(self): """ Cancels any timer thread running so the program can quit right away. """ if self.timer: self.timer.cancel() def _notify(self, message, icon, title="Caffeine"): """Easy way to use pynotify.""" # try: Notify.init("Caffeine") if self.notification: self.notification.update(title, message, icon) else: self.notification = Notify.Notification.new(title, message, icon) # XXX: Notify OSD doesn't seem to work when sleep is prevented # if self.screenSaverCookie is not None and \ # self.__inhibition_successful: # self.ssProxy.UnInhibit(self.screenSaverCookie) self.notification.show() # if self.screenSaverCookie is not None and \ # self.__inhibition_successful: # self.screenSaverCookie = \ # self.ssProxy.Inhibit("Caffeine", # "User has requested that Caffeine "+ # "disable the screen saver") # except Exception as e: # logger.error("Exception occurred:\n%s", e) # finally: # return False def timed_activation(self, time, show_notification=True): """Calls toggle_activated after the number of seconds specified by time has passed. """ message = (_("Timed activation set; ") + _("Caffeine will prevent powersaving for the next ") + str(time)) logger.info("Timed activation set for " + str(time)) if self.status_string == "": self.status_string = _("Activated for ") + str(time) self.emit("activation-toggled", self.get_activated(), self.status_string) self.set_activated(True, show_notification) if show_notification: self._notify(message, full_cup_icon) # and deactivate after time has passed. # Stop already running timer if self.timer: logger.info("Previous timed activation cancelled due to a " + "second timed activation request (was set for " + str(self.timer.interval) + " or " + str(time)+" seconds )") self.timer.cancel() self.timer = Timer(time, self._deactivate, args=[show_notification]) self.timer.name = "Active" self.timer.start() def _deactivate(self, show_notification): self.timer.name = "Expired" self.toggle_activated(show_notification) def __set_activated(self, activate): """Enables inhibition, but does not mark is as manually enabled. """ if self.get_activated() != activate: self.__toggle_activated(activate) def get_activated(self): """Returns True if inhibition was manually activated. """ return self.__inhibition_manually_requested def set_activated(self, activate, show_notification=True): """Sets inhibition as manually activated. """ if self.get_activated() != activate: self.toggle_activated(show_notification) def toggle_activated(self, show_notification=True): """ *Manually* toggles inhibition. """ self.__auto_activated = False self.__toggle_activated(note=show_notification) def __toggle_activated(self, note): """ Toggle inhibition. """ if self.__inhibition_manually_requested: # sleep prevention was on now turn it off self.__inhibition_manually_requested = False logger.info("Caffeine is now dormant; powersaving is re-enabled.") self.status_string = \ _("Caffeine is dormant; powersaving is enabled") # If the user clicks on the full coffee-cup to disable # sleep prevention, it should also # cancel the timer for timed activation. if self.timer is not None and self.timer.name != "Expired": message = (_("Timed activation cancelled (was set for ") + str(self.timer.interval) + ")") logger.info("Timed activation cancelled (was set for " + str(self.timer.interval) + ")") if note: self._notify(message, empty_cup_icon) self.timer.cancel() self.timer = None elif self.timer is not None and self.timer.name == "Expired": message = (str(self.timer.interval) + _(" have elapsed; powersaving is re-enabled")) logger.info("Timed activation period (" + str(self.timer.interval) + ") has elapsed") if note: self._notify(message, empty_cup_icon) self.timer = None else: self.__inhibition_manually_requested = True self._performTogglingActions() self.status_string == "Caffeine is preventing powersaving." self.emit("activation-toggled", self.get_activated(), self.status_string) self.status_string = "" def _performTogglingActions(self): """This method performs the actions that affect the screensaver and powersaving.""" for inhibitor in self.__inhibitors: if inhibitor.applicable: logger.info("Inhibitor %s is applicable, running it.", inhibitor.__class__) Thread(target=inhibitor.toggle).start() self.__inhibition_successful = not self.__inhibition_successful
class wn_resize(): def __init__(self): self.mousePressed = False self.startX = -1 self.startY = -1 self.isOpen = True self.nBoxesW = 6 self.nBoxesH = 6 self.windowSpaceSizeW = 300 self.windowSpaceSizeH = 300 self.windowBoxSizeW = 20 self.windowBoxSizeH = 20 self.margin = 25 self.windowSizeW = 220 self.windowSizeH = 220 self.mPosX = -self.windowBoxSizeW self.mPosY = -self.windowBoxSizeH self.ewmh = EWMH() self.activeWindow = self.ewmh.getActiveWindow() if self.activeWindow == self.ewmh.getClientListStacking()[0]: return self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_decorated(False) self.window.set_default_size(self.windowSizeW,self.windowSizeH) self.window.set_size_request(self.windowSizeW, self.windowSizeH) self.window.set_resizable(False) self.window.set_position(gtk.WIN_POS_CENTER) self.window.set_property("skip-taskbar-hint", True) self.window.connect("destroy", self.cb_destroy) self.window.connect("delete_event", self.cb_destroy) self.window.connect("focus_out_event", self.cb_destroy) self.box = gtk.EventBox() self.area = gtk.DrawingArea() self.area.connect("expose-event", self.expose_cairo) self.box.connect("button-press-event", self.cb_press) self.box.connect("button-release-event", self.cb_release) self.box.connect("motion_notify_event", self.cb_motion) self.box.set_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.POINTER_MOTION_MASK) self.box.add(self.area) self.window.add(self.box) self.window.set_keep_above(True) self.window.show_all() gtk.idle_add(self.present) def present(self): self.window.present() def expose_cairo(self, widget=None, event=None): nMonitors = screen.get_n_monitors() self.cairoWidget = widget self.cr = widget.window.cairo_create() self.cr.set_source_rgb(1, 1, 1) self.cr.rectangle(0, 0, self.windowSizeW, self.windowSizeH) self.cr.fill() for i in xrange(0, self.nBoxesW): for j in xrange(0, self.nBoxesH): self.cr.set_source_rgb(0.6, 0.6, 0.6) self.cr.rectangle((self.windowSpaceSizeW * i) + self.margin, (self.windowSpaceSizeH * j) + self.margin, self.windowBoxSizeW, self.windowBoxSizeH) self.cr.fill() if not self.mousePressed: if (self.mPosX - self.margin) % self.windowSpaceSizeW < self.windowBoxSizeW and self.mPosX < self.windowSizeW - self.margin and self.mPosX > self.margin: if (self.mPosY - self.margin) % self.windowSpaceSizeH < self.windowBoxSizeH and self.mPosY < self.windowSizeH - self.margin and self.mPosY > self.margin: self.cr.set_source_rgb(.3, .3, .3) self.cr.rectangle(self.mPosX - ((self.mPosX - self.margin) % self.windowSpaceSizeW), self.mPosY - ((self.mPosY - self.margin) % self.windowSpaceSizeH), self.windowBoxSizeW, self.windowBoxSizeH) self.cr.fill() else: x1 = self.startX y1 = self.startY x2 = ((self.mPosX - ((self.mPosX - self.margin) % self.windowSpaceSizeW)) - self.margin) / self.windowSpaceSizeW y2 = ((self.mPosY - ((self.mPosY - self.margin) % self.windowSpaceSizeH)) - self.margin) / self.windowSpaceSizeH if x2 < 0: x2 = 0 if y2 < 0: y2 = 0 if x2 > self.nBoxesW - 1: x2 = self.nBoxesW - 1 if y2 > self.nBoxesH - 1: y2 = self.nBoxesH - 1 if x1 > x2: x1 = x2 x2 = self.startX if y1 > y2: y1 = y2 y2 = self.startY for i in xrange(int(x1), int(x2) + 1): for j in xrange(int(y1), int(y2) + 1): self.cr.set_source_rgb(0.3, 0.3, 0.3) self.cr.rectangle((i * self.windowSpaceSizeW) + self.margin, (j * self.windowSpaceSizeH) + self.margin, self.windowBoxSizeW, self.windowBoxSizeH) self.cr.fill() def redraw(self): self.cairoWidget.queue_draw() def cb_destroy(self, widget=None, event=None): self.window.destroy() self.isOpen = False def cb_press(self, widget=None, event=None): self.mPosX = event.x self.mPosY = event.y if (self.mPosX - self.margin) % self.windowSpaceSizeW < self.windowBoxSizeW and self.mPosX < self.windowSizeW - self.margin and self.mPosX > self.margin: if (self.mPosY - self.margin) % self.windowSpaceSizeH < self.windowBoxSizeH and self.mPosY < self.windowSizeH - self.margin and self.mPosY > self.margin: self.mousePressed = True self.startX = int((self.mPosX - self.margin) / self.windowSpaceSizeW) self.startY = int((self.mPosY - self.margin) / self.windowSpaceSizeH) def cb_release(self, widget=None, event=None): x1 = self.startX y1 = self.startY if x1 < 0 or y1 < 0: return x2 = ((event.x - ((event.x - self.margin) % self.windowSpaceSizeW)) - self.margin) / self.windowSpaceSizeW y2 = ((event.y - ((event.y - self.margin) % self.windowSpaceSizeH)) - self.margin) / self.windowSpaceSizeH if x2 < 0: x2 = 0 if y2 < 0: y2 = 0 if x2 > self.nBoxesW - 1: x2 = self.nBoxesW - 1 if y2 > self.nBoxesH - 1: y2 = self.nBoxesH - 1 if x1 > x2: x1 = x2 x2 = self.startX if y1 > y2: y1 = y2 y2 = self.startY self.resize(x1, y1, x2, y2) self.cb_destroy() def getDesktopDimensions(self): window = gtk.Window() screen = window.get_screen() lMonitors = [] self.offset = 0 for i in xrange(0, screen.get_n_monitors()): lMonitors.append([screen.get_monitor_geometry(i).width, screen.get_monitor_geometry(i).height]) currentMonitorIndex = screen.get_monitor_at_window(screen.get_active_window()) if currentMonitorIndex != 0: for i in xrange(0, currentMonitorIndex): self.offset += lMonitors[i][0] return lMonitors[currentMonitorIndex][0], lMonitors[currentMonitorIndex][1] def resize(self, x1, y1, x2, y2): grav = 0 screenDimensions = self.getDesktopDimensions() sectionSizeW = screenDimensions[0] / self.nBoxesW sectionSizeH = screenDimensions[1] / self.nBoxesH xPos = int(screenDimensions[0] / self.nBoxesW * x1) yPos = int(screenDimensions[1] / self.nBoxesH * y1) width = int(((x2 + 1) - x1) * (screenDimensions[0]) / self.nBoxesW) height = int(((y2 + 1) - y1) * (screenDimensions[1]) / self.nBoxesH) self.ewmh.setWmState(self.activeWindow, 0, '_NET_WM_STATE_MAXIMIZED_HORZ') self.ewmh.setWmState(self.activeWindow, 0, '_NET_WM_STATE_MAXIMIZED_VERT') self.ewmh.setMoveResizeWindow(self.activeWindow, grav, self.offset + xPos, yPos, width, height) self.ewmh.display.flush() def cb_motion(self, widget=None, event=None): if event.is_hint: x, y, state = event.window.get_pointer() else: x = event.x y = event.y state = event.state self.mPosX = x self.mPosY = y self.redraw()
class MainClass: totalXDist = 2436 totalYDist = 1044 halfTotalXDist = totalXDist / 2 halfTotalYDist = totalYDist / 2 minSwipeXDist = 150 # 1/16 aproximate total distance minSwipeYDist = 20 def __init__(self): self.dev = InputDevice('/dev/input/event2') self.ewmh = EWMH() # initialize normal variables and start reading self.x = -1 self.y = -1 # self.readInput(self.dev) # self.testMouse(self.dev) """ ui = UInput() ui.write(ecodes.EV_KEY, ecodes.KEY_A, 1) # KEY_A down ui.write(ecodes.EV_KEY, ecodes.KEY_A, 0) # KEY_A up ui.syn() ui.close() """ def test_mouse(self, dev): for event in dev.read_loop(): print(event) def read_input(self, dev): first_time_x = True first_time_y = True double_tap = False x = -1 y = -1 for event in dev.read_loop(): if event.type == ecodes.EV_KEY: if event.code == ecodes.BTN_TOOL_double_tap: # catched a double tap double_tap = True if event.type == ecodes.EV_ABS: # absolute press # x event if event.code == ecodes.ABS_X: if first_time_x: x = event.value first_time_x = False self.x = event.value # y event if event.code == ecodes.ABS_Y: if first_time_y: y = event.value first_time_y = False self.y = event.value # maybe release touchpad event if event.code == ecodes.ABS_TOOL_WIDTH: if event.value == 0: # release touchpad self.print_pos(x, y, self.x,self.y, double_tap) self.reset_variables() x = -1 y = -1 first_time_x = True first_time_y = True double_tap = False def print_pos(self, x1, y1, x2, y2, double_tap): # print ("first x: " + str(x1) + ", first y: " + str(y1)) # print ("x: " + str(x2) + ", y: " + str(y2)) if double_tap: # swipe if its in double tap mode self.swipe(x1, y1, x2, y2) print() # self.test_window() def test_window(self): win = self.ewmh.getActiveWindow() print(win.get_wm_class()[0]) print(win.get_wm_class()[1]) def move_window_to_desktop(self, window, desktop): """ Move the window to the given desktop number :param window :param desktop: number """ self.ewmh.setWmDesktop(window, desktop) def move_to_desktop(self, desktop): """ Change the current workspace to the given desktop number :param desktop: number """ self.ewmh.setcurrent_desktop(desktop) def choose_desktop(self, swipe, current_desktop, total_desktop): """ Calculate the desktop to move to. :param swipe: number (-1 or 1, swipe left or right) :param current_desktop: number :param total_desktop: total number of desktops """ total = total_desktop - 1 action = current_desktop + swipe if action < 0: return total elif action > total: return 0 else: return action def swipe_move(self, x): """ Given a swipe move changes to the respective desktop :param swipe: number (-1 or 1, swipe left or right) """ win = self.ewmh.getActiveWindow() current_desktop = self.ewmh.getcurrent_desktop() total_desktops = self.ewmh.getNumberOfDesktops() desktop = self.choose_desktop(x, current_desktop, total_desktops) # self.move_window_to_desktop(win, desktop) self.move_to_desktop(desktop) self.ewmh.display.flush() def swipe(self, x1, y1, x2, y2): x = x2 - x1 y = y2 - y1 print("x1: " + str(x1) + ", x2: " + str(x2)) self.swipe_horizontal(x) # self.swipe_vertical(y) def swipe_horizontal(self, x): if abs(x) < MainClass.minSwipeXDist: print(x) print("no swipe") elif x > 0: self.swipe_move(-1) # print(x) # print("swipe left to right") else: self.swipe_move(1) # print(x) # print("swipe right to left") pass def swipe_vertical(self, y): if abs(y) < MainClass.minSwipeYDist: print("no swipe") elif y > 0: print("swipe top to bottom") else: print("swipe bottom to top") def figure_out_pos_in_touchpad(self, x, y): if x < MainClass.halfTotalXDist: if y < MainClass.halfTotalYDist: print ("A") else: print ("C") else: # x > MainClass.halfTotalXDist if y < MainClass.halfTotalYDist: print ("B") else: print ("D") def reset_variables(self): self.x = -1 self.y = -1 def emit_key_press(self, key): self.device.emit_click(key)
def get_top_window(): ewmh = EWMH() return ewmh.getActiveWindow()
def getActiveWindow_Linux(): try: import wnck except ImportError: if DEBUG is not None: print("wnck is not installed") wnck = None if wnck is not None: #TRY WITH WNCK screen = wnck.screen_get_default() # Recommended per wnck documentation screen.force_update() window = screen.get_active_window() if window is not None: return psutil.Process(window.get_pid()).name() else: try: import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk, Wnck G = "Installed" except ImportError: if DEBUG is not None: print("gi.repository not installed") G = None if G is not None: #TRY WITH GTK WNCK # Necessary if not using a Gtk.main() loop Gtk.init([]) screen = Wnck.Screen.get_default() # Recommended per Wnck documentation screen.force_update() active_window = screen.get_active_window() pid = active_window.get_pid() return psutil.Process(pid).name() else: try: from ewmh import EWMH ewmh = EWMH() except ImportError: if DEBUG is not None: print("EWMH not installed") ewmh = None if ewmh is not None: #TRY WITH EXTENDED XLib win = ewmh.getActiveWindow() return psutil.Process(ewmh.getWmPid(win)).name() else: try: import Xlib.display X = "Installed" except ImportError: X = None if X is not None: #TRY WITH Xlib (different result) display = Xlib.display.Display() window = display.get_input_focus().focus pid = window.get_wm_pid wmname = window.get_wm_name() wmclass = window.get_wm_class() if wmclass is None and wmname is None: window = window.query_tree().parent wmname = window.get_wm_name() return wmname #If nothing happened return None