Browse Source

Merge pull request #4195 from AvaloniaUI/osx-menu-embed-hide-and-focus

Fix some focus issues with OSX popups
danwalmsley 5 years ago
parent
commit
22d1beba93

+ 1 - 0
native/Avalonia.Native/inc/avalonia-native.h

@@ -278,6 +278,7 @@ AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase
     virtual HRESULT SetTitleBarColor (AvnColor color) = 0;
     virtual HRESULT SetTitleBarColor (AvnColor color) = 0;
     virtual HRESULT SetWindowState(AvnWindowState state) = 0;
     virtual HRESULT SetWindowState(AvnWindowState state) = 0;
     virtual HRESULT GetWindowState(AvnWindowState*ret) = 0;
     virtual HRESULT GetWindowState(AvnWindowState*ret) = 0;
+    virtual HRESULT TakeFocusFromChildren() = 0;
 };
 };
 
 
 AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown
 AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown

+ 28 - 5
native/Avalonia.Native/src/OSX/window.mm

@@ -116,10 +116,15 @@ public:
         {
         {
             SetPosition(lastPositionSet);
             SetPosition(lastPositionSet);
             UpdateStyle();
             UpdateStyle();
-            
-            [Window makeKeyAndOrderFront:Window];
-            [NSApp activateIgnoringOtherApps:YES];
-            
+            if(ShouldTakeFocusOnShow())
+            {
+                [Window makeKeyAndOrderFront:Window];
+                [NSApp activateIgnoringOtherApps:YES];
+            }
+            else
+            {
+                [Window orderFront: Window];
+            }
             [Window setTitle:_lastTitle];
             [Window setTitle:_lastTitle];
             
             
             _shown = true;
             _shown = true;
@@ -128,6 +133,11 @@ public:
         }
         }
     }
     }
     
     
+    virtual bool ShouldTakeFocusOnShow()
+    {
+        return true;
+    }
+    
     virtual HRESULT Hide () override
     virtual HRESULT Hide () override
     {
     {
         @autoreleasepool
         @autoreleasepool
@@ -774,6 +784,15 @@ private:
         }
         }
     }
     }
     
     
+    virtual HRESULT TakeFocusFromChildren () override
+    {
+        if(Window == nil)
+            return S_OK;
+        if([Window isKeyWindow])
+            [Window makeFirstResponder: View];
+        return S_OK;
+    }
+    
     void EnterFullScreenMode ()
     void EnterFullScreenMode ()
     {
     {
         _fullScreenActive = true;
         _fullScreenActive = true;
@@ -1858,7 +1877,6 @@ private:
         WindowEvents = events;
         WindowEvents = events;
         [Window setLevel:NSPopUpMenuWindowLevel];
         [Window setLevel:NSPopUpMenuWindowLevel];
     }
     }
-    
 protected:
 protected:
     virtual NSWindowStyleMask GetStyle() override
     virtual NSWindowStyleMask GetStyle() override
     {
     {
@@ -1876,6 +1894,11 @@ protected:
             return S_OK;
             return S_OK;
         }
         }
     }
     }
+public:
+    virtual bool ShouldTakeFocusOnShow() override
+    {
+        return false;
+    }
 };
 };
 
 
 extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl)
 extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl)

+ 9 - 0
samples/interop/NativeEmbedSample/MainWindow.xaml

@@ -20,7 +20,16 @@
     <DockPanel DockPanel.Dock="Top">
     <DockPanel DockPanel.Dock="Top">
       <Button DockPanel.Dock="Right" Click="ShowPopupDelay">Show popup (delay)</Button>
       <Button DockPanel.Dock="Right" Click="ShowPopupDelay">Show popup (delay)</Button>
       <Button DockPanel.Dock="Right" Click="ShowPopup">Show popup</Button>
       <Button DockPanel.Dock="Right" Click="ShowPopup">Show popup</Button>
+      <Border DockPanel.Dock="Right" Background="#c0c0c0">
+        <ToolTip.Tip>
+          <ToolTip>
+              <TextBlock>Text</TextBlock>
+          </ToolTip>
+        </ToolTip.Tip>
+        <TextBlock>Tooltip</TextBlock>
+      </Border>
       <TextBox Text="Lorem ipsum dolor sit amet"/>
       <TextBox Text="Lorem ipsum dolor sit amet"/>
+      
     </DockPanel>
     </DockPanel>
     <Grid ColumnDefinitions="*,5,*">
     <Grid ColumnDefinitions="*,5,*">
       <DockPanel>
       <DockPanel>

+ 12 - 0
src/Avalonia.Native/PopupImpl.cs

@@ -10,6 +10,7 @@ namespace Avalonia.Native
         private readonly IAvaloniaNativeFactory _factory;
         private readonly IAvaloniaNativeFactory _factory;
         private readonly AvaloniaNativePlatformOptions _opts;
         private readonly AvaloniaNativePlatformOptions _opts;
         private readonly GlPlatformFeature _glFeature;
         private readonly GlPlatformFeature _glFeature;
+        private readonly IWindowBaseImpl _parent;
 
 
         public PopupImpl(IAvaloniaNativeFactory factory,
         public PopupImpl(IAvaloniaNativeFactory factory,
             AvaloniaNativePlatformOptions opts,
             AvaloniaNativePlatformOptions opts,
@@ -19,6 +20,7 @@ namespace Avalonia.Native
             _factory = factory;
             _factory = factory;
             _opts = opts;
             _opts = opts;
             _glFeature = glFeature;
             _glFeature = glFeature;
+            _parent = parent;
             using (var e = new PopupEvents(this))
             using (var e = new PopupEvents(this))
             {
             {
                 var context = _opts.UseGpu ? glFeature?.DeferredContext : null;
                 var context = _opts.UseGpu ? glFeature?.DeferredContext : null;
@@ -58,6 +60,16 @@ namespace Avalonia.Native
             }
             }
         }
         }
 
 
+        public override void Show()
+        {
+            var parent = _parent;
+            while (parent is PopupImpl p) 
+                parent = p._parent;
+            if (parent is WindowImpl w)
+                w.Native.TakeFocusFromChildren();
+            base.Show();
+        }
+
         public override IPopupImpl CreatePopup() => new PopupImpl(_factory, _opts, _glFeature, this);
         public override IPopupImpl CreatePopup() => new PopupImpl(_factory, _opts, _glFeature, this);
 
 
         public void SetWindowManagerAddShadowHint(bool enabled)
         public void SetWindowManagerAddShadowHint(bool enabled)

+ 1 - 1
src/Avalonia.Native/WindowImplBase.cs

@@ -319,7 +319,7 @@ namespace Avalonia.Native
         }
         }
 
 
 
 
-        public void Show()
+        public virtual void Show()
         {
         {
             _native.Show();
             _native.Show();
         }
         }