Don't reset firstResponder when a window is deactivated
Don't call makeFirstResponder:nil from windowDidResignKey: because it's not a native behavior and subtly breaks some things (e.g. paste managers or keyboard switched under some settings). This was done to provide the illusion of Windows-like focus behavior when a TLW is deactivated. macOS separates the concept of active ("key") window and focus ("first responder") within it and it's possible and normal to have the latter assigned even in inactive (non-key) windows. wxOSX reset the responder to trigger wxEVT_KILL_FOCUS. Instead, keep the first responder untouched and only run wx-side code to handle focus lost as well as focus set in windowDidBecomeKey: This would preserve behavior compatibility with other ports, while also playing nice with macOS.
This commit is contained in:
committed by
Václav Slavík
parent
5d87c70eba
commit
1a1a2ffdf8
@@ -492,6 +492,15 @@ extern int wxOSXGetIdFromSelector(SEL action );
|
||||
wxNonOwnedWindowCocoaImpl* windowimpl = [window WX_implementation];
|
||||
if ( windowimpl )
|
||||
{
|
||||
// See windowDidResignKey: -- we emulate corresponding focus set
|
||||
// event for the first responder here as well:
|
||||
NSView *firstResponder = [window firstResponder];
|
||||
wxWidgetCocoaImpl *focused = firstResponder
|
||||
? (wxWidgetCocoaImpl*)wxWidgetImpl::FindFromWXWidget(wxOSXGetViewFromResponder(firstResponder))
|
||||
: NULL;
|
||||
if ( focused )
|
||||
focused->DoNotifyFocusSet();
|
||||
|
||||
wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
|
||||
if ( wxpeer )
|
||||
wxpeer->HandleActivated(0, true);
|
||||
@@ -508,9 +517,16 @@ extern int wxOSXGetIdFromSelector(SEL action );
|
||||
if ( wxpeer )
|
||||
{
|
||||
wxpeer->HandleActivated(0, false);
|
||||
// as for wx the deactivation also means losing focus we
|
||||
// must trigger this manually
|
||||
[window makeFirstResponder:nil];
|
||||
|
||||
// As for wx the deactivation also means losing focus, we
|
||||
// must emulate focus events _without_ resetting first responder
|
||||
// (because that would subtly break other things in Cocoa/macOS):
|
||||
NSView *firstResponder = [window firstResponder];
|
||||
wxWidgetCocoaImpl *focused = firstResponder
|
||||
? (wxWidgetCocoaImpl*)wxWidgetImpl::FindFromWXWidget(wxOSXGetViewFromResponder(firstResponder))
|
||||
: NULL;
|
||||
if ( focused )
|
||||
focused->DoNotifyFocusLost();
|
||||
|
||||
// TODO Remove if no problems arise with Popup Windows
|
||||
#if 0
|
||||
|
@@ -71,7 +71,24 @@ NSView* GetFocusedViewInWindow( NSWindow* keyWindow )
|
||||
|
||||
WXWidget wxWidgetImpl::FindFocus()
|
||||
{
|
||||
return GetFocusedViewInWindow( [NSApp keyWindow] );;
|
||||
NSWindow *key = [NSApp keyWindow];
|
||||
if ( key == nil )
|
||||
{
|
||||
// Application's keyWindow property may still not be updated and be
|
||||
// nil when windowDidBecomeKey: is called and even if the
|
||||
// just-activated's window isKeyWindow already returns YES. To get
|
||||
// accurate information about where the focus is at all times, we have
|
||||
// to explicitly check all application windos as well:
|
||||
for ( NSWindow *w in [NSApp windows] )
|
||||
{
|
||||
if ( [w isKeyWindow] )
|
||||
{
|
||||
key = w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return key ? GetFocusedViewInWindow(key) : nil;
|
||||
}
|
||||
|
||||
wxWidgetImpl* wxWidgetImpl::FindBestFromWXWidget(WXWidget control)
|
||||
|
Reference in New Issue
Block a user