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>
This commit is contained in:
parent
2dc1722b9e
commit
78d8c201f1
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -2584,7 +2584,7 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
|
||||
ret = 1;
|
||||
break;
|
||||
case PM_DockWidgetFrameWidth:
|
||||
ret = 2;
|
||||
ret = 0;
|
||||
break;
|
||||
case PM_DockWidgetTitleMargin:
|
||||
ret = 0;
|
||||
|
@ -943,18 +943,11 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event)
|
||||
case QEvent::NonClientAreaMouseMove:
|
||||
if (state == 0 || !state->dragging)
|
||||
break;
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
if (state->nca) {
|
||||
endDrag();
|
||||
}
|
||||
#ifdef Q_OS_MAC
|
||||
else { // workaround for lack of mouse-grab on Mac
|
||||
QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
|
||||
Q_ASSERT(layout != 0);
|
||||
|
||||
q->move(event->globalPos() - state->pressPos);
|
||||
if (!state->ctrlDrag)
|
||||
layout->hover(state->widgetItem, event->globalPos());
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case QEvent::NonClientAreaMouseButtonRelease:
|
||||
|
Loading…
Reference in New Issue
Block a user