Releases: Redth/Maui.Gtk
v0.6.0 — libsecret SecureStorage
What's New
- SecureStorage now uses libsecret (GNOME Keyring / freedesktop.org Secret Service) when available, with automatic fallback to AES-256 encrypted file storage
- New
LinuxSecureStorage.Backendproperty exposes the active backend ("libsecret"or"encrypted-file") - Sample app shows which SecureStorage backend is in use
Details
SecureStorage previously stored the AES encryption key as a plaintext file next to the encrypted data — security was file-permission based only. Now on GNOME desktops (and any system with a Secret Service provider), secrets are stored in the system keyring via libsecret P/Invoke. Systems without libsecret or a running keyring daemon fall back to the previous encrypted-file approach automatically.
v0.5.1
Fixes
- Modal dialog sizing: Use
SetSizeRequeston the content widget instead ofSetDefaultSizeon the window, so the requested dimensions describe the content area. GTK adds the CSD titlebar height automatically.
Full Changelog: v0.5.0...v0.5.1
v0.5.0
What's New
Native GTK4 Modal Dialog Windows (#9)
PushModalAsync now presents pages as native GTK4 modal windows by default — a real Gtk.Window with SetModal(true) and SetTransientFor(parent) — instead of inline widget swapping.
New GtkPage attached properties
Aligned with the macOS MacOSPage API from shinyorg/mauiplatforms:
| Property | Type | Default | Description |
|---|---|---|---|
ModalPresentationStyle |
GtkModalPresentationStyle |
Dialog |
Dialog (native window) or Inline (legacy) |
ModalSizesToContent |
bool |
false |
Measure MAUI content and size dialog to fit |
ModalWidth / ModalHeight |
double |
-1 |
Explicit dialog size (-1 = match parent) |
ModalMinWidth / ModalMinHeight |
double |
-1 |
Minimum size constraints |
Examples
// Default — full-size native dialog:
await Navigation.PushModalAsync(new MyPage());
// Custom size:
GtkPage.SetModalWidth(page, 400);
GtkPage.SetModalHeight(page, 300);
// Sizes to content:
GtkPage.SetModalSizesToContent(page, true);
GtkPage.SetModalMinWidth(page, 250);
// Legacy inline:
GtkPage.SetModalPresentationStyle(page, GtkModalPresentationStyle.Inline);Full Changelog: v0.4.0...v0.5.0
v0.4.0
What's New
Linux Packaging Support
Added MSBuild targets for producing Linux distribution packages from MAUI apps:
- AppImage —
dotnet publish -r linux-x64 --self-contained -p:CreateAppImage=true - Debian (.deb) —
dotnet publish -r linux-x64 --self-contained -p:CreateDeb=true - Flatpak —
dotnet publish -r linux-x64 --self-contained -p:CreateFlatpak=true
All formats automatically use MAUI conventions (ApplicationId, ApplicationTitle, ApplicationDisplayVersion, MauiIcon) and auto-detect BlazorWebView/WebKitGTK dependencies.
See AppImage docs, Deb docs, and Flatpak docs for details.
v0.3.1 — Switch Styling Fix
Bug Fixes
🔘 Switch Control — Rounded Corners Restored
The Switch track was rendering with rectangular corners instead of its native GTK4 pill shape.
Root cause: The MapClip handler in GtkViewHandler was applying border-radius: 0; to every widget when no clip geometry was set. This blanket CSS override stripped the Adwaita theme's default rounded styling from the Switch (and potentially other widgets with theme-defined border-radius).
Fixes:
- Removed the blanket
border-radius: 0;from the null-clip path inMapClip— the theme's native styling is now preserved when no clip is set - Added
border-radius: 9999px;toMapTrackColorCSS so custom track colors also preserve the pill shape
📄 Docs
- Fixed asset link in README
Full Changelog: v0.3.0...v0.3.1
v0.3.0 — Multi-Window & Theme Support
What's New
🪟 Multi-Window Support
Application.OpenWindow()andApplication.CloseWindow()now work — open and close additional windows at runtime- Full window lifecycle:
Activated,Deactivated,Destroyingevents fire correctly - Window registry tracks all open windows with proper cleanup on close
- Follows the same
CreateWindow(activationState)pattern as WinUI and macOS backends
🎨 App Theme (Light/Dark Mode) Support
- Force Light / Force Dark / Follow System — set
Application.UserAppThemeto override or follow the desktop theme Application.PlatformAppThemecorrectly reports the system theme (Light or Dark) from GTK settingsAppThemeBinding/SetAppThemeColorrespond to theme changes — UI updates automatically- System theme monitoring: if the desktop switches between light and dark, the app detects it and updates
- Switches both the GTK
prefer-dark-themeflag and the actual theme name (e.g.Yaru↔Yaru-dark)
🔧 Under the Hood
- New
GtkAppInfoImplementationregisters with MAUI Essentials soAppInfo.RequestedThemereturns the correct system theme GtkThemeManagerseparates system theme detection from app-level overrides (matches the iOS/macOS pattern wherePlatformAppThemealways reflects the OS preference)- Removed broken variadic
g_object_setP/Invoke (doesn't work on ARM64), uses GirCore property setters instead
📄 Sample Pages
- Multi-Window Page — Open/Close buttons, window count display, secondary window with its own content
- Theme Page — Force Light/Dark/System buttons, live theme status label,
AppThemeBindingcolor demo
v0.2.4
What's New
Bug Fixes
- Fix Shell flyout sidebar not rendering — The Shell flyout navigation sidebar was not visible when using
ShellContentitems directly underShell(flyout mode). This happened becauseShell.FlyoutIsPresenteddefaults tofalse(a mobile UX pattern), but on desktop GTK the sidebar should be shown by default. The Shell handler now auto-presents the flyout when it's enabled and has multiple items.
Upgrade Notes
Apps using Shell with direct ShellContent items (the default flyout pattern) will now correctly see a sidebar with navigation items on the left side of the window. Apps using TabBar are not affected.
v0.2.3 — Jitter-Free Layout & Scroll Fix
What's Changed
🏗️ CustomLayout Refactor — Jitter-Free Sizing
- Replaced GTK's FixedLayout with a CustomLayout via P/Invoke (
gtk_custom_layout_new), so children are allocated at their MAUI-arranged sizes directly during GTK's native layout phase — no more post-paint corrections that caused visible 1–2 frame jitter when scrolling or resizing. - Static native callbacks with instance tracking prevent GC delegate collection crashes.
- New API:
AddChild/RemoveChild/SetChildBounds/SetChildTransformreplaceFixed.Put/Moveinternals.
🔧 ScrollView Scrolling Fix
- Fixed scrolling not working after the CustomLayout refactor:
SetChildBoundsnow usesQueueResize()instead ofQueueAllocate()so parent widgets (ScrolledWindow/Viewport) re-measure and discover the full content extent.- Set GTK Viewport scroll policy to
NATURALvia P/Invoke, since our CustomLayout returnsminimum=0(to prevent window growth) butnatural=content_heightfor correct scroll range.
📐 Layout & Sizing Improvements
- Pages no longer auto-wrap content in a ScrollView — developers add ScrollView explicitly (matches iOS/Android behavior).
- Scrollable views (ScrollView, CollectionView) no longer expand the window to their full content height.
- CollectionView DataTemplate refactored to use the full MAUI handler pipeline (
ToPlatform+MarkExternallyManaged). - Added Border, Frame, and ContentView support inside CollectionView DataTemplates.
Full Changelog
v0.2.2 — RefreshView, SwipeView & Animation Fixes
What's Changed
Bug Fixes
-
Animations now work visually — Fixed property mapper chain: 12 handlers were chaining from
ViewHandler.ViewMapper(MAUI base) instead ofGtkViewHandler.ViewMapper, so transform/opacity mappers were never invoked during animations. Also addedRemoveAll<ITicker>()to ensureGtkPlatformTickerisn't overridden by MAUI's default.TranslateTo,FadeTo,ScaleTo,RotateToall verified working at ~60fps- Translation-only animations use
Gtk.Fixed.Move()directly for reliability
-
RefreshView layout fixed — Removed
SetVexpand(true)that caused RefreshView to consume all vertical space in a StackLayout. AddedPlatformArrangeoverride to size content correctly. -
SwipeView cleaned up:
- Action buttons now hidden at rest — only revealed as the card is dragged
- Left actions show only when dragging right, right actions only when dragging left
- Buttons hide again on snap-close and after action invoke
- Added
PlatformArrangefor proper Fixed container sizing
-
Dark theme compatibility — Removed hardcoded light background colors from RefreshView item list and SwipeView card that were invisible in dark themes.
Other
- Updated README with comprehensive feature parity tables (43 handlers, 20 Essentials services)
- CI now auto-publishes NuGet packages on GitHub release creation
Full Changelog: v0.2.1...v0.2.2
v0.2.1 — Animation Fix & CI Improvements
What's Changed
Bug Fixes
- Animations now work visually — Fixed two root causes:
- 12 handlers had their property mapper chained from
ViewHandler.ViewMapper(MAUI base) instead ofGtkViewHandler.ViewMapper, so transform/opacity mappers were never invoked during animations - Added
RemoveAll<ITicker>()before registeringGtkPlatformTickerto ensure MAUI's default timer doesn't override ours
- 12 handlers had their property mapper chained from
- Translation-only animations use
Gtk.Fixed.Move()directly for better reliability; rotation/scale still useGsk.Transform
CI/CD
- NuGet packages now auto-publish on GitHub release creation
- Added
release: publishedtrigger to the build workflow
Verified Working
TranslateTo,FadeTo,ScaleTo,RotateTo— all animation types confirmed working at ~60fps- Combined/parallel animations work correctly
Full Changelog: v0.2.0...v0.2.1