diff options
author | Thomas Letan <lthms@soap.coffee> | 2022-08-27 16:35:15 +0200 |
---|---|---|
committer | Thomas Letan <lthms@soap.coffee> | 2022-08-27 16:35:15 +0200 |
commit | d1d43098a9121c315d9a602eb148f5f5668b1c5c (patch) | |
tree | 12889e017aa408a96436008f783bb4df3f5551ce | |
parent | Rename 'Spatial_sway_ipc' into 'Spatial_ipc' (diff) |
Add a command to fetch the list of windows in the current workspace
-rw-r--r-- | bin/spatial/state.ml | 18 | ||||
-rw-r--r-- | bin/spatialmsg/main.ml | 26 | ||||
-rw-r--r-- | lib/spatial_ipc/dune | 2 | ||||
-rw-r--r-- | lib/spatial_ipc/spatial_ipc.ml | 38 | ||||
-rw-r--r-- | lib/spatial_ipc/spatial_ipc.mli | 8 |
5 files changed, 84 insertions, 8 deletions
diff --git a/bin/spatial/state.ml b/bin/spatial/state.ml index f592b5b..8b67191 100644 --- a/bin/spatial/state.ml +++ b/bin/spatial/state.ml @@ -183,7 +183,23 @@ let client_command_handle : true, None ) in - (Some res, ()) + (Some res, { success = true }) + | Get_windows -> ( + let ribbon = + Workspaces_registry.find state.current_workspace state.workspaces + in + ( None, + match ribbon.visible with + | Some (f, l) -> + { + focus = Some f; + windows = + List.map + (fun id -> + (Windows_registry.find id state.windows).app_id) + (l @ ribbon.hidden); + } + | None -> { focus = None; windows = [] } )) : _ * a) let pp fmt state = diff --git a/bin/spatialmsg/main.ml b/bin/spatialmsg/main.ml index e5357d6..3c3062a 100644 --- a/bin/spatialmsg/main.ml +++ b/bin/spatialmsg/main.ml @@ -1,5 +1,27 @@ open Spatial_ipc let () = - let cmd = Sys.argv.(1) |> command_of_string_exn in - Lwt_main.run (send_command (Run_command cmd)) + Clap.description "A client to communicate with a Spatial instance."; + + let ty = Clap.default_string ~short:'t' ~last:true "run_command" in + + match ty with + | "run_command" -> + let cmd = Clap.mandatory_string ~placeholder:"CMD" () in + Clap.close (); + + let cmd = command_of_string_exn cmd in + let { success } = Lwt_main.run (send_command (Run_command cmd)) in + if not success then exit 1 + | "get_windows" -> + Clap.close (); + + let reply = Lwt_main.run (send_command Get_windows) in + List.iteri + (fun idx name -> + Format.printf "- %s%s%s\n" + (if reply.focus = Some idx then "*" else "") + name + (if reply.focus = Some idx then "*" else "")) + reply.windows + | _ -> exit 2 diff --git a/lib/spatial_ipc/dune b/lib/spatial_ipc/dune index fd055c2..f44e3d3 100644 --- a/lib/spatial_ipc/dune +++ b/lib/spatial_ipc/dune @@ -1,4 +1,4 @@ (library (name spatial_ipc) (public_name spatial-sway.ipc) - (libraries mltp-ipc)) + (libraries mltp-ipc data-encoding)) diff --git a/lib/spatial_ipc/spatial_ipc.ml b/lib/spatial_ipc/spatial_ipc.ml index 66444c9..3c471ba 100644 --- a/lib/spatial_ipc/spatial_ipc.ml +++ b/lib/spatial_ipc/spatial_ipc.ml @@ -65,14 +65,44 @@ let command_to_string = function | Maximize switch -> Format.sprintf "maximize %s" (switch_to_string switch) | Split op -> Format.sprintf "split %s" (operation_to_string op) -type 'a t = Run_command : command -> unit t +type run_command_reply = { success : bool } + +let run_command_reply_encoding = + let open Data_encoding in + conv + (fun { success } -> success) + (fun success -> { success }) + (obj1 (req "success" bool)) + +type get_windows_reply = { focus : int option; windows : string list } + +let get_windows_reply_encoding : get_windows_reply Data_encoding.t = + let open Data_encoding in + conv + (fun { focus; windows } -> (focus, windows)) + (fun (focus, windows) -> { focus; windows }) + (obj2 (opt "focus" int31) (req "windows" @@ list string)) + +type 'a t = + | Run_command : command -> run_command_reply t + | Get_windows : get_windows_reply t + +let reply_encoding : type a. a t -> a Data_encoding.t = function + | Run_command _ -> run_command_reply_encoding + | Get_windows -> get_windows_reply_encoding let reply_to_string : type a. a t -> a -> string = - fun cmd reply -> match (cmd, reply) with Run_command _, () -> "" + fun cmd reply -> + Data_encoding.Json.(to_string (construct (reply_encoding cmd) reply)) let reply_of_string : type a. a t -> string -> a option = fun cmd reply -> - match (cmd, reply) with Run_command _, "" -> Some () | _, _ -> None + let open Data_encoding.Json in + try + match from_string reply with + | Ok json -> Some (destruct (reply_encoding cmd) json) + | _ -> None + with _ -> None let reply_of_string_exn cmd reply = match reply_of_string cmd reply with @@ -81,12 +111,14 @@ let reply_of_string_exn cmd reply = let to_raw_message : type a. a t -> Raw_message.t = function | Run_command cmd -> (0l, command_to_string cmd) + | Get_windows -> (1l, "") type packed = Packed : 'a t -> packed let of_raw_message (op, payload) = match op with | 0l -> (fun x -> Packed (Run_command x)) <$> command_of_string payload + | 1l -> Some (Packed Get_windows) | _ -> None exception Spatial_ipc_error of Socket.error diff --git a/lib/spatial_ipc/spatial_ipc.mli b/lib/spatial_ipc/spatial_ipc.mli index a99592f..c60d5e8 100644 --- a/lib/spatial_ipc/spatial_ipc.mli +++ b/lib/spatial_ipc/spatial_ipc.mli @@ -19,7 +19,13 @@ val command_of_string : string -> command option val command_of_string_exn : string -> command (** @raise [Invalid_argument] *) -type 'a t = Run_command : command -> unit t +type run_command_reply = { success : bool } +type get_windows_reply = { focus : int option; windows : string list } + +type 'a t = + | Run_command : command -> run_command_reply t + | Get_windows : get_windows_reply t + type socket val connect : unit -> socket Lwt.t |