def count_on_current_ws(ignored_classes: List[str], ewmh: EWMH) -> int: """ Count the number of open windows on the current workspace. Windows with a class in the given ignore list, bad windows, or ones missing a _NET_WM_DESKTOP property are not counted. :param ignored_classes: A list of window classes to ignore :param ewmh: An instance of EWMH for workspace retrieval :return: The number of open windows on the workspace """ window_count = 0 all_windows = ewmh.getClientList() windows_on_ws = [ w for w in all_windows if get_workspace(w, ewmh) == ewmh.getCurrentDesktop() ] for window in windows_on_ws: try: window_class = window.get_wm_class() except Xlib.error.BadWindow: logging.info('Ignoring bad window (id: %s)', window.id) continue if window_class is not None and window_class[1] in ignored_classes: logging.info("Ignoring window with class '%s'.", window_class[1]) continue window_count += 1 return window_count
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 find_by_pid(pid): ewmh = EWMH() wnds = list(ewmh.getClientList()) # pprint(wnds) matched = list(filter(check_wnd, wnds)) if matched: got_wnd(matched[0])
def __init__(self, parent = None, widget = None): super(BlinkYourEyesWidget, self).__init__() # Avoid this window appearing from alt-tab window selection # see the followings: # https://stackoverflow.com/questions/3553428/how-can-i-prevent-gnome-from-showing-two-windows-when-doing-alt-tab-c-qt-app # https://doc.qt.io/qt-5/qt.html#WindowType-enum self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint|QtCore.Qt.FramelessWindowHint |QtCore.Qt.Tool) #self.setAttribute(Qt.Qt.WA_NoSystemBackground) #self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.setWindowOpacity(0.8) #self.setFocusPolicy(QtCore.Qt.NoFocus) #self.setStyleSheet("background-color:transparent;") self.background_color = QtCore.Qt.black self.timer_count = 0 self.timer = QtCore.QTimer() self.timer.setInterval(100) # [milliseconds] self.timer.timeout.connect(self.timer_callback) self.initUI() self.timer.start() self.dragmode = None self.dragstartpos = None self.dragstartgeom = None if platform.system() == 'Linux': ewmh = EWMH() all_wins = ewmh.getClientList() wins = filter(lambda w: 'blinkyoureyes' in w.get_wm_class()[1], all_wins) for w in wins: ewmh.setWmDesktop(w, 0xffffffff) ewmh.display.flush()
def quoteOSHPark(self): """Function for navigating OSHPark's website.""" url, user, pw = self.readConfig('oshpark', 'rigid') # Open new tab and go to URL self.newTab() self.driver.get(url) # Enter login information self.driver.find_element_by_css_selector('#user_email').send_keys(user) self.driver.find_element_by_css_selector('#user_password').send_keys(pw) # Click login button self.driver.find_element_by_css_selector('.buttons > input:nth-child(1)').click() self.driver.find_element_by_css_selector('#ember291').click() self.driver.find_element_by_css_selector('#file_selector > input:nth-child(2)').click() e = EWMH() windows = e.getClientList() for window in windows: if e.getWmName(window) == 'File Upload': time.sleep(0.5) e.setActiveWindow(window) e.display.flush() time.sleep(0.5) pyautogui.hotkey('ctrl', 'a') pyautogui.press('backspace') # '''get file location from config file''' # pyautogui.typewrite(fileLocation) pyautogui.press('return')
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 find_monitors(self): self.dpy = display.Display() self.root = self.dpy.screen().root self.resources = self.root.xrandr_get_screen_resources()._data self.ewmh = EWMH() # Accessing modes sometimes makes outputs mysteriously disappear, # so save outputs first. outputs = self.resources['outputs'] # Build up a mode table. There's probably some clever IterTools # construct that could do this in one line. for m in self.resources['modes']: self.allmodes[m['id']] = '%dx%d' % (m['width'], m['height']) # Loop over the outputs. for output in outputs: print("Output info:", self.dpy.xrandr_get_output_info( output, self.resources['config_timestamp']), file=DEBUGFILE) mondata = self.dpy.xrandr_get_output_info( output, self.resources['config_timestamp'])._data if mondata['mm_width'] <= 0 or mondata['mm_height'] <= 0: # Not an actual monitor; I'm not sure what these are for # but they don't seem to have any useful info continue name = mondata['name'] self.monitors[name] = mondata if name.startswith('eDP') or name.startswith('LVDS'): self.laptop_screen = name # print("laptop monitor:", name) # Figure out if it's cloned or extended, and its xinerama position # https://stackoverflow.com/questions/49136692/python-xlib-how-to-deterministically-tell-whether-display-output-is-in-extendi # which references https://www.x.org/wiki/Development/Documentation/HowVideoCardsWork/#index3h3 # crtcInfo also includes rotation info but I'm not doing anything # with that since I don't personally use it. try: crtcInfo = self.dpy.xrandr_get_crtc_info( mondata['crtc'], self.resources['config_timestamp']) # print(crtcInfo) self.mon_geom[name] = { 'x': crtcInfo.x, 'y': crtcInfo.y, 'width': crtcInfo.width, 'height': crtcInfo.height, 'mm_width': mondata['mm_width'], 'mm_height': mondata['mm_height'] } except XError: # If get_crtc_info fails it means that the monitor is # connected but not active. pass
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
def __init__(self, output: str, fps: float = 30.0): self._ewmh = EWMH() self._sct = None self._geometry = self._ewmh.getDesktopGeometry() self._writer = None self._output = output self._delay = 1.0 / fps self._fps = fps self._width = 0 self._height = 0 if not os.path.exists('recorded'): os.mkdir('recorded')
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 main(): engine = create_engine('sqlite:///a.db') session_factory = sessionmaker(bind=engine) session = session_factory(autoflush=True) object_manager_builder = ActivityManagerObjectManagerBuilder() object_manager = object_manager_builder.build(session) window_manager_manager = EWMH() window_type_filterer = WindowTypeFilterer(window_manager_manager, '_NET_WM_WINDOW_TYPE_NORMAL') window_state_factory = WindowStateFactory(window_manager_manager, WindowState) def get_window_states(): return [ window_state_factory.create(window) for window in window_type_filterer.filter(window_manager_manager.getClientList()) ] window_poll_stack = NItemStack(2) window_poll_stack.push(WindowPollState([])) while True: window_poll_stack.push(WindowPollState(get_window_states())) print(window_poll_stack[1].changes_since(window_poll_stack[0])) print() time.sleep(2)
def __init__(self, configuration, parent=None): """ Constructor Get the XML configuration as a string """ # Parent constructor super().__init__(parent) # Parse configuration root = ET.fromstring(configuration) # Extract items for c in list(root): if c.tag == 'category': self.children.append(CategoryItem(c, self)) elif c.tag == 'program': self.children.append(ProgramItem(c, self)) else: # Unknown tag pass # Initialize interface to X server if has_ewmh: self.ewmh = EWMH() else: self.ewmh = None
def __init__(self, name, master=None, **kw): """ Create a desktop widget that sticks on the desktop. """ Toplevel.__init__(self, master) self.name = name if CONFIG.getboolean('General', 'splash_supported', fallback=True): self.attributes('-type', 'splash') else: self.attributes('-type', 'toolbar') self.style = Style(self) self._position = StringVar(self, CONFIG.get(self.name, 'position')) self._position.trace_add( 'write', lambda *x: CONFIG.set(self.name, 'position', self._position.get())) self.ewmh = EWMH() self.title('scheduler.{}'.format(self.name.lower())) self.withdraw() # control main menu checkbutton self.variable = BooleanVar(self, False) # --- menu self.menu = Menu(self, relief='sunken', activeborderwidth=0) self._populate_menu() self.create_content(**kw) self.x = None self.y = None # --- geometry geometry = CONFIG.get(self.name, 'geometry') self.update_idletasks() if geometry: self.geometry(geometry) self.update_idletasks() if CONFIG.getboolean(self.name, 'visible', fallback=True): self.show() # --- bindings self.bind('<Configure>', self._on_configure)
def getWins(): ''' getWins() -> retval. get all active window id and title. ''' ewmh = EWMH() wins, winHDs = [], ewmh.getClientListStacking() for winHD in winHDs: try: title = ewmh.getWmName(winHD) pid = ewmh.getWmPid(winHD) except: continue if title is not None: wins.append((winHD, title, pid)) return wins
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()
def get_recent_windows(exclude, limit): wm = EWMH() xlib_windows = wm.getClientListStacking() windows_recent_last = [ Window.from_xlib_window(xlib_win) for xlib_win in xlib_windows ] windows_recent_first = list(reversed(windows_recent_last)) windows_result = windows_recent_first if exclude: for win in windows_result: if win.name == exclude: windows_result.remove(win) if limit: windows_result = windows_result[:10] return windows_result
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) """
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 __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)
class NegEWMH(): """ Custom EWMH support functions """ disp = Xlib.display.Display() ewmh = EWMH() @staticmethod @contextmanager def window_obj(disp, win_id): """ Simplify dealing with BadWindow (make it either valid or None) """ window_obj = None if win_id: try: window_obj = disp.create_resource_object('window', win_id) except Xlib.error.XError: pass yield window_obj @staticmethod def is_dialog_win(win) -> bool: """ Check that window [win] is not dialog window At first check typical window roles and classes, because of it more fast, then using python EWMH module to detect dialog window type or modal state of window. win : target window to check """ if win.window_instance == "Places" \ or win.window_role in { "GtkFileChooserDialog", "confirmEx", "gimp-file-open"} \ or win.window_class == "Dialog": return True with NegEWMH.window_obj(NegEWMH.disp, win.window) as win_obj: win_type = NegEWMH.ewmh.getWmWindowType(win_obj, str=True) if '_NET_WM_WINDOW_TYPE_DIALOG' in win_type: return True win_state = NegEWMH.ewmh.getWmState(win_obj, str=True) if '_NET_WM_STATE_MODAL' in win_state: return True return False @staticmethod def find_visible_windows(windows_on_ws: List) -> List: """ Find windows visible on the screen now. windows_on_ws: windows list which going to be filtered with this function. """ visible_windows = [] for win in windows_on_ws: with NegEWMH.window_obj(NegEWMH.disp, win.window) as win_obj: win_state = NegEWMH.ewmh.getWmState(win_obj, str=True) if '_NET_WM_STATE_HIDDEN' not in win_state: visible_windows.append(win) return visible_windows
def _get_ewmh(): ''' Get the EWMH object. Returns ------- object The EWMH object. ''' global ewmh if ewmh is None: ewmh = EWMH() return ewmh
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 __init__(self): self.display = display.Display() self.ewmh = EWMH(self.display) mod_map = self.display.get_modifier_mapping() syms = {} for key, index in KEY_TO_MOD_INDEX.items(): mod = mod_map[index] sym = {key} syms[mod[0]] = {key} syms[mod[1]] = {key} self.mod_syms = syms
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 get_workspace(window, ewmh: EWMH) -> int: """ Return the given window's workspace number or -1 if the window is invalid or is missing the required _NET_WM_DESKTOP property. :param window: A window whose workspace number to get :param ewmh: An instance of EWMH for workspace retrieval :return: The window's workspace number or -1 if missing """ try: return ewmh.getWmDesktop(window) except Xlib.error.BadWindow: logging.info('Bad window (id: %s)', window.id) except TypeError: logging.warning('Window (id: %s) has no workspace number.', window.id) return -1
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 WmEWMH(WinInfo): ewmh = EWMH() wmclass = ewmh.display.get_atom("WM_CLASS") wmcm = ewmh.display.get_atom("WM_CLIENT_MACHINE") wmname = ewmh.display.get_atom("WM_NAME") def list_windows(self): wins = WmEWMH.ewmh.getClientListStacking() lines = [] for win in wins: id = '0x' + hex(win.id)[2:].zfill(8) disp = win.display.default_screen wmcm = win.get_full_property(self.wmcm, X.AnyPropertyType) if wmcm: wmcm = wmcm.value.decode("utf-8", 'backslashreplace') else: wmcm = "N/A" itemb = win.get_full_property(WmEWMH.wmclass, X.AnyPropertyType).value cls = '.'.join(itemb.decode("utf-8").rstrip('\x00').split('\x00')) nameb = win.get_full_property(WmEWMH.wmname, X.AnyPropertyType).value name = nameb.decode("utf-8", 'backslashreplace') line = "%s %s %s %s %s" % (id, disp, cls, wmcm, name) lines.append(line) return lines def kill(self, wm_id: str) -> None: win_id = int(wm_id, 16) win = WmEWMH.ewmh._createWindow(win_id) WmEWMH.ewmh.setCloseWindow(win) WmEWMH.ewmh.display.flush() def switch_to(self, wm_id): win_id = int(wm_id, 16) win = WmEWMH.ewmh._createWindow(win_id) WmEWMH.ewmh.setActiveWindow(win) WmEWMH.ewmh.display.flush()
def unmaximize(hwnd, x, y, width, height): ewmh = EWMH() ewmh.setWmState(hwnd, 0, '_NET_WM_STATE_FULLSCREEN') ewmh.display.flush()
def maximize(hwnd): ewmh = EWMH() ewmh.setWmState(hwnd, 1, '_NET_WM_STATE_FULLSCREEN') ewmh.display.flush()
def set_win_size(hwnd, x, y, width, height): ewmh = EWMH() ewmh.setMoveResizeWindow(hwnd, 0, x, y, width, height) ewmh.display.flush()
def get_desktop(): ewmh = EWMH() width, height = ewmh.getDesktopGeometry() return 0, 0, width, height
def get_top_window(): ewmh = EWMH() return ewmh.getActiveWindow()
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
from ewmh import EWMH ewmh = EWMH() def filter_window(wins, windowclass): for w in wins: if w.get_wm_class()[1] == windowclass: return w wins = ewmh.getClientList() user_input = raw_input("Enter a Valid Input:") diawin = filter_window(wins, 'Dia-normal') ewmh.setActiveWindow(diawin) if user_input == "1": ewmh.setWmState(diawin, 1, '_NET_WM_STATE_FULLSCREEN') ewmh.display.flush()
import rx import subprocess from datetime import datetime from rx import Observable, Observer from time import sleep from ewmh import EWMH ewmh = EWMH() def get_disks(_): result = subprocess.check_output(["df"]).split(b"\n") result = [x.split() for x in result[1:]] return {x[0]: float(x[4][:-1])/100.0 for x in result if len(x) > 5} def get_mail(_): result = subprocess.check_output(["/usr/bin/notmuch", "count", "tag:unread"]) return int(result) def get_mail_headings(_): result = subprocess.check_output(["/usr/bin/notmuch", "search", "tag:unread"]) result = [";".join(str(x).split(";")[1:]) for x in result.split(b"\n")[:15]] return "\n".join(result[::-1]) def get_cpu(_): with open("/proc/loadavg", "r") as infile: return float(infile.readline().split()[0]) def get_mem(_):
class Recorder: ID = {} QUEUE = {} def __init__(self, output: str, fps: float = 30.0): self._ewmh = EWMH() self._sct = None self._geometry = self._ewmh.getDesktopGeometry() self._writer = None self._output = output self._delay = 1.0 / fps self._fps = fps self._width = 0 self._height = 0 if not os.path.exists('recorded'): os.mkdir('recorded') async def record(self, wm_name: str): await self.__class__.wait(wm_name) asyncio.ensure_future(self._record(wm_name)) @classmethod def fromCase(cls, case): return Recorder(cls.naming(case)).record @classmethod async def wait(cls, wm_name: str): # ID if wm_name not in cls.ID.keys(): cls.ID[wm_name] = max([0, *cls.ID.values()]) _id = cls.ID[wm_name] # wait by ID while (_id in cls.QUEUE.keys()) or (_id > len(cls.QUEUE)): await asyncio.sleep(0.1) cls.QUEUE[wm_name] = { 'top': 0, 'left': 0, 'width': 0, 'height': 0, } @classmethod async def signal(cls, wm_name: str): del cls.QUEUE[wm_name] @classmethod def naming(cls, case): def _shorten(name): # int if isinstance(name, float) and name % 1 == 0: return str(int(name)) # maybe path if isinstance(name, str): return name.split('/')[-1] return str(name) return '_'.join(reversed([_shorten(c[1]) for c in case])) async def _record(self, wm_name: str): begin, tick = datetime.now(), 0 tracking = False await asyncio.sleep(1) while True: ts_last = datetime.now() # retrieve try: frames = [ w for w in self._ewmh.getClientList() if wm_name in (w.get_wm_name() or '') ] if len(frames) != 1: if len(frames) > 1: print( '-' * 36 + '\n' + f'! {len(frames)} windows have been captured.\n' + '.\n'.join(f'| {self._ewmh.getWmName(w).decode()}' for w in frames) + '\n' + ('-' * 36)) break if tracking: break await asyncio.sleep(self._delay / 2) continue # the only frame bbox = self._get_frame(frames[0]).get_geometry() monitor = { 'top': bbox.y, 'left': bbox.x, 'width': bbox.width, 'height': bbox.height } except Xlib.error.BadWindow: continue # move window if not tracking: tracking = True monitor = self._update_window(wm_name, monitor, frames[0]) self._sct = mss.mss() if bbox.x + bbox.width > self._geometry[0]: monitor['width'] = self._geometry[0] - bbox.x if bbox.y + bbox.height > self._geometry[1]: monitor['height'] = self._geometry[1] - bbox.y img = np.array(self._sct.grab(monitor)) img = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY) self._write(img, wm_name) # end tick += 1 ts = datetime.now() await asyncio.sleep( max( 0, self._delay * (tick - (ts - begin).total_seconds() * self._fps) * 0.9)) # flush self.__close__() await self.__class__.signal(wm_name) def _write(self, img, wm_name): height, width = img.shape[:2] if self._writer is None or self._width != width or self._height != height: fourcc = cv2.VideoWriter_fourcc(*'FMP4') self._writer = cv2.VideoWriter( f'recorded/{self._output}-{"_".join(wm_name.lower().split(" "))}.avi', fourcc, self._fps, (width, height), False) self._width, self._height = width, height self._writer.write(img) def _get_frame(self, client): frame = client while frame.query_tree().parent != self._ewmh.root: frame = frame.query_tree().parent return frame def _update_window(self, wm_name, monitor, frame): width = sum(m['width'] for m in self.__class__.QUEUE.values()) monitor['left'] = width monitor['top'] = 0 if frame.get_wm_class() is None: w, h = monitor['width'], monitor['height'] else: w, h = 0, None # TODO 2-d replacement self.__class__.QUEUE[wm_name] = monitor self._ewmh.setMoveResizeWindow(frame, x=monitor['left'], y=monitor['top'], w=w, h=h) self._ewmh.display.flush() return monitor def __close__(self): if hasattr(self, '_writer') and self._writer is not None: self._writer.release() self._writer = None if hasattr(self, '_sct') and self._sct is not None: self._sct.close() self._sct = None def __del__(self): self.__close__()
import argparse, sys, os, psutil, subprocess, re, signal from PyQt5.QtWidgets import QApplication from PyQt5.QtCore import Qt, QTimer import pkg_resources import oskb from oskb import im linux = sys.platform.startswith("linux") if linux: import getpass from ewmh import EWMH, ewmh wm = EWMH() moved_windows = [] def command_line_arguments(): ap = argparse.ArgumentParser() ap.add_argument( "keyboards", help= """Which keyboard(s) to load. These are either files or names of built-in keyboards. If multiple keyboards are loaded, the user can switch between them with a menu key. If no keyboards are chosen a full keyboard is shown if display is wider than 600 pixels, otherwise a phone-style keyboard is used. If oskb comes with a keyboard for the presently set keyboard layout, that keyboard is used. Otherwise oskb will show a US keyboard layout and switch the system keyboard layout to that.""", metavar="<kbd>", nargs="*", )
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)
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()
action="store_true", help="Do not change anything") args = parser.parse_args() r = redis.Redis(host='localhost', port=6379, db=0) if args.init: desktops_map = prepare_desktops_map() if not desktops_map: sys.exit(128) r.set("xserver/desktops_map", json.dumps(desktops_map)) sys.exit(0) desktops_map = json.loads(r.get("xserver/desktops_map")) window_rules = json.loads(r.get("xserver/window_rules")) ewmh = EWMH() NET_WM_NAME = ewmh.display.intern_atom('_NET_WM_NAME') UTF8_STRING = ewmh.display.intern_atom('UTF8_STRING') windows = ewmh.getClientList() for window in sorted( windows, key=lambda w: w.get_full_text_property(NET_WM_NAME, UTF8_STRING)): similarities = {} rule = None desktop_name = None print("================================") window_title = window.get_full_text_property(NET_WM_NAME, UTF8_STRING) window_class = window.get_wm_class()[1] if args.verbosity >= 1: print(f"window ({window_class}): {window_title}")
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]
class Display: def __init__(self): self.display = display.Display() self.ewmh = EWMH(self.display) mod_map = self.display.get_modifier_mapping() syms = {} for key, index in KEY_TO_MOD_INDEX.items(): mod = mod_map[index] sym = {key} syms[mod[0]] = {key} syms[mod[1]] = {key} self.mod_syms = syms def query_keymap_raw(self): return self.display.query_keymap() def query_keyboard(self): keymap = self.query_keymap_raw() chord = set() for index, num in enumerate(keymap): for bit in range(8): if num & (1 << bit): keycode = 8 * index + bit # print(keycode) if keycode in self.mod_syms: chord |= self.mod_syms[keycode] for ind in range(4): keysym = self.display.keycode_to_keysym(keycode, ind) if not keysym: continue s = self.display.lookup_string(keysym) if s: chord |= {s} break return chord def query_mouse(self): root = self.display.screen()['root'] pointer = root.query_pointer() mask = pointer._data['mask'] # print(mask) buttons = set() for button, motion in BUTTON_TO_MOTION_MASK.items(): if motion & mask: buttons |= {button} return buttons def get_active_window(self): focus = self.display.get_input_focus() return focus._data['focus'] def get_clipboard_owner_window(self, source): window = self.display.get_selection_owner( self.display.get_atom(source)) while not window.get_wm_class(): window = window.query_tree()._data['parent'] if window == 0: return None return window def get_window_name(self, window): title = window.get_wm_name() if not title: title = window.get_full_text_property(Xatom.WM_NAME) if isinstance(title, bytes): return title.decode(errors='ignore') return title def get_window_pid(self, window): return self.ewmh.getWmPid(window) def focus_window(self, window): self.display.set_input_focus(window, X.RevertToParent, X.CurrentTime)