Module: Plushie::Runtime::Windows
- Defined in:
- lib/plushie/runtime/windows.rb
Overview
Window lifecycle management for the Plushie runtime.
Detects window nodes in the UI tree, opens/closes/updates windows via the bridge, and tracks the set of active window IDs.
Constant Summary collapse
- WINDOW_PROP_KEYS =
Window setting keys that can be specified as node props on window elements.
%i[ title size width height position min_size max_size maximized fullscreen visible resizable closeable minimizable decorations transparent blur level exit_on_close_request scale_factor theme ].freeze
Class Method Summary collapse
-
.apply_ops(runtime, ops, tracked_windows) ⇒ Array(Set<String>, bool)
Apply planned window operations, updating tracked windows only after each operation is accepted by the bridge.
- .collect_window_ids(node, ids) ⇒ Object
- .decompose_nested_size(props, key) ⇒ Object
- .decompose_size(props) ⇒ Object
- .decompose_size_tuples(props) ⇒ Object
-
.detect_windows(tree) ⇒ Set<String>
Detect window node IDs from the tree.
-
.extract_window_props(tree, window_id) ⇒ Hash
Extract window-related props from a window node in the tree.
- .find_window_node(node, window_id) ⇒ Object
-
.plan_sync(runtime, new_tree, previous_tree, tracked_windows) ⇒ Array(Set<String>, Array<Hash>)
Plan window synchronization without sending anything to the renderer.
-
.sync_windows(runtime, new_tree, previous_tree, tracked_windows) ⇒ Set<String>
Synchronize tracked windows with the current tree.
Class Method Details
.apply_ops(runtime, ops, tracked_windows) ⇒ Array(Set<String>, bool)
Apply planned window operations, updating tracked windows only after each operation is accepted by the bridge.
whether any operation was accepted by the bridge
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 |
# File 'lib/plushie/runtime/windows.rb', line 86 def self.apply_ops(runtime, ops, tracked_windows) accepted = false ops.each do |op| op_name = op.fetch(:op) window_id = op.fetch(:window_id) settings = op.fetch(:settings) if op_name == "open" base_settings = begin runtime.app.window_config(runtime.model) rescue => e runtime.logger.warn("plushie: window_config error: #{e.class}: #{e.}") {} end settings = base_settings.merge(settings) end runtime.bridge_send_window_op(op_name, window_id, settings) accepted = true case op_name when "open" tracked_windows.add(window_id) when "close" tracked_windows.delete(window_id) end end [tracked_windows, accepted] end |
.collect_window_ids(node, ids) ⇒ Object
134 135 136 137 138 139 |
# File 'lib/plushie/runtime/windows.rb', line 134 def self.collect_window_ids(node, ids) ids << node.id if node.type == "window" return unless node.respond_to?(:children) && node.children node.children.each { |child| collect_window_ids(child, ids) } end |
.decompose_nested_size(props, key) ⇒ Object
170 171 172 173 174 175 |
# File 'lib/plushie/runtime/windows.rb', line 170 def self.decompose_nested_size(props, key) val = props[key] return props unless val.is_a?(Array) && val.length == 2 props.merge(key => {width: val[0], height: val[1]}) end |
.decompose_size(props) ⇒ Object
160 161 162 163 164 165 166 167 168 |
# File 'lib/plushie/runtime/windows.rb', line 160 def self.decompose_size(props) size = props[:size] return props unless size.is_a?(Array) && size.length == 2 props = props.except(:size) props[:width] ||= size[0] props[:height] ||= size[1] props end |
.decompose_size_tuples(props) ⇒ Object
154 155 156 157 158 |
# File 'lib/plushie/runtime/windows.rb', line 154 def self.decompose_size_tuples(props) props = decompose_size(props) props = decompose_nested_size(props, :min_size) decompose_nested_size(props, :max_size) end |
.detect_windows(tree) ⇒ Set<String>
Detect window node IDs from the tree.
21 22 23 24 25 26 27 |
# File 'lib/plushie/runtime/windows.rb', line 21 def self.detect_windows(tree) return Set.new unless tree ids = [] collect_window_ids(tree, ids) Set.new(ids) end |
.extract_window_props(tree, window_id) ⇒ Hash
Extract window-related props from a window node in the tree.
121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/plushie/runtime/windows.rb', line 121 def self.extract_window_props(tree, window_id) return {} unless tree node = find_window_node(tree, window_id) return {} unless node props = node.props .select { |k, _| WINDOW_PROP_KEYS.include?(k.to_sym) } .to_h { |k, v| [k.to_sym, v] } decompose_size_tuples(props) end |
.find_window_node(node, window_id) ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/plushie/runtime/windows.rb', line 141 def self.find_window_node(node, window_id) return node if node.type == "window" && node.id == window_id if node.respond_to?(:children) && node.children node.children.each do |child| found = find_window_node(child, window_id) return found if found end end nil end |
.plan_sync(runtime, new_tree, previous_tree, tracked_windows) ⇒ Array(Set<String>, Array<Hash>)
Plan window synchronization without sending anything to the renderer.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/plushie/runtime/windows.rb', line 53 def self.plan_sync(runtime, new_tree, previous_tree, tracked_windows) new_windows = detect_windows(new_tree) opened = new_windows - tracked_windows closed = tracked_windows - new_windows surviving = tracked_windows & new_windows ops = [] opened.each do |window_id| per_window_props = extract_window_props(new_tree, window_id) ops << {op: "open", window_id:, settings: per_window_props} end closed.each do |window_id| ops << {op: "close", window_id:, settings: {}} end surviving.each do |window_id| old_props = extract_window_props(previous_tree, window_id) new_props = extract_window_props(new_tree, window_id) ops << {op: "update", window_id:, settings: new_props} if old_props != new_props end [new_windows, ops] end |
.sync_windows(runtime, new_tree, previous_tree, tracked_windows) ⇒ Set<String>
Synchronize tracked windows with the current tree.
Opens new windows (calling window_config for base settings), closes removed windows, and sends update ops for windows whose props changed.
40 41 42 43 44 |
# File 'lib/plushie/runtime/windows.rb', line 40 def self.sync_windows(runtime, new_tree, previous_tree, tracked_windows) _new_windows, ops = plan_sync(runtime, new_tree, previous_tree, tracked_windows) next_tracked_windows, _accepted = apply_ops(runtime, ops, tracked_windows) next_tracked_windows end |