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>
This commit is contained in:
parent
2d8b0d1cd5
commit
0b3da1907d
@ -556,6 +556,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
|||||||
, has_xkb(false)
|
, has_xkb(false)
|
||||||
, m_buttons(0)
|
, m_buttons(0)
|
||||||
, m_focusWindow(0)
|
, m_focusWindow(0)
|
||||||
|
, m_mouseGrabber(0)
|
||||||
, m_clientLeader(0)
|
, m_clientLeader(0)
|
||||||
, m_systemTrayTracker(0)
|
, m_systemTrayTracker(0)
|
||||||
, m_glIntegration(Q_NULLPTR)
|
, m_glIntegration(Q_NULLPTR)
|
||||||
@ -1352,6 +1353,10 @@ void QXcbConnection::setFocusWindow(QXcbWindow *w)
|
|||||||
{
|
{
|
||||||
m_focusWindow = w;
|
m_focusWindow = w;
|
||||||
}
|
}
|
||||||
|
void QXcbConnection::setMouseGrabber(QXcbWindow *w)
|
||||||
|
{
|
||||||
|
m_mouseGrabber = w;
|
||||||
|
}
|
||||||
|
|
||||||
void QXcbConnection::grabServer()
|
void QXcbConnection::grabServer()
|
||||||
{
|
{
|
||||||
|
@ -469,6 +469,8 @@ public:
|
|||||||
|
|
||||||
QXcbWindow *focusWindow() const { return m_focusWindow; }
|
QXcbWindow *focusWindow() const { return m_focusWindow; }
|
||||||
void setFocusWindow(QXcbWindow *);
|
void setFocusWindow(QXcbWindow *);
|
||||||
|
QXcbWindow *mouseGrabber() const { return m_mouseGrabber; }
|
||||||
|
void setMouseGrabber(QXcbWindow *);
|
||||||
|
|
||||||
QByteArray startupId() const { return m_startupId; }
|
QByteArray startupId() const { return m_startupId; }
|
||||||
void setStartupId(const QByteArray &nextId) { m_startupId = nextId; }
|
void setStartupId(const QByteArray &nextId) { m_startupId = nextId; }
|
||||||
@ -649,6 +651,7 @@ private:
|
|||||||
Qt::MouseButtons m_buttons;
|
Qt::MouseButtons m_buttons;
|
||||||
|
|
||||||
QXcbWindow *m_focusWindow;
|
QXcbWindow *m_focusWindow;
|
||||||
|
QXcbWindow *m_mouseGrabber;
|
||||||
|
|
||||||
xcb_window_t m_clientLeader;
|
xcb_window_t m_clientLeader;
|
||||||
QByteArray m_startupId;
|
QByteArray m_startupId;
|
||||||
|
@ -194,6 +194,8 @@ void QXcbDrag::startDrag()
|
|||||||
|
|
||||||
setUseCompositing(current_virtual_desktop->compositingActive());
|
setUseCompositing(current_virtual_desktop->compositingActive());
|
||||||
QBasicDrag::startDrag();
|
QBasicDrag::startDrag();
|
||||||
|
if (connection()->mouseGrabber() == Q_NULLPTR)
|
||||||
|
shapedPixmapWindow()->setMouseGrabEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbDrag::endDrag()
|
void QXcbDrag::endDrag()
|
||||||
|
@ -594,12 +594,16 @@ QXcbWindow::~QXcbWindow()
|
|||||||
{
|
{
|
||||||
if (window()->type() != Qt::ForeignWindow)
|
if (window()->type() != Qt::ForeignWindow)
|
||||||
destroy();
|
destroy();
|
||||||
|
else if (connection()->mouseGrabber() == this)
|
||||||
|
connection()->setMouseGrabber(Q_NULLPTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbWindow::destroy()
|
void QXcbWindow::destroy()
|
||||||
{
|
{
|
||||||
if (connection()->focusWindow() == this)
|
if (connection()->focusWindow() == this)
|
||||||
doFocusOut();
|
doFocusOut();
|
||||||
|
if (connection()->mouseGrabber() == this)
|
||||||
|
connection()->setMouseGrabber(Q_NULLPTR);
|
||||||
|
|
||||||
if (m_syncCounter && m_usingSyncProtocol)
|
if (m_syncCounter && m_usingSyncProtocol)
|
||||||
Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
|
Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
|
||||||
@ -847,6 +851,9 @@ void QXcbWindow::hide()
|
|||||||
|
|
||||||
xcb_flush(xcb_connection());
|
xcb_flush(xcb_connection());
|
||||||
|
|
||||||
|
if (connection()->mouseGrabber() == this)
|
||||||
|
connection()->setMouseGrabber(Q_NULLPTR);
|
||||||
|
|
||||||
m_mapped = false;
|
m_mapped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2357,6 +2364,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
|
|||||||
QWindowSystemInterface::handleWindowStateChanged(window(), newState);
|
QWindowSystemInterface::handleWindowStateChanged(window(), newState);
|
||||||
m_lastWindowStateEvent = newState;
|
m_lastWindowStateEvent = newState;
|
||||||
m_windowState = newState;
|
m_windowState = newState;
|
||||||
|
if (m_windowState == Qt::WindowMinimized && connection()->mouseGrabber() == this)
|
||||||
|
connection()->setMouseGrabber(Q_NULLPTR);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
|
} else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
|
||||||
@ -2411,9 +2420,15 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab)
|
|||||||
|
|
||||||
bool QXcbWindow::setMouseGrabEnabled(bool grab)
|
bool QXcbWindow::setMouseGrabEnabled(bool grab)
|
||||||
{
|
{
|
||||||
|
if (!grab && connection()->mouseGrabber() == this)
|
||||||
|
connection()->setMouseGrabber(Q_NULLPTR);
|
||||||
#ifdef XCB_USE_XINPUT22
|
#ifdef XCB_USE_XINPUT22
|
||||||
if (connection()->xi2MouseEvents())
|
if (connection()->xi2MouseEvents()) {
|
||||||
return connection()->xi2SetMouseGrabEnabled(m_window, grab);
|
bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab);
|
||||||
|
if (grab && result)
|
||||||
|
connection()->setMouseGrabber(this);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (grab && !connection()->canGrab())
|
if (grab && !connection()->canGrab())
|
||||||
return false;
|
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);
|
xcb_grab_pointer_reply_t *reply = xcb_grab_pointer_reply(xcb_connection(), cookie, NULL);
|
||||||
bool result = !(!reply || reply->status != XCB_GRAB_STATUS_SUCCESS);
|
bool result = !(!reply || reply->status != XCB_GRAB_STATUS_SUCCESS);
|
||||||
free(reply);
|
free(reply);
|
||||||
|
if (result)
|
||||||
|
connection()->setMouseGrabber(this);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user