summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/kernel/qguiapplication.cpp17
-rw-r--r--src/gui/kernel/qplatformwindow.h3
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.cpp23
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.cpp15
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.h2
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa_p.h4
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp37
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.h1
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp9
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h6
-rw-r--r--src/widgets/kernel/qwidgetwindow_qpa.cpp12
-rw-r--r--src/widgets/kernel/qwidgetwindow_qpa_p.h1
-rw-r--r--src/widgets/widgets/qdockwidget.cpp7
14 files changed, 128 insertions, 14 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index a3d9c1f2ab..a27a8558cd 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1098,6 +1098,7 @@ bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArra
void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
{
switch(e->type) {
+ case QWindowSystemInterfacePrivate::FrameStrutMouse:
case QWindowSystemInterfacePrivate::Mouse:
QGuiApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
break;
@@ -1179,9 +1180,10 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
QEvent::Type type;
// move first
Qt::MouseButtons stateChange = e->buttons ^ buttons;
+ const bool frameStrut = e->type == QWindowSystemInterfacePrivate::FrameStrutMouse;
if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) {
QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
- new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->localPos, e->globalPos, e->buttons, e->modifiers);
+ new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers);
QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
stateChange = Qt::NoButton;
}
@@ -1204,7 +1206,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
bool doubleClick = false;
if (QGuiApplicationPrivate::lastCursorPosition != globalPoint) {
- type = QEvent::MouseMove;
+ type = frameStrut ? QEvent::NonClientAreaMouseMove : QEvent::MouseMove;
QGuiApplicationPrivate::lastCursorPosition = globalPoint;
if (qAbs(globalPoint.x() - mousePressX) > mouse_double_click_distance||
qAbs(globalPoint.y() - mousePressY) > mouse_double_click_distance)
@@ -1226,14 +1228,14 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (button & e->buttons) {
ulong doubleClickInterval = static_cast<ulong>(qApp->styleHints()->mouseDoubleClickInterval());
doubleClick = e->timestamp - mousePressTime < doubleClickInterval && button == mousePressButton;
- type = QEvent::MouseButtonPress;
+ type = frameStrut ? QEvent::NonClientAreaMouseButtonPress : QEvent::MouseButtonPress;
mousePressTime = e->timestamp;
mousePressButton = button;
const QPoint point = QGuiApplicationPrivate::lastCursorPosition.toPoint();
mousePressX = point.x();
mousePressY = point.y();
} else {
- type = QEvent::MouseButtonRelease;
+ type = frameStrut ? QEvent::NonClientAreaMouseButtonRelease : QEvent::MouseButtonRelease;
}
}
@@ -1253,7 +1255,9 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
cursor->pointerEvent(ev);
#endif
QGuiApplication::sendSpontaneousEvent(window, &ev);
- if (!e->synthetic && !ev.isAccepted() && qApp->testAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents)) {
+ if (!e->synthetic && !ev.isAccepted()
+ && !frameStrut
+ && qApp->testAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents)) {
if (!m_fakeTouchDevice) {
m_fakeTouchDevice = new QTouchDevice;
QWindowSystemInterface::registerTouchDevice(m_fakeTouchDevice);
@@ -1287,7 +1291,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
}
if (doubleClick) {
mousePressButton = Qt::NoButton;
- QMouseEvent dblClickEvent(QEvent::MouseButtonDblClick, localPoint, localPoint, globalPoint,
+ const QEvent::Type doubleClickType = frameStrut ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick;
+ QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint,
button, buttons, e->modifiers);
dblClickEvent.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index cded1fe316..a6a519e6fd 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -122,6 +122,9 @@ public:
virtual bool startSystemResize(const QPoint &pos, Qt::Corner corner);
+ virtual void setFrameStrutEventsEnabled(bool enabled);
+ virtual bool frameStrutEventsEnabled() const;
+
protected:
QScopedPointer<QPlatformWindowPrivate> d_ptr;
private:
diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp
index d2ec6833b0..3c2246cf00 100644
--- a/src/gui/kernel/qplatformwindow_qpa.cpp
+++ b/src/gui/kernel/qplatformwindow_qpa.cpp
@@ -374,6 +374,29 @@ bool QPlatformWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
}
/*!
+ Reimplement this method to set whether frame strut events
+ should be sent to \a enabled.
+
+ \sa frameStrutEventsEnabled
+*/
+
+void QPlatformWindow::setFrameStrutEventsEnabled(bool enabled)
+{
+ if (enabled)
+ qWarning("This plugin does not support frame strut events.");
+}
+
+/*!
+ Reimplement this method to return whether
+ frame strut events are enabled.
+*/
+
+bool QPlatformWindow::frameStrutEventsEnabled() const
+{
+ return false;
+}
+
+/*!
\class QPlatformWindow
\since 4.8
\internal
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
index c707d4eea2..139df98daf 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
@@ -149,6 +149,21 @@ void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
+void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+{
+ const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
+ handleFrameStrutMouseEvent(w, time, local, global, b, mods);
+}
+
+void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+{
+ QWindowSystemInterfacePrivate::MouseEvent * e =
+ new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp,
+ QWindowSystemInterfacePrivate::FrameStrutMouse,
+ local, global, b, mods);
+ QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
bool QWindowSystemInterface::tryHandleSynchronousShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
const QString & text, bool autorep, ushort count)
{
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h
index 34587f67d8..b55f3e3f33 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.h
@@ -68,6 +68,8 @@ class Q_GUI_EXPORT QWindowSystemInterface
public:
static void handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
static void handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
+ static void handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
+ static void handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
static bool tryHandleSynchronousShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
const QString & text = QString(), bool autorep = false, ushort count = 1);
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
index 919a7de39b..8fb0652eb6 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
@@ -60,6 +60,7 @@ public:
ActivatedWindow,
WindowStateChanged,
Mouse,
+ FrameStrutMouse,
Wheel,
Key,
Touch,
@@ -156,6 +157,9 @@ public:
MouseEvent(QWindow * w, ulong time, const QPointF & local, const QPointF & global,
Qt::MouseButtons b, Qt::KeyboardModifiers mods)
: InputEvent(w, time, Mouse, mods), localPos(local), globalPos(global), buttons(b) { }
+ MouseEvent(QWindow * w, ulong time, EventType t, const QPointF & local, const QPointF & global,
+ Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+ : InputEvent(w, time, t, mods), localPos(local), globalPos(global), buttons(b) { }
QPointF localPos;
QPointF globalPos;
Qt::MouseButtons buttons;
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 891753215d..ba32369c03 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -817,9 +817,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
#endif
case QtWindows::ExposeEvent:
return platformWindow->handleWmPaint(hwnd, message, wParam, lParam);
+ case QtWindows::NonClientMouseEvent:
+ if (platformWindow->frameStrutEventsEnabled())
+ return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
+ break;
case QtWindows::MouseWheelEvent:
case QtWindows::MouseEvent:
- case QtWindows::NonClientMouseEvent:
case QtWindows::LeaveEvent:
return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
case QtWindows::TouchEvent:
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index eb7d2912bb..e9a2b5c19d 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qwindowsmousehandler.h"
+#include "qwindowskeymapper.h"
#include "qwindowscontext.h"
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
@@ -130,14 +131,37 @@ QWindowsMouseHandler::QWindowsMouseHandler() :
{
}
+Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
+{
+ Qt::MouseButtons result = 0;
+ const bool mouseSwapped = GetSystemMetrics(SM_SWAPBUTTON);
+ if (GetAsyncKeyState(VK_LBUTTON) < 0)
+ result |= mouseSwapped ? Qt::RightButton: Qt::LeftButton;
+ if (GetAsyncKeyState(VK_RBUTTON) < 0)
+ result |= mouseSwapped ? Qt::LeftButton : Qt::RightButton;
+ if (GetAsyncKeyState(VK_MBUTTON) < 0)
+ result |= Qt::MidButton;
+ return result;
+}
+
bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
QtWindows::WindowsEventType et,
MSG msg, LRESULT *result)
{
- if (et & QtWindows::NonClientEventFlag)
- return false;
if (et == QtWindows::MouseWheelEvent)
return translateMouseWheelEvent(window, hwnd, msg, result);
+
+ const QPoint winEventPosition(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
+ if (et & QtWindows::NonClientEventFlag) {
+ const QPoint globalPosition = winEventPosition;
+ const QPoint clientPosition = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPosition);
+ const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
+ QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
+ globalPosition, buttons,
+ QWindowsKeyMapper::queryKeyboardModifiers());
+ return false; // Allow further event processing (dragging of windows).
+ }
+
*result = 0;
if (msg.message == WM_MOUSELEAVE) {
// When moving out of a child, MouseMove within parent is received first
@@ -161,7 +185,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
return true;
}
}
- const QPoint client(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
// Enter new window: track to generate leave event.
if (m_windowUnderMouse != window) {
// The tracking on m_windowUnderMouse might still be active and
@@ -186,9 +209,11 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
qWarning("TrackMouseEvent failed.");
#endif // !Q_OS_WINCE
}
- QWindowSystemInterface::handleMouseEvent(window, client,
- QWindowsGeometryHint::mapToGlobal(hwnd, client),
- keyStateToMouseButtons((int)msg.wParam));
+ const QPoint clientPosition = winEventPosition;
+ QWindowSystemInterface::handleMouseEvent(window, clientPosition,
+ QWindowsGeometryHint::mapToGlobal(hwnd, clientPosition),
+ keyStateToMouseButtons((int)msg.wParam),
+ QWindowsKeyMapper::queryKeyboardModifiers());
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h
index a978840d67..e3d329e872 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.h
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.h
@@ -70,6 +70,7 @@ public:
static inline Qt::KeyboardModifiers keyStateToModifiers(int);
static inline int mouseButtonsToKeyState(Qt::MouseButtons);
+ static Qt::MouseButtons queryMouseButtons();
QWindow *windowUnderMouse() const { return m_windowUnderMouse.data(); }
private:
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 7fa43e03e6..b553c15864 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1489,6 +1489,15 @@ bool QWindowsWindow::startSystemResize(const QPoint &, Qt::Corner corner)
return true;
}
+void QWindowsWindow::setFrameStrutEventsEnabled(bool enabled)
+{
+ if (enabled) {
+ setFlag(FrameStrutEventsEnabled);
+ } else {
+ clearFlag(FrameStrutEventsEnabled);
+ }
+}
+
#ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO
void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
{
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 182bef78e4..475982aba4 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -123,7 +123,8 @@ public:
OpenGLDoubleBuffered = 0x20,
OpenGlPixelFormatInitialized = 0x40,
BlockedByModal = 0x80,
- SizeGripOperation = 0x100
+ SizeGripOperation = 0x100,
+ FrameStrutEventsEnabled = 0x200
};
struct WindowData
@@ -178,6 +179,9 @@ public:
virtual bool startSystemResize(const QPoint &pos, Qt::Corner corner);
+ void setFrameStrutEventsEnabled(bool enabled);
+ bool frameStrutEventsEnabled() const { return testFlag(FrameStrutEventsEnabled); }
+
Qt::WindowState windowState_sys() const;
Qt::WindowStates windowStates_sys() const;
diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp
index f8a5178be5..1b076d1801 100644
--- a/src/widgets/kernel/qwidgetwindow_qpa.cpp
+++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp
@@ -137,6 +137,13 @@ bool QWidgetWindow::event(QEvent *event)
handleMouseEvent(static_cast<QMouseEvent *>(event));
return true;
+ case QEvent::NonClientAreaMouseMove:
+ case QEvent::NonClientAreaMouseButtonPress:
+ case QEvent::NonClientAreaMouseButtonRelease:
+ case QEvent::NonClientAreaMouseButtonDblClick:
+ handleNonClientAreaMouseEvent(static_cast<QMouseEvent *>(event));
+ return true;
+
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
@@ -208,6 +215,11 @@ void QWidgetWindow::handleEnterLeaveEvent(QEvent *event)
}
}
+void QWidgetWindow::handleNonClientAreaMouseEvent(QMouseEvent *e)
+{
+ QApplication::sendSpontaneousEvent(m_widget, e);
+}
+
void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
{
if (qApp->d_func()->inPopupMode()) {
diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h
index 8afa3f33cd..5750a05d40 100644
--- a/src/widgets/kernel/qwidgetwindow_qpa_p.h
+++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h
@@ -74,6 +74,7 @@ protected:
void handleEnterLeaveEvent(QEvent *);
void handleKeyEvent(QKeyEvent *);
void handleMouseEvent(QMouseEvent *);
+ void handleNonClientAreaMouseEvent(QMouseEvent *);
void handleTouchEvent(QTouchEvent *);
void handleMoveEvent(QMoveEvent *);
void handleResizeEvent(QResizeEvent *);
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index be216ecf9f..551549f97e 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -48,12 +48,14 @@
#include <qdrawutil.h>
#include <qevent.h>
#include <qfontmetrics.h>
+#include <qwindow.h>
#include <qmainwindow.h>
#include <qrubberband.h>
#include <qstylepainter.h>
#include <qtoolbutton.h>
#include <qdebug.h>
+#include <qpa/qplatformwindow.h>
#include <private/qwidgetresizehandler_p.h>
#include "qdockwidget_p.h"
@@ -1052,6 +1054,11 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect
}
}
+ if (unplug && floating && nativeDeco)
+ if (const QWindow *window = q->windowHandle())
+ if (QPlatformWindow *platformWindow = window->handle())
+ platformWindow->setFrameStrutEventsEnabled(true);
+
resizer->setActive(QWidgetResizeHandler::Resize, !unplug && floating && !nativeDeco);
}