docs
Loading...
Searching...
No Matches
App.h
Go to the documentation of this file.
1///
2/// Copyright (C) 2026 Ultralight, Inc. All rights reserved.
3/// A license is required for commercial use. https://ultralig.ht
4///
5#pragma once
6#include "Defines.h"
7#include "GPUMemoryStats.h"
8#include "GPUDriverCounters.h"
9#include <Ultralight/Bitmap.h>
10#include <Ultralight/RefPtr.h>
11#include <Ultralight/Renderer.h>
13
14namespace ultralight {
15
16class Monitor;
17class Window;
18
19///
20/// Interface for all App-related events.
21///
22/// @see App::set_listener()
23///
25public:
26 virtual ~AppListener() {}
27
28 ///
29 /// Called on every update of the app's loop. You should update all app logic here.
30 ///
31 /// @note This fires right before the library updates the Renderer (see Renderer::Update()).
32 ///
33 virtual void OnUpdate() {}
34
35 ///
36 /// Called when the app has been idle (low CPU use and no recent input) for a while.
37 ///
38 /// @param utilization Main-thread CPU utilization (0.0-1.0) over the last ~1 second. Lower
39 /// values mean more headroom for background work.
40 ///
41 /// @note This first fires after Settings::sustained_idle_time of continuous idle, then again
42 /// at that interval while the app stays idle. It stops as soon as there's input or CPU
43 /// use rises above Settings::idle_utilization_threshold.
44 ///
45 virtual void OnIdle(double utilization) {}
46};
47
48///
49/// App-specific settings.
50///
52 ///
53 /// The name of the developer of this app.
54 ///
55 /// Together with app_name, this generates the per-app folders where the library keeps the log
56 /// file (`ultralight.log`), profiler traces, and session data (cookies, cached resources,
57 /// databases). A Config::cache_path you set yourself takes over the session data. The log and
58 /// traces stay in the diagnostics folder either way.
59 ///
60 /// @note The folders are:
61 /// - Windows: `%APPDATA%<developer_name><app_name>`
62 /// - Linux: `$XDG_CACHE_HOME/com.<developer_name>.<app_name>`, or
63 /// `~/.cache/com.<developer_name>.<app_name>` when that variable is
64 /// unset
65 /// - macOS: `~/Library/Caches/<name>` for the log and traces, and
66 /// `~/Library/Application Support/<name>` for session data, where
67 /// `<name>` is the app bundle's identifier, or
68 /// `com.<developer_name>.<app_name>` when it has none
69 ///
70 String developer_name = "MyCompany";
71
72 ///
73 /// The name of this app, used with developer_name to build the per-app folders (see
74 /// developer_name).
75 ///
76 String app_name = "MyApp";
77
78 ///
79 /// The root folder for `file:///` URLs. You should set this to the relative path where all
80 /// of your app data is (eg, `file:///page.html` loads `page.html` from this folder).
81 ///
82 /// @note The path is relative to:
83 /// - Windows: the executable's folder
84 /// - Linux: the executable's folder
85 /// - macOS: `YourApp.app/Contents/Resources/`
86 ///
87 String file_system_path = "./assets/";
88
89 ///
90 /// Whether or not to always use the CPU renderer. By default the library uses the GPU
91 /// renderer when it finds a compatible GPU.
92 ///
93 bool force_cpu_renderer = false;
94
95 ///
96 /// Override the device scale factor for all windows.
97 ///
98 /// When this is 0 or less (the default), the device scale is auto-detected from the monitor's
99 /// DPI. Set a positive value (eg, 1.0, 1.5, 2.0) to use that scale for every window instead.
100 ///
102
103 ///
104 /// Whether or not to pick the font-appearance preset from the operating system, so text matches
105 /// the platform's native look (FontProfile::WindowsLike on Windows and Linux,
106 /// FontProfile::MacOSLike on macOS).
107 ///
108 /// This only applies while Config::font_profile is FontProfile::Default-- a profile you set
109 /// yourself always wins. Set this to false to keep the Default profile's platform-neutral
110 /// appearance everywhere.
111 ///
112 bool auto_font_profile = true;
113
114 ///
115 /// Whether or not to pick the default font families (serif, sans-serif, monospace, etc.) from
116 /// the operating system, so generic CSS families resolve to the same fonts as the platform's
117 /// browsers (eg, Menlo for `monospace` on macOS, Consolas on Windows).
118 ///
119 /// This applies to Views created without an explicit ViewConfig. A config you pass to
120 /// Container::AddPanel() keeps its own font families-- start from
121 /// Window::default_view_config() to inherit them. Set this to false to keep the
122 /// platform-neutral families everywhere.
123 ///
125
126 ///
127 /// Whether or not text editing in the Views this app creates should follow the host OS's native
128 /// conventions (eg, non-directional selections on macOS).
129 ///
130 /// This applies to Views created without an explicit ViewConfig. A config you pass to
131 /// Container::AddPanel() uses its own ViewConfig::match_native_editing_behavior instead. Set
132 /// this to false for editing behavior that is identical on every platform.
133 ///
135
136 ///
137 /// The minimum duration of user inactivity (in seconds) before idle detection begins.
138 ///
139 double idle_threshold = 0.5;
140
141 ///
142 /// The time (in seconds) the app must remain continuously idle before AppListener::OnIdle()
143 /// fires, and the interval between repeated calls after that.
144 ///
146
147 ///
148 /// The thread CPU utilization (0.0-1.0) below which the app is considered idle.
149 ///
151
152 ///
153 /// Whether or not to enable the built-in trace file profiler.
154 ///
155 /// When enabled, the library writes a Perfetto trace file that can be opened in
156 /// https://ui.perfetto.dev to visualize Ultralight's internal performance.
157 ///
158 /// Traces are written to a `profiler_traces` folder inside the app's diagnostics directory,
159 /// alongside the log file (see developer_name for where that is). Read
160 /// App::profiler_trace_path() for the exact file. This folder is the app's own, not the
161 /// Config::cache_path you may have set.
162 ///
163 /// \parblock
164 /// @note A profiler you set with Platform::set_profiler() before App::Create() is kept and
165 /// this flag is ignored, with a warning in the log.
166 /// \endparblock
167 ///
168 /// \parblock
169 /// @note If no trace file can be written, the log says so and nothing else changes.
170 /// App::is_profiler_active() reads false.
171 /// \endparblock
172 ///
173 /// @pre Requires the Pro edition or higher (the Profiler platform interface is not available
174 /// in the Free or Plus editions).
175 ///
176 bool enable_profiler = false;
177
178 ///
179 /// The paint rate (in frames per second) for windows created with WindowFlags::Hidden.
180 ///
181 /// Hidden windows receive no paint events from the OS, so by default they're never painted. Set
182 /// this to a positive value to paint them at a fixed rate instead, which is what offscreen and
183 /// headless capture need. The rate is independent of any monitor's refresh rate, so time-based
184 /// content advances the same on every host.
185 ///
186 uint32_t headless_paint_fps = 0;
187
188 ///
189 /// Whether or not to run the app's update loop at full speed, without sleeping between updates.
190 ///
191 /// By default the loop sleeps between updates, which keeps CPU usage low but paces how quickly
192 /// page work (resource loading, script, layout) advances. Enable this to update continuously
193 /// instead, so that work completes as fast as the CPU allows. Display refresh and hidden-window
194 /// painting are still paced (see headless_paint_fps) and painting stays invalidation-driven,
195 /// so animation timing is unchanged.
196 ///
197 /// @warning The loop thread busy-waits, so a single instance can fully occupy one CPU core.
198 /// This is meant for batch / offscreen workloads that render many pages back to
199 /// back, not interactive apps.
200 ///
201 bool full_speed_loop = false;
202
203 ///
204 /// Whether or not to time animations for the moment each frame appears on screen.
205 ///
206 /// A frame appears one or more display refreshes after the refresh that started it. With
207 /// this on (the default), `window.requestAnimationFrame()` timestamps, CSS animations, and
208 /// smooth scrolling use the time the frame will appear, which avoids lag while scrolling. Set
209 /// this to false to use the time of the refresh instead.
210 ///
211 /// \parblock
212 /// @note With this on, `window.requestAnimationFrame()` timestamps run ahead of
213 /// `performance.now()` by the display's presentation delay (one to a few refreshes),
214 /// so pages that compare the two will see the difference.
215 /// \endparblock
216 ///
217 /// \parblock
218 /// @note This applies on macOS and Windows, once the library has measured the display's
219 /// timing (a moment after rendering starts).
220 /// \endparblock
221 ///
223
224 ///
225 /// The application icon, as a 32-bit BGRA bitmap with straight (unpremultiplied) alpha.
226 ///
227 /// On macOS this is the Dock icon. On Windows and Linux it's the default icon for windows that
228 /// haven't set their own with Window::SetIcon(). Leave it null to keep the platform default.
229 ///
231};
232
233class AppImpl;
234
235///
236/// Handle to a repeating timer created with App::SetInterval().
237///
238/// The handle owns the timer. Destroying it (or calling Cancel()) stops the timer and destroys
239/// its user data. Handles are move-only and should be destroyed on the main thread.
240///
242public:
243 ///
244 /// Create an empty handle that refers to no timer.
245 ///
247
248 ///
249 /// Cancel the timer, if any.
250 ///
252
253 ///
254 /// Move constructor (the source is left empty).
255 ///
256 TimerHandle(TimerHandle&& other) noexcept : id_(other.id_) { other.id_ = 0; }
257
258 ///
259 /// Move assignment. Cancels the timer this handle held, if any; the source is left empty.
260 ///
261 TimerHandle& operator=(TimerHandle&& other) noexcept {
262 if (this != &other) {
263 Cancel();
264 id_ = other.id_;
265 other.id_ = 0;
266 }
267 return *this;
268 }
269
270 TimerHandle(const TimerHandle&) = delete;
272
273 ///
274 /// Stop the timer and destroy its user data. Safe to call more than once.
275 ///
276 void Cancel() {
277 if (id_) {
278 CancelInterval(id_);
279 id_ = 0;
280 }
281 }
282
283 ///
284 /// Whether or not this handle still refers to a timer (false after Cancel() or a move).
285 ///
286 explicit operator bool() const { return id_ != 0; }
287
288private:
289 friend class AppImpl;
290 explicit TimerHandle(uint64_t id) : id_(id) {}
291 static void CancelInterval(uint64_t timer_id);
292 uint64_t id_ = 0;
293};
294
295///
296/// Main application singleton (use this if you want to let the library manage window creation).
297///
298/// This convenience class sets up everything you need to display web-based content in a
299/// desktop application.
300///
301/// The App class initializes the Platform singleton with OS-specific defaults, creates a Renderer,
302/// and automatically manages window creation, run loop, input events, and painting.
303///
304/// ## Creating the App
305///
306/// Call App::Create() to initialize the library and create the App singleton.
307///
308/// ```
309/// auto app = App::Create();
310/// ```
311///
312/// ## Creating a Window
313///
314/// Call Window::Create() to create one or more windows during the lifetime of your app.
315///
316/// ```
317/// auto window = Window::Create(app->main_monitor(), 1024, 768, false,
318/// WindowFlags::Titled | WindowFlags::Resizable);
319/// ```
320///
321/// ### Adding a Panel to a Window
322///
323/// A window's content is a layout of panels, each showing a View. A bare AddPanel() fills
324/// the whole window.
325///
326/// ```
327/// auto panel = window->AddPanel();
328/// ```
329///
330/// Each Panel has a View instance that you can use to load web content into.
331///
332/// ```
333/// panel->view()->LoadURL("https://google.com");
334/// ```
335///
336/// ## Running the App
337///
338/// Call App::Run() to start the main run loop.
339///
340/// ```
341/// #include <AppCore/AppCore.h>
342///
343/// using namespace ultralight;
344///
345/// int main() {
346/// // Initialize app, window, panels, etc. here...
347///
348/// app->Run();
349///
350/// return 0;
351/// }
352/// ```
353///
354/// ## Shutting Down the App
355///
356/// Call App::Quit() to stop the main run loop and shut down the app.
357///
358/// ```
359/// app->Quit();
360/// ```
361///
362/// @note This is optional, you can use the Renderer class directly if you want to manage your
363/// own windows and run loop.
364///
365class AExport App : public RefCounted {
366public:
367 ///
368 /// Create the App singleton.
369 ///
370 /// @param settings Settings to customize App runtime behavior.
371 ///
372 /// @param config Config options for the Ultralight renderer.
373 ///
374 /// @return Returns a ref-pointer to the created App instance.
375 ///
376 /// \parblock
377 /// @note You should only create one App per application lifetime.
378 /// \endparblock
379 ///
380 /// \parblock
381 /// @note App::Create() adjusts a few Config fields: it always sets Config::face_winding to
382 /// FaceWinding::Clockwise, fills in Config::cache_path when you leave it empty, and
383 /// picks Config::font_profile while Settings::auto_font_profile is on.
384 /// \endparblock
385 ///
386 /// \parblock
387 /// @note A platform handler you set on Platform::instance() before App::Create() is kept (eg,
388 /// your own FileSystem, FontLoader, Logger, or Clipboard). App::Create() only installs
389 /// its default for a handler you left unset. A GPUDriver or SurfaceFactory you set
390 /// beforehand is kept too, but AppCore windows can't present Views with it.
391 /// \endparblock
392 ///
394
395 ///
396 /// Get the App singleton (nullptr before App::Create()).
397 ///
398 static App* instance();
399
400 ///
401 /// Get the settings this App was created with.
402 ///
403 virtual const Settings& settings() const = 0;
404
405 ///
406 /// Set an AppListener to receive callbacks for app-related events.
407 ///
408 /// @param listener A user-defined AppListener implementation, ownership remains with the
409 /// caller. Pass a nullptr to remove the current listener.
410 ///
412
413 ///
414 /// Get the AppListener (can be nullptr).
415 ///
416 virtual AppListener* listener() = 0;
417
418 ///
419 /// Whether or not the App is running.
420 ///
421 virtual bool is_running() const = 0;
422
423 ///
424 /// Get the main monitor (this is never NULL).
425 ///
426 virtual Monitor* main_monitor() = 0;
427
428 ///
429 /// Get the number of connected monitors.
430 ///
431 virtual uint32_t monitor_count() const { return 1; }
432
433 ///
434 /// Get a monitor by index (from 0 to `monitor_count() - 1`).
435 ///
436 /// Index 0 is always the main monitor.
437 ///
438 /// You can pass the returned monitor to Window::Create() to open a window on that display.
439 ///
440 /// @param index The index of the monitor to get.
441 ///
442 /// @return Returns the monitor, or nullptr when `index` is out of range.
443 ///
444 /// @note The returned pointer is owned by the App and remains valid for the lifetime of the
445 /// App. If a monitor is disconnected, it is no longer enumerated, but its pointer remains
446 /// safe to use and its accessors return fallback values.
447 ///
448 virtual Monitor* monitor(uint32_t index) { return index == 0 ? main_monitor() : nullptr; }
449
450 ///
451 /// Get the underlying Renderer instance.
452 ///
454
455 ///
456 /// Run the main loop (this returns after Quit()).
457 ///
458 virtual void Run() = 0;
459
460 ///
461 /// Quit the application.
462 ///
463 /// Stops the main loop so Run() returns; the process itself is not exited.
464 ///
465 /// @note On macOS, a Quit() issued while a modal loop is running (eg, a native message box
466 /// or an interactive window drag) is absorbed by that inner loop and does not end
467 /// Run()-- call Quit() again once the modal loop has finished.
468 ///
469 virtual void Quit() = 0;
470
471 ///
472 /// Advance the app by one iteration of the main loop, on behalf of your own run loop.
473 ///
474 /// This pumps pending OS events, updates the renderer, and refreshes the display and repaints
475 /// windows once the display interval has elapsed. When no events are pending, it waits up to
476 /// `max_wait_seconds` for one.
477 ///
478 /// You should call this repeatedly from your own loop instead of calling Run().
479 ///
480 /// @param max_wait_seconds The longest this call may block waiting for an event or timer
481 /// tick. Pass 0.0 to return immediately after processing whatever
482 /// is pending.
483 ///
484 /// @return Returns whether or not the app is still running (false once Quit() has been called).
485 ///
486 /// @note On macOS this pumps the event queue manually rather than running the native run
487 /// loop, so menu key-equivalent routing can differ from Run().
488 ///
489 virtual bool RunOnce(double max_wait_seconds = 0.0) = 0;
490
491 ///
492 /// Post a task to run on the main thread during a future update of the app's loop.
493 ///
494 /// Tasks run in posting order, sharing one queue with Renderer::PostTask().
495 ///
496 /// @param task Invoked once on the main thread.
497 ///
498 /// @param user_data Passed to `task` (can be nullptr).
499 ///
500 /// @param destroy_user_data Invoked exactly once after `task` runs, or without `task`
501 /// running if the App is destroyed first (can be nullptr).
502 ///
503 /// @note Safe to call from any thread. Posting wakes the main loop, so a task posted from
504 /// another thread runs without waiting for the next timer tick.
505 ///
506 virtual void PostTask(void (*task)(void* user_data), void* user_data,
507 void (*destroy_user_data)(void* user_data) = nullptr)
508 = 0;
509
510 ///
511 /// Post a task to run on the main thread once a delay has elapsed.
512 ///
513 /// The task runs on the first update tick after the delay elapses (ticks are about 2 ms apart).
514 ///
515 /// @param delay_ms The delay before the task runs, in milliseconds.
516 ///
517 /// @param task Invoked once on the main thread.
518 ///
519 /// @param user_data Passed to `task` (can be nullptr).
520 ///
521 /// @param destroy_user_data Invoked exactly once after `task` runs, or without `task`
522 /// running if the App is destroyed first (can be nullptr).
523 ///
524 /// @note Safe to call from any thread (it wakes the main loop like PostTask()).
525 ///
526 /// @see PostTask()
527 ///
528 virtual void PostDelayedTask(double delay_ms, void (*task)(void* user_data), void* user_data,
529 void (*destroy_user_data)(void* user_data) = nullptr)
530 = 0;
531
532 ///
533 /// Create a repeating timer that fires on the main thread.
534 ///
535 /// The timer fires on the first update tick after each interval elapses (ticks are about 2 ms
536 /// apart). Fires missed while the loop was stalled are skipped-- the timer resumes on its
537 /// interval.
538 ///
539 /// @param interval_ms The time between fires, in milliseconds.
540 ///
541 /// @param callback Invoked on each fire, on the main thread.
542 ///
543 /// @param user_data Passed to `callback` (can be nullptr).
544 ///
545 /// @param destroy_user_data Invoked exactly once when the timer is canceled or the App is
546 /// destroyed, and never while `callback` is running (a timer may
547 /// cancel itself from its own callback). Can be nullptr.
548 ///
549 /// @return Returns a handle that owns the timer. Destroy it (or call TimerHandle::Cancel()) to
550 /// stop the timer.
551 ///
552 /// @note Safe to call from any thread (it wakes the main loop like PostTask()).
553 ///
554 [[nodiscard]] virtual TimerHandle SetInterval(double interval_ms,
555 void (*callback)(void* user_data),
556 void* user_data,
557 void (*destroy_user_data)(void* user_data)
558 = nullptr)
559 = 0;
560
561 ///
562 /// Post a callable to run on the main thread during a future update of the app's loop.
563 ///
564 /// Convenience overload of PostTask(). The callable is invoked once on the main thread, then
565 /// destroyed (without being invoked if the App is destroyed first).
566 ///
567 /// @param callback The callable to invoke. Capture by value when posting from another thread.
568 ///
569 template <typename F, typename = std::enable_if_t<std::is_invocable_v<std::decay_t<F>&>>>
570 void PostTask(F&& callback) {
571 using Fn = std::decay_t<F>;
572 auto* fn = new Fn(std::forward<F>(callback));
573 PostTask(&detail::InvokeTaskCallable<Fn>, fn, &detail::DeleteTaskCallable<Fn>);
574 }
575
576 ///
577 /// Post a callable to run on the main thread once a delay has elapsed.
578 ///
579 /// Convenience overload of PostDelayedTask(). See PostTask() for the callable's lifetime.
580 ///
581 /// @param delay_ms The delay before the callable runs, in milliseconds.
582 ///
583 /// @param callback The callable to invoke.
584 ///
585 template <typename F, typename = std::enable_if_t<std::is_invocable_v<std::decay_t<F>&>>>
586 void PostDelayedTask(double delay_ms, F&& callback) {
587 using Fn = std::decay_t<F>;
588 auto* fn = new Fn(std::forward<F>(callback));
589 PostDelayedTask(delay_ms, &detail::InvokeTaskCallable<Fn>, fn,
590 &detail::DeleteTaskCallable<Fn>);
591 }
592
593 ///
594 /// Create a repeating timer that invokes a callable on the main thread.
595 ///
596 /// Convenience overload of SetInterval(). The callable is destroyed when the timer is canceled
597 /// or the App is destroyed.
598 ///
599 /// @param interval_ms The time between fires, in milliseconds.
600 ///
601 /// @param callback The callable to invoke on each fire.
602 ///
603 /// @return Returns a handle that owns the timer. Destroy it (or call TimerHandle::Cancel()) to
604 /// stop the timer.
605 ///
606 template <typename F, typename = std::enable_if_t<std::is_invocable_v<std::decay_t<F>&>>>
607 [[nodiscard]] TimerHandle SetInterval(double interval_ms, F&& callback) {
608 using Fn = std::decay_t<F>;
609 auto* fn = new Fn(std::forward<F>(callback));
610 return SetInterval(interval_ms, &detail::InvokeTaskCallable<Fn>, fn,
611 &detail::DeleteTaskCallable<Fn>);
612 }
613
614 ///
615 /// Whether or not the app is currently considered idle (low CPU utilization and no recent user
616 /// input, sustained past the configured threshold).
617 ///
618 /// @note This reads true once idle conditions have held for at least Settings::idle_threshold,
619 /// even before the first AppListener::OnIdle() callback fires.
620 ///
621 virtual bool is_idle() const = 0;
622
623 ///
624 /// Get the current main-thread CPU utilization (0.0-1.0), averaged over the last ~1 second.
625 ///
626 /// You can use this to make adaptive scheduling decisions.
627 ///
628 virtual double thread_utilization() const = 0;
629
630 ///
631 /// Get GPU memory statistics from the App's GPU driver.
632 ///
633 /// Statistics cover the GPU resources the library has allocated through the active GPU backend
634 /// (textures, render targets, geometry, swap chains) plus process-wide video memory usage and
635 /// budget reported by the operating system. See GPUMemoryStats for per-field details and
636 /// accuracy notes.
637 ///
638 /// @param stats Structure to fill. All fields are overwritten on success.
639 ///
640 /// @return Returns true if `stats` was filled. Returns false when rendering with the CPU
641 /// renderer or when the active GPU backend does not provide memory statistics.
642 ///
643 /// @note Among the stock GPU drivers, the Direct3D backends on Windows, the Metal backend on
644 /// macOS, and the OpenGL backend on Linux implement this (OpenGL reports no process
645 /// usage or budget).
646 ///
647 virtual bool GetGPUMemoryStats(GPUMemoryStats& stats) { return false; }
648
649#if UL_HAS(TESTING)
650 /// \cond ignore
651 virtual bool GetGPUDriverCounters(GPUDriverCounters& counters) { return false; }
652 virtual bool HasDisplayLinkForTesting() const { return false; }
653 virtual bool DisplayLinkPausedForTesting() const { return false; }
654 /// \endcond
655#endif
656
657 ///
658 /// Whether or not the built-in profiler is active (see Settings::enable_profiler).
659 ///
660 /// This is true when Settings::enable_profiler is set, you didn't set your own profiler with
661 /// Platform::set_profiler(), and your edition includes the profiler (Pro or higher).
662 ///
663 virtual bool is_profiler_active() const = 0;
664
665 ///
666 /// Get the file path of the active profiler trace file.
667 ///
668 /// @return Returns the path to the trace file, or an empty string when is_profiler_active()
669 /// reads false.
670 ///
671 virtual const char* profiler_trace_path() const = 0;
672
673protected:
674 virtual ~App();
675};
676
677} // namespace ultralight
#define AExport
Definition Defines.h:41
Main application singleton (use this if you want to let the library manage window creation).
Definition App.h:365
virtual Monitor * monitor(uint32_t index)
Get a monitor by index (from 0 to monitor_count() - 1).
Definition App.h:448
TimerHandle SetInterval(double interval_ms, F &&callback)
Create a repeating timer that invokes a callable on the main thread.
Definition App.h:607
virtual bool GetGPUMemoryStats(GPUMemoryStats &stats)
Get GPU memory statistics from the App's GPU driver.
Definition App.h:647
virtual TimerHandle SetInterval(double interval_ms, void(*callback)(void *user_data), void *user_data, void(*destroy_user_data)(void *user_data)=nullptr)=0
Create a repeating timer that fires on the main thread.
virtual bool is_profiler_active() const =0
Whether or not the built-in profiler is active (see Settings::enable_profiler).
virtual ~App()
virtual void PostTask(void(*task)(void *user_data), void *user_data, void(*destroy_user_data)(void *user_data)=nullptr)=0
Post a task to run on the main thread during a future update of the app's loop.
virtual void PostDelayedTask(double delay_ms, void(*task)(void *user_data), void *user_data, void(*destroy_user_data)(void *user_data)=nullptr)=0
Post a task to run on the main thread once a delay has elapsed.
virtual uint32_t monitor_count() const
Get the number of connected monitors.
Definition App.h:431
virtual RefPtr< Renderer > renderer()=0
Get the underlying Renderer instance.
virtual const Settings & settings() const =0
Get the settings this App was created with.
void PostDelayedTask(double delay_ms, F &&callback)
Post a callable to run on the main thread once a delay has elapsed.
Definition App.h:586
virtual double thread_utilization() const =0
Get the current main-thread CPU utilization (0.0-1.0), averaged over the last ~1 second.
static App * instance()
Get the App singleton (nullptr before App::Create()).
static RefPtr< App > Create(Settings settings=Settings(), Config config=Config())
Create the App singleton.
virtual Monitor * main_monitor()=0
Get the main monitor (this is never NULL).
virtual void Quit()=0
Quit the application.
virtual void Run()=0
Run the main loop (this returns after Quit()).
virtual const char * profiler_trace_path() const =0
Get the file path of the active profiler trace file.
virtual AppListener * listener()=0
Get the AppListener (can be nullptr).
virtual bool RunOnce(double max_wait_seconds=0.0)=0
Advance the app by one iteration of the main loop, on behalf of your own run loop.
virtual bool is_idle() const =0
Whether or not the app is currently considered idle (low CPU utilization and no recent user input,...
void PostTask(F &&callback)
Post a callable to run on the main thread during a future update of the app's loop.
Definition App.h:570
virtual bool is_running() const =0
Whether or not the App is running.
virtual void set_listener(AppListener *listener)=0
Set an AppListener to receive callbacks for app-related events.
Interface for all App-related events.
Definition App.h:24
virtual ~AppListener()
Definition App.h:26
virtual void OnUpdate()
Called on every update of the app's loop.
Definition App.h:33
virtual void OnIdle(double utilization)
Called when the app has been idle (low CPU use and no recent input) for a while.
Definition App.h:45
A platform-specific monitor.
Definition Monitor.h:25
Interface for all ref-counted objects that will be managed using the RefPtr<> smart pointer.
Definition RefPtr.h:49
A nullable smart pointer.
Definition RefPtr.h:126
Unicode string container with conversions for UTF-8, UTF-16, and UTF-32.
Definition String.h:31
Handle to a repeating timer created with App::SetInterval().
Definition App.h:241
TimerHandle()
Create an empty handle that refers to no timer.
Definition App.h:246
friend class AppImpl
Definition App.h:289
TimerHandle(const TimerHandle &)=delete
~TimerHandle()
Cancel the timer, if any.
Definition App.h:251
TimerHandle(TimerHandle &&other) noexcept
Move constructor (the source is left empty).
Definition App.h:256
void Cancel()
Stop the timer and destroy its user data.
Definition App.h:276
TimerHandle & operator=(const TimerHandle &)=delete
TimerHandle & operator=(TimerHandle &&other) noexcept
Move assignment.
Definition App.h:261
A native OS window that displays web content.
Definition Window.h:636
Root namespace for every public Ultralight type, function, and enumeration.
Core configuration for the renderer.
Definition Config.h:296
GPU memory statistics reported by the App's GPU driver.
Definition GPUMemoryStats.h:29
App-specific settings.
Definition App.h:51
double idle_threshold
The minimum duration of user inactivity (in seconds) before idle detection begins.
Definition App.h:139
bool enable_profiler
Whether or not to enable the built-in trace file profiler.
Definition App.h:176
double device_scale_override
Override the device scale factor for all windows.
Definition App.h:101
bool match_native_editing_behavior
Whether or not text editing in the Views this app creates should follow the host OS's native conventi...
Definition App.h:134
bool auto_font_profile
Whether or not to pick the font-appearance preset from the operating system, so text matches the plat...
Definition App.h:112
RefPtr< Bitmap > app_icon
The application icon, as a 32-bit BGRA bitmap with straight (unpremultiplied) alpha.
Definition App.h:230
bool sync_animations_to_present
Whether or not to time animations for the moment each frame appears on screen.
Definition App.h:222
double idle_utilization_threshold
The thread CPU utilization (0.0-1.0) below which the app is considered idle.
Definition App.h:150
double sustained_idle_time
The time (in seconds) the app must remain continuously idle before AppListener::OnIdle() fires,...
Definition App.h:145
String app_name
The name of this app, used with developer_name to build the per-app folders (see developer_name).
Definition App.h:76
String file_system_path
The root folder for file:/// URLs.
Definition App.h:87
bool force_cpu_renderer
Whether or not to always use the CPU renderer.
Definition App.h:93
bool full_speed_loop
Whether or not to run the app's update loop at full speed, without sleeping between updates.
Definition App.h:201
bool auto_font_families
Whether or not to pick the default font families (serif, sans-serif, monospace, etc....
Definition App.h:124
uint32_t headless_paint_fps
The paint rate (in frames per second) for windows created with WindowFlags::Hidden.
Definition App.h:186
String developer_name
The name of the developer of this app.
Definition App.h:70