API — ICoreEssentials/UI/System
The public contract of 23 header(s) under ICoreEssentials/UI/System — 25 class/struct definition(s), 194 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
ICoreAppLifecycle.h#
ICoreEssentials/UI/System/ICoreAppLifecycle.h
ICoreAppLifecycle#
ICoreAppLifecycle.h:36 · class · 6 declaration(s)
ICoreAppLifecycle -- what the operating system is doing to the application, on the platforms that suspend one (TB2.18).
class ICoreAppLifecycle {
public:
ICoreAppLifecycle() = delete;
// ⚠ APPEND-ONLY: the values are pinned by the lifecycle regression suite.
enum class State {
Active = 0, // on screen and receiving input
Inactive = 1, // on screen, input interrupted (a call, the app switcher)
Background = 2, // off screen; suspended once the handlers return
};
[[nodiscard]] static State state();
// Raised once per change of state(), never for a repeat.
[[nodiscard]] static ICoreSignal<State>& onStateChanged();
[[nodiscard]] static ICoreSignal<>& onMemoryWarning();
// Asked when the platform saves the window's state (iPadOS: as the scene
// goes to the background). Return what the next launch needs to put the
// user back -- a project path, a view -- small and plain; an empty string
// saves nothing. Replaces any earlier provider; an empty function removes it.
static void setRestorationProvider(std::function<ICoreString()> provider);
// What the provider returned before the platform last terminated the
// application, or empty: a cold start, a user who closed the window, or a
// platform that does not restore.
[[nodiscard]] static ICoreString restoredState();
};
ICoreAppLifecycleAccess.h#
ICoreEssentials/UI/System/ICoreAppLifecycleAccess.h
The backend's side of ICoreAppLifecycle (TB2.18): how a toolkit that has lifecycle events reports them. Application code uses ICoreAppLifecycle.h, never this.
Declares no class of its own — see the file.
ICoreApplication.h#
ICoreEssentials/UI/System/ICoreApplication.h
ICoreApplication#
ICoreApplication.h:49 · class · pImpl · 19 declaration(s)
ICoreApplication -- the process's toolkit application object, wrapped.
class ICoreApplication {
public:
// Builds the toolkit application. argc/argv come straight from main(); the
// STRINGS must outlive this object (their storage stays the caller's),
// while the ARRAY need not -- an internal copy of the pointers is what the
// toolkit is handed, because it shortens and shuffles that array in place
// as it consumes the platform switches it recognises.
//
// Tolerates argc == 0 or a null argv by standing in a placeholder argv[0],
// which is what a host embedding this in a process it did not start has.
ICoreApplication(int argc, char** argv);
~ICoreApplication();
ICoreApplication(const ICoreApplication&) = delete;
ICoreApplication& operator=(const ICoreApplication&) = delete;
ICoreApplication(ICoreApplication&&) = delete;
ICoreApplication& operator=(ICoreApplication&&) = delete;
// Lends the toolkit one slice. waitMs > 0 sleeps until something happens or
// that long passes, whichever comes first -- which is what keeps an idle
// application at 0% CPU instead of spinning the caller's loop. waitMs == 0
// drains what is pending and returns.
//
// ⚠ THE DRAIN IS BOUNDED: after about 100 ms of it, tick() returns even if
// work is still queued. A queue that refills as fast as it drains -- a
// timer whose handler takes longer than its interval -- would otherwise
// never come up empty, and a caller that ticks between steps of its own
// work (a script run yielding to keep its window alive) would never get
// control back. Nothing is lost: the next tick() carries on.
void tick(int waitMs = 0);
// Ends the session at the caller's next look at isRunning(). FIRST CODE
// WINS: a shutdown already under way is not relabelled, so a later
// "everything closed, exit 0" cannot overwrite an earlier failure code.
void requestQuit(int exitCode);
[[nodiscard]] bool isRunning() const noexcept;
[[nodiscard]] int exitCode() const noexcept;
// Runs the session to its end through the platform's own loop. `slice` is
// one turn of it and is handed the wait that turn may take; with no slice
// the turn is tick(). An owner whose turn does more than tick() -- the
// SDK's Application joins its parser thread there -- passes its own.
//
// desktop: `while (isRunning()) slice(16); return exitCode();` -- blocks,
// then returns the code for main() to return.
// web: the BROWSER owns the `while` (web backend plan §6.1): the
// slice becomes the body of a frame callback and is handed 0,
// because a frame must not wait. run() DOES NOT RETURN -- main()
// is unwound to the browser's event loop and the process ends
// with exitCode() once isRunning() goes false.
//
// ⚠ SO NOTHING AFTER run() IS REACHED ON THE WEB. Teardown that must happen
// belongs in the last slice (isRunning() false), which every loop -- this
// one and a hand-written desktop one -- passes through while the owner's
// objects are still alive. That is where the SDK joins its thread already.
//
// ⚠⚠ AND ON THE WEB THIS OBJECT MUST NOT LIVE ON main()'s STACK. The
// handoff unwinds main(), and under wasm exceptions that RUNS the
// destructors of everything in its frame (measured, web backend plan §10) --
// this application first. Give it, and whatever the slice uses, static or
// heap storage. A web build that breaks the rule aborts with that sentence
// instead of ending with no frame run.
//
// A caller that interleaves work of its own on a desktop may still write
// the while loop out of tick(); a caller that wants to run in a browser
// cannot, and this is the one spelling that works in both.
int run(const std::function<void(int waitMs)>& slice = {});
// The argument vector as the application proper sees it -- AFTER the
// toolkit has taken out the platform switches it handles itself. That is
// what makes it different from the argv handed to the constructor, and it
// is the one an owner reading its own switches wants.
[[nodiscard]] ICoreStringList arguments() const;
// ----------------------------------------------------------------------
// What the running application calls itself, and what it looks like before
// any window exists. Set these BEFORE the first widget is built: several
// are read once, when the platform integration comes up.
// ----------------------------------------------------------------------
// The name the window system knows this process by. It feeds the
// Wayland/X11 app-id that desktop shells match against a .desktop file's
// StartupWMClass, which is what lets a running window group under the
// installed launcher icon instead of a generic placeholder.
void setApplicationName(const ICoreString& name);
// The human-readable name, which is what window titles fall back to.
void setApplicationDisplayName(const ICoreString& name);
void setApplicationVersion(const ICoreString& version);
// The .desktop file's base name, sans extension -- the other half of the
// app-id match above, and ignored on platforms that have no such file.
void setDesktopFileName(const ICoreString& name);
// The mark on every window: title bars, the taskbar, Alt-Tab, and the
// Wayland/X11 fallback when no .desktop file is installed.
//
// ⚠ macOS IGNORES THIS and reads the bundle's .icns instead, so a Dock
// icon that looks wrong is a packaging question, not a call-site one.
void setWindowIcon(const ICoreIcon& icon);
// Copy, modify, hand back -- see ICorePalette. The getter returns the
// application's CURRENT palette, so a caller changing one role keeps
// whatever the platform style chose for the rest.
[[nodiscard]] ICorePalette palette() const;
void setPalette(const ICorePalette& palette);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreClipboard.h#
ICoreEssentials/UI/System/ICoreClipboard.h
ICoreClipboard#
ICoreClipboard.h:24 · class · 6 declaration(s)
The system clipboard, as a static facade (same shape as ICoreNativeDialogs: no instances, because there is only one clipboard and the OS owns it).
class ICoreClipboard {
public:
ICoreClipboard() = delete;
static void setText(const ICoreString& text);
static ICoreString text();
// Whether the clipboard holds a picture right now. Cheap: it asks which
// formats are on offer and decodes nothing.
static bool hasImage();
// The picture on the clipboard, decoded -- a NULL pixmap when there is none
// or it does not decode. Device pixel ratio 1.0.
static ICorePixmap image();
// Put `image` on the clipboard, replacing what was there. A null pixmap is
// ignored: the clipboard is left exactly as it was.
static void setImage(const ICorePixmap& image);
};
};
ICoreDrag.h#
ICoreEssentials/UI/System/ICoreDrag.h
ICoreDrag#
ICoreDrag.h:13 · class · 2 declaration(s)
Starting a drag, as a static facade: the library-navigator entries begin a drag carrying a block/template payload and a preview pixmap.
class ICoreDrag {
public:
ICoreDrag() = delete;
// `source` is the widget the drag starts from -- the toolkit uses it to
// decide which window owns the drag loop. Q1.8 swapped it from a raw
// QWidget*: all three call sites were passing icoreNativeWidget(this), so
// the wrapper was what they had in hand and the unwrap was pure ceremony.
static bool exec(ICoreNativeWidget* source,
const ICoreMimePayload& payload,
const ICorePixmap& dragPixmap,
const ICorePoint& hotSpot = ICorePoint());
};
};
ICoreDragSource.h#
ICoreEssentials/UI/System/ICoreDragSource.h
ICoreDragOffer#
ICoreDragSource.h:14 · struct · 0 declaration(s)
What a drag carries, and what it looks like while it is carried.
struct ICoreDragOffer {
public:
ICoreMimePayload payload;
// The image that follows the finger. A null pixmap lets the platform lift
// a picture of the widget itself.
ICorePixmap preview;
// Where in `preview` the finger holds it, where the platform lets the
// caller say (iPadOS centres the preview under the finger itself).
ICorePoint hotSpot;
};
};
ICoreDragSource#
ICoreDragSource.h:47 · class · pImpl · 10 declaration(s)
ICoreDragSource -- a widget that can be DRAGGED FROM, where the platform starts the drag from the user's own gesture.
class ICoreDragSource {
public:
// What to carry when a drag begins at `localPos` (the widget's own
// coordinates), or nothing -- that spot is not draggable.
using Provider = std::function<std::optional<ICoreDragOffer>(const ICorePoint& localPos)>;
// The drag ended: `dropped` is whether anything accepted it.
using Finished = std::function<void(bool dropped)>;
// A null widget registers nothing.
explicit ICoreDragSource(const ICoreNativeWidget* widget);
~ICoreDragSource();
ICoreDragSource(const ICoreDragSource&) = delete;
ICoreDragSource& operator=(const ICoreDragSource&) = delete;
void setProvider(Provider provider);
void setFinishedHandler(Finished finished);
// -- the backend's half --------------------------------------------------
// By native handle (what nativeWidgetHandle() returns), because a backend
// holds its own view.
// Whether a source with a provider is installed on this handle.
[[nodiscard]] static bool installedAt(const void* nativeHandle);
// The newest provider's answer, or nothing.
[[nodiscard]] static std::optional<ICoreDragOffer> offerAt(const void* nativeHandle, const ICorePoint& localPos);
// Tells the source whose offer was carried that the drag ended.
static void finishedAt(const void* nativeHandle, bool dropped);
// Called whenever the answer of installedAt() may have changed for
// `widget` -- a source gaining or losing its provider, or going away -- so
// a backend can install or remove its own drag machinery. One observer;
// setting another replaces it. Only a backend that starts drags from a
// gesture sets one.
using InstallObserver = std::function<void(const ICoreNativeWidget* widget)>;
static void setInstallObserver(InstallObserver observer);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreFileOpenRequests.h#
ICoreEssentials/UI/System/ICoreFileOpenRequests.h
ICoreFileOpenRequests#
ICoreFileOpenRequests.h:36 · class · 4 declaration(s)
ICoreFileOpenRequests -- files the operating system asks this application to open: a double-click in the Finder, "Open With", a file dropped on the Dock icon (ED11.6).
class ICoreFileOpenRequests {
public:
ICoreFileOpenRequests() = delete;
using Claimant = std::function<bool(const ICoreString& path)>;
// Adds `claimant` after the existing ones and answers its id, for
// removeClaimant(). An empty function adds nothing and answers 0.
static int addClaimant(Claimant claimant);
// Removes the claimant with this id. An unknown id changes nothing.
static void removeClaimant(int id);
// Offers `paths` to the claimants now and answers the ones none took, in
// their order. With no claimant at all the paths are held (see above) and
// the answer is empty. A claimant may add or remove claimants; that
// changes who sees the NEXT path, not the one being offered.
static ICoreStringList offer(const ICoreStringList& paths);
};
};
ICoreFontCatalog.h#
ICoreEssentials/UI/System/ICoreFontCatalog.h
ICoreFontCatalog#
ICoreFontCatalog.h:8 · class · 6 declaration(s)
The installed-fonts registry, as a static facade over QFontDatabase.
class ICoreFontCatalog {
public:
ICoreFontCatalog() = delete;
// The platform's fixed-pitch font (what code and terminals set).
static ICoreFont fixedFont();
// The application-wide default font (what an unstyled widget inherits) --
// QApplication::font() behind the boundary. Added at E4: the canvas and
// dialog labels all derive their fonts from it by nudging the point size.
static ICoreFont applicationFont();
static bool hasFamily(const ICoreString& family);
// Every font family installed on this machine, for a font picker.
static ICoreStringList families();
// Register a bundled font file; returns false if the file was rejected.
static bool addApplicationFont(const ICoreString& path);
};
};
ICoreLifetimeToken.h#
ICoreEssentials/UI/System/ICoreLifetimeToken.h
ICoreLifetimeToken#
ICoreLifetimeToken.h:49 · class · 8 declaration(s)
class ICoreLifetimeToken {
public:
// Constructs a LIVE token. There is no "empty" state to test for -- an
// owner that has one is alive, and that is the point.
ICoreLifetimeToken();
~ICoreLifetimeToken();
// Move-only. See the contract above: a copy would mean two owners of one
// lifetime, and the second destruction would expire watches that the first
// owner is still meant to be answering for.
ICoreLifetimeToken(const ICoreLifetimeToken&) = delete;
ICoreLifetimeToken& operator=(const ICoreLifetimeToken&) = delete;
ICoreLifetimeToken(ICoreLifetimeToken&& other) noexcept;
ICoreLifetimeToken& operator=(ICoreLifetimeToken&& other) noexcept;
// False only for a moved-from token. Watches on a moved-from token follow
// the token to its new owner -- the control block did not move, only the
// handle to it did.
[[nodiscard]] bool isValid() const noexcept;
// Expire every watch NOW, without waiting for the destructor. For the case
// this whole row exists for: the toolkit destroys the native half while the
// wrapper shell is still standing, and the shell must stop answering yes.
void expire() noexcept;
// One std::shared_ptr. Pinned by a static_assert in the .cpp, the same way
// every other small-value residue in this tree is.
static constexpr std::size_t kNativeStorageSize = 16;
static constexpr std::size_t kNativeStorageAlign = 8;
};
ICoreLifetimeWatch#
ICoreLifetimeToken.h:85 · class · 12 declaration(s)
class ICoreLifetimeWatch {
public:
// Already expired -- see the contract's last line.
ICoreLifetimeWatch();
~ICoreLifetimeWatch();
ICoreLifetimeWatch(const ICoreLifetimeWatch& other);
ICoreLifetimeWatch& operator=(const ICoreLifetimeWatch& other);
ICoreLifetimeWatch(ICoreLifetimeWatch&& other) noexcept;
ICoreLifetimeWatch& operator=(ICoreLifetimeWatch&& other) noexcept;
// Implicit on purpose: `ICoreLifetimeWatch w = owner.token();` is the
// spelling every call site wants, and there is no second candidate for it
// to tie with -- this type converts from nothing else.
ICoreLifetimeWatch(const ICoreLifetimeToken& token);
// The only question this type answers.
[[nodiscard]] bool expired() const noexcept;
explicit operator bool() const noexcept;
void clear() noexcept;
// Two watches are equal when they watch the same token -- INCLUDING two
// expired ones, which are equal only if both are empty. Needed because the
// seats compare handles.
bool operator==(const ICoreLifetimeWatch& other) const noexcept;
bool operator!=(const ICoreLifetimeWatch& other) const noexcept;
// One std::weak_ptr.
static constexpr std::size_t kNativeStorageSize = 16;
static constexpr std::size_t kNativeStorageAlign = 8;
};
ICoreMimePayload.h#
ICoreEssentials/UI/System/ICoreMimePayload.h
ICoreMimePayload#
ICoreMimePayload.h:12 · struct · 1 declaration(s)
What a drag (or clipboard interchange) carries, as a plain value.
struct ICoreMimePayload {
public:
ICoreString text;
ICoreStringList urls;
ICoreString customFormat;
std::string customData;
// Out of line for the header surface rule (H4.53). The fields above stay:
// they are PUBLIC, and this is a value struct whose content is its
// contract -- the rule bans private and protected data, not public.
[[nodiscard]] bool hasCustomFormat(const ICoreString& format) const;
};
};
ICoreNativeTitleBar.h#
ICoreEssentials/UI/System/ICoreNativeTitleBar.h
ICoreNativeTitleBar#
ICoreNativeTitleBar.h:43 · class · 5 declaration(s)
ICoreNativeTitleBar -- the one part of a window this application does not paint, made to agree with the part it does.
class ICoreNativeTitleBar {
public:
ICoreNativeTitleBar() = delete;
// Whether this platform lets a process choose its own caption appearance.
// False means every call below is accepted and does nothing.
[[nodiscard]] static bool isSupported();
// Follow ICoreThemeManager for the life of the process. Applies the active
// theme once immediately and re-applies on every switch, so a caller does
// not also have to set the initial state. Idempotent -- calling it twice
// subscribes once.
static void followActiveTheme();
// Force one appearance, ignoring the theme. Also arms the watcher that
// catches windows opened later, so a caller that wants a fixed caption
// calls this instead of followActiveTheme(), not as well.
static void setDark(bool dark);
// Re-push the current choice at every top-level window that exists now.
// Rarely needed: the watcher above catches new windows at the moment their
// native handle is created. It is here for a host that creates a window
// through the platform directly, behind the toolkit's back.
static void applyToOpenWindows();
};
};
ICorePlatform.h#
ICoreEssentials/UI/System/ICorePlatform.h
Which OS this build targets: exactly one ICORE_OS_* -- WINDOWS, IOS, MAC, WEB, ANDROID or LINUX. The chain and the reasons for its order live in System/ICoreOs.h, a directives-only header the non-UI tree can include too (TB0.7); this include is what keeps every file that asks here seeing the same macros.
Declares no class of its own — see the file.
ICoreRenderingPolicy.h#
ICoreEssentials/UI/System/ICoreRenderingPolicy.h
ICoreRenderingPolicy#
ICoreRenderingPolicy.h:27 · class · nested Provider · 9 declaration(s)
ICoreRenderingPolicy -- the Essentials-side seam for rendering-budget choices that are application policy, not SDK policy (ESSENTIALS_INDEPENDENCE D3).
class ICoreRenderingPolicy {
public:
struct Provider {
std::function<bool()> canvasAnimationsEnabled;
std::function<bool()> widgetAnimationsEnabled;
std::function<int()> animationDurationPercent;
std::function<bool()> canvasShadowsEnabled;
std::function<bool()> floatingPanelShadowsEnabled;
// ⚠ THE PLATFORM'S OWN FOCUS RING, WHICH IS AN APPLICATION CHOICE AND
// NOT A PLATFORM-SDK DEFAULT. On macOS a focusable view draws the
// system keyboard-focus ring whenever it holds first-responder status,
// and the tree's own fields draw a themed focused border of their own --
// so a host view that takes focus when its BORDER is clicked (rather
// than its editor) shows a blue ring around a field that is not
// editing. An application whose controls are all self-drawn turns the
// toolkit's ring off; the SDK keeps it on, because a consumer using
// stock controls wants the platform behaviour.
//
// Absent provider means ENABLED -- the platform's answer, not ours.
std::function<bool()> systemFocusRingEnabled;
};
static void installProvider(Provider provider);
// Each falls back to its default when the provider (or that one entry)
// is absent: enabled / 100.
static bool canvasAnimationsEnabled();
static bool widgetAnimationsEnabled();
static int animationDurationPercent();
static bool canvasShadowsEnabled();
static bool floatingPanelShadowsEnabled();
static bool systemFocusRingEnabled();
// Raised (synchronously, on the GUI thread) after the values above may
// have changed. Essentials code that caches a policy-derived state
// subscribes here; the host calls notifyChanged().
static ICoreSignal<>& changed();
static void notifyChanged();
};
};
ICoreScreen.h#
ICoreEssentials/UI/System/ICoreScreen.h
ICoreScreen#
ICoreScreen.h:8 · class · 5 declaration(s)
The monitors, as a static facade.
class ICoreScreen {
public:
ICoreScreen() = delete;
static ICoreRect primaryGeometry();
static ICoreRect primaryAvailableGeometry();
// The screen under `globalPos`, falling back to the primary one -- so the
// answer is always a usable rect, never a "no screen" sentinel.
static ICoreRect availableGeometryAt(const ICorePoint& globalPos);
static double devicePixelRatio();
};
};
ICoreSystemAppearance.h#
ICoreEssentials/UI/System/ICoreSystemAppearance.h
ICoreSystemAppearance#
ICoreSystemAppearance.h:8 · class · 3 declaration(s)
What the OS says about its own look, as a static facade over QStyleHints.
class ICoreSystemAppearance {
public:
ICoreSystemAppearance() = delete;
static bool isDarkMode();
// Fires on the GUI thread when the OS switches its colour scheme.
static ICoreSignal<>& onChanged();
};
};
ICoreSystemNotification.h#
ICoreEssentials/UI/System/ICoreSystemNotification.h
ICoreSystemNotification -- a notification from the operating system: the banner and the entry in Notification Center on macOS and iPadOS, a toast in Windows' Action Center, a desktop notification on Linux, a browser notification on the web.
ICoreSystemNotification done; done.setTitle("Export finished"); done.setBody("controller.vhd -- 4,812 lines"); done.setActivatedHandler([&] { revealTheFile(); }); done.show();
Everything is asynchronous. show() returns at once; the outcome arrives through the handlers, which run on the MAIN thread through the application's event loop (an ICoreApplication must be running): the shown handler once the
ICoreSystemNotification#
ICoreSystemNotification.h:58 · class · pImpl · 20 declaration(s)
Opened by row PS5.23 of the Platform SDK product plan.
class ICoreSystemNotification {
public:
enum class Permission : int {
Unavailable = 0, // no seat, or this process cannot post (see above)
NotDetermined = 1, // nobody has asked the user yet
Denied = 2, // the user (or a policy) turned them off
Granted = 3,
};
ICoreSystemNotification();
~ICoreSystemNotification();
ICoreSystemNotification(const ICoreSystemNotification&) = delete;
ICoreSystemNotification& operator=(const ICoreSystemNotification&) = delete;
// Whether this build has a seat at all. True does not promise permission.
[[nodiscard]] static bool isSupported();
// What the user has decided so far, without asking. `done` runs on the
// main thread.
static void queryPermission(std::function<void(Permission)> done);
// Asks the user if nobody has, then reports the answer; if the question was
// answered before, reports that answer without asking again. `done` runs
// on the main thread.
static void requestPermission(std::function<void(Permission)> done);
// UTF-8. The title is required; the body may be empty.
void setTitle(const std::string& title);
[[nodiscard]] std::string title() const;
void setBody(const std::string& body);
[[nodiscard]] std::string body() const;
// A silent notification appears without the system's sound. Default false.
void setSilent(bool silent);
[[nodiscard]] bool isSilent() const noexcept;
// Posts the notification, or replaces it if it is shown. False, with
// errorString() set, when refused at once (no title, or no seat); true
// means the outcome will arrive through the shown or failed handler.
bool show();
// Removes it from the screen and from the system's list. A show() still in
// flight is withdrawn as it lands and reports neither shown nor failed.
void withdraw();
// Accepted by the system and not withdrawn since.
[[nodiscard]] bool isShown() const noexcept;
// Why the last show() failed; empty after a success.
[[nodiscard]] std::string errorString() const;
void setShownHandler(std::function<void()> handler);
void setFailedHandler(std::function<void(const std::string& error)> handler);
// The user clicked the notification (on the web, and where the platform
// allows it, the application's window is brought forward first).
void setActivatedHandler(std::function<void()> handler);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreThemeFollow.h#
ICoreEssentials/UI/System/ICoreThemeFollow.h
ICoreThemeFollow#
ICoreThemeFollow.h:24 · class · 7 declaration(s)
Follow the theme for as long as a widget or a scene item lives.
class ICoreThemeFollow {
public:
ICoreThemeFollow() = delete;
// Runs `apply` once now, and again after every theme change, until `widget`
// is destroyed. A null widget runs it once and subscribes nothing.
static void subscribe(ICoreNativeWidget* widget, std::function<void()> apply);
// The same for a scene item. `apply` always runs once now; the subscription
// starts only if the item is in a scene that can carry one, and ends when the
// item is destroyed. On WinUI no item carries one yet, so there an item's
// `apply` runs once and never again; a widget's subscription works on every
// backend.
static void subscribe(ICoreNativeItem* item, std::function<void()> apply);
// Repaints `widget` (or `item`) after every theme change, for its lifetime:
// the common case of a subscriber whose drawing code reads the theme itself.
static void repaintOnThemeChange(ICoreNativeWidget* widget);
static void repaintOnThemeChange(ICoreNativeItem* item);
// `color` with its alpha replaced by `alpha`, 0..255. A value outside that
// range is clamped, as ICoreColor::setAlpha clamps it on every backend.
[[nodiscard]] static ICoreColor withAlpha(ICoreColor color, int alpha);
// The theme's ink colour that reads on `surface`: its light or dark text
// colour, whichever contrasts with the surface.
[[nodiscard]] static ICoreColor inkOn(const ICoreColor& surface);
};
};
ICoreTrayIcon.h#
ICoreEssentials/UI/System/ICoreTrayIcon.h
ICoreTrayIcon#
ICoreTrayIcon.h:25 · class · pImpl · 13 declaration(s)
An icon in the system's status area -- the menu bar's status items on macOS, the notification area on Windows, a StatusNotifierItem on Linux -- with a tooltip and a menu.
class ICoreTrayIcon {
public:
ICoreTrayIcon();
~ICoreTrayIcon();
ICoreTrayIcon(const ICoreTrayIcon&) = delete;
ICoreTrayIcon& operator=(const ICoreTrayIcon&) = delete;
// Whether this backend can show a tray icon at all: true on macOS (appkit),
// Windows (winui) and Linux (gtk4). On Linux the icon appears only where the
// desktop runs a StatusNotifier host (Plasma, waybar, the AppIndicator
// extension on GNOME); without one it is on the session bus and not drawn.
[[nodiscard]] static bool isSupported();
// The icon, from a resource path (":/...") or a file: SVG or any image the
// platform reads. Drawn as a template image where the platform has one, so
// it follows the status area's light or dark appearance (macOS); Windows
// shows it as drawn, at the notification area's small-icon size, and Linux
// hands the host four sizes to choose from. False if
// the image could not be read; the previous icon, if any, stays.
bool setIconPath(const ICoreString& path);
void setToolTip(const ICoreString& text);
[[nodiscard]] ICoreString toolTip() const;
// The menu shown under the icon when it is clicked, or null for none. Not
// owned: the menu must outlive this icon, or be unset first.
void setMenu(ICoreMenu* menu);
[[nodiscard]] ICoreMenu* menu() const;
// A new icon is hidden until this is called.
void setVisible(bool visible);
[[nodiscard]] bool isVisible() const;
// Fires when the icon is clicked, before its menu (if any) opens. On
// Windows a left click, a right click and the keyboard's selection all
// count, and the menu opens at the cursor. On Linux the desktop draws the
// menu itself, in its own style, from the ICoreMenu's rows; a row it runs
// runs as a click on the painted row would, and a change to the rows reaches
// it while it is open.
[[nodiscard]] ICoreSignal<>& onActivated();
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreUiMetrics.h#
ICoreEssentials/UI/System/ICoreUiMetrics.h
ICoreUiMetrics#
ICoreUiMetrics.h:6 · class · 3 declaration(s)
Platform interaction constants, as a static facade.
class ICoreUiMetrics {
public:
ICoreUiMetrics() = delete;
// Pointer travel, in pixels, that turns a press into a drag.
static int startDragDistance();
// Maximum gap, in milliseconds, between the two clicks of a double-click.
static int doubleClickIntervalMs();
};
};
ICoreUiTimer.h#
ICoreEssentials/UI/System/ICoreUiTimer.h
ICoreUiTimer#
ICoreUiTimer.h:13 · class · pImpl · 11 declaration(s)
The client-facing timer.
class ICoreUiTimer {
public:
ICoreUiTimer();
~ICoreUiTimer();
ICoreUiTimer(const ICoreUiTimer&) = delete;
ICoreUiTimer& operator=(const ICoreUiTimer&) = delete;
void start(int intervalMs);
void start(); // reuse the configured interval, like the toolkit's no-arg start
void stop();
bool isActive() const;
void setSingleShot(bool singleShot);
void setInterval(int intervalMs);
int interval() const;
ICoreSignal<> onTimeout;
// Fire-and-forget delay. The scope gates delivery: if it dies first, the
// callable never runs -- this is the safe spelling of the
// QTimer::singleShot(ms, this, ...) idiom.
static void singleShot(int delayMs, ICoreSignalScope& scope, std::function<void()> fn);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreWeakObject.h#
ICoreEssentials/UI/System/ICoreWeakObject.h
ICoreWeakObject#
ICoreWeakObject.h:60 · class · 17 declaration(s)
A pointer to a toolkit-owned object that becomes null when the object dies.
class ICoreWeakObject {
public:
ICoreWeakObject();
~ICoreWeakObject();
ICoreWeakObject(const ICoreWeakObject& other);
ICoreWeakObject& operator=(const ICoreWeakObject& other);
ICoreWeakObject(ICoreWeakObject&& other) noexcept;
ICoreWeakObject& operator=(ICoreWeakObject&& other) noexcept;
// ⚠ DECLARED ONLY, DEFINED IN EACH SEAT -- and the reason is the header
// surface rule, which caught the first version of this change. The two
// TEMPLATE members these replaced carried their bodies here legitimately
// (exemption 1: a template must). A plain function may not, so R4.2 failed
// on `[body] body of ICoreWeakObject` the moment they stopped being
// templates. **Losing a template loses its body exemption**, which is not
// obvious until a guard says so.
//
// `nullptr` still converts, so a call site's null branch is unchanged.
ICoreWeakObject(ICoreNativeHandle nativeObject);
ICoreWeakObject& operator=(ICoreNativeHandle nativeObject);
// ⚠⚠ THE GUARD-RAIL, AND IT IS A COMPILE ERROR RATHER THAN A COMMENT.
// `ICoreNativeHandle` is a typedef for `void*`, so WITHOUT these two lines
// every `T*` in the language converts to it silently -- and that is
// precisely §48.4's trap walking back in: `ICoreWeakObject w = someChart;`
// would store the UNADJUSTED address of a `QChart` whose `QObject` base
// sits at a non-zero offset, with no diagnostic. The deleted templates make
// any pointer that is not already a handle ill-formed, so a caller must go
// through the wrapper's own `nativeObjectHandle()` -- the only place that
// can do the adjustment correctly.
//
// `nullptr` still reaches the overloads above (template deduction fails on
// `std::nullptr_t`), and an actual `ICoreNativeHandle` argument prefers the
// non-template on the tie-break. Both are pinned by the seat suite.
//
// Found by reading `operator=(void*)` in a linker message and asking
// whether a typedef can protect anything. It cannot.
template <class T>
ICoreWeakObject(T*) = delete;
template <class T>
ICoreWeakObject& operator=(T*) = delete;
[[nodiscard]] bool isNull() const;
explicit operator bool() const;
bool operator==(const ICoreWeakObject& other) const;
bool operator!=(const ICoreWeakObject& other) const;
void clear();
// The seam as<T>() calls, and what the two converting members above do.
void assign(ICoreNativeHandle nativeObject);
[[nodiscard]] ICoreNativeHandle object() const;
// Public only so the .cpp can pin them: one QPointer, measured on this
// tree's Qt 6.10.2, macOS arm64.
static constexpr std::size_t kNativeStorageSize = 16;
static constexpr std::size_t kNativeStorageAlign = 8;
};
ICoreWeakWidget.h#
ICoreEssentials/UI/System/ICoreWeakWidget.h
⚠⚠ <QPointer> AND ICoreNativeHandleAccess.h STOOD HERE AND ARE GONE (§0.145 Ruling 4, 2026-08-23).
ICoreWeak<T>held aQPointer<QWidget>INSIDE ITS TEMPLATE BODY -- the one Qt type a scanned portable header could not shed, because a template body cannot reach a per-seat buffer. It delegates to the non-template ICoreWeakNativeWidget core below now, which CAN: the same sealed-buffer shape ICoreWeakObject proved (§0.143), with a per-seat state behind public members. This header names Qt ZERO times, and it was the last blocker on ICoreNativeHandleAccess.h's relocation (§0.142).
ICoreWeakWidget#
ICoreWeakWidget.h:58 · class · 13 declaration(s)
A pointer to a widget that becomes null when the widget dies, for the "remember what I was anchored to" cases where the remembered widget may be destroyed first.
class ICoreWeakWidget {
public:
ICoreWeakWidget();
~ICoreWeakWidget();
ICoreWeakWidget(const ICoreWeakWidget& other);
ICoreWeakWidget& operator=(const ICoreWeakWidget& other);
ICoreWeakWidget(ICoreWeakWidget&& other) noexcept;
ICoreWeakWidget& operator=(ICoreWeakWidget&& other) noexcept;
ICoreWeakWidget(ICoreWidget* widget);
ICoreWeakWidget& operator=(ICoreWidget* widget);
[[nodiscard]] ICoreWidget* get() const;
ICoreWidget* operator->() const;
operator ICoreWidget*() const; // QPointer's implicit conversion, kept
explicit operator bool() const;
bool operator==(const ICoreWidget* other) const;
void clear();
// Public only so the .cpp can pin them. Measured, not assumed:
// QPointer<QWidget> is a QWeakPointer, {d-pointer, value} -- 16 bytes /
// align 8 on this tree's Qt 6.10.2, macOS arm64 -- plus the cached wrapper
// pointer.
static constexpr std::size_t kNativeStorageSize = 24;
static constexpr std::size_t kNativeStorageAlign = 8;
};
ICoreWeakNativeWidget#
ICoreWeakWidget.h:133 · class · 9 declaration(s)
The non-template CORE the template below stands on -- "is the native widget behind this handle still alive?", asked through an opaque ICoreNativeHandle so the header names no toolkit.
class ICoreWeakNativeWidget {
public:
ICoreWeakNativeWidget();
~ICoreWeakNativeWidget();
ICoreWeakNativeWidget(const ICoreWeakNativeWidget& other);
ICoreWeakNativeWidget& operator=(const ICoreWeakNativeWidget& other);
ICoreWeakNativeWidget(ICoreWeakNativeWidget&& other) noexcept;
ICoreWeakNativeWidget& operator=(ICoreWeakNativeWidget&& other) noexcept;
// Bind to a native widget handle; null unbinds. PUBLIC because the
// template's header body must reach the buffer through a public member --
// §0.143's own rule, and the header-surface rule bans a private helper.
void assign(ICoreNativeHandle native);
// Dead, unbound, or never bound -- one answer, no second test.
//
// ⚠ W9.11's `assignHandle()` AND A SECOND `isNull()` WERE MERGED IN BESIDE
// THESE ON 2026-08-24 AND ARE REMOVED. The two lines named the same seam
// differently -- W9.11 `assignHandle`, §0.145 Ruling 4 `assign` -- and git
// merged both declarations into one class WITHOUT A CONFLICT, because they
// are adjacent additions rather than competing edits. `assignHandle` had no
// definition in either seat and no caller anywhere (the template below
// calls `assign`), so it was a declaration that could only ever have become
// a link error; the duplicate `isNull()` was an outright redeclaration and
// is what the compiler actually stopped on.
[[nodiscard]] bool isNull() const;
void clear();
// Public only so the seats can pin them. Qt: QPointer<QWidget> is
// {d-pointer, value}, 16 / 8 on this tree's Qt 6.10.2, macOS arm64.
// AppKit: one __weak object reference, 8 / 8. The asserts in each seat
// use <=, as ICoreWeakWidget's AppKit seat already does.
static constexpr std::size_t kNativeStorageSize = 16;
static constexpr std::size_t kNativeStorageAlign = 8;
};
ICoreWeak#
ICoreWeakWidget.h:188 · class · 2 declaration(s)
class ICoreWeak {
public:
ICoreWeak() = default;
ICoreWeak(T* widget) { assign(widget); }
ICoreWeak& operator=(T* widget) {
assign(widget);
return *this;
}
// The cached wrapper, returned only while the NATIVE half is alive -- a
// dead wrapper shell is never handed out. Same contract as before the
// §0.145 refactor; only where the liveness answer lives moved.
T* get() const { return m_native.isNull() ? nullptr : m_wrapper; }
T* operator->() const { return get(); }
operator T*() const { return get(); } // QPointer's implicit conversion, kept
explicit operator bool() const { return !m_native.isNull(); }
void clear() { m_native.clear(); m_wrapper = nullptr; }
};
ICoreWindowTracker.h#
ICoreEssentials/UI/System/ICoreWindowTracker.h
ICoreWindowTracker#
ICoreWindowTracker.h:22 · class · nested Hooks · 3 declaration(s)
ICoreWindowTracker -- the Essentials-side seam for application window bookkeeping (ESSENTIALS_INDEPENDENCE D2).
class ICoreWindowTracker {
public:
struct Hooks {
std::function<void(ICoreWidget*)> windowOpened;
std::function<void(ICoreWidget*)> windowClosed;
};
static void installHooks(Hooks hooks);
static void notifyWindowOpened(ICoreWidget* window);
static void notifyWindowClosed(ICoreWidget* window);
};
};