QWidgetAction: Don't deactivate the current window on Mac
We check the name of the window class the widget's QNSView changes window and set a flag when the that window is a native Cocoa menu window. Later, only those views not inside a native menu can become first responder, ensuring Qt won't deactivate the main window. We're allowed to reject becoming the first responder mainly because Cocoa itself doesn't support sending key event to menu views and, therefore, it doesn't change what's already possible. This patch also sets the widget action visible, which needs to be done right after reparenting it to the container widget. Besides that, it also contains a few small code cleaning changes related to Cocoa's support of QWidgetAction. Change-Id: Ia2170bdc5e1f40bfa2f1091c05e9e99397c47187 Task-number: QTBUG-44015 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@theqtcompany.com>
This commit is contained in:
parent
07475c662e
commit
b50ee28eb5
@ -197,6 +197,8 @@ void QCocoaMenuItem::setEnabled(bool enabled)
|
|||||||
void QCocoaMenuItem::setNativeContents(WId item)
|
void QCocoaMenuItem::setNativeContents(WId item)
|
||||||
{
|
{
|
||||||
NSView *itemView = (NSView *)item;
|
NSView *itemView = (NSView *)item;
|
||||||
|
if (m_itemView == itemView)
|
||||||
|
return;
|
||||||
[m_itemView release];
|
[m_itemView release];
|
||||||
m_itemView = [itemView retain];
|
m_itemView = [itemView retain];
|
||||||
[m_itemView setAutoresizesSubviews:YES];
|
[m_itemView setAutoresizesSubviews:YES];
|
||||||
|
@ -77,6 +77,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
|
|||||||
bool m_scrolling;
|
bool m_scrolling;
|
||||||
bool m_exposedOnMoveToWindow;
|
bool m_exposedOnMoveToWindow;
|
||||||
NSEvent *m_currentlyInterpretedKeyEvent;
|
NSEvent *m_currentlyInterpretedKeyEvent;
|
||||||
|
bool m_isMenuView;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)init;
|
- (id)init;
|
||||||
|
@ -160,6 +160,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
|||||||
touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition | QTouchDevice::MouseEmulation);
|
touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition | QTouchDevice::MouseEmulation);
|
||||||
QWindowSystemInterface::registerTouchDevice(touchDevice);
|
QWindowSystemInterface::registerTouchDevice(touchDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_isMenuView = false;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -269,11 +271,11 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
|||||||
|
|
||||||
- (void)viewDidMoveToWindow
|
- (void)viewDidMoveToWindow
|
||||||
{
|
{
|
||||||
|
m_isMenuView = [self.window.className isEqualToString:@"NSCarbonMenuWindow"];
|
||||||
if (self.window) {
|
if (self.window) {
|
||||||
// This is the case of QWidgetAction's generated QWidget inserted in an NSMenu.
|
// This is the case of QWidgetAction's generated QWidget inserted in an NSMenu.
|
||||||
// 10.9 and newer get the NSWindowDidChangeOcclusionStateNotification
|
// 10.9 and newer get the NSWindowDidChangeOcclusionStateNotification
|
||||||
if ((!_q_NSWindowDidChangeOcclusionStateNotification
|
if (!_q_NSWindowDidChangeOcclusionStateNotification && m_isMenuView) {
|
||||||
&& [self.window.className isEqualToString:@"NSCarbonMenuWindow"])) {
|
|
||||||
m_exposedOnMoveToWindow = true;
|
m_exposedOnMoveToWindow = true;
|
||||||
m_platformWindow->exposeWindow();
|
m_platformWindow->exposeWindow();
|
||||||
}
|
}
|
||||||
@ -402,7 +404,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
|||||||
|
|
||||||
NSString *notificationName = [windowNotification name];
|
NSString *notificationName = [windowNotification name];
|
||||||
if (notificationName == NSWindowDidBecomeKeyNotification) {
|
if (notificationName == NSWindowDidBecomeKeyNotification) {
|
||||||
if (!m_platformWindow->windowIsPopupType())
|
if (!m_platformWindow->windowIsPopupType() && !m_isMenuView)
|
||||||
QWindowSystemInterface::handleWindowActivated(m_window);
|
QWindowSystemInterface::handleWindowActivated(m_window);
|
||||||
} else if (notificationName == NSWindowDidResignKeyNotification) {
|
} else if (notificationName == NSWindowDidResignKeyNotification) {
|
||||||
// key window will be non-nil if another window became key... do not
|
// key window will be non-nil if another window became key... do not
|
||||||
@ -411,7 +413,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
|||||||
NSWindow *keyWindow = [NSApp keyWindow];
|
NSWindow *keyWindow = [NSApp keyWindow];
|
||||||
if (!keyWindow) {
|
if (!keyWindow) {
|
||||||
// no new key window, go ahead and set the active window to zero
|
// no new key window, go ahead and set the active window to zero
|
||||||
if (!m_platformWindow->windowIsPopupType())
|
if (!m_platformWindow->windowIsPopupType() && !m_isMenuView)
|
||||||
QWindowSystemInterface::handleWindowActivated(0);
|
QWindowSystemInterface::handleWindowActivated(0);
|
||||||
}
|
}
|
||||||
} else if (notificationName == NSWindowDidMiniaturizeNotification
|
} else if (notificationName == NSWindowDidMiniaturizeNotification
|
||||||
@ -621,13 +623,15 @@ QT_WARNING_POP
|
|||||||
{
|
{
|
||||||
if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) )
|
if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) )
|
||||||
return NO;
|
return NO;
|
||||||
if (!m_platformWindow->windowIsPopupType())
|
if (!m_platformWindow->windowIsPopupType() && !m_isMenuView)
|
||||||
QWindowSystemInterface::handleWindowActivated([self topLevelWindow]);
|
QWindowSystemInterface::handleWindowActivated([self topLevelWindow]);
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)acceptsFirstResponder
|
- (BOOL)acceptsFirstResponder
|
||||||
{
|
{
|
||||||
|
if (m_isMenuView)
|
||||||
|
return NO;
|
||||||
if (m_platformWindow->shouldRefuseKeyWindowAndFirstResponder())
|
if (m_platformWindow->shouldRefuseKeyWindowAndFirstResponder())
|
||||||
return NO;
|
return NO;
|
||||||
if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) )
|
if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) )
|
||||||
|
@ -1265,7 +1265,7 @@ void QMenuPrivate::_q_platformMenuAboutToShow()
|
|||||||
#ifdef Q_OS_OSX
|
#ifdef Q_OS_OSX
|
||||||
if (platformMenu)
|
if (platformMenu)
|
||||||
Q_FOREACH (QAction *action, q->actions())
|
Q_FOREACH (QAction *action, q->actions())
|
||||||
if (QWidget *widget = widgetItems.value(const_cast<QAction *>(action)))
|
if (QWidget *widget = widgetItems.value(action))
|
||||||
if (widget->parent() == q) {
|
if (widget->parent() == q) {
|
||||||
QPlatformMenuItem *menuItem = platformMenu->menuItemForTag(reinterpret_cast<quintptr>(action));
|
QPlatformMenuItem *menuItem = platformMenu->menuItemForTag(reinterpret_cast<quintptr>(action));
|
||||||
moveWidgetToPlatformItem(widget, menuItem);
|
moveWidgetToPlatformItem(widget, menuItem);
|
||||||
|
@ -115,6 +115,7 @@ void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem*
|
|||||||
QObject::connect(platformMenu, SIGNAL(destroyed()), container, SLOT(deleteLater()));
|
QObject::connect(platformMenu, SIGNAL(destroyed()), container, SLOT(deleteLater()));
|
||||||
container->resize(widget->sizeHint());
|
container->resize(widget->sizeHint());
|
||||||
widget->setParent(container);
|
widget->setParent(container);
|
||||||
|
widget->setVisible(true);
|
||||||
|
|
||||||
NSView *containerView = container->nativeView();
|
NSView *containerView = container->nativeView();
|
||||||
QWindow *containerWindow = container->windowHandle();
|
QWindow *containerWindow = container->windowHandle();
|
||||||
|
Loading…
Reference in New Issue
Block a user