def focus_window(self, win: window.WindowType, surface: Surface = None): if self.seat.destroyed: return if surface is None and win is not None: surface = win.surface.surface previous_surface = self.seat.keyboard_state.focused_surface if previous_surface == surface: return if previous_surface is not None and previous_surface.is_xdg_surface: # Deactivate the previously focused surface previous_xdg_surface = XdgSurface.from_surface(previous_surface) previous_xdg_surface.set_activated(False) if not win: self.seat.keyboard_clear_focus() return if isinstance(win.surface, LayerSurfaceV1): if not win.surface.current.keyboard_interactive: return logger.debug("Focussing new window") if surface.is_xdg_surface and isinstance(win.surface, XdgSurface): win.surface.set_activated(True) self.seat.keyboard_notify_enter(surface, self.seat.keyboard)
def _on_foreign_request_activate( self, _listener, event: ftm.ForeignToplevelHandleV1ActivatedEvent ): logger.debug("Signal: foreign_toplevel_management request_activate") if self.group: self.qtile.current_screen.set_group(self.group) self.group.focus(self)
def get_vol(self) -> None: """Get the volume value""" try: output = subprocess.check_output(["amixer sget Master"], shell=True).decode("utf-8") vol = int( self.vol_value.search(output).groups()[0]) # type: ignore icon = next( iter({k: v for k, v in volume_level_icons.items() if vol >= v})) if re.search("off", output): vol = 0 icon = "\ufa80" if self.show_text: self.text = f"{icon} <span foreground='{colors['text']}'>{vol}%</span>" else: self.text = f"{icon}" self.bar.draw() except Exception as err: logger.debug(f"Failed to get amixer volume level: {err}")
def guess_terminal(): """Try to guess terminal.""" test_terminals = [ 'roxterm', 'sakura', 'hyper', 'alacritty', 'terminator', 'termite', 'gnome-terminal', 'konsole', 'xfce4-terminal', 'lxterminal', 'mate-terminal', 'kitty', 'yakuake', 'tilda', 'guake', 'eterm', 'st', 'urxvt', 'xterm', 'x-terminal-emulator', ] for terminal in test_terminals: logger.debug('Guessing terminal: {}'.format(terminal)) if not which(terminal, os.X_OK): continue logger.info('Terminal found: {}'.format(terminal)) return terminal logger.error('Default terminal has not been found.')
def _on_map(self, _listener, data): logger.debug("Signal: window map") self.mapped = True self.damage() if self.is_layer: self.output.organise_layers() self.core.focus_window(self, self.surface.surface)
def execute(self, call: CommandGraphCall, args: tuple, kwargs: dict) -> Any: """Execute the given call, returning the result of the execution Perform the given command graph call, calling the function with the given arguments and keyword arguments. Parameters ---------- call: CommandGraphCall The call on the command graph that is to be performed. args: The arguments to pass into the command graph call. kwargs: The keyword arguments to pass into the command graph call. """ obj = self._command_object.select(call.selectors) cmd = None try: cmd = obj.command(call.name) except SelectError: pass if cmd is None: return "No such command." logger.debug("Command: %s(%s, %s)", call.name, args, kwargs) return cmd(*args, **kwargs)
async def _server_callback(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None: """Callback when a connection is made to the server Read the data sent from the client, execute the requested command, and send the reply back to the client. """ logger.debug("Connection made to server") data = await reader.read() logger.debug("EOF received by server") try: req, is_json = _IPC.unpack(data) except IPCError: logger.warn("Invalid data received, closing connection") writer.close() if sys.version_info >= (3, 7): await writer.wait_closed() return if req[1] == "restart": logger.debug("Closing connection on restart") writer.write_eof() rep = self.handler(req) result = _IPC.pack(rep, is_json=is_json) logger.debug("Sending result on receive EOF") writer.write(result) logger.debug("Closing connection on receive EOF") writer.write_eof()
def _on_new_xdg_surface(self, _listener: Listener, surface: XdgSurface) -> None: logger.debug("Signal: xdg_shell new_surface_event") if surface.role == XdgSurfaceRole.TOPLEVEL: assert self.qtile is not None win = window.XdgWindow(self, self.qtile, surface) self.pending_windows.add(win)
def _on_set_title(self, _listener, _data): logger.debug("Signal: xwindow set_title") title = self.surface.title if title != self.name: self.name = title self.ftm_handle.set_title(title) hook.fire("client_name_updated", self)
async def _server_callback(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None: """Callback when a connection is made to the server Read the data sent from the client, execute the requested command, and send the reply back to the client. """ try: logger.debug("Connection made to server") data = await reader.read() logger.debug("EOF received by server") req, is_json = _IPC.unpack(data) except IPCError: logger.warn("Invalid data received, closing connection") else: if req[1] == "restart": # if we are going to restart, close the connection first, as we won't be back logger.debug("Closing connection on restart") writer.write_eof() rep = self.handler(req) result = _IPC.pack(rep, is_json=is_json) logger.debug("Sending result on receive EOF") writer.write(result) logger.debug("Closing connection on receive EOF") writer.write_eof() finally: writer.close() await writer.wait_closed()
async def async_start(self) -> None: """Start the server""" assert self.server is None logger.debug("Starting server") self.server = await asyncio.start_unix_server(self._server_callback, sock=self.sock)
def _on_cursor_motion(self, _listener, event: pointer.PointerEventMotion): assert self.qtile is not None logger.debug("Signal: cursor motion") self.cursor.move(event.delta_x, event.delta_y, input_device=event.device) self._process_cursor_motion(event.time_msec)
def remove_listener(self) -> None: """Remove the listener from the given event loop""" if self.fd is not None: logger.debug("Removing io watch") loop = asyncio.get_running_loop() loop.remove_reader(self.fd) self.fd = None
def _on_key(self, _listener, event: KeyboardKeyEvent): logger.debug("Signal: keyboard key") if self.qtile is None: # shushes mypy self.qtile = self.core.qtile assert self.qtile is not None if event.state == KEY_PRESSED: # translate libinput keycode -> xkbcommon keycode = event.keycode + 8 layout_index = lib.xkb_state_key_get_layout( self.keyboard._ptr.xkb_state, keycode) nsyms = lib.xkb_keymap_key_get_syms_by_level( self.keyboard._ptr.keymap, keycode, layout_index, 0, xkb_keysym, ) keysyms = [xkb_keysym[0][i] for i in range(nsyms)] mods = self.keyboard.modifier for keysym in keysyms: if (keysym, mods) in self.grabbed_keys: self.qtile.process_key_event(keysym, mods) return self.seat.keyboard_notify_key(event)
def _on_destroy(self, _listener, _data): logger.debug("Signal: window destroy") if self.mapped: logger.warning("Window destroyed before unmap event.") self.mapped = False self.qtile.unmanage(self.wid) self.finalize()
def enable(self): logger.debug("Enabling pointer constraints.") self.core.active_pointer_constraint = self self._get_region() self.add_listener(self.wlr_constraint.surface.commit_event, self._on_commit) self.wlr_constraint.send_activated()
def focus_window( self, win: window.WindowType, surface: Surface = None, enter: bool = True ) -> None: if self.seat.destroyed: return if surface is None and win is not None: if isinstance(win, base.Internal): self.focused_internal = win self.seat.keyboard_clear_focus() return surface = win.surface.surface if self.focused_internal: self.focused_internal = None if isinstance(win.surface, LayerSurfaceV1): if not win.surface.current.keyboard_interactive: return if isinstance(win.surface, xwayland.Surface): if not win.surface.or_surface_wants_focus(): return previous_surface = self.seat.keyboard_state.focused_surface if previous_surface == surface: return if previous_surface is not None: # Deactivate the previously focused surface if previous_surface.is_xdg_surface: previous_xdg_surface = XdgSurface.from_surface(previous_surface) if not win or win.surface != previous_xdg_surface: previous_xdg_surface.set_activated(False) if previous_xdg_surface.data: previous_xdg_surface.data.set_activated(False) elif previous_surface.is_xwayland_surface: prev_xwayland_surface = xwayland.Surface.from_wlr_surface(previous_surface) if not win or win.surface != prev_xwayland_surface: prev_xwayland_surface.activate(False) if prev_xwayland_surface.data: prev_xwayland_surface.data.set_activated(False) if not win: self.seat.keyboard_clear_focus() return logger.debug("Focussing new window") if surface.is_xdg_surface and isinstance(win.surface, XdgSurface): win.surface.set_activated(True) win.ftm_handle.set_activated(True) elif surface.is_xwayland_surface and isinstance(win.surface, xwayland.Surface): win.surface.activate(True) win.ftm_handle.set_activated(True) if enter and self.seat.keyboard._ptr: # This pointer is NULL when headless self.seat.keyboard_notify_enter(surface, self.seat.keyboard)
def start(self) -> None: """Start the server""" assert self.server is None logger.debug("Starting server") server_coroutine = asyncio.start_unix_server(self._server_callback, sock=self.sock) self.server = self.loop.run_until_complete(server_coroutine)
def cmd_get_state(self): """Get pickled state for restarting qtile""" buf = io.BytesIO() self.dump_state(buf) state = buf.getvalue().decode(errors="backslashreplace") logger.debug('State = ') logger.debug(''.join(state.split('\n'))) return state
def _on_output_power_manager_set_mode( self, _listener: Listener, mode: OutputPowerV1SetModeEvent) -> None: logger.debug("Signal: output_power_manager set_mode_event") wlr_output = mode.output wlr_output.enable(enable=True if mode.mode == OutputPowerManagementV1Mode.ON else False) wlr_output.commit()
def _load_file(self, path): try: with open(path, 'r') as f: return float(f.read().strip()) except FileNotFoundError: logger.debug('Failed to get %s' % path) raise RuntimeError('Unable to read status for {}'.format( os.path.basename(path)))
def _on_unmap(self, _listener, data): logger.debug("Signal: window unmap") self.mapped = False if self.surface.surface == self.core.seat.keyboard_state.focused_surface: self.core.seat.keyboard_clear_focus() if self.is_layer: self.output.organise_layers() self.damage()
async def async_close(self) -> None: """Close and shutdown the server""" logger.debug("Stopping server on close") assert self.server is not None self.server.close() await self.server.wait_closed() self.server = None
def _on_new_layer_surface(self, _listener, layer_surface: layer_shell_v1.LayerSurfaceV1): logger.debug("Signal: layer_shell new_surface_event") assert self.qtile is not None wid = max(self.qtile.windows_map.keys(), default=0) + 1 win = window.Static(self, self.qtile, layer_surface, wid) logger.info(f"Managing new layer_shell window with window ID: {wid}") self.qtile.manage(win)
def _on_new_layer_surface(self, _listener, layer_surface: LayerSurfaceV1): logger.debug("Signal: layer_shell new_surface_event") assert self.qtile is not None wid = self.new_wid() win = window.Static(self, self.qtile, layer_surface, wid) logger.info(f"Managing new layer_shell window with window ID: {wid}") self.qtile.manage(win)
def _on_unmap(self, _listener, _data): logger.debug("Signal: window unmap") self.mapped = False self.damage() seat = self.core.seat if not seat.destroyed: if self.surface.surface == seat.keyboard_state.focused_surface: seat.keyboard_clear_focus()
def start(self) -> None: """Start the server""" assert self.server is None server_coroutine = self.loop.create_unix_server( lambda: _ServerProtocol(self.handler), sock=self.sock) logger.debug('Starting server') self.server = self.loop.run_until_complete(server_coroutine)
def _on_request_start_drag(self, _listener, event: seat.RequestStartDragEvent): logger.debug("Signal: seat request_start_drag") if not self.live_dnd and self.seat.validate_pointer_grab_serial( event.origin, event.serial): self.seat.start_pointer_drag(event.drag, event.serial) else: event.drag.source.destroy()
def _get_keysyms(xkb_state, keycode): syms_out = ffi.new("const xkb_keysym_t **") nsyms = lib.xkb_state_key_get_syms(xkb_state, keycode, syms_out) if nsyms > 0: assert syms_out[0] != ffi.NULL syms = [syms_out[0][i] for i in range(nsyms)] logger.debug(f"Got {nsyms} syms: {syms}") return syms
def setup_monitors(action=None, device=None): if action == "change": logger.debug("qtile: display change detected...") return # setup monitors with xrandr import subprocess subprocess.call(home + "/bin/swt") # no need to lazy.restart() here, we just reconfigure X startup()
def change_transparency(window): """change window transparency based on his name/type.""" kls = window.window.get_wm_class()[1].lower() logger.debug("Change transparency for window: %s", kls) if 'urxvt' in kls: window.cmd_opacity(.7) elif 'firefox' in kls or 'chromium' in kls: window.cmd_opacity(.9) else: if window.floating and 'urxvt' not in kls: # all floating are almost transparent by default (for popups windows) window.cmd_opacity(.95) else: window.cmd_opacity(.8)
def client_focus(window): """Change transparency on focus.""" global last_focus if last_focus is not None and last_focus != window: try: change_transparency(last_focus) except Exception: pass # ignore if error if last_focus != window: last_focus = window kls = window.window.get_wm_class()[1].lower() logger.debug("Change transparency for current window: %s", kls) window.cmd_opacity(1) # current focused window: no transp
def safe_import(module_name, class_name): """ try to import a module, and if it fails because an ImporError it logs on WARNING, and logs the traceback on DEBUG level """ if type(class_name) is list: for name in class_name: safe_import(module_name, name) return package = __package__ # python 3.2 don't set __package__ if not package: package = __name__ try: module = importlib.import_module(module_name, package) globals()[class_name] = getattr(module, class_name) except ImportError as error: logger.warning("Can't Import Widget: '%s.%s', %s", module_name, class_name, error) logger.debug("%s", traceback.format_exc())