package oxbow
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Dynamic window manager for the river Wayland compositor
Install
dune-project
Dependency
Authors
Maintainers
Sources
v0.1.0.tar.gz
md5=a637acaa0e19046cd65fff733874eb97
sha512=76230cbecd7510de7a05b5d1f335915ef7b6c4aa557d8dbfd23591606618d2cfa25082d17b93f2f4b53a118d1cbf6a80e4ad51cf0f099b4921fb83d6df0c9801
doc/src/oxbow.ops/targets.ml.html
Source file targets.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144open! Oxbow_core open! Oxbow_state open! Result.Syntax let outputs_by_recency (wm : Wm.t) (seat : Seat.t) = match seat.output with | None -> wm.outputs | Some o -> o :: List.filter (( != ) o) wm.outputs ;; let windows_by_recency wm seat = let stacks = outputs_by_recency wm seat in let ordered = List.(map (fun (o : Output.t) -> o.focus_stack) stacks |> flatten) in let orphans = List.filter (fun (w : Window.t) -> Option.is_none w.output) wm.windows in ordered @ orphans ;; let no_match kind to_string m = Error (Printf.sprintf "no %s matching %s" kind (to_string m)) ;; let matched_windows wm seat (wmatch : Window_match.t) = let* matches = Window_pattern.compile wmatch.pattern in let+ windows = Window_scope.filter wm seat wmatch.scope in let hits = windows_by_recency wm seat |> List.filter (fun w -> List.memq w windows && Window_scope.holds matches w) in matches, windows, hits ;; let matched_outputs wm seat (omatch : Output_match.t) = let+ matches = Output_match.compile omatch in let hits = outputs_by_recency wm seat |> List.filter (fun (o : Output.t) -> matches ~name:o.name ~labels:o.labels) in matches, hits ;; let return_window_cycle seat matches scoped ~best = let stable = List.find_all (Window_scope.holds matches) scoped in let next = match Seat.focused_window seat with | Some w when List.memq w stable -> Ring.next_or_first w stable | _ -> List.nth_opt stable 0 in Ok (Option.value next ~default:best) ;; let return_output_cycle (seat : Seat.t) hits ~best = let next = match seat.output with | Some o when List.memq o hits -> Ring.next_or_first o hits | _ -> List.nth_opt hits 0 in Ok (Option.value next ~default:best) ;; let resolve_one_window wm seat (target : Target.Window.One.t) = match target with | Focused -> With.focused_window seat @@ fun _o w -> Ok w | Matching { wmatch; select } -> let* matches, windows, hits = matched_windows wm seat wmatch in (match hits with | [] -> no_match "window" Window_match.to_string wmatch | best :: _ -> if select = Best then Ok best else return_window_cycle seat matches windows ~best) ;; let resolve_one_output wm seat (target : Target.Output.One.t) = match target with | Focused -> With.focused_output seat @@ fun o -> Ok o | Matching { omatch; select } -> let* _, hits = matched_outputs wm seat omatch in (match hits with | [] -> no_match "output" Output_match.to_string omatch | best :: _ -> if select = Best then Ok best else return_output_cycle seat hits ~best) ;; let resolve_all_windows wm seat (target : Target.Window.Any.t) = match target with | One o -> let+ w = resolve_one_window wm seat o in [ w ] | All { wmatch } -> let* _, _, hits = matched_windows wm seat wmatch in (match hits with | [] -> no_match "window" Window_match.to_string wmatch | _ -> Ok hits) ;; let resolve_all_outputs wm seat (target : Target.Output.Any.t) = match target with | One o -> let+ o = resolve_one_output wm seat o in [ o ] | All { omatch } -> let* _, hits = matched_outputs wm seat omatch in (match hits with | [] -> no_match "output" Output_match.to_string omatch | _ -> Ok hits) ;; let transact windows plan = let+ rev_actions = List.fold_left (fun acc w -> Result.bind acc @@ fun actions -> Result.bind (plan w) @@ fun action -> Ok (action :: actions)) (Ok []) windows in (* The actions run reversed of the window order. This is depended on by [Stacking.push], which puts the first window on top. If the actions were in window order, the last window would be the head. *) List.iter (fun action -> action ()) rev_actions; windows ;; let transact_all_windows wm seat target ~plan = let* windows = resolve_all_windows wm seat target in transact windows plan ;; let transact_all_outputs wm seat target ~plan = let* outputs = resolve_all_outputs wm seat target in transact outputs plan ;; let apply_one bind wm seat target plan = let* x = bind wm seat target in let+ action = plan x in action (); x ;; let transact_one_window wm seat target ~plan = apply_one resolve_one_window wm seat target plan ;; let transact_one_output wm seat target ~plan = apply_one resolve_one_output wm seat target plan ;;
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>