summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorJames Turner <james.turner@kdab.com>2012-07-06 12:28:44 +0100
committerQt by Nokia <qt-info@nokia.com>2012-07-23 17:12:57 +0200
commit78d8c201f16374df4d5b8682f9eda2885125e1a6 (patch)
tree7b25d860559f35cb164f3e2a5fe76f0e6cffaf17 /src/plugins
parent2dc1722b9eda058748b19b6401a56cb764072599 (diff)
QTBUG-26296, dock widget moving
Cocoa lacked implementation of FrameStrut events, and also frameMargins on QPlatformWindow. Fix both of these issues. Unfortunately QDockWidget also contains a tangle of #ifdef MAC behaviour which I am unclear about. What's included here disables some logic on Mac that seems definitely wrong - while moving a window on Mac we now generate NonClientArea events (as intended, I believe), but this should not cause dock-widget dragging to end. Note the window titlebar is the only frame-strut/non-client area on Mac (as far as I can see) Task-number: QTBUG-26296 Change-Id: Id0c6e954db64b9f9f71d16355cb92922877e5ebe Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h8
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm112
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h1
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm33
4 files changed, 153 insertions, 1 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index debc8c42a2..32d9044ff6 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -55,12 +55,14 @@ class QT_PREPEND_NAMESPACE(QCocoaWindow);
@public QCocoaWindow *m_cocoaPlatformWindow;
}
+- (void)clearPlatformWindow;
- (BOOL)canBecomeKeyWindow;
@end
@interface QNSPanel : NSPanel {
@public QT_PREPEND_NAMESPACE(QCocoaWindow) *m_cocoaPlatformWindow;
}
+- (void)clearPlatformWindow;
- (BOOL)canBecomeKeyWindow;
@end
@@ -105,6 +107,7 @@ public:
void setOpacity(qreal level);
bool setKeyboardGrabEnabled(bool grab);
bool setMouseGrabEnabled(bool grab);
+ QMargins frameMargins() const;
WId winId() const;
void setParent(const QPlatformWindow *window);
@@ -122,6 +125,10 @@ public:
bool setWindowModified(bool modified) Q_DECL_OVERRIDE;
+ void setFrameStrutEventsEnabled(bool enabled);
+ bool frameStrutEventsEnabled() const
+ { return m_frameStrutEventsEnabled; }
+
void setMenubar(QCocoaMenuBar *mb);
QCocoaMenuBar *menubar() const;
protected:
@@ -152,6 +159,7 @@ public: // for QNSView
QCocoaMenuBar *m_menubar;
bool m_hasModalSession;
+ bool m_frameStrutEventsEnabled;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 971bc3ce95..96a27c2641 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -47,7 +47,7 @@
#include "qnsview.h"
#include <QtCore/private/qcore_mac_p.h>
#include <qwindow.h>
-#include <QtGui/qwindowsysteminterface.h>
+#include <QtGui/QWindowSystemInterface>
#include <qpa/qplatformscreen.h>
#include <Cocoa/Cocoa.h>
@@ -55,6 +55,45 @@
#include <QDebug>
+static bool isMouseEvent(NSEvent *ev)
+{
+ switch ([ev type]) {
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
+ case NSRightMouseDown:
+ case NSRightMouseUp:
+ case NSMouseMoved:
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ return true;
+ default:
+ return false;
+ }
+}
+
+@interface NSWindow (CocoaWindowCategory)
+- (void) clearPlatformWindow;
+- (NSRect) legacyConvertRectFromScreen:(NSRect) rect;
+@end
+
+@implementation NSWindow (CocoaWindowCategory)
+- (void) clearPlatformWindow
+{
+}
+
+- (NSRect) legacyConvertRectFromScreen:(NSRect) rect
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
+ return [self convertRectFromScreen: rect];
+ }
+#endif
+ NSRect r = rect;
+ r.origin = [self convertScreenToBase:rect.origin];
+ return r;
+}
+@end
+
@implementation QNSWindow
- (BOOL)canBecomeKeyWindow
@@ -77,6 +116,30 @@
return canBecomeMain;
}
+- (void) sendEvent: (NSEvent*) theEvent
+{
+ [super sendEvent: theEvent];
+
+ if (!m_cocoaPlatformWindow)
+ return;
+
+ if (m_cocoaPlatformWindow->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
+ NSPoint loc = [theEvent locationInWindow];
+ NSRect windowFrame = [self legacyConvertRectFromScreen:[self frame]];
+ NSRect contentFrame = [[self contentView] frame];
+ if (NSMouseInRect(loc, windowFrame, NO) &&
+ !NSMouseInRect(loc, contentFrame, NO))
+ {
+ QNSView *contentView = (QNSView *) m_cocoaPlatformWindow->contentView();
+ [contentView handleFrameStrutMouseEvent: theEvent];
+ }
+ }
+}
+
+- (void)clearPlatformWindow
+{
+ m_cocoaPlatformWindow = 0;
+}
@end
@@ -92,6 +155,31 @@
return YES;
}
+- (void) sendEvent: (NSEvent*) theEvent
+{
+ [super sendEvent: theEvent];
+
+ if (!m_cocoaPlatformWindow)
+ return;
+
+ if (m_cocoaPlatformWindow->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
+ NSPoint loc = [theEvent locationInWindow];
+ NSRect windowFrame = [self legacyConvertRectFromScreen:[self frame]];
+ NSRect contentFrame = [[self contentView] frame];
+ if (NSMouseInRect(loc, windowFrame, NO) &&
+ !NSMouseInRect(loc, contentFrame, NO))
+ {
+ QNSView *contentView = (QNSView *) m_cocoaPlatformWindow->contentView();
+ [contentView handleFrameStrutMouseEvent: theEvent];
+ }
+ }
+}
+
+- (void)clearPlatformWindow
+{
+ m_cocoaPlatformWindow = 0;
+}
+
@end
QCocoaWindow::QCocoaWindow(QWindow *tlw)
@@ -102,6 +190,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_glContext(0)
, m_menubar(0)
, m_hasModalSession(false)
+ , m_frameStrutEventsEnabled(false)
{
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::QCocoaWindow" << this;
@@ -118,6 +207,10 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
QCocoaWindow::~QCocoaWindow()
{
+#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
+ qDebug() << "QCocoaWindow::~QCocoaWindow" << this;
+#endif
+
clearNSWindow(m_nsWindow);
[m_contentView release];
[m_nsWindow release];
@@ -542,6 +635,7 @@ void QCocoaWindow::setNSWindow(NSWindow *window)
void QCocoaWindow::clearNSWindow(NSWindow *window)
{
[window setDelegate:nil];
+ [window clearPlatformWindow];
[[NSNotificationCenter defaultCenter] removeObserver:m_contentView];
}
@@ -616,3 +710,19 @@ QCocoaMenuBar *QCocoaWindow::menubar() const
{
return m_menubar;
}
+
+QMargins QCocoaWindow::frameMargins() const
+{
+ NSRect frameW = [m_nsWindow frame];
+ NSRect frameC = [m_nsWindow contentRectForFrameRect:frameW];
+
+ return QMargins(frameW.origin.x - frameC.origin.x,
+ (frameW.origin.y + frameW.size.height) - (frameC.origin.y + frameC.size.height),
+ (frameW.origin.x + frameW.size.width) - (frameC.origin.x + frameC.size.width),
+ frameC.origin.y - frameW.origin.y);
+}
+
+void QCocoaWindow::setFrameStrutEventsEnabled(bool enabled)
+{
+ m_frameStrutEventsEnabled = enabled;
+}
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 2e8d9cebe9..b7218a4d26 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -88,6 +88,7 @@ QT_END_NAMESPACE
- (void)otherMouseDown:(NSEvent *)theEvent;
- (void)otherMouseDragged:(NSEvent *)theEvent;
- (void)otherMouseUp:(NSEvent *)theEvent;
+- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent;
- (int) convertKeyCode : (QChar)keyCode;
- (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 6c83e42fbc..aeecefab4a 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -310,6 +310,39 @@ static QTouchDevice *touchDevice = 0;
QWindowSystemInterface::handleMouseEvent(m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons);
}
+- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent
+{
+ // get m_buttons in sync
+ NSEventType ty = [theEvent type];
+ switch (ty) {
+ case NSLeftMouseDown:
+ m_buttons |= Qt::LeftButton;
+ break;
+ case NSLeftMouseUp:
+ m_buttons &= QFlag(~int(Qt::LeftButton));
+ break;
+ case NSRightMouseDown:
+ m_buttons |= Qt::RightButton;
+ break;
+ case NSRightMouseUp:
+ m_buttons &= QFlag(~int(Qt::RightButton));
+ break;
+ default:
+ break;
+ }
+
+ NSWindow *window = [self window];
+ int windowHeight = [window frame].size.height;
+ NSPoint windowPoint = [theEvent locationInWindow];
+ NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil];
+ QPoint qtWindowPoint = QPoint(windowPoint.x, windowHeight - windowPoint.y);
+ NSPoint screenPoint = [window convertBaseToScreen : windowPoint];
+ QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y));
+
+ ulong timestamp = [theEvent timestamp] * 1000;
+ QWindowSystemInterface::handleFrameStrutMouseEvent(m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons);
+}
+
- (void)mouseDown:(NSEvent *)theEvent
{
if (m_platformWindow->m_activePopupWindow) {