Add bindings for next/prev workspace in vswitch#3041
Open
rpaciorek wants to merge 1 commit into
Open
Conversation
Similar to left/right but jump to next row instead wrap to first column.
Member
|
I wonder whether we really want to add even more bindings to vswitch. This functionality for example could easily be implemented via an IPC script. AI-generated, human-reviewed example: #!/usr/bin/python3
import argparse
import signal
import sys
from typing import Any
from wayfire import WayfireSocket
DEFAULT_BINDINGS = {
"next": "<super> <alt> KEY_PAGEUP",
"prev": "<super> <alt> KEY_PAGEDOWN",
"with_win_next": "<super> <alt> <shift> KEY_PAGEUP",
"with_win_prev": "<super> <alt> <shift> KEY_PAGEDOWN",
"send_win_next": "",
"send_win_prev": "",
}
def option_value(response: Any, default: Any = None) -> Any:
if isinstance(response, dict):
return response.get("value", default)
return default
def is_enabled(value: Any) -> bool:
if isinstance(value, bool):
return value
if isinstance(value, str):
return value.lower() in {"1", "true", "yes", "on"}
return bool(value)
def focused_view_id(sock: WayfireSocket) -> int | None:
view = sock.get_focused_view()
if not isinstance(view, dict):
return None
view_id = view.get("id")
if view_id is None:
return None
return int(view_id)
def target_workspace(sock: WayfireSocket, direction: int) -> tuple[int, int] | None:
output = sock.get_focused_output()
workspace = output["workspace"]
grid_width = int(workspace["grid_width"])
grid_height = int(workspace["grid_height"])
current_x = int(workspace["x"])
current_y = int(workspace["y"])
current_index = current_y * grid_width + current_x
target_index = current_index + direction
workspace_count = grid_width * grid_height
wraparound = is_enabled(option_value(sock.get_option_value("vswitch/wraparound"), False))
if wraparound:
target_index %= workspace_count
elif target_index < 0 or target_index >= workspace_count:
return None
return target_index % grid_width, target_index // grid_width
def switch_linear(sock: WayfireSocket, direction: int, with_window: bool, send_only: bool) -> None:
target = target_workspace(sock, direction)
if target is None:
return
target_x, target_y = target
if with_window or send_only:
view_id = focused_view_id(sock)
if view_id is None:
return
if send_only:
sock.send_view_to_workspace(view_id, target_x, target_y)
return
output = sock.get_focused_output()
sock.set_workspace(
target_x,
target_y,
view_id=view_id if with_window else None,
output_id=output["id"],
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Register IPC bindings for numeric next/previous vswitch workspaces."
)
parser.add_argument("--next", default=DEFAULT_BINDINGS["next"], help="binding for next workspace")
parser.add_argument("--prev", default=DEFAULT_BINDINGS["prev"], help="binding for previous workspace")
parser.add_argument(
"--with-win-next",
default=DEFAULT_BINDINGS["with_win_next"],
help="binding for next workspace with focused window",
)
parser.add_argument(
"--with-win-prev",
default=DEFAULT_BINDINGS["with_win_prev"],
help="binding for previous workspace with focused window",
)
parser.add_argument(
"--send-win-next",
default=DEFAULT_BINDINGS["send_win_next"],
help="binding for sending focused window to next workspace without switching",
)
parser.add_argument(
"--send-win-prev",
default=DEFAULT_BINDINGS["send_win_prev"],
help="binding for sending focused window to previous workspace without switching",
)
return parser.parse_args()
def main() -> int:
args = parse_args()
sock = WayfireSocket()
actions = {
"next": (args.next, 1, False, False),
"prev": (args.prev, -1, False, False),
"with_win_next": (args.with_win_next, 1, True, False),
"with_win_prev": (args.with_win_prev, -1, True, False),
"send_win_next": (args.send_win_next, 1, True, True),
"send_win_prev": (args.send_win_prev, -1, True, True),
}
registered = {}
for name, (binding, direction, with_window, send_only) in actions.items():
if not binding:
continue
response = sock.register_binding(binding, mode="press", exec_always=True)
binding_id = response["binding-id"]
registered[binding_id] = (name, direction, with_window, send_only)
print(f"registered {name}: {binding} ({binding_id})")
def unregister_and_exit(signum, frame):
for binding_id in registered:
sock.unregister_binding(binding_id)
raise SystemExit(0)
signal.signal(signal.SIGINT, unregister_and_exit)
signal.signal(signal.SIGTERM, unregister_and_exit)
while True:
msg = sock.read_next_event()
if msg.get("event") != "command-binding":
continue
action = registered.get(msg.get("binding-id"))
if action is None:
continue
name, direction, with_window, send_only = action
try:
switch_linear(sock, direction, with_window, send_only)
except Exception as error:
print(f"{name}: {error}", file=sys.stderr)
if __name__ == "__main__":
raise SystemExit(main()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Similar to left/right but based on workspace number (instead of location), so jump to next row instead stay on last / wrap to first column in current row.