{"id":46026457,"url":"https://github.com/wieslawsoltes/nativemessagebox","last_synced_at":"2026-03-01T03:01:58.018Z","repository":{"id":322797530,"uuid":"1090600079","full_name":"wieslawsoltes/NativeMessageBox","owner":"wieslawsoltes","description":"Cross-platform native message box library exposing a stable C ABI and a modern .NET 8 managed wrapper.","archived":false,"fork":false,"pushed_at":"2025-11-13T14:16:29.000Z","size":1786,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-13T16:22:29.634Z","etag":null,"topics":["messagebox","native"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wieslawsoltes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-05T22:11:03.000Z","updated_at":"2025-11-13T08:38:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/wieslawsoltes/NativeMessageBox","commit_stats":null,"previous_names":["wieslawsoltes/nativemessagebox"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/wieslawsoltes/NativeMessageBox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wieslawsoltes%2FNativeMessageBox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wieslawsoltes%2FNativeMessageBox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wieslawsoltes%2FNativeMessageBox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wieslawsoltes%2FNativeMessageBox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wieslawsoltes","download_url":"https://codeload.github.com/wieslawsoltes/NativeMessageBox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wieslawsoltes%2FNativeMessageBox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29959284,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T01:47:18.291Z","status":"online","status_checked_at":"2026-03-01T02:00:07.437Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["messagebox","native"],"created_at":"2026-03-01T03:01:57.123Z","updated_at":"2026-03-01T03:01:57.935Z","avatar_url":"https://github.com/wieslawsoltes.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NativeMessageBox\n\n[![NuGet](https://img.shields.io/nuget/v/NativeMessageBox.svg)](https://www.nuget.org/packages/NativeMessageBox/)\n[![NuGet (Downloads)](https://img.shields.io/nuget/dt/NativeMessageBox.svg)](https://www.nuget.org/packages/NativeMessageBox/)\n\nNativeMessageBox is a production-ready native dialog runtime that ships a stable C ABI, high-level .NET 8 wrapper, and first-class tooling for Windows, macOS, Linux, iOS, and Android. The project focuses on predictable behaviour, strong diagnostics, and packaging that fits both managed and native distribution pipelines.\n\n## Contents\n- [Feature Summary](#feature-summary)\n- [Feature Matrix](#feature-matrix)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Platform Implementations](#platform-implementations)\n- [Building From Source](#building-from-source)\n- [Samples](#samples)\n- [Documentation](#documentation)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Feature Summary\n\n| Feature | Description |\n| --- | --- |\n| Stable C ABI | `include/native_message_box.h` exposes a forward-compatible ABI with explicit struct sizing, version negotiation, and allocator hooks. |\n| Native implementations | Dedicated Windows (Task Dialog / MessageBox), macOS (NSAlert), Linux (GTK 3/4 with zenity fallback), iOS (UIKit), Android (AlertDialog), plus a WebAssembly browser overlay host. |\n| Managed .NET 8 wrapper | `NativeMessageBox` NuGet package with source-generated interop, async APIs, configurable host abstraction, and logging hooks. |\n| Rich dialog options | Multiple buttons, custom IDs, icons, verification checkboxes, timeouts, secondary content, and optional text/password/combo inputs (platform-dependent). |\n| Mobile packaging | Automated AAR (Android) and XCFramework (iOS) outputs with manifests describing ABIs, architectures, and build metadata. |\n| Tooling and CI | Cross-platform `build.sh`/`build.ps1`, native tests via `ctest`, managed unit tests, and packaging jobs suitable for CI/CD pipelines. |\n| Samples | Avalonia desktop and mobile samples demonstrating host integration, lifecycle management, and advanced dialog scenarios. |\n| Documentation | DocFX site under `docs/` covering architecture, API reference, troubleshooting, and platform-specific guidance. |\n\n## Feature Matrix\n\n| Capability | Windows | macOS | Linux (GTK) | iOS | Android | Web (Browser) |\n| --- | --- | --- | --- | --- | --- | --- |\n| Multi-button dialogs | Yes (Task Dialog supports 8+) | Yes | Yes | Yes | Partial (AlertDialog: 3 buttons) | Yes |\n| Custom button text/IDs | Yes | Yes | Yes | Yes | Yes (first 3 buttons) | Yes |\n| Button roles (default/cancel/destructive/help) | Yes | Yes | Partial (default/cancel) | Yes | Partial (positive/negative/neutral) | Yes (primary/cancel/destructive) |\n| Standard icons | Yes | Yes | Yes | No (ignored) | No (ignored) | No (style via CSS) |\n| Verification checkbox | Yes | Yes | Yes | No | No | Yes |\n| Text/password input | No (planned) | Yes | Yes | Yes (text/password) | No | Yes |\n| Combo box input | No | Yes | Yes | No | No | Yes |\n| Secondary informative/expanded content | Yes | Yes | Yes | No | No | Yes |\n| Help links / hyperlinks | Yes (Task Dialog hyperlink events) | Yes (opens via `NSWorkspace`) | Yes (GtkLinkButton) | No | No | No (render text only) |\n| Auto-close timeout | Yes | Yes | Yes | Yes | No | Yes |\n| Threading requirements | STA enforced for advanced dialogs | Must run on main thread | GTK main loop required | Must be called on main thread | Requires `Activity` on UI thread | Browser main thread (async overlay) |\n\n\u003e Notes: iOS ignores icons and secondary content but supports buttons, timeout, and single-line text/password input. Android is backed by `AlertDialog` and therefore limited to three buttons and no accessory controls. Windows falls back to `MessageBoxW` if Task Dialog APIs are unavailable.\n\n## Installation\n\n### .NET\n```bash\ndotnet add package NativeMessageBox\n```\n\n### Native C / C++\n1. Download the appropriate runtime archive from `artifacts/native-\u003crid\u003e.zip` (produced by the build).  \n2. Add `include/native_message_box.h` to your project.  \n3. Link against `nativemessagebox` for your runtime identifier (RID).  \n\n### Mobile\n- **Android**: Consume `artifacts/android/NativeMessageBox.aar` (or the published artifact) as an `\u003cAndroidLibrary\u003e` or Gradle dependency.  \n- **iOS**: Add `artifacts/ios/NativeMessageBox.xcframework` as a native reference in Xcode or the .NET for iOS project system.  \n\n## Usage\n\n### .NET example\n\n```csharp\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing NativeMessageBox;\n\nstatic async Task\u003cMessageBoxResult\u003e ShowExportPromptAsync()\n{\n    NativeMessageBoxClient.ConfigureHost(options =\u003e\n    {\n        // Allow background threads while still ensuring STA when required.\n        options.RequireStaThreadForWindows = true;\n    });\n\n    NativeMessageBoxClient.RegisterLogHandler(message =\u003e\n    {\n        Console.WriteLine($\"[NativeMessageBox] {message}\");\n    });\n\n    var buttons = new[]\n    {\n        new MessageBoxButton(100, \"Export\", MessageBoxButtonKind.Primary, isDefault: true),\n        new MessageBoxButton(200, \"Export \u0026\u0026 Open\", MessageBoxButtonKind.Secondary),\n        new MessageBoxButton(0, \"Cancel\", MessageBoxButtonKind.Secondary, isCancel: true)\n    };\n\n    var input = new MessageBoxInputOptions(\n        MessageBoxInputMode.Text,\n        prompt: \"File name:\",\n        placeholder: \"report.pdf\",\n        defaultValue: \"report.pdf\");\n\n    var secondary = new MessageBoxSecondaryContent(\n        informativeText: \"Select how you would like to export the report.\",\n        expandedText: \"Exports use the system temporary directory unless a custom path is provided.\",\n        footerText: \"Need automation? Configure auto-export from Settings.\",\n        helpLink: \"https://github.com/NativeMessageBox/NativeMessageBox/wiki/Export\");\n\n    var options = new MessageBoxOptions(\n        message: \"Export completed successfully. What would you like to do next?\",\n        buttons: buttons,\n        title: \"Export Finished\",\n        icon: MessageBoxIcon.Information,\n        inputOptions: input,\n        secondaryContent: secondary,\n        verificationText: \"Remember my choice\",\n        showSuppressCheckbox: true,\n        timeout: TimeSpan.FromSeconds(30),\n        timeoutButtonId: 0);\n\n    return await NativeMessageBoxClient.ShowAsync(options);\n}\n```\n\nThe returned `MessageBoxResult` exposes `Outcome`, the selected `ButtonId`, any `InputValue`, `CheckboxChecked`, and whether the dialog timed out. Use `NativeMessageBoxClient.ShowOrThrow` when failure conditions should surface as exceptions.\n\n### Native C example\n\n```c\n#include \"native_message_box.h\"\n\nint main(void)\n{\n    NmbInitializeOptions init = {0};\n    init.struct_size = sizeof(init);\n    init.abi_version = NMB_ABI_VERSION;\n    init.runtime_name_utf8 = \"demo-app\";\n    nmb_initialize(\u0026init);\n\n    NmbButtonOption buttons[2] = {};\n    buttons[0].struct_size = sizeof(NmbButtonOption);\n    buttons[0].id = NMB_BUTTON_ID_OK;\n    buttons[0].label_utf8 = \"Retry\";\n    buttons[0].is_default = NMB_TRUE;\n\n    buttons[1].struct_size = sizeof(NmbButtonOption);\n    buttons[1].id = NMB_BUTTON_ID_CANCEL;\n    buttons[1].label_utf8 = \"Cancel\";\n    buttons[1].is_cancel = NMB_TRUE;\n\n    NmbMessageBoxOptions options = {0};\n    options.struct_size = sizeof(options);\n    options.abi_version = NMB_ABI_VERSION;\n    options.title_utf8 = \"Connection lost\";\n    options.message_utf8 = \"The remote endpoint is unavailable.\";\n    options.buttons = buttons;\n    options.button_count = 2;\n    options.icon = NMB_ICON_WARNING;\n    options.timeout_milliseconds = 15000;\n    options.timeout_button_id = NMB_BUTTON_ID_CANCEL;\n\n    NmbMessageBoxResult result = {0};\n    result.struct_size = sizeof(result);\n\n    NmbResultCode rc = nmb_show_message_box(\u0026options, \u0026result);\n    if (rc == NMB_OK)\n    {\n        // Inspect result.button, result.was_timeout, etc.\n    }\n\n    nmb_shutdown();\n    return 0;\n}\n```\n\n## Platform Implementations\n\n### Windows\n- Uses `TaskDialogIndirect` when available (Windows Vista+ with `comctl32` v6).  \n- Falls back to `MessageBoxW` when advanced features are not requested or Task Dialog is unavailable.  \n- Supports icons, verification checkbox, hyperlink footer, auto-close timers, and ESC/close policy controls.  \n- Advanced scenarios require running on an STA thread; the managed host enforces this unless explicitly disabled.\n\n### macOS\n- Backed by `NSAlert`, accessory views, and `NSStackView` compositions.  \n- Supports checkboxes, text/password fields, combo boxes, secondary informative text, footers, help buttons, and auto-close timers.  \n- Requires invocation on the main thread. Timeout handling uses `dispatch_source_t` to trigger button actions safely.\n\n### Linux (GTK 3/4)\n- Implements dialogs via `GtkMessageDialog` and custom content areas.  \n- Supports multiple buttons, checkbox verification, text/password/combo inputs, secondary/expanded text, help links, and timeouts via `g_timeout_add`.  \n- Respects modality flags and ESC handling. When GTK is unavailable, the fallback shell path uses `zenity`.\n\n### iOS\n- Implements dialogs through `UIAlertController`.  \n- Supports custom button labels, default/cancel/destructive roles, single text/password input, and timeouts using `dispatch_after`.  \n- Ignores secondary content, verification checkboxes, and icon hints (these limitations are logged via the runtime callback). Requires a presenter `UIViewController`.\n\n### Android\n- Uses a lightweight Java bridge around `AlertDialog`.  \n- Supports up to three buttons (positive/negative/neutral) with custom labels and IDs.  \n- Does not support accessory input, verification checkboxes, icons, or auto-close timers.  \n- Requires an `Activity` reference supplied through `MessageBoxOptions.ParentWindow`.\n\n## Building From Source\n- macOS / Linux: `./build/build.sh --all`  \n- Windows / PowerShell 7+: `pwsh build/build.ps1 -All`  \n- WebAssembly-only packaging: `./build/build.sh --wasm` (requires an Emscripten environment)  \n- See `docs/building.md` for prerequisites, optional flags (`--skip-tests`, `--config Debug`, `-Targets android,ios,wasm`), and environment variables used by the Android/iOS packaging scripts.\n\n## Samples\n- `samples/Showcase` demonstrates feature coverage on desktop platforms.  \n- `samples/DialogPlayground` enables experimenting with different button layouts, icons, and inputs.  \n- `samples/CrossPlatformSample` targets desktop, Android, iOS, and the browser. Run `dotnet publish samples/CrossPlatformSample/NativeMessageBox.CrossPlatformSample.Browser -c Release` (optionally after `./build/scripts/package-wasm.sh`) to exercise the Web overlay.  \n- Mobile samples consume the generated AAR/XCFramework to illustrate lifecycle integration. Build the solution via `dotnet build samples/AvaloniaSamples.sln`.\n\n## Documentation\n- Run `docs/build-docs.sh` to generate the DocFX site under `docs/docfx/_site`.  \n- Key entry points: `docs/quickstart.md`, `docs/managed-api.md`, `docs/advanced-usage.md`, `docs/architecture.md`, `docs/android-packaging.md`, `docs/ios-packaging.md`, and `docs/browser-deployment.md`.\n\n## Contributing\n- Review `CONTRIBUTING.md`, `MAINTENANCE.md`, and `SECURITY.md`.  \n- Use topic branches and include unit tests when extending native or managed functionality.  \n- File issues with platform details, reproduction steps, and diagnostics captured via `NativeMessageBoxClient.RegisterLogHandler`.\n\n## License\n\nThis project is licensed under the MIT License. See `LICENSE` for full details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwieslawsoltes%2Fnativemessagebox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwieslawsoltes%2Fnativemessagebox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwieslawsoltes%2Fnativemessagebox/lists"}