* Make FlyoutBase.IsOpen a public StyledProperty with two-way binding support
Convert IsOpen from a DirectProperty with a protected setter to a
StyledProperty with a public setter and TwoWay default binding mode.
This enables MVVM scenarios where a ViewModel can control flyout
visibility through data binding.
The implementation mirrors the established Popup.IsOpen pattern:
- Reentrancy guard (BeginIgnoringIsOpen scope) prevents recursive
property change notifications when internal code syncs the property
- SetCurrentValue preserves active bindings and styles (enforced by
analyzer AVP1012)
- _isOpen field tracks actual open state independently of the property
value, since the property system sets the value before the change
handler fires
- _lastPlacementTarget enables re-opening at the last known target
when IsOpen is set to true via binding
- IsOpen reverts to false when no target is available or opening is
cancelled, and reverts to true when closing is cancelled, keeping
the property honest
Fixes#18716
* ci: retrigger checks
* Add API suppression for FlyoutBase.IsOpenProperty type change
Suppress CP0002 for the intentional binary breaking change from
DirectProperty<FlyoutBase, bool> to StyledProperty<bool>.
* Pre-register owning control as flyout placement target
When Button.Flyout or SplitButton.Flyout is set, the owning control
now registers itself as the default placement target via an internal
SetDefaultPlacementTarget method. This allows IsOpen = true to work
on first use without a prior ShowAt call, addressing review feedback
from MrJul.
* Remove TwoWay default binding mode from IsOpenProperty
Follow Avalonia convention: Popup.IsOpen and ToolTip.IsOpen use the
default OneWay binding mode. TwoWay is reserved for input controls.
Users opt in with Mode=TwoWay when needed.
* refactor: Replace IsPopup with Enable*Layer properties on VisualLayerManager
- Remove IsPopup from VisualLayerManager, add granular Enable*Layer properties:
EnableAdornerLayer (default true), EnableOverlayLayer (default false),
EnablePopupOverlayLayer (internal, default false), EnableTextSelectorLayer (default false)
- Add PART_VisualLayerManager template part to TopLevel with protected property
- Window and EmbeddableControlRoot override OnApplyTemplate to enable
overlay, popup overlay, and text selector layers
- OverlayLayer is now wrapped in a Panel with a dedicated AdornerLayer sibling
- AdornerLayer.GetAdornerLayer checks for OverlayLayer's dedicated AdornerLayer
- Update all 8 XAML templates (both themes) to name PART_VisualLayerManager
and remove IsPopup="True" from PopupRoot/OverlayPopupHost
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add XML doc to VisualLayerManager
* Also search for AdornerLayer from TopLevel
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* Allow `TextSearch.TextBinding` on non-controls.
Allow setting `TextSearch.TextBinding` on non-controls: in particular I would like to be able to set it on (tree) data grid columns. For example:
```
<TreeDataGrid>
<TreeDataGridTemplateColumn TextSearch.TextBinding="{Binding Foo}">
<DataTemplate>
<TextBlock Text="{Binding Foo}"/>
</DataTemplate>
</TreeDataGridTemplateColumn>
</TreeDataGrid>
```
* Allow TextSearch.Text on non-controls
* Update API suppressions
* Rename TextSearch.GetText parameter
---------
Co-authored-by: Max Katz <maxkatz6@outlook.com>
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* Don't tick with render loop when app is idle
* Update src/Avalonia.Base/Rendering/Composition/Transport/BatchStreamArrayPool.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* wip
* wip
* api diff
* fixes
* Address review: clear wakeupPending at tick start, guard CarbonEmissionsHack subscriptions
- Clear _wakeupPending at start of TimerTick so wakeups already processed
by the current tick don't force an unnecessary extra tick
- Guard CarbonEmissionsHack against duplicate subscriptions using a private
attached property
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix lock-order inversion in Add/Remove vs TimerTick
Move Wakeup() and Stop() calls outside the _items lock in Add/Remove
to prevent deadlock with TimerTick which acquires _timerLock then _items.
Add/Remove are UI-thread-only so the extracted logic remains safe.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address review: remove unused usings, guard double Stop(), fix SleepLoop extra frame
- Remove unused using directives from IRenderLoopTask.cs
- Guard TimerTick Stop() with _running check to prevent double Stop()
when Remove() already stopped the timer
- SleepLoopRenderTimer: use WaitOne(timeout) instead of Thread.Sleep
so Stop() can interrupt the sleep, and recheck _stopped before Tick
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix DisplayLinkTimer foreground handler bypassing render loop state
Only resume the display link on WillEnterForeground if the timer was
calling Start() to avoid setting _stopped=false when the render loop
had the timer stopped.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix DisplayLinkTimer thread safety, revert global NU5104 suppression
- Stop() now only sets _stopped flag; OnLinkTick() self-pauses the
CADisplayLink from the timer thread to avoid thread-affinity issues
- Revert NU5104 global suppression in SharedVersion.props
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Cap _ticksSinceLastCommit to prevent int overflow
Stop incrementing once it reaches CommitGraceTicks to prevent
wrapping negative and keeping the render loop awake indefinitely.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* refactor: remove Start/Stop from IRenderTimer, merge into Tick setter
Timer start/stop is now controlled entirely by setting the Tick
property: non-null starts, null stops. This eliminates the explicit
Start()/Stop() methods from IRenderTimer, making the API simpler.
DefaultRenderLoop controls the timer purely through Tick assignment
under its _timerLock. A new _hasItems flag tracks subscriber presence
since Tick is now transient (null when idle).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: address review comments on timer thread safety and guards
- ChoreographerTimer: add _frameCallbackActive guard to prevent double
PostFrameCallback from both Tick setter and SubscribeView
- ServerCompositor: cap _ticksSinceLastCommit at int.MaxValue
- SleepLoopRenderTimer: make _tick volatile, remove _stopped recheck
(guard moved to DefaultRenderLoop)
- DefaultRenderLoop: add _running check at tick start to drop late ticks
- ThreadProxyRenderTimer: add lock for internal state manipulation
- DisplayLinkTimer: add lock for all internal state manipulation
- Re-add NU5104 suppression to SharedVersion.props
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: make _hasItems volatile for cross-thread visibility
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: guard against redundant starts in DefaultRenderTimer, make _tick volatile across all timers
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Remove CarbonEmissionsHack, revert iOS/Android timers to always-ticking
- Delete CarbonEmissionsHack class and its XAML reference
- Revert DisplayLinkTimer (iOS) to original always-ticking implementation
- Revert ChoreographerTimer (Android) to original always-ticking implementation
- Add TODO comments for future start/stop on RenderLoop request
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix DirectCompositionConnection WaitOne not respecting process exit cancellation
Use WaitHandle.WaitAny with both _wakeEvent and cts.Token.WaitHandle so
the loop can exit when ProcessExit fires while the timer is stopped.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* timers
* XML docs
* Cache delegate
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Implemented new drawn window decorations API
TODO: check if it works on Win32, bring back titlebar automation peer
* Adjusting naming a bit
* Naming / configuration changes
* Various fixes
* popover fix?
* wip
* Address review
* Extra window roles
* WIP
* Fixed drawn titlebar automation
* Purge ExtendClientAreaChromeHints.
* Fixed dynamically enabling drawn decorations
* api diff
* Add automation IDs for drawn decorations buttons
* Resolved the issues
* build
* Retry a few times when Pager isn't available after test is finished
* Only do faulty test detection if asked
* duplicate package reference
* Try disabling faulty tests on appium1
* Fix ExtendClientAreaWindowTests
* Apply initial button states
* Enable CSD shadow for X11
* net8?
* Address review
* more review comments
* Moar review comments
* Extra hit-test checks
* Moar review
* Prefix integration test app exitfullscreen to avoid clashes
* Disable drawn decorations if parts = None
* Respect SystemDecorations value on mac in extend-client-area mode
* Tidy up logic a bit
* Adjust win32 tests to titlebar not being in the tree when CSD are not enabled
---------
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* move gesture events from Gestures to InputElement. Fix holding gesture interactions with context menu
* update api diff
* address review comments
* fix some test types
* rename Cancelled to Canceled
* update api diff
* Make MathUtilities internal
* Remove old overloads from LayoutHelper
* Make DrawingContextHelper.WrapSkiaCanvas internal
* Update API suppressions
---------
Co-authored-by: Max Katz <maxkatz6@outlook.com>
* Make some overlay-related types/members internal
* Make sure that TopLevel is no longer the actual root of the visual tree. This is needed for our future changes.
* API diff
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fixed incorrect test
* Make automation to target FocusRoot
* api diff
* Hide WindowBase/EmbeddableControlRoot's parents from automation
* api diff
* Separate automation root and visual root for automation purposes
* Hide ChromeOverlayLayer from public API
* Synchronize WindowBase visibility to VisualRoot
* Hide WindowBase.ArrangeSetBounds
* api diff
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Extracted IInputRoot out of TopLevel
* Move some input handling out of TopLevel
* Remove old class, make layout manager private
* Removed IRenderRoot
* Make VisualTreeAttachmentEventArgs a bit more sensible
* Move ILayoutRoot to PresentationSource
# Conflicts:
# tests/Avalonia.Controls.UnitTests/TabControlTests.cs
* Updated some VisualRoot / GetVisualRoot usages
* Updated more XxxRoot usages
* More Root usages
* Addressed review
* Hurr-durr xml
* More fixes
* Maybe fix android compilation
* API diff
* Yet another cast
* I had to use MSIL analysis to detect those casts
* Fixed automation
* Fix PointerOverPreProcessor
* Fix?
* Removed yet another cast to Visual
* The amount of random downcasts is astonishing
* Maybe fix mac
* Addressed review
* Make binding plugin API internal.
Making everything pluggable like has performance implications even if the plugins are never customized (which will be the 99% case).
`IPropertyAccessor` is used in `CompiledBindingPathBuilder` so needs to be kept public for the moment.
* Disable Data Annotations validation by default.
It [conflicts with `CommunityToolkit.Mvvm`](https://github.com/AvaloniaUI/Avalonia/issues/8397) which is now the default MVVM framework, so require it to be enabled in the `AppBuilder`.
* Update API supressions.
* Add back missing using
---------
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* Merge ISkiaGpuWithPlatformGraphicsContext into ISkiaGpu
* Merge ISkiaGpuRenderTarget2 into ISkiaGpuRenderTarget
* Merge IRenderTarget2 into IRenderTarget
* Update API suppressions
* Update API suppressions
* Remove the flowDirection parameter from TextCollapsingProperties.CreateCollapsedRuns
* Simplify text formatting constructors
* Update API suppressions
* Introduce TextOptions API
* Store BaselinePixelAlignment as byte. Move to a dedicated file.
* Update API suppressions
---------
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* Introduce a universal IGlyphTypeface implementation that does not rely on any platform implementation
* Revert changes
* Fix Android
* Make the test happy
* Fix build
* Update baseline
* Fix naming
* Fix headless
* Move interfaces to dedicated files
Make GlyphTypeface.GlyphCount an integer
* Fix GlyphCount
* Make IGlyphTypeface NotClientImplementable
* Make sure we cache platform typefaces by their desired name, style, weight and stretch
* Update baseline
* Only use IGlyphTypeface
* Fix Android
* Try to clear the buffer before we encode somethimg
* Add needed test font
* Add more unit tests
* Reduce allocations
* Remove Direct2D1 test files
* More tests
* More complete table implementations
* More adjustments
* Use batch APIs
* Handle invalid timestamps
* Update baseline
* Introduce a CharacterToGlyphMap struct for faster access
* Remove AggressiveInlining
* Remove AggressiveInlining
* Make the head table optional for legacy fonts
* Remove Load method. Fix TextBlockTests
* Fix nullables
* Remove redundant folder
* Update Api baseline
* revert diff helper changes
* revert changes
* Use bare minimum font for Headless platform and introduce a test font manager that uses the Inter font for testing.
* Add missing font file for Headless platform
---------
Co-authored-by: Gillibald <stebner@avaloniaui.net>
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* Update ncrunch config.
* Tidy up reflection and multi-binding APIs:
- Move `BindingBase` and `MultiBinding` into Avalonia.Base
- `BindingBase` becomes a true base class for all bindings, and contains only the `Instance` method
- Properties common between reflection and compiled bindings are moved into `StandardBindingBase`
- `Binding` is moved to Avalonia.Base and renamed to `ReflectionBinding`
- A compatibility shim for `Binding` remains in Avalonia.Markup
- Remove `IBinding` and `IBinding2`
- Remove `ITreeDataTemplate's usage of `InstancedBinding`
- Remove `NativeMenuBarPresenter`s usage of `InstancedBinding`
- Remove `InstancedBinding` as it is now unused
This required an update to the DataGrid submodule: cell data validation has been temporarily removed as this used `InstancedBinding`.
* `Instance()` => `CreateInstance()`.
The use of "Instance" as a verb is quite unusual apparently ;)
* Seal classes where appropriate.
* Seal classes where appropriate.
* Remove `StandardBindingBase`.
Simply duplicate the members in reflection and compiled binding classes.
* Delete deleted submodule directory.
* Add missing attribute.
Fixes compile error.
* Fix reference to removed class.
* Update suppressions.
* Improve effect render performance by providing Skia with information about subscene bounds
* Fixed test
* apidiff
* Update API diff
---------
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* Improve FontCollection user story
* Make adjustments after review
* Refactor IsFontFile
* Make FontFamilyLoader internal
Make tests happy again
* Update baseline
* Adjust modifier
---------
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>