Browse Source

Merge pull request #4300 from kekekeks/embedded-popup-focus

[Win32] only steal input focus if it's currently held by Popup's parent's child
pull/4301/head
danwalmsley 6 years ago
committed by GitHub
parent
commit
4ec1fb7ecc
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  2. 29
      src/Windows/Avalonia.Win32/PopupImpl.cs

12
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

@ -1060,9 +1060,21 @@ namespace Avalonia.Win32.Interop
[DllImport("user32.dll")]
public static extern bool SetFocus(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr GetFocus();
[DllImport("user32.dll")]
public static extern bool SetParent(IntPtr hWnd, IntPtr hWndNewParent);
[DllImport("user32.dll")]
public static extern IntPtr GetParent(IntPtr hWnd);
public enum GetAncestorFlags
{
GA_PARENT = 1,
GA_ROOT = 2,
GA_ROOTOWNER = 3
}
[DllImport("user32.dll")]
public static extern IntPtr GetAncestor(IntPtr hwnd, GetAncestorFlags gaFlags);
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommand nCmdShow);

29
src/Windows/Avalonia.Win32/PopupImpl.cs

@ -7,6 +7,7 @@ namespace Avalonia.Win32
{
class PopupImpl : WindowImpl, IPopupImpl
{
private readonly IWindowBaseImpl _parent;
private bool _dropShadowHint = true;
private Size? _maxAutoSize;
@ -19,18 +20,25 @@ namespace Avalonia.Win32
public override void Show()
{
UnmanagedMethods.ShowWindow(Handle.Handle, UnmanagedMethods.ShowWindowCommand.ShowNoActivate);
var parent = UnmanagedMethods.GetParent(Handle.Handle);
if (parent != IntPtr.Zero)
{
IntPtr nextParent = parent;
while (nextParent != IntPtr.Zero)
{
parent = nextParent;
nextParent = UnmanagedMethods.GetParent(parent);
}
UnmanagedMethods.SetFocus(parent);
// 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;
@ -118,6 +126,7 @@ namespace Avalonia.Win32
private PopupImpl(IWindowBaseImpl parent, bool dummy) : base()
{
_parent = parent;
PopupPositioner = new ManagedPopupPositioner(new ManagedPopupPositionerPopupImplHelper(parent, MoveResize));
}

Loading…
Cancel
Save