diff options
author | Thomas Letan <lthms@soap.coffee> | 2022-08-30 22:26:13 +0200 |
---|---|---|
committer | Thomas Letan <lthms@soap.coffee> | 2022-08-30 22:26:13 +0200 |
commit | a7c9ae0b105c6b09aa22e80a0fa94662ea832dc5 (patch) | |
tree | c4e8ae209d651ce3c3ab05af1b71c93a6b24e5c6 | |
parent | Abstract polling ready file descriptors into a nice fold (diff) |
Introduce a command to jump to a given window
The intended user of this command is a custom module of waybar, to
allow a on-click event.
We use this opportunity to prefer next/prev over left/right to use the
same type for workspaces-related commands.
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | bin/spatial/ribbon.ml | 24 | ||||
-rw-r--r-- | bin/spatial/state.ml | 20 | ||||
-rw-r--r-- | bin/spatialmsg/main.ml | 12 | ||||
-rw-r--r-- | lib/spatial_ipc/spatial_ipc.ml | 46 | ||||
-rw-r--r-- | lib/spatial_ipc/spatial_ipc.mli | 13 |
6 files changed, 90 insertions, 33 deletions
@@ -23,16 +23,16 @@ exec $spatialmsg # focus is on the last window on the left of the visible area, windows # will shift right to make room for the next candidate on the loop, # and the window on the far right will disappear. -bindsym $mod+t exec $spatialmsg "focus left" +bindsym $mod+t exec $spatialmsg "focus prev" # Same thing, for the right. -bindsym $mod+n exec $spatialmsg "focus right" +bindsym $mod+n exec $spatialmsg "focus next" # Move the focused window on the left, shift the loop if necessary. -bindsym $mod+Shift+t exec $spatialmsg "move left" +bindsym $mod+Shift+t exec $spatialmsg "move prev" # Move the focused window on the right, shift the loop if necessary. -bindsym $mod+Shift+n exec $spatialmsg "move right" +bindsym $mod+Shift+n exec $spatialmsg "move next" # Toggle between a mode where only one window is visible (maximized # mode), or a fixed numbers (split mode). spatial-sway will remember diff --git a/bin/spatial/ribbon.ml b/bin/spatial/ribbon.ml index 24777ac..5af50c1 100644 --- a/bin/spatial/ribbon.ml +++ b/bin/spatial/ribbon.ml @@ -165,13 +165,25 @@ let move_focus_right ribbon = let x, l = pop_front_exn l in { ribbon with visible = Some (f, push_back x l) }) -let split_visible ribbon = - let rec split_visible acc f = function - | x :: rst when f = 0 -> Some (List.rev acc, x, rst) - | x :: rst -> split_visible (x :: acc) (f - 1) rst - | [] -> raise (Invalid_argument "Ribbon.split_visible") +let rec focus_index ribbon index = + match ribbon.visible with + | Some (_, l) when index < List.length l -> + { ribbon with visible = Some (index, l) } + | Some (_, l) when index < List.length l + List.length ribbon.hidden -> + let ribbon = move_focus_right ribbon in + focus_index ribbon (index - 1) + | _ -> ribbon + +let split_at l i = + let rec split_visible acc i = function + | x :: rst when i = 0 -> Some (List.rev acc, x, rst) + | x :: rst -> split_visible (x :: acc) (i - 1) rst + | [] -> raise (Invalid_argument "Ribbon.split_at") in - match ribbon.visible with None -> None | Some (f, l) -> split_visible [] f l + split_visible [] i l + +let split_visible ribbon = + match ribbon.visible with None -> None | Some (f, l) -> split_at l f let move_window_left ribbon = match split_visible ribbon with diff --git a/bin/spatial/state.ml b/bin/spatial/state.ml index e978166..2b4f994 100644 --- a/bin/spatial/state.ml +++ b/bin/spatial/state.ml @@ -27,6 +27,16 @@ let insert_window default_full_view default_maximum_visible workspace window Windows_registry.register window { app_id; workspace } state.windows; } +let focus_index workspace state index = + { + state with + workspaces = + Workspaces_registry.update workspace + (function + | Some ribbon -> Some (Ribbon.focus_index ribbon index) | None -> None) + state.workspaces; + } + let toggle_full_view workspace state = { state with @@ -138,7 +148,7 @@ let client_command_handle : | Run_command cmd -> let res = match cmd with - | Focus Left -> + | Focus Prev -> ( { state with workspaces = @@ -150,7 +160,7 @@ let client_command_handle : }, true, None ) - | Focus Right -> + | Focus Next -> ( { state with workspaces = @@ -162,9 +172,11 @@ let client_command_handle : }, true, None ) - | Move Left -> + | Focus (Index x) -> + (focus_index state.current_workspace state x, true, None) + | Move Prev -> (move_window_left state.current_workspace state, true, None) - | Move Right -> + | Move Next -> (move_window_right state.current_workspace state, true, None) | Maximize Toggle -> (toggle_full_view state.current_workspace state, true, None) diff --git a/bin/spatialmsg/main.ml b/bin/spatialmsg/main.ml index 9e7be1b..057b536 100644 --- a/bin/spatialmsg/main.ml +++ b/bin/spatialmsg/main.ml @@ -21,9 +21,17 @@ let () = match (cmd, reply.focus) with | Some idx, Some focus when idx < List.length reply.windows -> - let name = List.nth reply.windows idx in + let tooltip = List.nth reply.windows idx in + let name = + match tooltip with + | "firefox" -> "" + | "kitty" -> "" + | "Slack" -> "" + | "emacs" -> "" + | _ -> " " ^ tooltip + in let cls = if idx = focus then "focus" else "unfocus" in - Format.(printf "%s\n%s\n%s" name name cls) + Format.(printf "%s\n%s\n%s" name tooltip cls) | Some _, _ -> () | None, _ -> List.iteri diff --git a/lib/spatial_ipc/spatial_ipc.ml b/lib/spatial_ipc/spatial_ipc.ml index 662582a..a574fc1 100644 --- a/lib/spatial_ipc/spatial_ipc.ml +++ b/lib/spatial_ipc/spatial_ipc.ml @@ -7,14 +7,30 @@ open Mltp_ipc let socket_path = "/tmp/spatial-sway.socket" let magic_string = "spatial-ipc" -type direction = Left | Right - -let direction_of_string_opt = function - | "left" -> Some Left - | "right" -> Some Right - | _ -> None - -let direction_to_string = function Left -> "left" | Right -> "right" +type focus = Focus_kind +type move = Move_kind + +type 'kind target = + | Prev : 'kind target + | Next : 'kind target + | Index : int -> focus target + +let restrict_move_target : 'k target -> move target option = function + | Index _ -> None + | Next -> Some Next + | Prev -> Some Prev + +let target_of_string_opt = function + | "prev" -> Some Prev + | "next" -> Some Next + | x -> + Option.bind (int_of_string_opt x) @@ fun x -> + if 0 <= x then Some (Index x) else None + +let target_to_string : type kind. kind target -> string = function + | Prev -> "prev" + | Next -> "next" + | Index x -> string_of_int x type switch = On | Off | Toggle @@ -36,8 +52,8 @@ let operation_of_string_opt = function let operation_to_string = function Incr -> "increment" | Decr -> "decrement" type command = - | Focus of direction - | Move of direction + | Focus of focus target + | Move of move target | Maximize of switch | Split of operation @@ -47,8 +63,10 @@ let command_of_string str = String.split_on_char ' ' str |> List.filter (function "" -> false | _ -> true) |> function - | [ "focus"; dir ] -> (fun x -> Focus x) <$> direction_of_string_opt dir - | [ "move"; dir ] -> (fun x -> Move x) <$> direction_of_string_opt dir + | [ "focus"; target ] -> (fun x -> Focus x) <$> target_of_string_opt target + | [ "move"; target ] -> + Option.bind (target_of_string_opt target) @@ fun target -> + (fun x -> Move x) <$> restrict_move_target target | [ "maximize"; switch ] -> (fun x -> Maximize x) <$> switch_of_string_opt switch | [ "split"; op ] -> (fun x -> Split x) <$> operation_of_string_opt op @@ -60,8 +78,8 @@ let command_of_string_exn str = | None -> raise (Invalid_argument "Spatial_ipc.command_of_string_exn") let command_to_string = function - | Focus dir -> Format.sprintf "focus %s" (direction_to_string dir) - | Move dir -> Format.sprintf "move %s" (direction_to_string dir) + | Focus dir -> Format.sprintf "focus %s" (target_to_string dir) + | Move dir -> Format.sprintf "move %s" (target_to_string dir) | Maximize switch -> Format.sprintf "maximize %s" (switch_to_string switch) | Split op -> Format.sprintf "split %s" (operation_to_string op) diff --git a/lib/spatial_ipc/spatial_ipc.mli b/lib/spatial_ipc/spatial_ipc.mli index d742867..6a00c14 100644 --- a/lib/spatial_ipc/spatial_ipc.mli +++ b/lib/spatial_ipc/spatial_ipc.mli @@ -4,13 +4,20 @@ val socket_path : string -type direction = Left | Right +type focus = Focus_kind +type move = Move_kind + +type 'kind target = + | Prev : 'kind target + | Next : 'kind target + | Index : int -> focus target + type switch = On | Off | Toggle type operation = Incr | Decr type command = - | Focus of direction - | Move of direction + | Focus of focus target + | Move of move target | Maximize of switch | Split of operation |