summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorBłażej Szczygieł <spaz16@wp.pl>2015-10-18 00:16:15 +0200
committerBłażej Szczygieł <spaz16@wp.pl>2016-01-05 21:12:34 +0000
commit0b3da1907d46a03e8838c4086b23d48ba69c8776 (patch)
treef341edac0ae35e2b2b8e003c645fa125f302d0e1 /src/plugins/platforms
parent2d8b0d1cd566cc0c3ab600650b66cdc771d8314f (diff)
xcb: fix drag and drop when window is hidden
This patch fixes drag and drop operation on XCB platform when window will be hidden. The window can be hidden during dnd operation by switching virtual desktops or by minimizing all windows (show desktop) using key shortcut. The ShapedPixmapWindow must grab mouse before dnd operation if mouse is not grabbed by other window (like in Qt4). Task-number: QTBUG-46243 Change-Id: I807bc842719a2d0ea0f4dcb733c06c1fd08813e1 Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp21
4 files changed, 29 insertions, 2 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index f93cfde4a5..abb48034cd 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -556,6 +556,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
, has_xkb(false)
, m_buttons(0)
, m_focusWindow(0)
+ , m_mouseGrabber(0)
, m_clientLeader(0)
, m_systemTrayTracker(0)
, m_glIntegration(Q_NULLPTR)
@@ -1352,6 +1353,10 @@ void QXcbConnection::setFocusWindow(QXcbWindow *w)
{
m_focusWindow = w;
}
+void QXcbConnection::setMouseGrabber(QXcbWindow *w)
+{
+ m_mouseGrabber = w;
+}
void QXcbConnection::grabServer()
{
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 6d26e88fa2..a6a7b9e7ca 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -469,6 +469,8 @@ public:
QXcbWindow *focusWindow() const { return m_focusWindow; }
void setFocusWindow(QXcbWindow *);
+ QXcbWindow *mouseGrabber() const { return m_mouseGrabber; }
+ void setMouseGrabber(QXcbWindow *);
QByteArray startupId() const { return m_startupId; }
void setStartupId(const QByteArray &nextId) { m_startupId = nextId; }
@@ -649,6 +651,7 @@ private:
Qt::MouseButtons m_buttons;
QXcbWindow *m_focusWindow;
+ QXcbWindow *m_mouseGrabber;
xcb_window_t m_clientLeader;
QByteArray m_startupId;
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index d19ea241f1..9296a6d141 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -194,6 +194,8 @@ void QXcbDrag::startDrag()
setUseCompositing(current_virtual_desktop->compositingActive());
QBasicDrag::startDrag();
+ if (connection()->mouseGrabber() == Q_NULLPTR)
+ shapedPixmapWindow()->setMouseGrabEnabled(true);
}
void QXcbDrag::endDrag()
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index bec167fec2..4e4a0cdaef 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -594,12 +594,16 @@ QXcbWindow::~QXcbWindow()
{
if (window()->type() != Qt::ForeignWindow)
destroy();
+ else if (connection()->mouseGrabber() == this)
+ connection()->setMouseGrabber(Q_NULLPTR);
}
void QXcbWindow::destroy()
{
if (connection()->focusWindow() == this)
doFocusOut();
+ if (connection()->mouseGrabber() == this)
+ connection()->setMouseGrabber(Q_NULLPTR);
if (m_syncCounter && m_usingSyncProtocol)
Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
@@ -847,6 +851,9 @@ void QXcbWindow::hide()
xcb_flush(xcb_connection());
+ if (connection()->mouseGrabber() == this)
+ connection()->setMouseGrabber(Q_NULLPTR);
+
m_mapped = false;
}
@@ -2357,6 +2364,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
QWindowSystemInterface::handleWindowStateChanged(window(), newState);
m_lastWindowStateEvent = newState;
m_windowState = newState;
+ if (m_windowState == Qt::WindowMinimized && connection()->mouseGrabber() == this)
+ connection()->setMouseGrabber(Q_NULLPTR);
}
return;
} else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
@@ -2411,9 +2420,15 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab)
bool QXcbWindow::setMouseGrabEnabled(bool grab)
{
+ if (!grab && connection()->mouseGrabber() == this)
+ connection()->setMouseGrabber(Q_NULLPTR);
#ifdef XCB_USE_XINPUT22
- if (connection()->xi2MouseEvents())
- return connection()->xi2SetMouseGrabEnabled(m_window, grab);
+ if (connection()->xi2MouseEvents()) {
+ bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab);
+ if (grab && result)
+ connection()->setMouseGrabber(this);
+ return result;
+ }
#endif
if (grab && !connection()->canGrab())
return false;
@@ -2432,6 +2447,8 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab)
xcb_grab_pointer_reply_t *reply = xcb_grab_pointer_reply(xcb_connection(), cookie, NULL);
bool result = !(!reply || reply->status != XCB_GRAB_STATUS_SUCCESS);
free(reply);
+ if (result)
+ connection()->setMouseGrabber(this);
return result;
}