Skip to content

0.4.4: the system's object models — windows::com and macos::objc - #24

Merged
Sunrisepeak merged 5 commits into
mainfrom
platform-com-objc
Nov 9, 2026
Merged

Sunrisepeak merged 5 commits into
mainfrom
platform-com-objc

Conversation

@Sunrisepeak

@Sunrisepeak Sunrisepeak commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

Summary

Version 0.4.4: only additions, so a consumer's ^0.4 (and mtest's ^0.4.1, which the package under test must satisfy to stand for itself) still holds.

Two platform modules gain the system's object models, through which its services that are objects rather than functions are reached (toast notifications, the shell's dialogs, the Windows Runtime's classes; Foundation, AppKit, UserNotifications):

  • mcpplibs::os::windows::com: apartment::enter, object (one reference, AddRef/Release paired), object::call(slot, args...), query, create, hstring (UTF-8 there and back), activate, factory, delegate (an agile object the system calls back: Invoke(sender, args)), id("…") at compile time, checked(HRESULT) → errc.
  • mcpplibs::os::macos::objc: id (one reference, objc_retain/objc_release paired), send<R>(receiver, selector, args...), autorelease_pool, class_named, selector, load_framework, string/utf8 (NSString), define_class (a delegate's methods), block(function) (a block the runtime holds and releases).

The rules

  • R2: only the object models themselves; what a service is (a notification's contract) belongs to the library above. The first consumer is mpal (openmui), for Windows toast and macOS UserNotifications.
  • R4: native pointers only in these platform types.
  • R5: declared on every target, defined on its own platform; not defined in an image (it loads no library of the system) — the README's image table says so, and a consumer asks if constexpr (os::is_windows). checks/discarded now covers a member template (object::call, objc::send) in a discarded branch.
  • R6: every reference is paired here (AddRef/Release, retain/release, the block's copy/dispose helpers).
  • R7: hstring and NSString from and to UTF-8; the tests carry four scripts and an emoji.
  • No system header, no macro, no new link input: ole32/combase are found with LoadLibraryW/GetProcAddress (as advapi32 is), libobjc and libSystem's blocks through os::library.

Test plan

  • Linux native (mcpp 2026.11.9.1, gcc 16.1): windows_test, macos_test (nothing to ask there), checks/discarded links.
  • Windows units compile with the mingw cross gcc 16.1 (com.cpp, windows_test.cpp); that toolchain's link fails here for every test alike (libstdc++'s _Sp_make_shared_tag twice), so the run is CI's.
  • CI: Windows (llvm, msvc, hosted) — a Windows Runtime Uri made and its methods called by slot, an interface it lacks refused (not_supported), an unknown class not_found, a delegate called back and released.
  • CI: macOS (llvm, hosted) — NSString round trips, NSProcessInfo asked, a class defined here receiving messages, an NSArray enumerated with a block that is released after; in a static program, available() is not_supported.
  • CI: images and Emscripten build and pass the two suites (nothing to ask).

The services of a system that are objects rather than functions (toast
notifications, the shell's dialogs, the Windows Runtime's classes; Foundation,
AppKit, UserNotifications) are reached through two platform modules' new
namespaces (R2, R5): declared on every target, defined on their own platform,
not defined in an image. Their libraries are found when first used (ole32,
combase; libobjc and libSystem's blocks through os::library), so nothing is
added to a program's link and no system header is included.

Windows: apartment, object (AddRef/Release paired), call by slot, query,
create, hstring (UTF-8, R7), activate, factory, delegate (an agile object the
system calls back), HRESULT -> errc. macOS: id (retain/release paired),
send<R>, autorelease_pool, class_named, selector, load_framework, NSString
to and from UTF-8, define_class, block.

Tests: windows_test and macos_test (counterparts in checks/hosted and
checks/emscripten, in CI's lists); the R5 discarded check covers a member
template.
@Sunrisepeak Sunrisepeak changed the title 0.5.0: the system's object models — windows::com and macos::objc 0.4.4: the system's object models — windows::com and macos::objc Nov 9, 2026
…class, not libobjc's (a string made before any framework was loaded was sent to nil)
…tform defines — object's and id's assignments (they release) and utf8(const id&) out of line; clang and MSVC on Windows emitted id::operator= into every program
@Sunrisepeak
Sunrisepeak merged commit 394c1a6 into main Nov 9, 2026
23 checks passed
Sunrisepeak added a commit to Sunrisepeak/mui that referenced this pull request Nov 9, 2026
…s 0.4.4's object models — no system header; mpal on every system in minutes (mpal.yml)

- mcpplibs.os 0.4.4 (mcpplibs/os#24, released, mcpp-index#746): windows::com and
  macos::objc. Every os pin moves to 0.4.4.
- mpal:native (internal partition): a system's notification centre, declared
  everywhere, defined in src/macos and src/windows, built for that system alone;
  Notifier and notify() dispatch to it in a native macOS or Windows build.
- macOS: UserNotifications for a program with a bundle identifier (a bare one
  is told: unavailable); permission asked once, a refusal with the system's
  reason; each notification's category carries its actions and asks for the
  dismissal; a delegate class (made at run time) brings the person's answer to
  Notifier::next; shown in front too.
- Windows: Windows Runtime toasts; an unpackaged program is named by a Start
  menu shortcut with its AppUserModelID (IShellLinkW, IPropertyStore,
  IPersistFile, made when missing); Activated and Dismissed come back through
  com::delegate (weakly holding the centre); close hides the toast.
- .github/workflows/mpal.yml: mpal's tests on Linux, macOS and Windows when
  mpal changes (the full matrix takes about two hours).
- Tests: on macOS a bare program gets unavailable, and a copy of the test
  program inside a temporary .app (mtest child) gets "shown" or "refused" with
  the reason; on Windows a toast shown (or refused with its reason) and the
  shortcut made. The real-bus case waits for dbus-daemon to end before removing
  its directory (a race seen once).

Verified locally: mcpp test -p mpal 8 passed (three runs) on os 0.4.4; lint 0.
macOS and Windows: mpal.yml on this push.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant