diff --git a/forks/nottui/lib/nottui/nottui_main.ml b/forks/nottui/lib/nottui/nottui_main.ml index 8d6abe9..061e724 100644 --- a/forks/nottui/lib/nottui/nottui_main.ml +++ b/forks/nottui/lib/nottui/nottui_main.ml @@ -61,6 +61,10 @@ end = struct let clock = ref 0 let currently_focused : var ref = ref (make () |> fst) let focus_stack : var list ref = ref [] + let focus_stack_to_str ()= + (!focus_stack|>List.map Lwd.peek|>List.map (string_of_int)|>String.concat ","|>Printf.sprintf "[%s]") + + let focusLock= Mutex.create() let request_var (v : var) = incr clock; @@ -68,27 +72,33 @@ end = struct currently_focused := v ;; - let request ((v, _) : handle) = request_var v + let request ((v, _) : handle) = + Mutex.protect focusLock @@ fun _-> + request_var v let release ((v, _) : handle) = + Mutex.protect focusLock @@ fun _-> incr clock; Lwd.set v 0 ;; let var_equal a b = Lwd.peek a = Lwd.peek b + let request_reversable ((v, _) : handle) = - Log.debug (fun m -> m "Maybe requesting revesable focus %d" (Lwd.peek v)); + Mutex.protect focusLock @@ fun _-> + Log.debug (fun m -> m "Maybe requesting reversable focus %d" (Lwd.peek v)); if not @@ var_equal !currently_focused v then ( focus_stack := !currently_focused :: !focus_stack; request_var v; - Log.debug (fun m -> m "Requested reversable focus %d" (Lwd.peek v))) + Log.debug (fun m -> m "Requested reversable focus %d. stack:%s" (Lwd.peek v) (focus_stack_to_str ()))) ;; let release_reversable ((v, _) : handle) = + (* Mutex.protect focusLock @@ fun _-> *) Log.debug (fun m -> - m "Maybe release or remove %d from reversable focus stack" (Lwd.peek v)); + m "Maybe release or remove %d from reversable focus stack. stack: %s" (Lwd.peek v) (focus_stack_to_str ())); (* we should only release if we actually have the focus*) if var_equal !currently_focused v then ( @@ -97,7 +107,7 @@ end = struct | hd :: tl -> request_var hd; Log.debug (fun m -> - m "Released reversable focus %d in echange form %d" (Lwd.peek v) (Lwd.peek v)); + m "Released reversable focus %d in exchange for: %d" (Lwd.peek v) (Lwd.peek hd)); focus_stack := tl | _ -> ()) else ( diff --git a/forks/nottui/lib/nottui/widgets/overlays.ml b/forks/nottui/lib/nottui/widgets/overlays.ml index 3e765c3..424b22e 100644 --- a/forks/nottui/lib/nottui/widgets/overlays.ml +++ b/forks/nottui/lib/nottui/widgets/overlays.ml @@ -3,6 +3,7 @@ open Nottui_main open Shared open Lwd_infix +module Log = (val Logs.src_log (Logs.Src.create "nottui_widgets")) open struct module BB = Border_box @@ -225,8 +226,8 @@ let popup ?(focus = Focus.make ()) ?on_key ~show_popup_var ui = match show_popup with | Some (content, label) -> let ui = - let$ prompt_field = content in Focus.request_reversable focus; + let$ prompt_field = content in prompt_field |> Ui.resize ~w:5 ~sw:1 in ui diff --git a/jj_tui/bin/global_vars.ml b/jj_tui/bin/global_vars.ml index e77f72a..42b7256 100644 --- a/jj_tui/bin/global_vars.ml +++ b/jj_tui/bin/global_vars.ml @@ -68,6 +68,7 @@ module type Vars = sig val get_active_revs : unit -> string list val get_active_revs_lwd : unit -> string list Lwd.t val config : Config.t Lwd.var + val show_popup: ((ui Lwd.t * string) option ) ->unit end module Vars : Vars = struct @@ -102,6 +103,7 @@ module Vars : Vars = struct let term_width_height : (int * int) Lwd.var = Lwd.var (0, 0) let get_term () = Option.get !term + let reset_selection () = Flock.fork(fun _ -> Picos_std_structured.Control.sleep ~seconds:0.7; @@ -144,5 +146,8 @@ module Vars : Vars = struct else selected |> List.map get_unique_id ;; + let show_popup popup= + [%log debug "setting show popup"]; + Lwd.set ui_state.show_popup popup let config = ui_state.config end diff --git a/jj_tui/bin/graph_commands.ml b/jj_tui/bin/graph_commands.ml index f1ed2f8..6d8b7db 100644 --- a/jj_tui/bin/graph_commands.ml +++ b/jj_tui/bin/graph_commands.ml @@ -41,8 +41,8 @@ module Make (Vars : Global_vars.Vars) = struct (fun () -> Fun (fun _ -> - ui_state.show_popup - $= Some (commands_list_ui ~include_arrows:true (get_commands ()), "Help"); + show_popup + @@ Some (commands_list_ui ~include_arrows:true (get_commands ()), "Help"); ui_state.input $= `Mode (fun _ -> `Unhandled))) } ; { @@ -288,7 +288,7 @@ module Make (Vars : Global_vars.Vars) = struct Fun (fun _ -> ui_state.input $= `Normal; - ui_state.show_popup $= None) + show_popup None) } ] |> List.map (fun x -> x.key, x) @@ -304,7 +304,7 @@ module Make (Vars : Global_vars.Vars) = struct |> Lwd.pure in let ui = W.vbox [ log; commands_list_ui subcmds ] in - ui_state.show_popup $= Some (ui, "Git push will:"); + show_popup @@ Some (ui, "Git push will:"); ui_state.input $= `Mode (command_input ~is_sub:true subcmds))) } ; { diff --git a/jj_tui/bin/jj_commands.ml b/jj_tui/bin/jj_commands.ml index 30dad85..589fd23 100644 --- a/jj_tui/bin/jj_commands.ml +++ b/jj_tui/bin/jj_commands.ml @@ -6,6 +6,7 @@ open Jj_tui.Logging open Jj_tui.Key_map open Jj_tui.Key open Jj_tui +open Log (** Internal to this module. I'm trying this out as a way to avoid .mli files*) module Shared = struct @@ -72,6 +73,7 @@ module Intern (Vars : Global_vars.Vars) = struct open Jj_process.Make (Vars) open Notty open Nottui + open Log open! Jj_tui.Util exception Handled @@ -149,8 +151,9 @@ module Intern (Vars : Global_vars.Vars) = struct |> W.Scroll.area ;; - let rec handleCommand description cmd = - [%log info "Handling command: %s" description]; + let rec handleCommand description (cmd:string command_variant) = + [%log + info "Handling command. description: %s" description]; let noOut args = let _ = args in let _result = jj args in @@ -202,52 +205,52 @@ module Intern (Vars : Global_vars.Vars) = struct let send_cmd args = change_view (`Cmd_I args) in match cmd with | Cmd_I args -> - ui_state.show_popup $= None; + show_popup None; send_cmd args; raise Handled | Cmd args -> - ui_state.show_popup $= None; + show_popup None; noOut args; raise Handled | Cmd_r args -> - ui_state.show_popup $= None; + show_popup None; noOut (args @ [ "-r"; Vars.get_hovered_rev () ]); raise Handled | Cmd_with_revs rev_type -> let args, revs = get_revs rev_type in - ui_state.show_popup $= None; + show_popup None; noOut (args @ ("-r" :: revs)); reset_selection_post_cmd rev_type; raise Handled | Prompt (str, args) -> - ui_state.show_popup $= None; + show_popup None; prompt str (`Cmd args); raise Handled | Prompt_r (str, args) -> - ui_state.show_popup $= None; + show_popup None; prompt str (`Cmd (args @ [ "-r"; Vars.get_hovered_rev () ])); raise Handled | PromptThen (label, next) -> - ui_state.show_popup $= None; + show_popup None; (*We run a prompt that then runs our next command when finished*) prompt label @@ `Fun (fun x -> next x |> command_no_input description); raise Handled | Prompt_I (str, args) -> - ui_state.show_popup $= None; + show_popup None; prompt str (`Cmd_I args); raise Handled | Selection_prompt (str, items, predicate, cmd) -> - ui_state.show_popup $= None; + show_popup None; ui_state.show_prompt $= None; prompt_selection str items predicate cmd; raise Handled | Fun func -> - ui_state.show_popup $= None; + show_popup None; func (); Global_funcs.update_status (); raise Handled | SubCmd sub_map -> - ui_state.show_popup $= Some (commands_list_ui sub_map, description); + show_popup @@ Some (commands_list_ui sub_map, description); ui_state.input $= `Mode (command_input ~is_sub:true sub_map); raise Handled | Dynamic f -> @@ -314,8 +317,8 @@ module Make (Vars : Global_vars.Vars) = struct ; cmd = Fun (fun _ -> - ui_state.show_popup - $= Some + show_popup@@ + Some (commands_list_ui ~include_arrows:true (make_default_list ()), "Help"); ui_state.input $= `Mode (fun _ -> `Unhandled)) } diff --git a/jj_tui/bin/jj_ui.ml b/jj_tui/bin/jj_ui.ml index 499278a..a5de275 100644 --- a/jj_tui/bin/jj_ui.ml +++ b/jj_tui/bin/jj_ui.ml @@ -74,7 +74,7 @@ module Make (Vars : Global_vars.Vars) = struct | `Mode _, _, _ -> (match event with | `Escape, [] -> - ui_state.show_popup $= None; + show_popup None; ui_state.input $= `Normal; `Handled | _ -> diff --git a/todo.md b/todo.md index f1858e7..703a41b 100644 --- a/todo.md +++ b/todo.md @@ -43,3 +43,7 @@ I want to capture all invalidation between the last call to stabalize in nottui # Small screen mode: mode that only shows the graph or diff for small screens + + +## Fix focus issues. +I need to use the new variant of Lwd.peek so that we are fetching the latest value when doing the focus switching. mostly the focus comparison is key