terminal user interface to jujutsu. Focused on speed and clarity
9
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix potentially re-focusing trying to fix focus issues

+51 -13
+2 -1
flake.nix
··· 188 188 duneVersion = "3"; 189 189 src = ./forks/nottui/.; 190 190 buildInputs = with ocamlPackages; [ 191 - signal 191 + logs 192 + signal 192 193 lwd 193 194 notty-mine 194 195 seq
+2
forks/nottui/dune-project
··· 31 31 (= :version)) 32 32 (notty 33 33 (>= 0.2)) 34 + (logs 35 + (>= 0.7.0)) 34 36 (cbor :with-test) ; for the examples 35 37 (containers :with-test))) 36 38
+1 -1
forks/nottui/lib/nottui/dune
··· 4 4 (name nottui) 5 5 (public_name nottui) 6 6 (wrapped true) 7 - (libraries lwd notty notty.unix signal) 7 + (libraries lwd notty notty.unix signal logs) 8 8 )
+39 -4
forks/nottui/lib/nottui/nottui_main.ml
··· 1 1 open Notty 2 2 open Lwd_utils 3 + module Log = (val Logs.src_log (Logs.Src.create "nottui")) 3 4 4 5 module Focus : sig 5 6 type var = int Lwd.var ··· 29 30 val has_focus : status -> bool 30 31 val merge : status -> status -> status 31 32 end = struct 33 + let () = () 34 + 32 35 (*The focus system works by having a clock which changes each time the focus changes. An item has focus so long as its `var` is greater than 0 33 36 When we render the UI we go through and set anything with a focus value not matching that of the clock to 0 *) 34 37 ··· 57 60 let peek_has_focus (h : handle) : bool = fst h |> Lwd.peek > 0 58 61 let clock = ref 0 59 62 let currently_focused : var ref = ref (make () |> fst) 60 - let focus_stack : var Stack.t = Stack.create () 63 + let focus_stack : var list ref = ref [] 61 64 62 65 let request_var (v : var) = 63 66 incr clock; ··· 72 75 Lwd.set v 0 73 76 ;; 74 77 78 + let var_equal a b = Lwd.peek a = Lwd.peek b 79 + 75 80 let request_reversable ((v, _) : handle) = 76 - focus_stack |> Stack.push !currently_focused; 77 - request_var v 81 + Log.debug (fun m -> m "Maybe requesting revesable focus %d" (Lwd.peek v)); 82 + if not @@ var_equal !currently_focused v 83 + then ( 84 + focus_stack := !currently_focused :: !focus_stack; 85 + request_var v; 86 + Log.debug (fun m -> m "Requested reversable focus %d" (Lwd.peek v))) 78 87 ;; 79 88 80 89 let release_reversable ((v, _) : handle) = 90 + Log.debug (fun m -> m "Maybe release or remove %d from reversable focus stack" (Lwd.peek v)); 81 91 (* we should only release if we actually have the focus*) 82 - if Lwd.peek v > 0 then focus_stack |> Stack.pop_opt |> Option.iter request_var 92 + if var_equal !currently_focused v 93 + then ( 94 + (*just load the last item in the stack *) 95 + match !focus_stack with 96 + | hd :: tl -> 97 + request_var hd; 98 + Log.debug (fun m -> m "Released reversable focus %d in echange form %d" (Lwd.peek v) (Lwd.peek v)); 99 + focus_stack := tl 100 + | _ -> ()) 101 + else ( 102 + (*we might be in the stack and we should be removed*) 103 + let rec loop start stack = 104 + match stack with 105 + | hd :: tl -> 106 + if hd == v 107 + then ( 108 + (* we find an instance of the handle we are trying to release in our focus stack 109 + *) 110 + (*request focus for the next item in the stack if it's at the head*) 111 + (*update the stack with the new focus*) 112 + Log.debug (fun m -> m "Removed %d from reversable focus stack" (Lwd.peek v)); 113 + focus_stack := List.rev start @ tl) 114 + else loop (hd :: start) tl 115 + | _ -> () 116 + in 117 + loop [] !focus_stack) 83 118 ;; 84 119 85 120 let merge s1 s2 : status =
+3 -1
forks/nottui/lib/nottui/nottui_main.mli
··· 48 48 "more". *) 49 49 50 50 (** Request the focus and add to the focus stack. 51 - WARNING: The focus stack is global, if you render multiple nottui ui's you may not want to use this *) 51 + WARNING: The focus stack is global, if you render multiple nottui ui's you may not want to use this 52 + NOTE: Calling this twice has the same result as calling it once. Trying to focus the currently focused item will not add to the stack*) 53 + 52 54 val request_reversable : handle -> unit 53 55 54 56 (** Release the focus (if the handle has it) and restore the last focus on the stack *)
+4 -6
forks/nottui/lib/nottui/widgets/overlays.ml
··· 225 225 match show_popup with 226 226 | Some (content, label) -> 227 227 let ui = 228 - let$ status = Focus.status focus 229 - and$ prompt_field = content in 230 - if not (Focus.has_focus status) then Focus.request_reversable focus; 228 + let$ prompt_field = content in 229 + Focus.request_reversable focus; 231 230 prompt_field |> Ui.resize ~w:5 ~sw:1 232 231 in 233 232 ui |> BB.focusable ~focus ~label_top:label ?on_key |> clear_bg 234 233 | None -> 235 - let$ status = Focus.status focus in 236 - if Focus.has_focus status then Focus.release_reversable focus; 237 - Ui.empty 234 + Focus.release_reversable focus; 235 + Ui.empty |> Lwd.pure 238 236 in 239 237 W.zbox [ ui; popup_ui |>$ Ui.resize ~crop:neutral_grav ~pad:neutral_grav ] 240 238 ;;