Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
window_host.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <pulp/view/view.hpp>
5#include <algorithm>
6#include <cstdint>
7#include <set>
8#include <string>
9#include <memory>
10#include <functional>
11#include <vector>
12
14
15namespace pulp::render {
16class RenderLoop;
17}
18
19namespace pulp::canvas {
20class Canvas;
21}
22
23namespace pulp::view {
24
25class NativeViewHost;
26
27enum class WindowType; // Forward-declared from window_manager.hpp
28
30 struct MenuCommand {
36 std::string menu;
37 std::string title;
39 std::uint16_t modifiers = kModNone;
40 std::function<void()> action;
45 enum class AppMenuSection : std::uint8_t { commands, after_about };
47 };
48
49 std::string title = "Pulp";
50 float width = 400;
51 float height = 300;
52 float min_width = 0;
53 float min_height = 0;
54 bool resizable = true;
55 bool use_gpu = false;
56
65 std::uint32_t background_rgb = 0x1E1E2E;
66
75 bool initially_hidden = false;
76
86 bool secondary_window = false;
87
88 // ── Multi-window hints ──────────────────────────────────────────────
89 // These are used by WindowManager to configure platform-specific
90 // window behavior. Callers creating standalone windows can ignore them.
91
93 void* parent_native_handle = nullptr;
94 void* shared_gpu_device = nullptr;
95
99 std::vector<MenuCommand> menu_commands;
100};
101
102// Native window that hosts a View tree and renders it.
103//
104// Platform support:
105// - macOS: native NSWindow-backed impl in window_host_mac.mm, including
106// native content handles and child-view attach/bounds/detach.
107// - iOS: native UIWindow-backed impl in window_host_ios.mm. The standalone
108// iOS host does not currently expose native child-view embedding.
109// - Windows/Linux/Android: no built-in impl — the host app or a future
110// platform module registers a factory via set_factory(). Without a
111// factory, create() returns nullptr so callers can surface "platform
112// unsupported" through has_factory() rather than a silent null.
114public:
115 struct ContentSize {
116 uint32_t width = 0;
117 uint32_t height = 0;
118 };
119
120 using ResizeCallback = std::function<void(uint32_t width, uint32_t height)>;
121
122 // Create a window hosting the given view tree
123 static std::unique_ptr<WindowHost> create(View& root, const WindowOptions& options);
124
125 // Host-registered factory. Installed by the platform layer of a host app
126 // on non-Apple targets. Apple targets use the built-in native impl and
127 // ignore the factory.
128 using Factory = std::function<std::unique_ptr<WindowHost>(
129 View& root, const WindowOptions& options)>;
130 static void set_factory(Factory factory);
131 static void clear_factory();
132 static bool has_factory();
133
137 virtual ~WindowHost();
138
139 // Show/hide the window
140 virtual void show() = 0;
141 virtual void hide() = 0;
142 virtual bool is_visible() const = 0;
143
144 // Request a repaint immediately. Platform impls translate this to the
145 // native invalidation call (setNeedsDisplay, InvalidateRect, …).
146 virtual void repaint() = 0;
147
148 // ── VBlank-locked safe-repaint ──────────────────────────────────────
149 //
150 // The canonical pattern for "something changed, the UI needs to redraw"
151 // is *"set a dirty flag, repaint on the next frame"* rather than the
152 // legacy periodic-polling pattern (Binding::poll() on a timer).
153 //
154 // mark_dirty() is the consumer entry point. When a RenderLoop has been
155 // attached via attach_render_loop(), it coalesces every call between
156 // two vblanks into exactly one request_frame() — so N state changes in
157 // one frame cost one repaint, locked to the display refresh. When no
158 // RenderLoop is attached it falls through to repaint() so existing
159 // callers keep working unchanged.
160 //
161 // Non-virtual on purpose: the coalescing policy is platform-agnostic
162 // and lives here so every platform host shares one implementation.
164
165 // Bounded variant: accumulate a dirty region (in root/window coordinates)
166 // so a host's paint path can invalidate + composite only the changed area
167 // instead of the whole surface — the "static chrome doesn't re-composite"
168 // win when a single live sub-view (meter, grid, custom overlay) updates.
169 // Schedules a repaint exactly like the no-arg mark_dirty(). A zero/negative
170 // rect, or any call after a full mark_dirty() in the same frame, escalates
171 // to a full repaint. A host that never consults pending_dirty_bounds()
172 // simply repaints in full, so bounded marks are always safe to ignore.
173 void mark_dirty(const Rect& root_rect);
174
175 // Schedule a frame WITHOUT adding damage: for work that changed nothing
176 // yet needs a frame to run (a requestAnimationFrame callback queued by a
177 // message handler). Whatever that frame changes marks its own damage; a
178 // frame that marks nothing repaints in full, as an unbounded one always
179 // has.
181 schedule_repaint();
182 }
183
184 // True when the pending repaint covers the whole surface. Defaults true
185 // (the first frame is always full) and after any no-arg mark_dirty();
186 // becomes false once clear_pending_dirty() runs and only bounded
187 // mark_dirty(rect) calls have arrived since.
188 bool pending_repaint_is_full() const { return damage_.is_full(); }
189
190 // Bounding box (root coords) of the bounded mark_dirty(rect) calls since the
191 // last clear_pending_dirty(). Only meaningful when pending_repaint_is_full()
192 // is false and has_pending_dirty_bounds() is true.
193 bool has_pending_dirty_bounds() const { return damage_.has_bounds(); }
194 Rect pending_dirty_bounds() const { return damage_.bounds(); }
195
196 // Reset the accumulated dirty region. A host calls this after it has
197 // painted and submitted the frame (mirrors DirtyTracker::clear()).
198 void clear_pending_dirty() { damage_.clear(); }
199
200 // Read this frame's damage and clear it in one step, so a host cannot
201 // consult the accessors above and then clear a different logical state.
202 // A frame that does NOT reach its intended output hands the snapshot back
203 // with restore_pending_dirty(). Same contract as PluginViewHost — both
204 // hosts share one PendingDamage.
205 PendingDamage::Snapshot take_pending_dirty() { return damage_.take(); }
207 damage_.restore(snapshot);
208 }
209
210 // Consume the accumulated dirty region and paint `root`, then clear the
211 // pending region. This is the reference consumer for the bounded-invalidation
212 // path (invalidate → accumulate → consume).
213 //
214 // SAFE BY DEFAULT: with `surface_preserves_outside_clip == false` (the
215 // default) this always paints the whole tree — identical to
216 // `root.paint_all(canvas)` plus the clear. Only when the caller AFFIRMS that
217 // its surface preserves the previous frame's content outside the clip does a
218 // bounded (non-full) pending region clip the canvas to pending_dirty_bounds()
219 // so a clip-honoring backend (Skia) skips re-rasterizing static chrome. The
220 // opt-in is a hard requirement, not just advice: clipping a frame whose
221 // surface does NOT preserve outside content (a swapchain that clears each
222 // frame, or any frame invalidated with a full `setNeedsDisplay:YES`) would
223 // leave the static chrome blank. A host earns `true` by invalidating only the
224 // dirty region through the platform's native damage path (AppKit
225 // `setNeedsDisplayInRect:`, an X/Win damage rect, a content-preserving
226 // swapchain) — and by escalating any relayout that MOVES a live sub-view to a
227 // full repaint, so the accumulated bounds can't clip away the sub-view's new
228 // position. `root`'s own background/border fill happens inside paint_all(),
229 // so it is clipped too. Backends that ignore clips still paint correctly.
231 bool surface_preserves_outside_clip = false);
232
233 // Attach (or detach, with nullptr) a vblank-paced RenderLoop that
234 // mark_dirty() should drive. Ownership stays with the caller; the loop
235 // must outlive the host or be detached first. Optional — hosts that
236 // already run their own native display-link loop can leave this unset
237 // and mark_dirty() degrades to a direct repaint().
238 void attach_render_loop(render::RenderLoop* loop) { render_loop_ = loop; }
239
240 // The attached RenderLoop, or nullptr.
241 render::RenderLoop* render_loop() const { return render_loop_; }
242
243 // Native host/window handles for embedding child platform views such as
244 // WebViews. These are instance capabilities, not platform guarantees:
245 // callers must check for non-null handles before attempting native child
246 // embedding. Default implementations return nullptr on hosts that do not
247 // expose native handles.
250 virtual void position_beside(WindowHost* other) { (void)other; }
251
252 virtual void* native_window_handle() const { return nullptr; }
253 virtual void* native_content_view_handle() const { return nullptr; }
254 virtual void* dawn_device_handle() const { return nullptr; }
255 virtual void* dawn_queue_handle() const { return nullptr; }
256 virtual void* dawn_instance_handle() const { return nullptr; }
257 virtual render::GpuSurface* gpu_surface() const { return nullptr; }
258
268 virtual double gpu_render_time_ms() const { return 0.0; }
269
274 virtual bool gpu_render_timing_available() const { return false; }
275
277
278 // Attach/detach a platform-native child view inside this host. Coordinates
279 // use Pulp's top-left origin convention. Returning false is the canonical
280 // unsupported/rejected signal. Non-Apple factory-backed hosts that support
281 // native child embedding must override all three methods and should keep
282 // attachment state in the concrete host.
283 virtual bool attach_native_child_view(void* child_view,
284 float x,
285 float y,
286 float width,
287 float height) {
288 (void) child_view;
289 (void) x;
290 (void) y;
291 (void) width;
292 (void) height;
293 return false;
294 }
295 virtual bool set_native_child_view_bounds(void* child_view,
296 float x,
297 float y,
298 float width,
299 float height) {
300 (void) child_view;
301 (void) x;
302 (void) y;
303 (void) width;
304 (void) height;
305 return false;
306 }
307 virtual void detach_native_child_view(void* child_view) { (void) child_view; }
308
309 // Clip an attached native child to `(x, y, width, height)` — the visible
310 // sub-rectangle expressed in the child's OWN [0,0,frame_w,frame_h] box, in
311 // Pulp's top-left origin convention (same units as
312 // set_native_child_view_bounds). The host masks the native view to that rect
313 // (e.g. a CALayer mask on Apple) so a child inside a scroll region does not
314 // spill past the viewport; masking preserves the child's content size rather
315 // than reflowing it by resizing the frame. When has_clip is false, any
316 // existing clip is removed. Returns false when unsupported or when the child
317 // is not attached to this host. Default: no-op unsupported.
318 virtual bool set_native_child_view_clip(void* child_view,
319 bool has_clip,
320 float x,
321 float y,
322 float width,
323 float height) {
324 (void) child_view;
325 (void) has_clip;
326 (void) x;
327 (void) y;
328 (void) width;
329 (void) height;
330 return false;
331 }
332
333 // Capture the current visible content as a PNG image.
334 //
335 // Semantics: "whatever the compositor sees" — on macOS this prefers
336 // `screencapture` and the content-view cache before falling back to a
337 // direct GPU-backbuffer readback. Suitable for live screenshots of a
338 // visible window.
339 virtual std::vector<uint8_t> capture_png() { return {}; }
340
341 // Capture the host's own back-buffer as a PNG image (issue #2001).
342 //
343 // Semantics: "host-managed pixels, deterministically." Implementations
344 // MUST NOT call show()/makeKeyAndOrderFront/etc., and MUST bypass any
345 // compositor-side capture path (`screencapture`, content-view caching).
346 // For GPU-backed hosts, this reads the actual rendered back-buffer; for
347 // non-GPU hosts, it can fall back to the rasterized content view.
348 //
349 // Default delegates to capture_png() so non-overriding hosts keep their
350 // current behavior. Test harnesses (`test/mac_window_harness.{hpp,mm}`)
351 // depend on the override existing on macOS GPU hosts so hidden-window
352 // tests get reproducible bytes.
353 virtual std::vector<uint8_t> capture_back_buffer_png() {
354 return capture_png();
355 }
356
357 // Clear any cached host-side input targets before the view tree is rebuilt.
358 virtual void invalidate_input_state() {}
359
360 // Request the host to close and exit its event loop.
361 virtual void request_close() {}
362
363 // Called periodically while the host event loop is running.
364 // Used for editor-side polling such as hot reload.
365 virtual void set_idle_callback(std::function<void()> cb) { (void)cb; }
367
368 // Install an APP-LEVEL key monitor: keyDown/keyUp events anywhere in the app
369 // are forwarded to `handler` before the focused window's responder chain sees
370 // them; return true to CONSUME (the event then doesn't reach any window). Use
371 // it to route keyboard input to a popout window (e.g. a Musical Typing
372 // keyboard) regardless of WHICH window is currently key — so typing keeps
373 // working after the user clicks a control in another window. Pass `{}` to
374 // remove. No-op on platforms without an app-global key hook.
375 virtual void set_app_key_monitor(std::function<bool(const KeyEvent&)> handler) {
376 (void)handler;
377 note_unsupported_feature("set_app_key_monitor");
378 }
379
380 // Install a handler for files the OS asks this app to open: a double-click
381 // in Finder, a drag onto the app icon or Dock tile, or `open -a`. Paths are
382 // delivered on the main thread.
383 //
384 // Install it BEFORE run_event_loop(). A launch-time open arrives while the
385 // app is still finishing launch — before the loop starts — so a handler set
386 // afterwards would miss the very file that caused the launch. Any paths that
387 // arrive before a handler exists are held and delivered as soon as one is
388 // installed; passing `{}` removes the handler without discarding them.
389 //
390 // Declaring the document type is the other half of this: without a
391 // CFBundleDocumentTypes entry (pulp_declare_standalone_document_type() in
392 // CMake) the OS never routes the file here at all.
394 std::function<void(const std::vector<std::string>&)> handler) {
395 (void)handler;
396 note_unsupported_feature("set_open_files_handler");
397 }
398
399 // Set a callback for when the window is closed
400 virtual void set_close_callback(std::function<void()> cb) = 0;
401
402 // Run the event loop (blocks until the window is closed)
403 // Call this for standalone UI preview mode
404 virtual void run_event_loop() = 0;
405
406 // ── D.1 Client-side window decoration ───────────────────────────────
408 virtual void set_client_decoration(bool enabled) {
409 (void)enabled;
410 note_unsupported_feature("set_client_decoration");
411 }
412
420
421 // ── D.2 Window features ─────────────────────────────────────────────
423 virtual void set_fixed_aspect_ratio(float ratio) {
424 (void)ratio;
425 note_unsupported_feature("set_fixed_aspect_ratio");
426 }
427
429 virtual void set_always_on_top(bool on_top) {
430 (void)on_top;
431 note_unsupported_feature("set_always_on_top");
432 }
433
443 virtual void request_content_size(float w, float h) {
444 (void)w; (void)h;
445 note_unsupported_feature("request_content_size");
446 }
447
483 virtual void set_design_viewport(float design_w, float design_h) {
484 (void)design_w; (void)design_h;
485 note_unsupported_feature("set_design_viewport");
486 }
487
502 float window_w, float window_h,
503 float design_w, float design_h,
504 float& sx, float& sy, float& tx, float& ty,
505 bool top_align = false) {
506 if (design_w <= 0.0f || design_h <= 0.0f ||
507 window_w <= 0.0f || window_h <= 0.0f) {
508 return false;
509 }
510 const float s = std::min(window_w / design_w, window_h / design_h);
511 sx = s;
512 sy = s;
513 tx = (window_w - design_w * s) * 0.5f;
514 ty = top_align ? 0.0f : (window_h - design_h * s) * 0.5f;
515 return true;
516 }
517
535 float window_w, float window_h,
536 float design_w, float design_h,
537 bool top_align = false) {
538 float sx, sy, tx, ty;
539 if (!compute_design_viewport_transform(window_w, window_h,
540 design_w, design_h,
541 sx, sy, tx, ty, top_align)) {
542 return pt;
543 }
544 if (sx <= 0.0f || sy <= 0.0f) return pt;
545 return {(pt.x - tx) / sx, (pt.y - ty) / sy};
546 }
547
548 // Report the active design-viewport transform that maps ROOT (design-space)
549 // coordinates to HOST (window-space) coordinates:
550 // x' = x*sx + tx, y' = y*sy + ty, w' = w*sx, h' = h*sy
551 // Returns true and fills the outputs when a design viewport is active;
552 // returns false (identity — outputs untouched) when no viewport is set.
553 //
554 // Mirrors `PluginViewHost::design_viewport_transform`. `NativeViewHost`
555 // uses it to place an embedded native child at the same letterbox-scaled
556 // position as the surrounding Pulp widgets. Default: no viewport → false.
557 // Only the GPU window host (which actually scales paint) overrides it; the
558 // CPU window host does not implement a design viewport at all, so the
559 // false default is correct there.
560 virtual bool design_viewport_transform(float& sx, float& sy,
561 float& tx, float& ty) const {
562 (void)sx; (void)sy; (void)tx; (void)ty;
563 return false;
564 }
565
566 // ── D.3 DPI / Monitor utilities ─────────────────────────────────────
568 virtual float dpi_scale() const { return 1.0f; }
569
571 virtual Size max_dimensions() const { return {1920, 1080}; }
572
574 float convert_to_logical(float px) const { return px / dpi_scale(); }
575
577 float convert_to_native(float logical) const { return logical * dpi_scale(); }
578
580 struct MonitorInfo {
582 float dpi_scale = 1.0f;
583 std::string name;
584 };
585
587 virtual std::vector<MonitorInfo> get_monitors() const {
588 return {{{{0, 0, 1920, 1080}, 1.0f, "Default"}}};
589 }
590
591 // ── D.4 Mouse relative mode ─────────────────────────────────────────
593 virtual void set_mouse_relative_mode(bool enabled) {
594 (void)enabled;
595 note_unsupported_feature("set_mouse_relative_mode");
596 }
597
598 // Keep new virtuals at the tail of the public vtable. WindowHost is an SDK
599 // extension surface (set_factory accepts downstream subclasses), so
600 // inserting a virtual among existing methods would shift every later slot.
601 virtual bool is_gpu_backed() const { return gpu_surface() != nullptr; }
602
606 virtual bool supports_deferred_close() const {
607 return false;
608 }
609
612 virtual void request_close_deferred() {
613 note_unsupported_feature("request_close_deferred");
614 }
615
618 virtual bool supports_compositor_capture() const { return false; }
619
622 virtual bool event_loop_blocks_until_close() const { return true; }
623
626 virtual bool event_loop_supports_exit_drain() const {
627 return false;
628 }
629
633 virtual void run_event_loop_until(std::function<bool()> ready_to_return) {
635 if (ready_to_return)
636 (void)ready_to_return();
637 }
638
643 virtual bool supports_back_buffer_capture() const { return false; }
644
648 virtual bool supports_gpu_submission_evidence() const {
649 return false;
650 }
651
665 return false;
666 }
667
673 virtual std::vector<double> frame_time_samples_ms() const { return {}; }
674
680
686 bool feature_marked_unsupported(const char* method) const {
687 return unsupported_features_logged_.count(method) > 0;
688 }
689
690protected:
696 void note_unsupported_feature(const char* method);
697
698private:
699 // Method names already logged by note_unsupported_feature(), so each
700 // unsupported feature diagnoses exactly once per host instead of once per
701 // call.
702 std::set<std::string> unsupported_features_logged_;
703
704 // Shared vblank-paced-or-direct repaint scheduling for mark_dirty() and
705 // mark_dirty(Rect).
706 void schedule_repaint();
707
708 // Optional vblank-paced RenderLoop driven by mark_dirty().
709 render::RenderLoop* render_loop_ = nullptr;
710
711 // Accumulated dirty region for the pending frame (root/window coords).
712 // The SAME abstraction the plug-in host uses (PluginViewHost::damage_) —
713 // this used to be three hand-rolled fields plus a copy of the union logic,
714 // which is how the two hosts drifted apart on what "damage" even means.
715 PendingDamage damage_;
716
717private:
718 // ── Attached-view registry ──────────────────────────────────────────────
719 //
720 // See the equivalent block in PluginViewHost. A NativeViewHost holds a RAW,
721 // non-owning pointer back here and dereferences it in its destructor; if the
722 // host dies first, that is a use-after-free. Every built-in host nulls the
723 // back-reference in its own destructor, but that is a per-subclass
724 // convention, and `set_factory` is public API.
725 //
726 // The BASE destructor clears every still-attached view's pointer. It does
727 // NOT call detach_native_child_view() — the derived object is already gone,
728 // so that would dispatch to the base default and the real OS detach would
729 // silently not happen. Derived destructors keep doing the OS detach through
730 // their live vtable; this only makes the pointer invariant structural.
731 friend class NativeViewHost;
732 void register_native_view(NativeViewHost* view);
733 void unregister_native_view(NativeViewHost* view);
734
735 std::vector<NativeViewHost*> attached_native_views_;
736};
737
738} // namespace pulp::view
Definition canvas.hpp:240
Abstract GPU surface — a presentable rendering target backed by a native window/view.
Definition gpu_surface.hpp:112
Definition render_loop.hpp:129
A Yoga-laid-out widget that embeds a single platform-native child view (a system WebView,...
Definition native_view_host.hpp:72
One frame's damage, taken atomically out of a PendingDamage.
Definition pending_damage.hpp:39
Accumulated repaint damage for one frame, in root/window coordinates.
Definition pending_damage.hpp:32
Definition view.hpp:73
Definition window_host.hpp:113
void restore_pending_dirty(const PendingDamage::Snapshot &snapshot)
Definition window_host.hpp:206
virtual void request_close_deferred()
Schedule request_close() for a later native event-loop turn.
Definition window_host.hpp:612
static Point design_viewport_window_to_root(Point pt, float window_w, float window_h, float design_w, float design_h, bool top_align=false)
Inverse of compute_design_viewport_transform: map a HOST/window-space point back into ROOT (design) s...
Definition window_host.hpp:534
void paint_root(canvas::Canvas &canvas, View &root, bool surface_preserves_outside_clip=false)
virtual bool supports_deferred_close() const
True only when request_close_deferred() schedules close handling for a later native event-loop turn.
Definition window_host.hpp:606
virtual bool attach_native_child_view(void *child_view, float x, float y, float width, float height)
Definition window_host.hpp:283
virtual void * dawn_device_handle() const
Definition window_host.hpp:254
virtual void set_always_on_top(bool on_top)
Keep window above all others.
Definition window_host.hpp:429
virtual void set_close_callback(std::function< void()> cb)=0
static std::unique_ptr< WindowHost > create(View &root, const WindowOptions &options)
virtual bool last_frame_gpu_submission_observed() const
True when the most recent frame rendered by this host was submitted toward its intended output (a pre...
Definition window_host.hpp:664
virtual ContentSize get_content_size() const
virtual void show()=0
float convert_to_native(float logical) const
Convert logical coordinates to physical pixels.
Definition window_host.hpp:577
virtual void * dawn_queue_handle() const
Definition window_host.hpp:255
virtual void request_close()
Definition window_host.hpp:361
virtual bool set_native_child_view_clip(void *child_view, bool has_clip, float x, float y, float width, float height)
Definition window_host.hpp:318
virtual void * dawn_instance_handle() const
Definition window_host.hpp:256
virtual float dpi_scale() const
Get the DPI scale factor for this window.
Definition window_host.hpp:568
virtual void * native_window_handle() const
Definition window_host.hpp:252
virtual bool event_loop_blocks_until_close() const
Browser hosts override this query because their page-owned loop returns immediately.
Definition window_host.hpp:622
virtual void detach_native_child_view(void *child_view)
Definition window_host.hpp:307
virtual void repaint()=0
virtual void position_beside(WindowHost *other)
Position this window alongside another window.
Definition window_host.hpp:250
virtual ~WindowHost()
Out-of-line, and NOT trivial: it clears the back-pointer of every NativeViewHost still attached to th...
virtual void request_content_size(float w, float h)
Request the native window resize so its CONTENT area becomes (w × h), keeping the window's TOP-LEFT c...
Definition window_host.hpp:443
void mark_dirty(const Rect &root_rect)
void clear_pending_dirty()
Definition window_host.hpp:198
virtual render::GpuSurface * gpu_surface() const
Definition window_host.hpp:257
virtual void set_fixed_aspect_ratio(float ratio)
Constrain window resize to maintain aspect ratio.
Definition window_host.hpp:423
bool feature_marked_unsupported(const char *method) const
True once note_unsupported_feature(method) has fired for method on this host — i.e.
Definition window_host.hpp:686
Rect pending_dirty_bounds() const
Definition window_host.hpp:194
render::RenderLoop * render_loop() const
Definition window_host.hpp:241
void note_unsupported_feature(const char *method)
Log ONCE (per method, per host instance) that a window feature is a base-class no-op on this host,...
virtual std::vector< double > frame_time_samples_ms() const
Main-thread milliseconds spent on each host frame dispatched so far (idle pump + layout + paint + sub...
Definition window_host.hpp:673
bool pending_repaint_is_full() const
Definition window_host.hpp:188
virtual void hide()=0
virtual std::vector< uint8_t > capture_back_buffer_png()
Definition window_host.hpp:353
friend class NativeViewHost
Definition window_host.hpp:731
virtual bool supports_compositor_capture() const
True when capture_png() returns pixels from the visible compositor rather than a deterministic host-m...
Definition window_host.hpp:618
virtual void set_client_decoration(bool enabled)
Remove native title bar and let the app draw its own.
Definition window_host.hpp:408
virtual Size max_dimensions() const
Get the maximum available dimensions for this window's screen.
Definition window_host.hpp:571
virtual bool design_viewport_transform(float &sx, float &sy, float &tx, float &ty) const
Definition window_host.hpp:560
virtual std::vector< MonitorInfo > get_monitors() const
Get list of connected monitors. Default returns one virtual monitor.
Definition window_host.hpp:587
bool has_pending_dirty_bounds() const
Definition window_host.hpp:193
std::function< void(uint32_t width, uint32_t height)> ResizeCallback
Definition window_host.hpp:120
static bool has_factory()
PendingDamage::Snapshot take_pending_dirty()
Definition window_host.hpp:205
virtual void run_event_loop_until(std::function< bool()> ready_to_return)
Run the event loop, then keep dispatching main-thread work until ready_to_return reports that stack-b...
Definition window_host.hpp:633
virtual void invalidate_input_state()
Definition window_host.hpp:358
virtual void set_open_files_handler(std::function< void(const std::vector< std::string > &)> handler)
Definition window_host.hpp:393
static bool compute_design_viewport_transform(float window_w, float window_h, float design_w, float design_h, float &sx, float &sy, float &tx, float &ty, bool top_align=false)
Pure math behind set_design_viewport — used both by the platform host's paint_scene and by tests.
Definition window_host.hpp:501
void attach_render_loop(render::RenderLoop *loop)
Definition window_host.hpp:238
virtual void log_gpu_diagnostics_summary()
Log this host's GPU-diagnostics summary line(s) — whether the Skia log bridge is wired and what reach...
Definition window_host.hpp:679
virtual bool is_visible() const =0
virtual bool set_native_child_view_bounds(void *child_view, float x, float y, float width, float height)
Definition window_host.hpp:295
virtual void set_resize_callback(ResizeCallback cb)
static void clear_factory()
virtual void set_mouse_relative_mode(bool enabled)
Hide cursor and report relative deltas (infinite drag for knobs).
Definition window_host.hpp:593
virtual bool supports_back_buffer_capture() const
True when capture_back_buffer_png() is implemented by this host.
Definition window_host.hpp:643
virtual double gpu_render_time_ms() const
Most recent whole-recording GPU render time in milliseconds for the last presented frame,...
Definition window_host.hpp:268
virtual bool gpu_render_timing_available() const
Whether whole-recording GPU render timing is available this run — the host owns a SkiaSurface whose S...
Definition window_host.hpp:274
void request_frame()
Definition window_host.hpp:180
std::function< std::unique_ptr< WindowHost >( View &root, const WindowOptions &options)> Factory
Definition window_host.hpp:128
static void set_factory(Factory factory)
virtual void set_app_key_monitor(std::function< bool(const KeyEvent &)> handler)
Definition window_host.hpp:375
virtual void set_design_viewport(float design_w, float design_h)
Set a fixed "design viewport".
Definition window_host.hpp:483
virtual void * native_content_view_handle() const
Definition window_host.hpp:253
HitTestRegion
Hit-test region types for client-decorated windows.
Definition window_host.hpp:414
@ resize_ne
Definition window_host.hpp:417
@ resize_s
Definition window_host.hpp:416
@ resize_e
Definition window_host.hpp:416
@ none
Definition window_host.hpp:415
@ resize_sw
Definition window_host.hpp:417
@ client
Definition window_host.hpp:415
@ resize_nw
Definition window_host.hpp:417
@ close
Definition window_host.hpp:418
@ caption
Definition window_host.hpp:415
@ resize_n
Definition window_host.hpp:416
@ minimize
Definition window_host.hpp:418
@ resize_se
Definition window_host.hpp:417
@ resize_w
Definition window_host.hpp:416
@ maximize
Definition window_host.hpp:418
virtual void run_event_loop()=0
virtual bool event_loop_supports_exit_drain() const
True only when run_event_loop_until() continues dispatching accepted main-thread work after the nativ...
Definition window_host.hpp:626
virtual bool is_gpu_backed() const
Definition window_host.hpp:601
virtual void set_idle_callback(std::function< void()> cb)
Definition window_host.hpp:365
virtual std::vector< uint8_t > capture_png()
Definition window_host.hpp:339
virtual bool supports_gpu_submission_evidence() const
True when this host can report whether the last rendered frame's GPU work was submitted toward its in...
Definition window_host.hpp:648
float convert_to_logical(float px) const
Convert physical pixels to logical coordinates.
Definition window_host.hpp:574
Definition affine_transform.hpp:24
Definition gpu_fwd.hpp:31
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
WindowType
Definition window_manager.hpp:17
@ kModNone
Definition input_events.hpp:16
@ px
Absolute pixels.
Definition geometry.hpp:393
KeyCode
Definition input_events.hpp:35
@ s
Definition input_events.hpp:41
@ h
Definition input_events.hpp:39
@ y
Definition input_events.hpp:42
@ x
Definition input_events.hpp:41
@ unknown
Definition input_events.hpp:36
@ w
Definition input_events.hpp:41
@ height
Definition css_animation.hpp:128
@ width
Definition css_animation.hpp:127
Rich key event with key code, modifiers, and repeat state.
Definition input_events.hpp:193
Definition geometry.hpp:20
float x
Definition geometry.hpp:21
float y
Definition geometry.hpp:21
Axis-aligned rectangle in continuous (float) coordinates.
Definition geometry.hpp:52
Definition geometry.hpp:28
Definition window_host.hpp:115
uint32_t width
Definition window_host.hpp:116
uint32_t height
Definition window_host.hpp:117
Monitor information.
Definition window_host.hpp:580
float dpi_scale
Definition window_host.hpp:582
Rect bounds
Definition window_host.hpp:581
std::string name
Definition window_host.hpp:583
Definition window_host.hpp:30
AppMenuSection app_menu_section
Definition window_host.hpp:46
KeyCode key
Definition window_host.hpp:38
std::string title
Definition window_host.hpp:37
std::uint16_t modifiers
Definition window_host.hpp:39
std::string menu
Top-level menu to place this command under.
Definition window_host.hpp:36
AppMenuSection
Where an application-menu command (empty menu) sits.
Definition window_host.hpp:45
std::function< void()> action
Definition window_host.hpp:40
Definition window_host.hpp:29
std::string title
Definition window_host.hpp:49
void * parent_native_handle
Parent window handle (HWND, NSWindow*).
Definition window_host.hpp:93
WindowType * window_type
Optional type hint for platform styling.
Definition window_host.hpp:92
bool use_gpu
Use GPU rendering (Dawn/Skia Graphite) instead of CoreGraphics.
Definition window_host.hpp:55
bool secondary_window
Explicit window role for the close policy.
Definition window_host.hpp:86
void * shared_gpu_device
Shared Dawn device for multi-window GPU.
Definition window_host.hpp:94
float min_width
Minimum window width (0 = no minimum).
Definition window_host.hpp:52
std::uint32_t background_rgb
The window's own background, 0xRRGGBB.
Definition window_host.hpp:65
bool initially_hidden
When true, the window is created and the run loop drives the bridge per-vsync as usual,...
Definition window_host.hpp:75
float width
Definition window_host.hpp:50
float height
Definition window_host.hpp:51
float min_height
Minimum window height (0 = no minimum).
Definition window_host.hpp:53
std::vector< MenuCommand > menu_commands
Commands exposed through the platform's native application menu bar.
Definition window_host.hpp:99
bool resizable
Definition window_host.hpp:54