diff options
author | Alex Corrado <alexc@xamarin.com> | 2020-02-22 02:20:38 +0300 |
---|---|---|
committer | Alex Corrado <alexc@xamarin.com> | 2020-02-22 04:02:10 +0300 |
commit | 56c38aad77e0267b36282525aa211b30aec82950 (patch) | |
tree | 0dbc88fa0ad01f89f305820c77803f6a2b525456 /Xamarin.PropertyEditing.Mac | |
parent | d148a22c16ca83f86303b4fd281d721c1648071a (diff) |
[Mac] More generalized solution for restoring focus when popover is repopped up
Diffstat (limited to 'Xamarin.PropertyEditing.Mac')
3 files changed, 61 insertions, 31 deletions
diff --git a/Xamarin.PropertyEditing.Mac/Controls/BrushEditorControl.cs b/Xamarin.PropertyEditing.Mac/Controls/BrushEditorControl.cs index 7520f31..cb8bc44 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/BrushEditorControl.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/BrushEditorControl.cs @@ -22,8 +22,6 @@ namespace Xamarin.PropertyEditing.Mac if (!Popover.Shown) { Popover.Show (new CGRect (26, this.Frame.Height / 2 - 2, 2, 2), this, NSRectEdge.MinYEdge); - Window.MakeFirstResponder (this); - Window.MakeFirstResponder (Popover); } } @@ -37,33 +35,6 @@ namespace Xamarin.PropertyEditing.Mac } } - internal class ColorPopOverDelegate : NSPopoverDelegate - { - private BrushTabViewController brushTabViewController; - private CommonBrushType selectedBrushType = CommonBrushType.None; - - internal ColorPopOverDelegate (BrushTabViewController brushTabViewController) - { - if (brushTabViewController == null)
- throw new ArgumentNullException (nameof (brushTabViewController)); - - this.brushTabViewController = brushTabViewController; - } - - public override void WillShow (NSNotification notification) - { - if (this.brushTabViewController.ViewModel != null) { - var ct = new CancellationTokenSource (); - Task.Factory.StartNew (()=> { - if (this.selectedBrushType == CommonBrushType.None) - this.selectedBrushType = this.brushTabViewController.ViewModel.SelectedBrushType; - else - this.brushTabViewController.ViewModel.SelectedBrushType = this.selectedBrushType; - }, ct.Token, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext ()); - } - } - } - internal class BrushEditorControl : PropertyEditorControl<BrushPropertyViewModel> { public BrushEditorControl (IHostResourceProvider hostResources) @@ -81,8 +52,6 @@ namespace Xamarin.PropertyEditing.Mac } }; - this.popover.Delegate = new ColorPopOverDelegate (this.brushTabViewController); - this.popUpButton = new ColorPopUpButton { ControlSize = NSControlSize.Small, Font = NSFont.SystemFontOfSize (NSFont.SystemFontSizeForControlSize (NSControlSize.Small)), diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/AutoClosePopOver.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/AutoClosePopOver.cs index f3a25ac..bb1fafd 100644 --- a/Xamarin.PropertyEditing.Mac/Controls/Custom/AutoClosePopOver.cs +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/AutoClosePopOver.cs @@ -1,5 +1,6 @@ using System; using AppKit; +using Foundation; namespace Xamarin.PropertyEditing.Mac { @@ -17,6 +18,7 @@ namespace Xamarin.PropertyEditing.Mac this.hostResources = hostResources; Behavior = NSPopoverBehavior.Semitransient; + Delegate = new PopoverFocusRestoreDelegate (); CloseOnEnter = true; this.SetAppearance (this.hostResources.GetVibrantAppearance (effectiveAppearance)); diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/PopoverFocusRestoreDelegate.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/PopoverFocusRestoreDelegate.cs new file mode 100644 index 0000000..4092a8a --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/PopoverFocusRestoreDelegate.cs @@ -0,0 +1,59 @@ +using System; +using AppKit; +using Foundation; + +namespace Xamarin.PropertyEditing.Mac +{ + internal class PopoverFocusRestoreDelegate : NSPopoverDelegate + { + static readonly NSString key = new NSString ("firstResponder"); + + private bool ignore; + private NSResponder prevFirstResponder; + + public PopoverFocusRestoreDelegate () + { + } + + public override void DidShow (NSNotification notification) + { + this.ignore = false; + var window = ((NSPopover)notification.Object).ContentViewController.View.Window; + + if (this.prevFirstResponder != null) { + window.MakeFirstResponder (this.prevFirstResponder); + } else { + window.AddObserver (this, key, NSKeyValueObservingOptions.Initial | NSKeyValueObservingOptions.New, IntPtr.Zero); + } + } + + public override void WillClose (NSNotification notification) + { + this.ignore = true; + } + + public override void ObserveValue (NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context) + { + var window = ofObject as NSWindow; + if (window != null && keyPath == key) { + if (!ignore) { + var firstResponder = change [ChangeNewKey] as NSResponder; + if (firstResponder != null && !(firstResponder is NSWindow)) + this.prevFirstResponder = ResolveResponder (firstResponder); + } + } else { + base.ObserveValue (keyPath, ofObject, change, context); + } + } + + // See first paragraph under "How the Field Editor Works" + // https://developer.apple.com/library/archive/documentation/TextFonts/Conceptual/CocoaTextArchitecture/TextEditing/TextEditing.html#//apple_ref/doc/uid/TP40009459-CH3-SW29 + static NSResponder ResolveResponder (NSResponder responder) + { + if (responder is NSText text && text.FieldEditor) + return (text.WeakDelegate as NSResponder) ?? responder; + + return responder; + } + } +} |