* [osx] Use NSTrackingInVisibleRect for tracking mouse movement
* nit: comment
* Update native/Avalonia.Native/src/OSX/AvnView.mm
Co-authored-by: Max Katz <maxkatz6@outlook.com>
---------
Co-authored-by: Max Katz <maxkatz6@outlook.com>
* osx: anchor new windows to the primary screen origin
WindowBaseImpl::CreateNSWindow anchors the new NSWindow's content rect to the
primary screen's frame.origin. The primary screen is at Cocoa (0,0) on a
healthy Mac, but can be offset (often negative) while the display server is
mid-reconfiguration -- e.g. CGMainDisplayID() briefly returns 0 after
wake-from-sleep -- or on multi-monitor layouts where the primary is not at the
origin. Anchoring keeps the window on a real screen so it is positioned
on-screen and its flipped Position lands inside a Screen.Bounds.
See #18895.
Co-authored-by: Cursor <cursoragent@cursor.com>
* osx: keep window construction resilient when no screen contains it
When locating the screen that sizes a new window, fall back to a default size
if AppKit reports no screens -- or none whose bounds contain the last-known
position -- during a display reconfiguration. The window is repositioned on the
next ScreenChanged event once the display server settles.
See #18895.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Less verbose comments
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* fix(macOS): always raise keyDown before the input context sees the event
AvnView passed every keyDown to the NSTextInputContext first and only
raised a KeyDown when the context did not consume the event. The context
consumes every printable key by routing it to insertText:, so while a
text input client was active no KeyDown was raised for space, letters or
digits and a KeyGesture on those keys could never match. Only modified
keys were special-cased.
keyDown: now always raises exactly one KeyDown per NSEvent before the
input context is consulted. Composition state only decides which key is
reported: while hasMarkedText is set the key is masked as
AvnKeyImeProcessed, the same way Win32 reports VK_PROCESSKEY, so user
code still observes the event but no gesture matches it. The physical key
and the key symbol keep their real values in both cases.
If user code handles the event the input context is skipped entirely, so
no text and no preedit is produced. This mirrors the Win32 behaviour of
swallowing WM_CHAR after a handled WM_KEYDOWN.
The modifier special case, the handleKeyDown: helper and
_lastKeyDownEvent are gone. doCommandBySelector: is kept but empty, since
falling back to NSResponder would perform the default action and beep.
Adds a Keyboard page to IntegrationTestApp that reports the last key
down, a key down count and the last text input, plus Appium tests
covering gestures with and without a modifier, text suppression for a
handled gesture, and a single key down per key press.
* fix(macOS): mask the composition starting key for composing input methods
hasMarkedText only becomes true once a composition is in progress, so the
keystroke that starts one was still reported with its real key and could
match a KeyGesture. Win32 reports VK_PROCESSKEY for that keystroke too.
keyDown: now also masks the key as AvnKeyImeProcessed when a printable
character key is typed into a text input client while the selected
keyboard input source is a composing input method.
Whether an input source composes is resolved through
TISGetInputSourceProperty: anything that is not a plain keyboard layout
composes, except an input method in the alphanumeric input mode, which
passes keys straight through and therefore keeps the real key. Unknown
input sources keep the real key as well, so gestures are never lost to a
failed lookup. The lookup includes installed but not enabled input
sources, since an input method mode can be selected without being listed
as enabled, and the result is cached per input source id because this runs
for every key down.
Only printable character keys are masked. KeySymbolFromScanCode reports
the control character for Backspace, Enter, Tab and Escape, so the
presence of a key symbol is not enough to decide: masking those would stop
TextBox from reacting to them, which broke Backspace while an input method
was selected. Command and Control combinations are shortcuts and are not
masked either.
Plain keyboard layouts are unaffected: dead key compositions are not
driven by the input source and stay covered by hasMarkedText.
The Keyboard page now subscribes to KeyDown and TextInput with
handledEventsToo, so keys TextBox handles in its class handler, such as
Backspace and the arrows, stay visible in the readout.
* test(macOS): skip the Keyboard tests on the Appium 1 leg
The tests synthesize key input through W3C actions, which the mac2
driver bundled with Appium 1 does not implement, so on the macOS CI leg
they could only fail. They keep running on Windows, where WinAppDriver
handles W3C actions, and on macOS builds with IsRunningAppium2, which
target a current mac2 driver. The infrastructure change that would run
them on macOS CI is split out for a separate pull request.
---------
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* Add new IPlatformSettings APIs
* Add control catalog PlatformSettingsPage
* Windows PreferredApplicationLanguage implementation
* Browser PreferredApplicationLanguage implementation
* Run API suppressions for the IPlatformSettings
* Rebase PlatformSettingsPage on new ContentPage
* Return CultureInfo.InstalledUICulture instead of CultureInfo.CurrentUICulture for default PreferredApplicationLanguage implementation
* Android PreferredApplicationLanguage implementation
* iOS PreferredApplicationLanguage implementation
* Use GetUserPreferredUILanguages for Win32 implementation instead of GetUserDefaultLocaleName
* MacOS implementation of PreferredApplicationLanguage
* Use GlobalizationPreferences for WIn32 prefered language, GetUserPreferredUILanguages doesn't work as expected with Windows settigns
* Avoid AvaloniaLocator in control catalog
* Remove unused method
* Add value/remarks XML docs on the PreferredApplicationLanguage
The native `NSSavePanel` does not let you pick file packges like
`Application.app`-bundles by default.
Since the file picker does not return these bundles either,
picking these bundles is currently impossible.
By enabling `treatsFilePackagesAsDirectories` users can select
a bundle and pick it as a folder, and also select the contents of that
package.
SetSubMenu left the item's own didSelectItem: action in place, so AppKit dispatched the click to it and dismissed the menu. Install submenuAction: as -[NSMenu setSubmenu:forItem:] does, and restore didSelectItem: when the submenu is removed, since the same NSMenuItem is reused.
Fixes#21886
attributedSubstringForProposedRange:actualRange: read *actualRange on
entry and used it as the proposed range. actualRange is an out parameter
and is uninitialized on entry, so the substring was taken from an
arbitrary range. It also never wrote the out parameter. It now intersects
the requested range with the document and writes the result, or
{NSNotFound, 0} when the intersection is empty.
The same class of issue affected the rest of the protocol implementation:
- firstRectForCharacterRange:actualRange: never wrote actualRange, and
dereferenced the parent without a null check.
- unmarkText dereferenced the parent without a null check.
- selectedRange and setSelection:: passed the managed selection through
unclamped, so a stale or reversed selection produced a range past the
end of the document, which AppKit then fed back into the substring
call. Reversed pairs are now swapped and both ends clamped.
- markedRange returned {selectionLocation, 0} instead of the documented
{NSNotFound, 0} when there is no marked text.
- The replacement ranges in setMarkedText:selectedRange:replacementRange:
and insertText:replacementRange: are clamped before being passed to
SelectInSurroundingText.
- setText: re-clamps the stored ranges, as replacing the document can
strand them out of bounds.
Nil strings and nil UTF8String results are no longer passed across the
COM boundary, and SetSurroundingText no longer calls
stringWithUTF8String: on a null pointer.
BeginMoveDrag on macOS drags from the Avalonia view's last recorded
mouse-down. A press that begins inside an embedded native view (for
example a webview hosted through NativeControlHost) is consumed by that
view and never delivered to the Avalonia view, so lastMouseDownEvent is
nil and BeginMoveDrag silently does nothing - applications embedding
native views cannot implement custom title-bar dragging through the
managed API and must reproduce performWindowDragWithEvent: through
platform interop.
When no mouse-down was recorded, fall back to the event the application
is currently tracking, guarded to left-button press or drag events that
belong to this window. Presses recorded by the Avalonia view behave
exactly as before.
* Fix off-thread accessibility hit-test crash on macOS
GetAutomationPeer() returns null when called off the UI thread, but
-[AvnWindow automationPeer] called SetNode on it without checking, which
segfaults. Guard against the null peer so it returns nil instead.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Removed comment
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Gate macOS setAccessibilityValue on value read-only state
A read-only value provider must not advertise the setAccessibilityValue selector, so AX clients see the value as not settable.
* Gate macOS read-only range value mutations
Report a read-only IRangeValueProvider (ProgressBar, read-only NumericUpDown) as not settable, and stop advertising setAccessibilityValue/increment/decrement for it; keep min/max exposed.
* Support deselect and toggle expand/collapse in macOS AX
setAccessibilitySelected:NO now removes from selection, and AXPress toggles an expand/collapse provider instead of always expanding.
* Harden macOS AX select, value-set, and disabled-control actions
setAccessibilitySelected:YES now adds to the selection instead of replacing it, the value setter respects read-only, and mutating actions are gated on IsEnabled.
TreeViewItemAutomationPeer implements ISelectionItemProvider, and AvnAccessibilityElement maps setAccessibilitySelected to it, so AX clients can select a TreeViewItem.
AvnAccessibilityElement answers accessibilityIsAttributeSettable for the value attribute using IValueProvider.IsReadOnly, so AX clients see a read-only TextBox as not settable.
* Post macOS AXLayoutChanged on the changed peer's templated parent
The changed peer is usually a template-internal layout container that AppKit will not deliver notifications for; post on its templated parent (the owning control), falling back to the nearest exposed ancestor when there is none.
* Update with comment
AutomationElementIdentifiers.AutomationIdProperty was missing, so
runtime changes to AutomationProperties.AutomationId never raised
UIA_AutomationPropertyChangedEventId on Windows (or the equivalent
on macOS). UIA clients that subscribe to property changes would
silently receive stale automation IDs.
- Add AutomationIdProperty sentinel to AutomationElementIdentifiers
- Raise the event in ControlAutomationPeer.OwnerPropertyChanged
when AutomationProperties.AutomationIdProperty changes
- Add AutomationIdProperty -> UiaPropertyId.AutomationId to the Win32
AutomationNode.s_propertyMap
- Add AutomationPeer_AutomationId to AvnAutomationProperty (avn.idl)
and wire it in AvnAutomationPeer.s_propertyMap and automation.mm
- Add unit tests covering runtime AutomationId change notifications
* Added macOS events for expand & collapse events
* Fix CFString bridging to NSString
* Don't use ExpandCollapseProvider functions when event was not for ExpandCollapseProvider
---------
Co-authored-by: Adam Demasi <adam@hbang.com.au>
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* Announce changes to live regions on macOS
It is necessary to manually request announcement of the new name of a live
region, alongside posting the general kAXLiveRegionChangedNotification.
* Refactor -raisePropertyChanged: to use switch statement
* Fix warning about switch not covering all cases
---------
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* fix: correct null check variable in TryResolveFileReferenceUri on macOS
The null check on line 401 tested `fileUri` instead of `filePathUri`,
making it dead code since `fileUri` was already checked on line 394.
When `[fileUri filePathURL]` returned nil (non-file URL or unreachable
resource), the nil `filePathUri` was passed to `[filePathUri absoluteString]`
and then to `CreateAvnString`, causing a native crash.
* fix: initialize NSError to nil in SaveBookmarkToBytes on macOS
NSError* was declared without initialization, containing stack garbage.
On the success path (bookmarkData non-nil), Cocoa does not guarantee
zeroing the error out-parameter, so the subsequent `if (error != nil)`
check could read garbage and incorrectly call CreateAvnString with a
garbage pointer.
Initialize to nil and restructure to `else if` so the error is only
inspected when bookmarkData is nil (the failure path).
* chore: retrigger CI
* fix: guard out-parameters in SaveBookmarkToBytes
Initialize *ppv to nullptr on entry so callers never read garbage on
the nil-fileUri / nil-bookmarkData paths. Guard *err write with a
nullptr check for callers that pass no error out-parameter.
* chore: retrigger CI
---------
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* Bump MicroCOM to 0.11.4, add workaround for WinRT bug
* menu.h - use ComPtr for COM stored references
* Replaced raw COM pointers with smart ones
* fixes
* Use weak com ref from AvnMenuItem
* Better smart pointer handling
* Avalonia native readme update
* review
* missing dif
* Just call the ctor like a normal person
* 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>
* Native DockMenu code
* Add Native Interop
* Update ControlCatalog sample
* Add unit tests
* Add Action<IAvnMenu> to AvaloniaNativeMenuExporter
* Add dynamic dock item demo
* Move s_dockMenu reference to App
* Use Appium tests
* Revert INativeMenuExporterResetHandler
* Properly set the button for the checkbox
* Add dock test
* I hate Appium
* Rename NativeMenu.DockMenu to NativeDock.Menu
* Make static
* Remove Dock Click Test
* Add white space back for cleaner diff
* Reduce MenuExporter back to one
* Revert UpdateIfNeeded to private
* Revert QueueReset to private too... and fix some whitespace
* Revert IAvnMenuItem/IAvnMenu back
* That's what I get not comparing it to master
* And update this too
* Add documentation
* Implement -accessibilityPlaceholderValue on macOS
macOS uses a unique -accessibilityPlaceholderValue property for the
placeholder of a text field; -accessibilityHelp has different meaning from
HelpText on Windows. Map TextBox.PlaceholderText to be returned by
-accessibilityPlaceholderValue.
Ref: https://www.w3.org/TR/core-aam-1.2/#ariaPlaceholder
* Use TextBox placeholder as a fallback for HelpText on Windows
This matches the behavior introduced in 8593ef3 on macOS, as this is where
UIA designates that placeholder text should go.
Ref: https://www.w3.org/TR/core-aam-1.2/#ariaPlaceholder
* Implemented LiveSetting property
* Make sure PropertyChanged callback is called on AvnAutomationPeer
* Remove `optional` from `AvnAccessibility`: we were never checking whether they respond to the selector or not anyway
* Formatting
* Use ARIA and Live Region Changed constants from mac APIs
* Fixed Mac build
* Reverted constants that don't exist on integration test XCode version
---------
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* Added `ExpanderAutomationPeer` for `Expander` control
* Use Group/"group" on UIA and NSAccessibilityDisclosureTriangleRole on AX
---------
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
* Added LandmarkType to automation properties
* Set AutomationProperties.AccessibilityView on Main landmark in IntegrationTestApp, which is required for Narrator to find the landmark
* Implement AXRoleDescription as suggested by W3C
* Fixed wrong role descriptions
* support reading images from clipboard(win32/android)
* Add DataFormat.Image. Prioritize png format when retrieving image from clipboard
* add browser support
* addressed comments
* win32 - add support for CF_DIB and CF_BITMAP formats
* win32 - add support for copying bitmaps to clipboard as DIB
* browser - add support for copying bitmap to clipboard
* Implement bitmap clipboard for iOS
* rename DataFormat.Image to DataFormat.Bitmap
* Implement Bitmap clipboard on macOS
* Use MemoryStream for bitmap clipboard/dnd on macOS backend
* Add public.jpeg support on macOS backend (convert it to png while in objc)
* Support TIFF format on iOS backend, by converting it to UIImage first
* Add Bitmap DND sample
* add clipboard bitmap support on linux
* simply bitmap format search on win32 clipboard
* fix linux clipboard image
* Bump MACOSX_DEPLOYMENT_TARGET
* Fix IDL incompatibility
* address review
* more reviews
* Fix Android crash on copy when a bitmap is present in the clipboard
* Handle any error that might occur pasting from an external content provider
* Add data transfer extension methods for Bitmap
---------
Co-authored-by: Max Katz <maxkatz6@outlook.com>
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>