From 4b494d9edb8857514597e14ce91e4a82d436bd55 Mon Sep 17 00:00:00 2001 From: Benedikt Stebner Date: Sun, 21 Jul 2024 06:25:42 +0200 Subject: [PATCH] Make sure Popups do not attempt to take focus when they are shown (#16365) Co-authored-by: Max Katz --- native/Avalonia.Native/src/OSX/AvnView.mm | 17 +++++++++++++- src/Avalonia.Native/PopupImpl.cs | 28 +++++++++++------------ src/Avalonia.Native/TopLevelImpl.cs | 2 +- src/Windows/Avalonia.Win32/PopupImpl.cs | 19 --------------- 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/AvnView.mm b/native/Avalonia.Native/src/OSX/AvnView.mm index 36e2307f42..8c38b1cf2d 100644 --- a/native/Avalonia.Native/src/OSX/AvnView.mm +++ b/native/Avalonia.Native/src/OSX/AvnView.mm @@ -297,7 +297,22 @@ ) ) ) - [self becomeFirstResponder]; + { + WindowBaseImpl* windowBase = dynamic_cast(_parent.getRaw()); + + if(windowBase != nullptr){ + WindowBaseImpl* parent = windowBase->Parent; + + if(parent != nullptr){ + auto parentWindow = parent->Window; + + [parentWindow makeFirstResponder:parent->View]; + } + } else{ + [self becomeFirstResponder]; + } + } + if(_parent != nullptr) { diff --git a/src/Avalonia.Native/PopupImpl.cs b/src/Avalonia.Native/PopupImpl.cs index 7630cd176c..14383c93c8 100644 --- a/src/Avalonia.Native/PopupImpl.cs +++ b/src/Avalonia.Native/PopupImpl.cs @@ -8,8 +8,6 @@ namespace Avalonia.Native class PopupImpl : WindowBaseImpl, IPopupImpl { private readonly ITopLevelImpl _parent; - private readonly IAvnPopup _native; - private readonly AvaloniaNativeTextInputMethod _inputMethod; public PopupImpl(IAvaloniaNativeFactory factory, ITopLevelImpl parent) : base(factory) @@ -18,7 +16,7 @@ namespace Avalonia.Native using (var e = new PopupEvents(this)) { - Init(new MacOSTopLevelHandle(_native = factory.CreatePopup(e))); + Init(new MacOSTopLevelHandle(factory.CreatePopup(e))); } PopupPositioner = new ManagedPopupPositioner(new ManagedPopupPositionerPopupImplHelper(parent, MoveResize)); @@ -28,13 +26,25 @@ namespace Avalonia.Native parent = popupImpl._parent; } + if (parent is WindowBaseImpl windowBaseImpl) + { + Native!.SetParent(windowBaseImpl.Native); + } + //Use the parent's input context to process events if (parent is TopLevelImpl topLevelImpl) { - _inputMethod = topLevelImpl.InputMethod; + InputMethod = topLevelImpl.InputMethod; } } + public override void Dispose() + { + Native!.SetParent(null); + + base.Dispose(); + } + internal sealed override void Init(MacOSTopLevelHandle handle) { base.Init(handle); @@ -71,16 +81,6 @@ namespace Avalonia.Native } } - public override void Show(bool activate, bool isDialog) - { - var parent = _parent; - while (parent is PopupImpl p) - parent = p._parent; - if (parent is WindowImpl w) - w.Native.TakeFocusFromChildren(); - base.Show(false, isDialog); - } - public override IPopupImpl CreatePopup() => new PopupImpl(Factory, this); public void SetWindowManagerAddShadowHint(bool enabled) diff --git a/src/Avalonia.Native/TopLevelImpl.cs b/src/Avalonia.Native/TopLevelImpl.cs index 8c65a3bd76..1e434d2854 100644 --- a/src/Avalonia.Native/TopLevelImpl.cs +++ b/src/Avalonia.Native/TopLevelImpl.cs @@ -106,7 +106,7 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface public IAvnTopLevel? Native => _handle?.Native; public IPlatformHandle? Handle => _handle; - public AvaloniaNativeTextInputMethod? InputMethod { get; private set; } + public AvaloniaNativeTextInputMethod? InputMethod { get; protected set; } public Size ClientSize { get diff --git a/src/Windows/Avalonia.Win32/PopupImpl.cs b/src/Windows/Avalonia.Win32/PopupImpl.cs index bd097804df..388ee505e1 100644 --- a/src/Windows/Avalonia.Win32/PopupImpl.cs +++ b/src/Windows/Avalonia.Win32/PopupImpl.cs @@ -22,25 +22,6 @@ namespace Avalonia.Win32 { // Popups are always shown non-activated. UnmanagedMethods.ShowWindow(Handle.Handle, UnmanagedMethods.ShowWindowCommand.ShowNoActivate); - - // We need to steal focus if it's held by a child window of our toplevel window - var parent = _parent; - while(parent != null) - { - if(parent is PopupImpl pi) - parent = pi._parent; - else - break; - } - - if(parent == null) - return; - - var focusOwner = UnmanagedMethods.GetFocus(); - if (focusOwner != IntPtr.Zero && - UnmanagedMethods.GetAncestor(focusOwner, UnmanagedMethods.GetAncestorFlags.GA_ROOT) - == parent.Handle?.Handle) - UnmanagedMethods.SetFocus(parent.Handle.Handle); } protected override bool ShouldTakeFocusOnClick => false;