Cocoa: Make QScreen::topLevelAt() work correctly
The QPlatformScreen::topLevelAt() default implementation is flawed in that it does not check z-ordering but simply returns the first window in the window list that contains the test point. Add QCocoaScreen::topLevelAt(). Use [NSApp orderedWindows] to iterate through the window list in z order. Add a NSWindow->QCococaWindow mapping hash to QCocoaIntegration for getting the corresponding QWindow once a NSWindow is found. Task-number: QTBUG-37597 Change-Id: I7af70163a32528cb56f8d6caa037b98f580ee191 Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
This commit is contained in:
parent
bb73d8d070
commit
bd2ec12a7b
@ -80,6 +80,7 @@ public:
|
||||
qreal refreshRate() const { return m_refreshRate; }
|
||||
QString name() const { return m_name; }
|
||||
QPlatformCursor *cursor() const { return m_cursor; }
|
||||
QWindow *topLevelAt(const QPoint &point) const;
|
||||
QList<QPlatformScreen *> virtualSiblings() const { return m_siblings; }
|
||||
|
||||
// ----------------------------------------------------
|
||||
@ -138,6 +139,8 @@ public:
|
||||
void setToolbar(QWindow *window, NSToolbar *toolbar);
|
||||
NSToolbar *toolbar(QWindow *window) const;
|
||||
void clearToolbars();
|
||||
void setWindow(NSWindow* nsWindow, QCocoaWindow *window);
|
||||
QCocoaWindow *window(NSWindow *window);
|
||||
private:
|
||||
static QCocoaIntegration *mInstance;
|
||||
|
||||
@ -156,6 +159,7 @@ private:
|
||||
QScopedPointer<QCocoaKeyMapper> mKeyboardMapper;
|
||||
|
||||
QHash<QWindow *, NSToolbar *> mToolbars;
|
||||
QHash<NSWindow *, QCocoaWindow*> mWindows;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -156,6 +156,24 @@ qreal QCocoaScreen::devicePixelRatio() const
|
||||
}
|
||||
}
|
||||
|
||||
QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
|
||||
{
|
||||
// Get a z-ordered list of windows. Iterate through it until
|
||||
// we find a window which contains the point.
|
||||
for (NSWindow *nsWindow in [NSApp orderedWindows]) {
|
||||
QCocoaWindow *cocoaWindow = QCocoaIntegration::instance()->window(nsWindow);
|
||||
if (!cocoaWindow)
|
||||
continue;
|
||||
QWindow *window = cocoaWindow->window();
|
||||
if (!window->isTopLevel())
|
||||
continue;
|
||||
if (window->geometry().contains(point))
|
||||
return window;
|
||||
}
|
||||
|
||||
return QPlatformScreen::topLevelAt(point);
|
||||
}
|
||||
|
||||
extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev);
|
||||
|
||||
QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height) const
|
||||
@ -500,6 +518,16 @@ NSToolbar *QCocoaIntegration::toolbar(QWindow *window) const
|
||||
return mToolbars.value(window);
|
||||
}
|
||||
|
||||
void QCocoaIntegration::setWindow(NSWindow* nsWindow, QCocoaWindow *window)
|
||||
{
|
||||
mWindows.insert(nsWindow, window);
|
||||
}
|
||||
|
||||
QCocoaWindow *QCocoaIntegration::window(NSWindow *window)
|
||||
{
|
||||
return mWindows.value(window);
|
||||
}
|
||||
|
||||
void QCocoaIntegration::clearToolbars()
|
||||
{
|
||||
QHash<QWindow *, NSToolbar *>::const_iterator it = mToolbars.constBegin();
|
||||
|
@ -261,6 +261,8 @@ static bool isMouseEvent(NSEvent *ev)
|
||||
{
|
||||
[self close];
|
||||
|
||||
QCocoaIntegration::instance()->setWindow(self, 0);
|
||||
|
||||
if (self.helper.grabbingMouse) {
|
||||
self.helper.releaseOnMouseUp = YES;
|
||||
} else {
|
||||
@ -327,6 +329,7 @@ static bool isMouseEvent(NSEvent *ev)
|
||||
{
|
||||
[self.helper detachFromPlatformWindow];
|
||||
[self close];
|
||||
QCocoaIntegration::instance()->setWindow(self, 0);
|
||||
[self release];
|
||||
}
|
||||
|
||||
@ -1402,6 +1405,8 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
|
||||
|
||||
applyContentBorderThickness(createdWindow);
|
||||
|
||||
QCocoaIntegration::instance()->setWindow(createdWindow, this);
|
||||
|
||||
return createdWindow;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user