From 1ecfa3443ccb2b4f19155a96fe0c74627e228134 Mon Sep 17 00:00:00 2001 From: fdev31 Date: Tue, 16 May 2023 18:30:36 +0200 Subject: [PATCH] add the expose plugin --- README.md | 25 +++++++++++++++++++ pyprland/plugins/expose.py | 51 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 pyprland/plugins/expose.py diff --git a/README.md b/README.md index d340cb4..74c071c 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ A single config file `~/.config/hypr/pyprland.json` is used, using the following - `scratchpads` implements dropdowns & togglable poppups - `monitors` allows relative placement of monitors depending on the model +- `expose` easily switch between scratchpads and active workspace - `workspaces_follow_focus` provides commands and handlers allowing a more flexible workspaces usage on multi-monitor setups. If you think the multi-screen behavior of hyprland is not usable or broken/unexpected, this is probably for you. - `lost_windows` brings lost floating windows to the current workspace - `toggle_dpms` toggles the DPMS status of every plugged monitor @@ -89,6 +90,30 @@ Create a configuration file in `~/.config/hypr/pyprland.json` enabling a list of } ``` +# Plugin: `expose` + +Moves the focused window to some (hidden) special workspace and back with one command. + +### Command + +- `toggle_minimized [name]`: moves the focused window to the special workspace "name", or move it back to the active workspace. + If none set, special workspace "minimized" will be used. +- `expose`: expose every client on the active workspace. If expose is active restores everything and move to the focused window + +Example usage in `hyprland.conf`: + +``` +bind = $mainMod, N, exec, pypr toggle_minimized + ``` + +### Configuration + + +#### `include_special` (optional, defaults to false) + +Also include windows in the special workspaces during the expose. + + # Plugin: `shift_monitors` Swaps the workspaces of every screen in the given direction. diff --git a/pyprland/plugins/expose.py b/pyprland/plugins/expose.py new file mode 100644 index 0000000..52897a7 --- /dev/null +++ b/pyprland/plugins/expose.py @@ -0,0 +1,51 @@ +from typing import Any +from .interface import Plugin + +from ..ipc import hyprctlJSON, hyprctl + + +class Extension(Plugin): + async def init(self) -> None: + self.exposed = False + + async def run_toggle_minimized(self, special_workspace="minimized"): + """[name] Toggles switching the focused window to the special workspace "name" (default: minimized)""" + aw: dict[str, Any] = await hyprctlJSON("activewindow") + wid = aw["workspace"]["id"] + assert isinstance(wid, int) + if wid < 1: # special workspace: unminimize + wrk = await hyprctlJSON("activeworkspace") + await hyprctl(f"togglespecialworkspace {special_workspace}") + await hyprctl(f"movetoworkspacesilent {wrk['id']},address:{aw['address']}") + await hyprctl(f"focuswindow address:{aw['address']}") + else: + await hyprctl( + f"movetoworkspacesilent special:{special_workspace},address:{aw['address']}" + ) + + @property + def exposed_clients(self): + if self.config.get("include_special", False): + return self.exposed + else: + return [c for c in self.exposed if c["workspace"]["id"] > 0] + + async def run_expose(self, arg=""): + """Expose every client on the active workspace. If expose is active restores everything and move to the focused window""" + if self.exposed: + aw: dict[str, Any] = await hyprctlJSON("activewindow") + focused_addr = aw["address"] + for client in self.exposed_clients: + await hyprctl( + f"movetoworkspacesilent {client['workspace']['id']},address:{client['address']}" + ) + await hyprctl("togglespecialworkspace exposed") + await hyprctl(f"focuswindow address:{focused_addr}") + self.exposed = False + else: + self.exposed = await hyprctlJSON("clients") + for client in self.exposed_clients: + await hyprctl( + f"movetoworkspacesilent special:exposed,address:{client['address']}" + ) + await hyprctl("togglespecialworkspace exposed")