Skip to content

2.12.0

Choose a tag to compare

@github-actions github-actions released this 24 Sep 04:29
· 146 commits to develop since this release
1770d3f

✨ Highlights

Eto.Forms 2.12 is a big release: it adds app-wide themes, custom WPF color palettes, new cross-platform dialogs, gestures, IME support for custom-drawn controls, high DPI for WinForms, and much better Wayland support. It also includes well over 100 fixes across every platform.

🎨 Themes

Apps can now pick a theme and switch it while running. Application.Instance.Theme sets it, Themes.AllThemes lists the ones the platform offers, and Application.ThemeChanged / Control.ThemeChanged tell you when it changes. Themes.System, Themes.Light and Themes.Dark work on every desktop platform:

  • WPF: native Fluent light/dark themes on .NET 9+, and follows the system's light/dark setting automatically. You need to opt in (see below).
  • macOS: maps to NSAppearance (Aqua, Dark Aqua, …)
  • GTK: GTK theme names plus the prefer-dark setting
  • WinForms: maps to the .NET color mode

Important

WPF apps keep the classic look unless they opt in. We recommend using the system theme, so your app follows the user's Windows light/dark setting. Set it before showing your first window:

Application.Instance.Theme = Themes.System;

The Fluent themes (Themes.System, Themes.Light, Themes.Dark) need .NET 9 or later. On .NET Framework, WPF stays on the classic look.

theme-light theme-dark

🖌️ Custom palette themes for WPF

You can re-skin every standard WPF control by supplying only a list of colors in a resource dictionary. No control templates or custom handlers needed. You can also opt in to rounded corners and roomier padding, and the Windows 11 title bar is tinted to match. Themes can be switched at runtime, and windows that are already open restyle immediately.

ThemesHandler.Instance.Themes.Add(new PaletteTheme("Mocha", ThemeStyle.Dark,
    new Uri("pack://application:,,,/MyApp;component/themes/MochaPalette.xaml")));
theme-mocha theme-midnight theme-latte

All three are the same window; only the palette file differs. See #3054 for the full palette reference and a sample file.

🧩 New cross-platform dialogs and controls, with no third-party WPF dependency

Eto.Wpf no longer depends on Extended.Wpf.Toolkit. The controls it provided have been replaced with new themed controls that follow the active theme and work on any platform:

  • Color dialog with a color spectrum, hue strip, RGB/alpha sliders, hex input and live preview
  • Font dialog
  • NumericStepper, ListBox and TreeView versions that follow the theme
  • A new built-in DateTimePicker for WPF
color-dialog-mocha font-dialog-light

👆 Gestures

The new Control.Gestures collection adds pinch-to-zoom, rotate, pan and scroll gestures (MagnificationGesture, RotationGesture, PanGesture, ScrollGesture) on Mac, WPF, WinForms and GTK. Gestures can be recognized at the same time as each other, panning can be driven by a chosen mouse button, and IsDirectionInverted tells you whether the user has "natural" scrolling turned on.

⌨️ IME support for custom-drawn text controls

A Drawable can now accept full IME input (for example Chinese, Japanese or Korean) through TextComposition, TextInsertionBoundsRequested, CommitTextComposition() and CancelTextComposition(). Key events are also suppressed during IME composition on WPF and Mac.

🖥️ Platform improvements

  • WinForms: supports high DPI on .NET 9+. Call Application.SetHighDpiMode(...) before starting your app.
  • Linux / Wayland: native Wayland clipboard (including change notifications), correct primary screen, positioning of borderless child windows, the DateTimePicker drop-down, window sizing fixes, and many GTK sizing and selection fixes.
  • macOS: much faster TreeGridView with large numbers of rows, a series of fixes for Tahoe (button colors, checkbox/radio alignment), better handling of alternative keyboard layouts, and fixed WebView leaks.
  • WPF: can choose the text rendering mode (TextFormattingMode) for fonts, FormattedText and Graphics. Fixes layout hangs and deadlocks, focus and keyboard problems, and icons cut off at unusual DPI settings. WebView2 no longer takes the app down if the browser process crashes.

🆕 Other new APIs

  • Clipboard.Changed event, on all desktop platforms and iOS
  • Window.PreviewKeyDown / PreviewKeyUp to see every keystroke, even ones a control handles
  • Control.TabStop
  • Label.Trimming, LinkButton.Trimming and LinkButton.Wrap
  • Button.ImageNextToText
  • TextBox.GetCharacterIndex(location)
  • TextChangingEventArgs.Source
  • ContextMenu.IncludeSystemItems, for example to hide AutoFill on macOS
  • Font.UnderlinePosition / UnderlineThickness
  • An improved NumericMaskedTextStepper, and updates to DateTimePicker

⚠️ Worth knowing when upgrading

  • Eto.Wpf no longer references Extended.Wpf.Toolkit. If your app used it indirectly, add the package reference yourself.
  • WPF's color dialog, font dialog, NumericStepper and TreeView now use the new themed controls, so they will look different.
  • Application now initializes its platform handler in its constructor, not in Run().

What's Changed

🚀 Features

🐛 Bug Fixes

  • Gtk: avoid duplicate clipboard entries on repeated updates by @Descolada in #2916
  • Gtk: Fix DateTimePicker drop down on Wayland by @cwensley in #2919
  • Fix GTK GroupBox to adhere to user-preferred size by @Descolada in #2918
  • Ensure setting/getting colors in a Bitmap and on Drawable are correct by @cwensley in #2920
  • WPF: Fix issue with scrollable controls when used in a AutoSize window by @cwensley in #2922
  • Wpf: Fix selection of drop down items with fluent theme by @cwensley in #2923
  • Mac: Fix VS Code launching and dmg path by @cwensley in #2924
  • Include Mac.props/targets when using LocalEtoPath with Sdk by @cwensley in #2925
  • Mac: Don't set RunCommand when MacBuildBundle is not true by @cwensley in #2932
  • Fix concurrent issues with DefaultStyleProvider by @cwensley in #2934
  • Mac: Don't beep during IME composition when e.Handled = true by @cwensley in #2937
  • Mac: Fix CellEventArgs.CellTextColor after switching from dark to light by @cwensley in #2939
  • Wpf: Only enable column virtualization when GridView.RowHeight is specified by @cwensley in #2943
  • Mac: Fix issues editing when for controls that don't implement IMacViewHandler by @cwensley in #2944
  • Mac: Fix calculation of font size/position/trimming in DropDown when formatting items by @cwensley in #2948
  • Mac: Check if WebView is disposed before calling events by @cwensley in #2951
  • Wpf: Fix deadlock calling UpdateLayout during resize by @cwensley in #2953
  • Wpf: Fix scaling of child controls when setting content of loaded control by @cwensley in #2954
  • Wpf: Use DispatcherPriority.Loaded during updatelayout by @cwensley in #2957
  • Wpf: Fix infinite layouts/hang when using Scrollable by @cwensley in #2956
  • Wpf/WinForms: Use 64 bit apis for HwndFormHandler WndProc hook by @cwensley in #2958
  • Eto.Gtk: render fonts via Pango AttrFontDesc instead of OverrideFont by @cwensley in #2959
  • Eto.Gtk: treat null TextArea.Text as empty string by @cwensley in #2961
  • Eto.Gtk: implement AlwaysShowMnemonic by @cwensley in #2960
  • Wpf: Set TextBox CaretBrush when setting TextColor by @cwensley in #2967
  • Mac: Avoid crash if a drag drop cannot be started with DoDragDrop by @cwensley in #2968
  • Wpf/WinForms: Don't throw an exception in WebView2 when it was aborted by @cwensley in #2969
  • Fix NumericMaskedTextStepper add/subtract in netfx by @cwensley in #2974
  • Fix wrapping of CheckBox when using Display (GDI) font rendering by @cwensley in #2975
  • Fix autosize and scrollable content width by @cwensley in #2976
  • Fix wrapping with TextArea by @cwensley in #2979
  • Mac: Fix Button.Color, especially in Tahoe by @cwensley in #2980
  • FileDialog: Preserve the current working directory by @Descolada in #2962
  • Gtk: Fix Screens.PrimaryScreen under wayland by @cwensley in #2982
  • Gtk: Fix critical when using Tree/GridView and ListBox by @cwensley in #2984
  • Gtk: Fix critical when calling GetPreferredSize() on controls by @cwensley in #2985
  • Gtk: Window.Visible should not be true before shown by @cwensley in #2986
  • Gtk: Fix setting size when allocation is 1,1 on Wayland by @cwensley in #2987
  • Eto.Gtk: use IMContextSimple for native text widgets by @cwensley in #2988
  • Gtk: Implement child window positioning for WindowStyle.None on Wayland by @cwensley in #2989
  • Gtk: If no main window is set, application should not exit when last window is closed by @cwensley in #2991
  • Gtk: Fix Tree/GridView.GetPreferredSize() by @cwensley in #2992
  • Gtk: Fix TextChanged firing multiple times when inserting text by @cwensley in #2994
  • Mac: ScrollGesture should not activate for MouseWheel by @cwensley in #2995
  • Wpf: Fix sizing of Tree/GridView content when not in autosized window by @cwensley in #2996
  • Wpf/Mac: Suppress key events during IME composition by @cwensley in #2999
  • Wpf: Fix using icons with ListBox by @cwensley in #3006
  • Don't use TryGetData by @cyanfish in #3005
  • Mac: Fix ToEtoKeyEventArgs for alternative keyboard layouts by @cyanfish in #3003
  • Wpf: Fix clearing selection of a Tree/GridView with single selection by @cwensley in #3007
  • Wpf: Fix MouseUp buttons when losing capture on a control by @cwensley in #3008
  • DragDropLib fixes by @cwensley in #3009
  • Wpf: Allow WindowStyle.None windows to be small again by @cwensley in #3012
  • Handle SegmentedItem.SelectedChangedEvent to avoid warnings in debug by @cwensley in #3013
  • Wpf: Fix last unit tests by @cwensley in #3014
  • MouseUp on lost capture now passes MouseButtons.None by @cwensley in #3015
  • Mac: Fix WebView leaks and default size by @cwensley in #3016
  • Mac: Resource tests only work when run from the app, so skip in CI by @cwensley in #3018
  • Mac: Provide default size for TreeView and NativeControl by @cwensley in #3019
  • Fix timeout of TreeGridViewTests on CI by @cwensley in #3020
  • Fix DateTimeMaskedTextProvider for non-space whitespace characters by @cwensley in #3022
  • Manually pack 24-bit RGB in GetPixel by @khang06 in #3000
  • Gtk: Fix BitmapTests and 24bpp translation by @cwensley in #3024
  • Gtk: Fix splitter tests by @cwensley in #3025
  • Gtk: Fix controltests and gc by @cwensley in #3026
  • More fixes for DragDropLib by @cwensley in #3030
  • Wpf: Fix measurement of text area scroll view by @cwensley in #3032
  • Mac: Make NumericStepper properly handle Culture by @cwensley in #3034
  • Fixes a fews bugs in FilteredCollection by @clicky in #3035
  • Wpf: Add option to disable automation for Tree/GridView for performance reasons by @cwensley in #3036
  • Mac: Fix message box size flashing, and allow override for which image to show by @cwensley in #3038
  • Mac: fix incorrect runtime warning for SegmentedItem.SelectedChanged event by @cwensley in #3042
  • Mac: KeyEventArgs.IsChar should not be true for non-characters by @cwensley in #3043
  • Mac: Fix double extension when it starts with a "." by @cwensley in #3045
  • Wpf: Fix KeyDown/Up events on Form when no control has focus by @cwensley in #3046
  • Wpf: Fix keyboard focus after window is disabled/enabled by @cwensley in #3047
  • Wpf: Tweak restore focus to the window instead of first control when re-enabled by @cwensley in #3048
  • missing opacity field assignment in TextureBrush constructor by @sbaer in #3049
  • Update templates to detect isNetCore for net10.0 by @cwensley in #3051
  • Wpf: Fix dpi awareness switch in release mode by @cwensley in #3053
  • Wpf: GridView/ListBox should only scroll itself when making a row visible by @cwensley in #3055
  • Mac: Properly align checkbox/radiobutton on Tahoe by @cwensley in #3057
  • Mac: Keep selection of TreeGridView when reloading by @cwensley in #3058
  • provide lock for some static resources by @sbaer in #3061
  • Wpf: Allow SystemColors to be read on non-ui threads by @cwensley in #3062
  • Mac: Fix MouseUp on some controls by @cwensley in #3063
  • Wpf: Fix issue with chopped off icons in odd DPIs by @cwensley in #3066
  • Gtk: Fix scrollable tests by @cwensley in #3068
  • WebView2: don't take the app down when the browser process has crashed by @cwensley in #3067
  • Gtk: Ensure selection isn't set when AllowEmptySelection is true by @cwensley in #3069
  • Gtk: Ensure TreeGridView.SelectedItemChanged fires when setting SelectedRows by @cwensley in #3070
  • Other Changes

    New Contributors

    • @github-actions[bot] made their first contribution in #2915
    • @khang06 made their first contribution in #3000
    • @sbaer made their first contribution in #3049

    Full Changelog: 2.11.0...2.12.0