forked from pool/libqt5-qtbase
Accepting request 401298 from KDE:Qt5
Update to 5.6.1 OBS-URL: https://build.opensuse.org/request/show/401298 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libqt5-qtbase?expand=0&rev=54
This commit is contained in:
parent
26d10f1197
commit
df05d9d28f
@ -1,554 +0,0 @@
|
||||
From e4c22c34fb105fc9c30be855048692d95b31c760 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= <spaz16@wp.pl>
|
||||
Date: Fri, 8 Jan 2016 19:37:52 +0100
|
||||
Subject: [PATCH 01/16] xcb: XInput2 fixes, enter/leave event fixes
|
||||
|
||||
Added enter/leave event handling in XInput2 to avoid problems with
|
||||
those events when the mouse is grabbed.
|
||||
|
||||
This commit amends: 53d289ec4c0f512a3475da4bbf1f940cd6838ace
|
||||
This commit amends: ed2e15780385f7cf0a0d3aedc9cb2059d470bd58
|
||||
|
||||
Task-number: QTBUG-50340
|
||||
Change-Id: I7a120b46daa4f8fa4c218346273ae90b6abfa156
|
||||
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
(cherry picked from commit e4fb521b3f3b9e59146b7569b72aee08dbaeb268)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbconnection.cpp | 16 +-
|
||||
src/plugins/platforms/xcb/qxcbconnection.h | 12 +-
|
||||
src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 54 +++++--
|
||||
src/plugins/platforms/xcb/qxcbkeyboard.cpp | 8 +-
|
||||
src/plugins/platforms/xcb/qxcbkeyboard.h | 2 +
|
||||
src/plugins/platforms/xcb/qxcbwindow.cpp | 177 ++++++++++++++---------
|
||||
src/plugins/platforms/xcb/qxcbwindow.h | 9 ++
|
||||
7 files changed, 183 insertions(+), 95 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
|
||||
index 9cedd296e1e9ad870900a09f2d955e3460484205..aeb730670d62b3ce2239fba48b58ccb4752e912d 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
|
||||
@@ -613,8 +613,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
||||
initializeScreens();
|
||||
|
||||
initializeXRender();
|
||||
- m_xi2Enabled = false;
|
||||
#if defined(XCB_USE_XINPUT2)
|
||||
+ m_xi2Enabled = false;
|
||||
initializeXInput2();
|
||||
#endif
|
||||
initializeXShape();
|
||||
@@ -1133,8 +1133,16 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
||||
handleClientMessageEvent((xcb_client_message_event_t *)event);
|
||||
break;
|
||||
case XCB_ENTER_NOTIFY:
|
||||
+#ifdef XCB_USE_XINPUT22
|
||||
+ if (isAtLeastXI22() && xi2MouseEvents())
|
||||
+ break;
|
||||
+#endif
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
|
||||
case XCB_LEAVE_NOTIFY:
|
||||
+#ifdef XCB_USE_XINPUT22
|
||||
+ if (isAtLeastXI22() && xi2MouseEvents())
|
||||
+ break;
|
||||
+#endif
|
||||
m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state);
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
|
||||
case XCB_FOCUS_IN:
|
||||
@@ -2216,13 +2224,15 @@ void QXcbConnection::initializeXKB()
|
||||
#endif
|
||||
}
|
||||
|
||||
+#if defined(XCB_USE_XINPUT22)
|
||||
bool QXcbConnection::xi2MouseEvents() const
|
||||
{
|
||||
static bool mouseViaXI2 = !qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE");
|
||||
- // Don't use XInput2 when Xinerama extension is enabled,
|
||||
- // because it causes problems with multi-monitor setup.
|
||||
+ // FIXME: Don't use XInput2 mouse events when Xinerama extension
|
||||
+ // is enabled, because it causes problems with multi-monitor setup.
|
||||
return mouseViaXI2 && !has_xinerama_extension;
|
||||
}
|
||||
+#endif
|
||||
|
||||
#if defined(XCB_USE_XINPUT2)
|
||||
static int xi2ValuatorOffset(unsigned char *maskPtr, int maskLen, int number)
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
|
||||
index a6a7b9e7ca1898fe2add7a51107bfc9e535d9b44..6c2b8583af24e9abd7a087144fb33504ec36fbf8 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbconnection.h
|
||||
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
|
||||
@@ -347,8 +347,10 @@ public:
|
||||
virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {}
|
||||
virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {}
|
||||
virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {}
|
||||
+#ifdef XCB_USE_XINPUT22
|
||||
virtual void handleXIMouseEvent(xcb_ge_event_t *) {}
|
||||
-
|
||||
+ virtual void handleXIEnterLeave(xcb_ge_event_t *) {}
|
||||
+#endif
|
||||
virtual QXcbWindow *toWindow() { return 0; }
|
||||
};
|
||||
|
||||
@@ -485,8 +487,8 @@ public:
|
||||
static bool xEmbedSystemTrayAvailable();
|
||||
static bool xEmbedSystemTrayVisualHasAlphaChannel();
|
||||
|
||||
-#ifdef XCB_USE_XINPUT2
|
||||
- void handleEnterEvent(const xcb_enter_notify_event_t *);
|
||||
+#ifdef XCB_USE_XINPUT21
|
||||
+ void handleEnterEvent();
|
||||
#endif
|
||||
|
||||
#ifdef XCB_USE_XINPUT22
|
||||
@@ -500,7 +502,9 @@ public:
|
||||
|
||||
QXcbGlIntegration *glIntegration() const { return m_glIntegration; }
|
||||
|
||||
+#ifdef XCB_USE_XINPUT22
|
||||
bool xi2MouseEvents() const;
|
||||
+#endif
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e) Q_DECL_OVERRIDE;
|
||||
@@ -534,9 +538,9 @@ private:
|
||||
void initializeScreens();
|
||||
bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const;
|
||||
|
||||
+#ifdef XCB_USE_XINPUT2
|
||||
bool m_xi2Enabled;
|
||||
int m_xi2Minor;
|
||||
-#ifdef XCB_USE_XINPUT2
|
||||
void initializeXInput2();
|
||||
void finalizeXInput2();
|
||||
void xi2SetupDevices();
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
|
||||
index e055ad1424f9ec51a5f4e814babd85601c920c90..0c78c0e0d2bc9d05e9f6768ead72cad4a51d03a7 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
|
||||
@@ -293,6 +293,11 @@ void QXcbConnection::xi2Select(xcb_window_t window)
|
||||
bitMask |= XI_ButtonPressMask;
|
||||
bitMask |= XI_ButtonReleaseMask;
|
||||
bitMask |= XI_MotionMask;
|
||||
+
|
||||
+ // There is a check for enter/leave events in plain xcb enter/leave event handler
|
||||
+ bitMask |= XI_EnterMask;
|
||||
+ bitMask |= XI_LeaveMask;
|
||||
+
|
||||
qCDebug(lcQpaXInput, "XInput 2.2: Selecting press/release/motion events in addition to touch");
|
||||
}
|
||||
XIEventMask mask;
|
||||
@@ -307,9 +312,12 @@ void QXcbConnection::xi2Select(xcb_window_t window)
|
||||
if (result != Success)
|
||||
qCDebug(lcQpaXInput, "XInput 2.2: failed to select pointer/touch events, window %x, result %d", window, result);
|
||||
}
|
||||
-#endif // XCB_USE_XINPUT22
|
||||
|
||||
const bool pointerSelected = isAtLeastXI22() && xi2MouseEvents();
|
||||
+#else
|
||||
+ const bool pointerSelected = false;
|
||||
+#endif // XCB_USE_XINPUT22
|
||||
+
|
||||
QSet<int> tabletDevices;
|
||||
#ifndef QT_NO_TABLETEVENT
|
||||
if (!m_tabletData.isEmpty()) {
|
||||
@@ -474,6 +482,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
||||
xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
|
||||
int sourceDeviceId = xiEvent->deviceid; // may be the master id
|
||||
xXIDeviceEvent *xiDeviceEvent = 0;
|
||||
+ xXIEnterEvent *xiEnterEvent = 0;
|
||||
QXcbWindowEventListener *eventListener = 0;
|
||||
|
||||
switch (xiEvent->evtype) {
|
||||
@@ -488,14 +497,16 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
||||
{
|
||||
xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
|
||||
eventListener = windowEventListenerFromId(xiDeviceEvent->event);
|
||||
- if (eventListener) {
|
||||
- long result = 0;
|
||||
- if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(event), &result))
|
||||
- return;
|
||||
- }
|
||||
sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master
|
||||
break;
|
||||
}
|
||||
+ case XI_Enter:
|
||||
+ case XI_Leave: {
|
||||
+ xiEnterEvent = reinterpret_cast<xXIEnterEvent *>(event);
|
||||
+ eventListener = windowEventListenerFromId(xiEnterEvent->event);
|
||||
+ sourceDeviceId = xiEnterEvent->sourceid; // use the actual device id instead of the master
|
||||
+ break;
|
||||
+ }
|
||||
case XI_HierarchyChanged:
|
||||
xi2HandleHierachyEvent(xiEvent);
|
||||
return;
|
||||
@@ -506,11 +517,19 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (eventListener) {
|
||||
+ long result = 0;
|
||||
+ if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(event), &result))
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
#ifndef QT_NO_TABLETEVENT
|
||||
- for (int i = 0; i < m_tabletData.count(); ++i) {
|
||||
- if (m_tabletData.at(i).deviceId == sourceDeviceId) {
|
||||
- if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener))
|
||||
- return;
|
||||
+ if (!xiEnterEvent) {
|
||||
+ for (int i = 0; i < m_tabletData.count(); ++i) {
|
||||
+ if (m_tabletData.at(i).deviceId == sourceDeviceId) {
|
||||
+ if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener))
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
#endif // QT_NO_TABLETEVENT
|
||||
@@ -543,6 +562,13 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
||||
xi2ProcessTouch(xiDeviceEvent, platformWindow);
|
||||
break;
|
||||
}
|
||||
+ } else if (xiEnterEvent && xi2MouseEvents() && eventListener) {
|
||||
+ switch (xiEnterEvent->evtype) {
|
||||
+ case XI_Enter:
|
||||
+ case XI_Leave:
|
||||
+ eventListener->handleXIEnterLeave(event);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
#endif // XCB_USE_XINPUT22
|
||||
}
|
||||
@@ -718,6 +744,8 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab)
|
||||
XISetMask(mask, XI_ButtonPress);
|
||||
XISetMask(mask, XI_ButtonRelease);
|
||||
XISetMask(mask, XI_Motion);
|
||||
+ XISetMask(mask, XI_Enter);
|
||||
+ XISetMask(mask, XI_Leave);
|
||||
XISetMask(mask, XI_TouchBegin);
|
||||
XISetMask(mask, XI_TouchUpdate);
|
||||
XISetMask(mask, XI_TouchEnd);
|
||||
@@ -827,9 +855,9 @@ void QXcbConnection::updateScrollingDevice(ScrollingDevice &scrollingDevice, int
|
||||
#endif
|
||||
}
|
||||
|
||||
-void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *)
|
||||
-{
|
||||
#ifdef XCB_USE_XINPUT21
|
||||
+void QXcbConnection::handleEnterEvent()
|
||||
+{
|
||||
QHash<int, ScrollingDevice>::iterator it = m_scrollingDevices.begin();
|
||||
const QHash<int, ScrollingDevice>::iterator end = m_scrollingDevices.end();
|
||||
while (it != end) {
|
||||
@@ -845,8 +873,8 @@ void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *)
|
||||
XIFreeDeviceInfo(xiDeviceInfo);
|
||||
++it;
|
||||
}
|
||||
-#endif
|
||||
}
|
||||
+#endif
|
||||
|
||||
void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice)
|
||||
{
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
|
||||
index 2e088d3ca51dfff7fcf41f476b4f8db7c8f40543..631dd17908f458533f413409773b6c078b743d98 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
|
||||
@@ -797,9 +797,9 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
|
||||
}
|
||||
}
|
||||
|
||||
+#ifdef XCB_USE_XINPUT22
|
||||
void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo)
|
||||
{
|
||||
-#ifdef XCB_USE_XINPUT22
|
||||
if (m_config && !connection()->hasXKB()) {
|
||||
xXIModifierInfo *mods = static_cast<xXIModifierInfo *>(modInfo);
|
||||
xXIGroupInfo *group = static_cast<xXIGroupInfo *>(groupInfo);
|
||||
@@ -815,12 +815,8 @@ void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo)
|
||||
//qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
|
||||
}
|
||||
}
|
||||
-#else
|
||||
- Q_UNUSED(modInfo);
|
||||
- Q_UNUSED(groupInfo);
|
||||
- Q_ASSERT(false); // this can't be
|
||||
-#endif
|
||||
}
|
||||
+#endif
|
||||
|
||||
quint32 QXcbKeyboard::xkbModMask(quint16 state)
|
||||
{
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
|
||||
index d2e37d624cfe5960bf50d8f18f2a82756824fa4d..457a27affb166e2a3e54c78761361ff3713a4d18 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
|
||||
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
|
||||
@@ -68,7 +68,9 @@ public:
|
||||
void updateXKBMods();
|
||||
quint32 xkbModMask(quint16 state);
|
||||
void updateXKBStateFromCore(quint16 state);
|
||||
+#ifdef XCB_USE_XINPUT22
|
||||
void updateXKBStateFromXI(void *modInfo, void *groupInfo);
|
||||
+#endif
|
||||
#ifndef QT_NO_XKB
|
||||
// when XKEYBOARD is present on the X server
|
||||
int coreDeviceId() const { return core_device_id; }
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
index f97f570831a099c7d1d87cb12ed3c44baa7237eb..91c5eadf3456e15467ba94dd72a886a365aa6a7d 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
@@ -2157,6 +2157,78 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x,
|
||||
handleMouseEvent(timestamp, local, global, modifiers);
|
||||
}
|
||||
|
||||
+static bool ignoreLeaveEvent(quint8 mode, quint8 detail)
|
||||
+{
|
||||
+ return (mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM
|
||||
+ || detail == XCB_NOTIFY_DETAIL_VIRTUAL
|
||||
+ || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL;
|
||||
+}
|
||||
+
|
||||
+static bool ignoreEnterEvent(quint8 mode, quint8 detail)
|
||||
+{
|
||||
+ return ((mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM
|
||||
+ || (mode != XCB_NOTIFY_MODE_NORMAL && mode != XCB_NOTIFY_MODE_UNGRAB)
|
||||
+ || detail == XCB_NOTIFY_DETAIL_VIRTUAL
|
||||
+ || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL);
|
||||
+}
|
||||
+
|
||||
+class EnterEventChecker
|
||||
+{
|
||||
+public:
|
||||
+ bool checkEvent(xcb_generic_event_t *event)
|
||||
+ {
|
||||
+ if (!event)
|
||||
+ return false;
|
||||
+ if ((event->response_type & ~0x80) != XCB_ENTER_NOTIFY)
|
||||
+ return false;
|
||||
+
|
||||
+ xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event;
|
||||
+ if (ignoreEnterEvent(enter->mode, enter->detail))
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y,
|
||||
+ quint8 mode, quint8 detail, xcb_timestamp_t timestamp)
|
||||
+{
|
||||
+ connection()->setTime(timestamp);
|
||||
+#ifdef XCB_USE_XINPUT21
|
||||
+ connection()->handleEnterEvent();
|
||||
+#endif
|
||||
+
|
||||
+ if (ignoreEnterEvent(mode, detail))
|
||||
+ return;
|
||||
+
|
||||
+ const QPoint local(event_x, event_y);
|
||||
+ QPoint global = QPoint(root_x, root_y);
|
||||
+ QWindowSystemInterface::handleEnterEvent(window(), local, global);
|
||||
+}
|
||||
+
|
||||
+void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y,
|
||||
+ quint8 mode, quint8 detail, xcb_timestamp_t timestamp)
|
||||
+{
|
||||
+ connection()->setTime(timestamp);
|
||||
+
|
||||
+ if (ignoreLeaveEvent(mode, detail))
|
||||
+ return;
|
||||
+
|
||||
+ EnterEventChecker checker;
|
||||
+ xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker);
|
||||
+ QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0;
|
||||
+
|
||||
+ if (enterWindow) {
|
||||
+ QPoint local(enter->event_x, enter->event_y);
|
||||
+ QPoint global = QPoint(root_x, root_y);
|
||||
+ QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global);
|
||||
+ } else {
|
||||
+ QWindowSystemInterface::handleLeaveEvent(window());
|
||||
+ }
|
||||
+
|
||||
+ free(enter);
|
||||
+}
|
||||
+
|
||||
void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y,
|
||||
Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp)
|
||||
{
|
||||
@@ -2191,12 +2263,10 @@ static inline int fixed1616ToInt(FP1616 val)
|
||||
{
|
||||
return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF);
|
||||
}
|
||||
-#endif
|
||||
|
||||
// With XI 2.2+ press/release/motion comes here instead of the above handlers.
|
||||
void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event)
|
||||
{
|
||||
-#ifdef XCB_USE_XINPUT22
|
||||
QXcbConnection *conn = connection();
|
||||
xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event);
|
||||
const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods);
|
||||
@@ -2234,12 +2304,41 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event)
|
||||
qWarning() << "Unrecognized XI2 mouse event" << ev->evtype;
|
||||
break;
|
||||
}
|
||||
-#else
|
||||
- Q_UNUSED(event);
|
||||
- Q_ASSERT(false); // this can't be
|
||||
-#endif
|
||||
}
|
||||
|
||||
+// With XI 2.2+ enter/leave comes here and are blocked in plain xcb events
|
||||
+void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event)
|
||||
+{
|
||||
+ xXIEnterEvent *ev = reinterpret_cast<xXIEnterEvent *>(event);
|
||||
+
|
||||
+ // Compare the window with current mouse grabber to prevent deliver events to any other windows.
|
||||
+ // If leave event occurs and the window is under mouse - allow to deliver the leave event.
|
||||
+ QXcbWindow *mouseGrabber = connection()->mouseGrabber();
|
||||
+ if (mouseGrabber && mouseGrabber != this
|
||||
+ && (ev->evtype != XI_Leave || QGuiApplicationPrivate::currentMouseWindow != window())) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ const int root_x = fixed1616ToInt(ev->root_x);
|
||||
+ const int root_y = fixed1616ToInt(ev->root_y);
|
||||
+
|
||||
+ switch (ev->evtype) {
|
||||
+ case XI_Enter: {
|
||||
+ const int event_x = fixed1616ToInt(ev->event_x);
|
||||
+ const int event_y = fixed1616ToInt(ev->event_y);
|
||||
+ qCDebug(lcQpaXInput, "XI2 mouse enter %d,%d, mode %d, detail %d, time %d", event_x, event_y, ev->mode, ev->detail, ev->time);
|
||||
+ handleEnterNotifyEvent(event_x, event_y, root_x, root_y, ev->mode, ev->detail, ev->time);
|
||||
+ break;
|
||||
+ }
|
||||
+ case XI_Leave:
|
||||
+ qCDebug(lcQpaXInput, "XI2 mouse leave, mode %d, detail %d, time %d", ev->mode, ev->detail, ev->time);
|
||||
+ connection()->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group);
|
||||
+ handleLeaveNotifyEvent(root_x, root_y, ev->mode, ev->detail, ev->time);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
QXcbWindow *QXcbWindow::toWindow() { return this; }
|
||||
|
||||
void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers)
|
||||
@@ -2248,74 +2347,14 @@ void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, con
|
||||
QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers);
|
||||
}
|
||||
|
||||
-static bool ignoreLeaveEvent(const xcb_leave_notify_event_t *event)
|
||||
-{
|
||||
- return event->detail == XCB_NOTIFY_DETAIL_VIRTUAL
|
||||
- || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL
|
||||
- || event->mode == XCB_NOTIFY_MODE_GRAB;
|
||||
-}
|
||||
-
|
||||
-static bool ignoreEnterEvent(const xcb_enter_notify_event_t *event)
|
||||
-{
|
||||
- return (event->mode != XCB_NOTIFY_MODE_NORMAL
|
||||
- || event->detail == XCB_NOTIFY_DETAIL_VIRTUAL
|
||||
- || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL);
|
||||
-}
|
||||
-
|
||||
-class EnterEventChecker
|
||||
-{
|
||||
-public:
|
||||
- bool checkEvent(xcb_generic_event_t *event)
|
||||
- {
|
||||
- if (!event)
|
||||
- return false;
|
||||
- if ((event->response_type & ~0x80) != XCB_ENTER_NOTIFY)
|
||||
- return false;
|
||||
-
|
||||
- xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event;
|
||||
- if (ignoreEnterEvent(enter))
|
||||
- return false;
|
||||
-
|
||||
- return true;
|
||||
- }
|
||||
-};
|
||||
-
|
||||
void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
|
||||
{
|
||||
- connection()->setTime(event->time);
|
||||
-#ifdef XCB_USE_XINPUT2
|
||||
- connection()->handleEnterEvent(event);
|
||||
-#endif
|
||||
-
|
||||
- if (ignoreEnterEvent(event))
|
||||
- return;
|
||||
-
|
||||
- const QPoint local(event->event_x, event->event_y);
|
||||
- QPoint global = QPoint(event->root_x, event->root_y);
|
||||
- QWindowSystemInterface::handleEnterEvent(window(), local, global);
|
||||
+ handleEnterNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->mode, event->detail, event->time);
|
||||
}
|
||||
|
||||
void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
|
||||
{
|
||||
- connection()->setTime(event->time);
|
||||
-
|
||||
- if (ignoreLeaveEvent(event))
|
||||
- return;
|
||||
-
|
||||
- EnterEventChecker checker;
|
||||
- xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker);
|
||||
- QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0;
|
||||
-
|
||||
- if (enterWindow) {
|
||||
- QPoint local(enter->event_x, enter->event_y);
|
||||
- QPoint global = QPoint(event->root_x, event->root_y);
|
||||
-
|
||||
- QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global);
|
||||
- } else {
|
||||
- QWindowSystemInterface::handleLeaveEvent(window());
|
||||
- }
|
||||
-
|
||||
- free(enter);
|
||||
+ handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time);
|
||||
}
|
||||
|
||||
void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
|
||||
@@ -2419,7 +2458,7 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab)
|
||||
if (!grab && connection()->mouseGrabber() == this)
|
||||
connection()->setMouseGrabber(Q_NULLPTR);
|
||||
#ifdef XCB_USE_XINPUT22
|
||||
- if (connection()->xi2MouseEvents()) {
|
||||
+ if (connection()->isAtLeastXI22() && connection()->xi2MouseEvents()) {
|
||||
bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab);
|
||||
if (grab && result)
|
||||
connection()->setMouseGrabber(this);
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
|
||||
index d2c02fe3df4e0d0667711dfa9bfc10fed30d9554..69790f29ae098bbfcc5aa6edec75e3d0fea8ea75 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbwindow.h
|
||||
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
|
||||
@@ -132,7 +132,10 @@ public:
|
||||
void handleFocusInEvent(const xcb_focus_in_event_t *event) Q_DECL_OVERRIDE;
|
||||
void handleFocusOutEvent(const xcb_focus_out_event_t *event) Q_DECL_OVERRIDE;
|
||||
void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) Q_DECL_OVERRIDE;
|
||||
+#ifdef XCB_USE_XINPUT22
|
||||
void handleXIMouseEvent(xcb_ge_event_t *) Q_DECL_OVERRIDE;
|
||||
+ void handleXIEnterLeave(xcb_ge_event_t *) Q_DECL_OVERRIDE;
|
||||
+#endif
|
||||
|
||||
QXcbWindow *toWindow() Q_DECL_OVERRIDE;
|
||||
|
||||
@@ -212,6 +215,12 @@ protected:
|
||||
void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y,
|
||||
Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp);
|
||||
|
||||
+ void handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y,
|
||||
+ quint8 mode, quint8 detail, xcb_timestamp_t timestamp);
|
||||
+
|
||||
+ void handleLeaveNotifyEvent(int root_x, int root_y,
|
||||
+ quint8 mode, quint8 detail, xcb_timestamp_t timestamp);
|
||||
+
|
||||
xcb_window_t m_window;
|
||||
|
||||
uint m_depth;
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,55 +0,0 @@
|
||||
From 592f96911bf453dcdc6ae14814927303db544ac8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= <spaz16@wp.pl>
|
||||
Date: Sat, 17 Oct 2015 17:22:16 +0200
|
||||
Subject: [PATCH 02/16] xcb: Correct enter/leave event handling when mouse
|
||||
button is pressed
|
||||
|
||||
This patch fixes cursor shape when mouse leaves the window and enters
|
||||
the window again with pressed mouse button - ignore the mouse enter
|
||||
and leave event when any of mouse buttons is pressed.
|
||||
|
||||
Task-number: QTBUG-46576
|
||||
Change-Id: Id6ce50cd0d66da51a251d4811bc42cd31606de29
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
(cherry picked from commit b9f76db30d261421e4da58f29053181af04ceb4d)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbwindow.cpp | 13 ++++++++++---
|
||||
1 file changed, 10 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
index 91c5eadf3456e15467ba94dd72a886a365aa6a7d..354c29152fadd9200e8d10bc245aed89526a5f6e 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
@@ -2198,11 +2198,14 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in
|
||||
connection()->handleEnterEvent();
|
||||
#endif
|
||||
|
||||
- if (ignoreEnterEvent(mode, detail))
|
||||
+ const QPoint global = QPoint(root_x, root_y);
|
||||
+
|
||||
+ if (ignoreEnterEvent(mode, detail)
|
||||
+ || (connection()->buttons() != Qt::NoButton
|
||||
+ && QGuiApplicationPrivate::lastCursorPosition != global))
|
||||
return;
|
||||
|
||||
const QPoint local(event_x, event_y);
|
||||
- QPoint global = QPoint(root_x, root_y);
|
||||
QWindowSystemInterface::handleEnterEvent(window(), local, global);
|
||||
}
|
||||
|
||||
@@ -2211,7 +2214,11 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y,
|
||||
{
|
||||
connection()->setTime(timestamp);
|
||||
|
||||
- if (ignoreLeaveEvent(mode, detail))
|
||||
+ const QPoint global(root_x, root_y);
|
||||
+
|
||||
+ if (ignoreLeaveEvent(mode, detail)
|
||||
+ || (connection()->buttons() != Qt::NoButton
|
||||
+ && QGuiApplicationPrivate::lastCursorPosition != global))
|
||||
return;
|
||||
|
||||
EnterEventChecker checker;
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,98 +0,0 @@
|
||||
From f371c645e2a06234355693551e16d69961839ac1 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bersenev <bay@hackerdom.ru>
|
||||
Date: Fri, 6 Nov 2015 01:39:27 +0500
|
||||
Subject: [PATCH 03/16] xcb: Fix not delivering focusIn event on hide/show
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Consider a window which was hidden and shown with hide() and show()
|
||||
methods and mouse pointer was in window when hide() was called.
|
||||
|
||||
At first, window got focusOutEvent and then Qt library sends X server
|
||||
a message to unmap the window.
|
||||
|
||||
Then X server will send client two messages:
|
||||
1) FocusOut(10) detail=Nonlinear(0x03)
|
||||
2) FocusIn(9) detail=Pointer(0x05)
|
||||
|
||||
QXcbWindow has a logic for not seting active window to 0 if there is
|
||||
a FocusIn coming (see QXcbWindow::doFocusOut).
|
||||
|
||||
So QGuiApplicationPrivate::focus_window still points to the current
|
||||
window.
|
||||
|
||||
Then when show() is called, qt compares previous focus with new focus
|
||||
and, since they are equal, doesn't do anything. Event focusInEvent
|
||||
isn't delivered to the window.
|
||||
|
||||
Here are two links why X server sends FocusIn just after FocusOut:
|
||||
http://lists.freedesktop.org/archives/xorg/2008-December/041684.html
|
||||
https://tronche.com/gui/x/xlib/events/input-focus/normal-and-grabbed.html
|
||||
|
||||
Proposed fix ignores FocusIn events with detail==Pointer.
|
||||
The text of explaining comment is taken from the Chromium project:
|
||||
https://chromium.googlesource.com/chromium/src/+/master/ui/views/widget/desktop_aura/x11_desktop_handler.cc
|
||||
from X11DesktopHandler::ProcessXEvent function.
|
||||
|
||||
[ChangeLog][module][Linux/XCB] Fix not delivering focusIn event on
|
||||
hide/show with XCB
|
||||
|
||||
Task-number: QTBUG-49071
|
||||
Change-Id: I433c8b638834c25f113cc134ee4185778c44f540
|
||||
Reviewed-by: André Hartmann <aha_1980@gmx.de>
|
||||
Reviewed-by: Lisandro Damián Nicanor Pérez Meyer <perezmeyer@gmail.com>
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
(cherry picked from commit 8eaf3352590690079735eda9fb872ec8c9c58f0a)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbwindow.cpp | 21 +++++++++++++++++----
|
||||
1 file changed, 17 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
index 354c29152fadd9200e8d10bc245aed89526a5f6e..46b7b70f8025a8481ab2db37257a52494a84d234 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
@@ -894,8 +894,13 @@ static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event
|
||||
return true;
|
||||
}
|
||||
uint response_type = event->response_type & ~0x80;
|
||||
- if (response_type == XCB_FOCUS_IN)
|
||||
- return true;
|
||||
+ if (response_type == XCB_FOCUS_IN) {
|
||||
+ // Ignore focus events that are being sent only because the pointer is over
|
||||
+ // our window, even if the input focus is in a different window.
|
||||
+ xcb_focus_in_event_t *e = (xcb_focus_in_event_t *) event;
|
||||
+ if (e->detail != XCB_NOTIFY_DETAIL_POINTER)
|
||||
+ return true;
|
||||
+ }
|
||||
|
||||
/* We are also interested in XEMBED_FOCUS_IN events */
|
||||
if (response_type == XCB_CLIENT_MESSAGE) {
|
||||
@@ -2415,14 +2420,22 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
|
||||
}
|
||||
}
|
||||
|
||||
-void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *)
|
||||
+void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *event)
|
||||
{
|
||||
+ // Ignore focus events that are being sent only because the pointer is over
|
||||
+ // our window, even if the input focus is in a different window.
|
||||
+ if (event->detail == XCB_NOTIFY_DETAIL_POINTER)
|
||||
+ return;
|
||||
doFocusIn();
|
||||
}
|
||||
|
||||
|
||||
-void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
|
||||
+void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *event)
|
||||
{
|
||||
+ // Ignore focus events that are being sent only because the pointer is over
|
||||
+ // our window, even if the input focus is in a different window.
|
||||
+ if (event->detail == XCB_NOTIFY_DETAIL_POINTER)
|
||||
+ return;
|
||||
doFocusOut();
|
||||
}
|
||||
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,89 +0,0 @@
|
||||
From a9b7b17655d7b0826c5adc36f66407283564eb72 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= <spaz16@wp.pl>
|
||||
Date: Mon, 15 Feb 2016 20:50:16 +0100
|
||||
Subject: [PATCH 04/16] xcb: Fix drag and drop between xcb screens
|
||||
|
||||
Set the proper screen before creating a shaped pixmap window in
|
||||
QBasicDrag::startDrag(). Grab mouse again when D&D window is
|
||||
recreated.
|
||||
|
||||
Task-number: QTBUG-51215
|
||||
Change-Id: I5cb47d3b11672b56d17b32072d84a722bdcdcd9a
|
||||
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
(cherry picked from commit 78ad8f208d8dbe3575194bb9b97d4e42efdc32d5)
|
||||
---
|
||||
src/gui/kernel/qsimpledrag.cpp | 5 +++--
|
||||
src/gui/kernel/qsimpledrag_p.h | 3 +++
|
||||
src/plugins/platforms/xcb/qxcbdrag.cpp | 4 ++++
|
||||
3 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
|
||||
index 9f38c9b78ad4f8537e9e4c3a39af9d2c56fb67c7..00589d23039ed4f043d026e89187d645ad2ee214 100644
|
||||
--- a/src/gui/kernel/qsimpledrag.cpp
|
||||
+++ b/src/gui/kernel/qsimpledrag.cpp
|
||||
@@ -88,7 +88,8 @@ static QWindow* topLevelAt(const QPoint &pos)
|
||||
QBasicDrag::QBasicDrag() :
|
||||
m_restoreCursor(false), m_eventLoop(0),
|
||||
m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
|
||||
- m_drag(0), m_drag_icon_window(0), m_useCompositing(true)
|
||||
+ m_drag(0), m_drag_icon_window(0), m_useCompositing(true),
|
||||
+ m_screen(Q_NULLPTR)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -211,7 +212,7 @@ void QBasicDrag::startDrag()
|
||||
pos = QPoint();
|
||||
}
|
||||
#endif
|
||||
- recreateShapedPixmapWindow(Q_NULLPTR, pos);
|
||||
+ recreateShapedPixmapWindow(m_screen, pos);
|
||||
enableEventFilter();
|
||||
}
|
||||
|
||||
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
|
||||
index 055136c436ed3b3504c2ee564e49cee1bd4439d4..b208c8ccc97a668205ef08fdce591e4c0d78c939 100644
|
||||
--- a/src/gui/kernel/qsimpledrag_p.h
|
||||
+++ b/src/gui/kernel/qsimpledrag_p.h
|
||||
@@ -90,6 +90,8 @@ protected:
|
||||
bool useCompositing() const { return m_useCompositing; }
|
||||
void setUseCompositing(bool on) { m_useCompositing = on; }
|
||||
|
||||
+ void setScreen(QScreen *screen) { m_screen = screen; }
|
||||
+
|
||||
Qt::DropAction executedDropAction() const { return m_executed_drop_action; }
|
||||
void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; }
|
||||
|
||||
@@ -108,6 +110,7 @@ private:
|
||||
QDrag *m_drag;
|
||||
QShapedPixmapWindow *m_drag_icon_window;
|
||||
bool m_useCompositing;
|
||||
+ QScreen *m_screen;
|
||||
};
|
||||
|
||||
class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
|
||||
index 9296a6d1410f72d00efcf8c249bdd8a037b8b4be..aa6445d2da56f09696c98cba76baf6c74e44841c 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
|
||||
@@ -193,6 +193,7 @@ void QXcbDrag::startDrag()
|
||||
XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData());
|
||||
|
||||
setUseCompositing(current_virtual_desktop->compositingActive());
|
||||
+ setScreen(current_virtual_desktop->screens().constFirst()->screen());
|
||||
QBasicDrag::startDrag();
|
||||
if (connection()->mouseGrabber() == Q_NULLPTR)
|
||||
shapedPixmapWindow()->setMouseGrabEnabled(true);
|
||||
@@ -322,6 +323,9 @@ void QXcbDrag::move(const QPoint &globalPos)
|
||||
if (virtualDesktop != current_virtual_desktop) {
|
||||
setUseCompositing(virtualDesktop->compositingActive());
|
||||
recreateShapedPixmapWindow(static_cast<QPlatformScreen*>(screen)->screen(), deviceIndependentPos);
|
||||
+ if (connection()->mouseGrabber() == Q_NULLPTR)
|
||||
+ shapedPixmapWindow()->setMouseGrabEnabled(true);
|
||||
+
|
||||
current_virtual_desktop = virtualDesktop;
|
||||
} else {
|
||||
QBasicDrag::moveShapedPixmapWindow(deviceIndependentPos);
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,35 +0,0 @@
|
||||
From bbfc5818bb9f8d87d64f6b6f94bbfe1cea199ec9 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Volkov <a.volkov@rusbitech.ru>
|
||||
Date: Thu, 18 Feb 2016 18:12:57 +0300
|
||||
Subject: [PATCH 05/16] xcb: Properly initialize available geometry when XRandR
|
||||
is missing
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Take an intersection of the screen geometry and the work area.
|
||||
|
||||
Change-Id: Ia61d090ac103cb4d13d656ec09037f642b255a79
|
||||
Reviewed-by: Błażej Szczygieł <spaz16@wp.pl>
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
(cherry picked from commit 7cd23a7d5f5b7b10c0e317afcf8bc49020a42e53)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbscreen.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
index f3d381b99e014116317286b791a0876ad6d8ca6d..0ef7166b9076e47fc71d4b2106cbfdc6420166d3 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
@@ -208,7 +208,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
|
||||
m_geometry = QRect(QPoint(), m_virtualSize);
|
||||
|
||||
if (m_availableGeometry.isEmpty())
|
||||
- m_availableGeometry = m_geometry;
|
||||
+ m_availableGeometry = m_geometry & m_virtualDesktop->workArea();
|
||||
|
||||
readXResources();
|
||||
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,42 +0,0 @@
|
||||
From 412a0b8502614ff6fac6b6b45c48091a19d67014 Mon Sep 17 00:00:00 2001
|
||||
From: Shawn Rutledge <shawn.rutledge@digia.com>
|
||||
Date: Thu, 18 Feb 2016 14:05:39 +0100
|
||||
Subject: [PATCH 06/16] xcb: properly initialize size in millimeters if XRandR
|
||||
is not supported
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
QXcbScreen did not set the m_sizeMillimeters if the xcb connection does
|
||||
not support XRandR. This caused physicalSize() to return an invalid QSize.
|
||||
|
||||
This change fixes a regression compared to Qt 5.4 discovered by a
|
||||
broken unit test for KWin on KDE's CI system, which uses Xvfb and by
|
||||
that no XRandR support.
|
||||
|
||||
Task-number: QTBUG-49885
|
||||
Change-Id: Ie472a194ba410f0748ccfda8aa467727fafa10a3
|
||||
Reviewed-by: Błażej Szczygieł <spaz16@wp.pl>
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
(cherry picked from commit 3f4eba746d23550be19dc4edafe193fa5ce0d3d4)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbscreen.cpp | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
index 0ef7166b9076e47fc71d4b2106cbfdc6420166d3..28b175371264cd445c1bd67a8d33f6de5a8fa219 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
@@ -210,6 +210,9 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
|
||||
if (m_availableGeometry.isEmpty())
|
||||
m_availableGeometry = m_geometry & m_virtualDesktop->workArea();
|
||||
|
||||
+ if (m_sizeMillimeters.isEmpty())
|
||||
+ m_sizeMillimeters = m_virtualSizeMillimeters;
|
||||
+
|
||||
readXResources();
|
||||
|
||||
QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> rootAttribs(
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,337 +0,0 @@
|
||||
From 3ecd1178940a6fd9f486f62f711df4dc75197390 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= <spaz16@wp.pl>
|
||||
Date: Tue, 19 Jan 2016 22:32:52 +0100
|
||||
Subject: [PATCH 07/16] xcb: Deliver mouse enter event to window when closing
|
||||
modal window
|
||||
|
||||
When a modal window is closed and the mouse is not under the modal
|
||||
window - find a proper window and send a fake enter event.
|
||||
|
||||
Added auto test for checking enter event on window when modal window
|
||||
is closed.
|
||||
|
||||
Task-number: QTBUG-35109
|
||||
Change-Id: I370b52d386503820ac9de21e6d05fd019ca456ec
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
(cherry picked from commit 7091be1b7999d93fe2126042161dcd1d8fd20026)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbwindow.cpp | 48 +++++++
|
||||
tests/auto/gui/kernel/qwindow/BLACKLIST | 2 +
|
||||
tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 193 ++++++++++++++++++++++++++
|
||||
3 files changed, 243 insertions(+)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
index 46b7b70f8025a8481ab2db37257a52494a84d234..7eae2d92ab39843d09cb6294f9afd7fc51260ecb 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "qxcbsystemtraytracker.h"
|
||||
|
||||
#include <qpa/qplatformintegration.h>
|
||||
+#include <qpa/qplatformcursor.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -261,6 +262,26 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s)
|
||||
}
|
||||
#endif // XCB_USE_XLIB
|
||||
|
||||
+// TODO move this into a utility function in QWindow or QGuiApplication
|
||||
+static QWindow *childWindowAt(QWindow *win, const QPoint &p)
|
||||
+{
|
||||
+ foreach (QObject *obj, win->children()) {
|
||||
+ if (obj->isWindowType()) {
|
||||
+ QWindow *childWin = static_cast<QWindow *>(obj);
|
||||
+ if (childWin->isVisible()) {
|
||||
+ if (QWindow *recurse = childWindowAt(childWin, p))
|
||||
+ return recurse;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (!win->isTopLevel()
|
||||
+ && !(win->flags() & Qt::WindowTransparentForInput)
|
||||
+ && win->geometry().contains(win->parent()->mapFromGlobal(p))) {
|
||||
+ return win;
|
||||
+ }
|
||||
+ return Q_NULLPTR;
|
||||
+}
|
||||
+
|
||||
static const char *wm_window_type_property_id = "_q_xcb_wm_window_type";
|
||||
|
||||
QXcbWindow::QXcbWindow(QWindow *window)
|
||||
@@ -855,6 +876,33 @@ void QXcbWindow::hide()
|
||||
connection()->setMouseGrabber(Q_NULLPTR);
|
||||
|
||||
m_mapped = false;
|
||||
+
|
||||
+ // Hiding a modal window doesn't send an enter event to its transient parent when the
|
||||
+ // mouse is already over the parent window, so the enter event must be emulated.
|
||||
+ if (window()->isModal()) {
|
||||
+ // Get the cursor position at modal window screen
|
||||
+ const QPoint nativePos = xcbScreen()->cursor()->pos();
|
||||
+ const QPoint cursorPos = QHighDpi::fromNativePixels(nativePos, xcbScreen()->screenForPosition(nativePos)->screen());
|
||||
+
|
||||
+ // Find the top level window at cursor position.
|
||||
+ // Don't use QGuiApplication::topLevelAt(): search only the virtual siblings of this window's screen
|
||||
+ QWindow *enterWindow = Q_NULLPTR;
|
||||
+ foreach (QPlatformScreen *screen, xcbScreen()->virtualSiblings()) {
|
||||
+ if (screen->geometry().contains(cursorPos)) {
|
||||
+ const QPoint devicePosition = QHighDpi::toNativePixels(cursorPos, screen->screen());
|
||||
+ enterWindow = screen->topLevelAt(devicePosition);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (enterWindow && enterWindow != window()) {
|
||||
+ // Find the child window at cursor position, otherwise use the top level window
|
||||
+ if (QWindow *childWindow = childWindowAt(enterWindow, cursorPos))
|
||||
+ enterWindow = childWindow;
|
||||
+ const QPoint localPos = enterWindow->mapFromGlobal(cursorPos);
|
||||
+ QWindowSystemInterface::handleEnterEvent(enterWindow, localPos, cursorPos);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
static QWindow *tlWindow(QWindow *window)
|
||||
diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST
|
||||
index ee9709e68ba75bfc29903111087abe31040a059d..a34066dd7cec05f2e089582c87791e81d388a482 100644
|
||||
--- a/tests/auto/gui/kernel/qwindow/BLACKLIST
|
||||
+++ b/tests/auto/gui/kernel/qwindow/BLACKLIST
|
||||
@@ -4,3 +4,5 @@ ubuntu-14.04
|
||||
ubuntu-14.04
|
||||
[modalWithChildWindow]
|
||||
ubuntu-14.04
|
||||
+[modalWindowEnterEventOnHide_QTBUG35109]
|
||||
+ubuntu-14.04
|
||||
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
|
||||
index a89f0da4d27c01a345a475ebf7fcaffb83d797c3..0cce5a072caf6a9ed63bab8c9318edbc8453e717 100644
|
||||
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
|
||||
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
|
||||
@@ -92,6 +92,9 @@ private slots:
|
||||
void modalWithChildWindow();
|
||||
void modalWindowModallity();
|
||||
void modalWindowPosition();
|
||||
+#ifndef QT_NO_CURSOR
|
||||
+ void modalWindowEnterEventOnHide_QTBUG35109();
|
||||
+#endif
|
||||
void windowsTransientChildren();
|
||||
void requestUpdate();
|
||||
void initTestCase();
|
||||
@@ -706,10 +709,24 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
+ bool event(QEvent *e) {
|
||||
+ switch (e->type()) {
|
||||
+ case QEvent::Enter:
|
||||
+ ++enterEventCount;
|
||||
+ break;
|
||||
+ case QEvent::Leave:
|
||||
+ ++leaveEventCount;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return QWindow::event(e);
|
||||
+ }
|
||||
void resetCounters() {
|
||||
mousePressedCount = mouseReleasedCount = mouseMovedCount = mouseDoubleClickedCount = 0;
|
||||
mouseSequenceSignature = QString();
|
||||
touchPressedCount = touchReleasedCount = touchMovedCount = 0;
|
||||
+ enterEventCount = leaveEventCount = 0;
|
||||
}
|
||||
|
||||
InputTestWindow() {
|
||||
@@ -727,6 +744,7 @@ public:
|
||||
QPointF mousePressScreenPos, mouseMoveScreenPos, mousePressLocalPos;
|
||||
int touchPressedCount, touchReleasedCount, touchMovedCount;
|
||||
QEvent::Type touchEventType;
|
||||
+ int enterEventCount, leaveEventCount;
|
||||
|
||||
bool ignoreMouse, ignoreTouch;
|
||||
|
||||
@@ -1732,6 +1750,181 @@ void tst_QWindow::modalWindowPosition()
|
||||
QCOMPARE(window.geometry(), origGeo);
|
||||
}
|
||||
|
||||
+#ifndef QT_NO_CURSOR
|
||||
+void tst_QWindow::modalWindowEnterEventOnHide_QTBUG35109()
|
||||
+{
|
||||
+ if (QGuiApplication::platformName() == QLatin1String("cocoa"))
|
||||
+ QSKIP("This test fails on OS X on CI");
|
||||
+
|
||||
+ const QPoint center = QGuiApplication::primaryScreen()->availableGeometry().center();
|
||||
+
|
||||
+ const int childOffset = 16;
|
||||
+ const QPoint rootPos = center - QPoint(m_testWindowSize.width(),
|
||||
+ m_testWindowSize.height())/2;
|
||||
+ const QPoint modalPos = rootPos + QPoint(childOffset * 5,
|
||||
+ childOffset * 5);
|
||||
+ const QPoint cursorPos = rootPos - QPoint(80, 80);
|
||||
+
|
||||
+ // Test whether tlw can receive the enter event
|
||||
+ {
|
||||
+ QCursor::setPos(cursorPos);
|
||||
+ QCoreApplication::processEvents();
|
||||
+
|
||||
+ InputTestWindow root;
|
||||
+ root.setTitle(__FUNCTION__);
|
||||
+ root.setGeometry(QRect(rootPos, m_testWindowSize));
|
||||
+ root.show();
|
||||
+ QVERIFY(QTest::qWaitForWindowExposed(&root));
|
||||
+ root.requestActivate();
|
||||
+ QVERIFY(QTest::qWaitForWindowActive(&root));
|
||||
+
|
||||
+ // Move the mouse over the root window, but not over the modal window.
|
||||
+ QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2,
|
||||
+ childOffset * 5 / 2));
|
||||
+
|
||||
+ // Wait for the enter event. It must be delivered here, otherwise second
|
||||
+ // compare can PASS because of this event even after "resetCounters()".
|
||||
+ QTRY_COMPARE(root.enterEventCount, 1);
|
||||
+ QTRY_COMPARE(root.leaveEventCount, 0);
|
||||
+
|
||||
+ QWindow modal;
|
||||
+ modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__);
|
||||
+ modal.setTransientParent(&root);
|
||||
+ modal.resize(m_testWindowSize/2);
|
||||
+ modal.setFramePosition(modalPos);
|
||||
+ modal.setModality(Qt::ApplicationModal);
|
||||
+ modal.show();
|
||||
+ QVERIFY(QTest::qWaitForWindowExposed(&modal));
|
||||
+ modal.requestActivate();
|
||||
+ QVERIFY(QTest::qWaitForWindowActive(&modal));
|
||||
+
|
||||
+ QCoreApplication::processEvents();
|
||||
+ QTRY_COMPARE(root.leaveEventCount, 1);
|
||||
+
|
||||
+ root.resetCounters();
|
||||
+ modal.close();
|
||||
+
|
||||
+ // Check for the enter event
|
||||
+ QTRY_COMPARE(root.enterEventCount, 1);
|
||||
+ }
|
||||
+
|
||||
+ // Test whether child window can receive the enter event
|
||||
+ {
|
||||
+ QCursor::setPos(cursorPos);
|
||||
+ QCoreApplication::processEvents();
|
||||
+
|
||||
+ QWindow root;
|
||||
+ root.setTitle(__FUNCTION__);
|
||||
+ root.setGeometry(QRect(rootPos, m_testWindowSize));
|
||||
+
|
||||
+ QWindow childLvl1;
|
||||
+ childLvl1.setParent(&root);
|
||||
+ childLvl1.setGeometry(childOffset,
|
||||
+ childOffset,
|
||||
+ m_testWindowSize.width() - childOffset,
|
||||
+ m_testWindowSize.height() - childOffset);
|
||||
+
|
||||
+ InputTestWindow childLvl2;
|
||||
+ childLvl2.setParent(&childLvl1);
|
||||
+ childLvl2.setGeometry(childOffset,
|
||||
+ childOffset,
|
||||
+ childLvl1.width() - childOffset,
|
||||
+ childLvl1.height() - childOffset);
|
||||
+
|
||||
+ root.show();
|
||||
+ childLvl1.show();
|
||||
+ childLvl2.show();
|
||||
+
|
||||
+ QVERIFY(QTest::qWaitForWindowExposed(&root));
|
||||
+ root.requestActivate();
|
||||
+ QVERIFY(QTest::qWaitForWindowActive(&root));
|
||||
+ QVERIFY(childLvl1.isVisible());
|
||||
+ QVERIFY(childLvl2.isVisible());
|
||||
+
|
||||
+ // Move the mouse over the child window, but not over the modal window.
|
||||
+ // Be sure that the value is almost left-top of second child window for
|
||||
+ // checking proper position mapping.
|
||||
+ QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2,
|
||||
+ childOffset * 5 / 2));
|
||||
+
|
||||
+ // Wait for the enter event. It must be delivered here, otherwise second
|
||||
+ // compare can PASS because of this event even after "resetCounters()".
|
||||
+ QTRY_COMPARE(childLvl2.enterEventCount, 1);
|
||||
+ QTRY_COMPARE(childLvl2.leaveEventCount, 0);
|
||||
+
|
||||
+ QWindow modal;
|
||||
+ modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__);
|
||||
+ modal.setTransientParent(&root);
|
||||
+ modal.resize(m_testWindowSize/2);
|
||||
+ modal.setFramePosition(modalPos);
|
||||
+ modal.setModality(Qt::ApplicationModal);
|
||||
+ modal.show();
|
||||
+ QVERIFY(QTest::qWaitForWindowExposed(&modal));
|
||||
+ modal.requestActivate();
|
||||
+ QVERIFY(QTest::qWaitForWindowActive(&modal));
|
||||
+
|
||||
+ QCoreApplication::processEvents();
|
||||
+ QTRY_COMPARE(childLvl2.leaveEventCount, 1);
|
||||
+
|
||||
+ childLvl2.resetCounters();
|
||||
+ modal.close();
|
||||
+
|
||||
+ // Check for the enter event
|
||||
+ QTRY_COMPARE(childLvl2.enterEventCount, 1);
|
||||
+ }
|
||||
+
|
||||
+ // Test whether tlw can receive the enter event if mouse is over the invisible child windnow
|
||||
+ {
|
||||
+ QCursor::setPos(cursorPos);
|
||||
+ QCoreApplication::processEvents();
|
||||
+
|
||||
+ InputTestWindow root;
|
||||
+ root.setTitle(__FUNCTION__);
|
||||
+ root.setGeometry(QRect(rootPos, m_testWindowSize));
|
||||
+
|
||||
+ QWindow child;
|
||||
+ child.setParent(&root);
|
||||
+ child.setGeometry(QRect(QPoint(), m_testWindowSize));
|
||||
+
|
||||
+ root.show();
|
||||
+
|
||||
+ QVERIFY(QTest::qWaitForWindowExposed(&root));
|
||||
+ root.requestActivate();
|
||||
+ QVERIFY(QTest::qWaitForWindowActive(&root));
|
||||
+ QVERIFY(!child.isVisible());
|
||||
+
|
||||
+ // Move the mouse over the child window, but not over the modal window.
|
||||
+ QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2,
|
||||
+ childOffset * 5 / 2));
|
||||
+
|
||||
+ // Wait for the enter event. It must be delivered here, otherwise second
|
||||
+ // compare can PASS because of this event even after "resetCounters()".
|
||||
+ QTRY_COMPARE(root.enterEventCount, 1);
|
||||
+ QTRY_COMPARE(root.leaveEventCount, 0);
|
||||
+
|
||||
+ QWindow modal;
|
||||
+ modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__);
|
||||
+ modal.setTransientParent(&root);
|
||||
+ modal.resize(m_testWindowSize/2);
|
||||
+ modal.setFramePosition(modalPos);
|
||||
+ modal.setModality(Qt::ApplicationModal);
|
||||
+ modal.show();
|
||||
+ QVERIFY(QTest::qWaitForWindowExposed(&modal));
|
||||
+ modal.requestActivate();
|
||||
+ QVERIFY(QTest::qWaitForWindowActive(&modal));
|
||||
+
|
||||
+ QCoreApplication::processEvents();
|
||||
+ QTRY_COMPARE(root.leaveEventCount, 1);
|
||||
+
|
||||
+ root.resetCounters();
|
||||
+ modal.close();
|
||||
+
|
||||
+ // Check for the enter event
|
||||
+ QTRY_COMPARE(root.enterEventCount, 1);
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
class ColoredWindow : public QRasterWindow {
|
||||
public:
|
||||
explicit ColoredWindow(const QColor &color, QWindow *parent = 0) : QRasterWindow(parent), m_color(color) {}
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,28 +0,0 @@
|
||||
From e467aba779546f73f8308838071fe7da00d2ec7e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= <spaz16@wp.pl>
|
||||
Date: Thu, 3 Mar 2016 01:43:41 +0100
|
||||
Subject: [PATCH 08/16] xcb: resourceType names must have only small letters
|
||||
|
||||
Change-Id: I563ae26c9e7e6111399fd0b9af7bfb3ff750b34a
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
(cherry picked from commit caa82c3518b4a5c09b1de990874190d5d765656f)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
|
||||
index dfb0a125e25ea72c6a9f5aaf3e3145a2eb3efbeb..f6bd878bde4ef1b659fc22d357a691e5ae6bfc71 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
|
||||
@@ -76,7 +76,7 @@ static int resourceType(const QByteArray &key)
|
||||
QByteArrayLiteral("startupid"), QByteArrayLiteral("traywindow"),
|
||||
QByteArrayLiteral("gettimestamp"), QByteArrayLiteral("x11screen"),
|
||||
QByteArrayLiteral("rootwindow"),
|
||||
- QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingEnabled"),
|
||||
+ QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingenabled"),
|
||||
QByteArrayLiteral("nofonthinting"),
|
||||
QByteArrayLiteral("atspibus")
|
||||
};
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,153 +0,0 @@
|
||||
From fd6049144e0ba5b4696798eadd84da021438d050 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Volkov <a.volkov@rusbitech.ru>
|
||||
Date: Thu, 10 Sep 2015 14:44:52 +0300
|
||||
Subject: [PATCH 09/16] Expose the number of X screen through the
|
||||
QXcbScreenFunctions
|
||||
|
||||
X screen corresponds to Qt virtual desktop, and RandR output
|
||||
corresponds to QScreen. There can be more than one X screen,
|
||||
so we need a way to get the number of X screen for QScreen,
|
||||
in particular for the right implementation of some methods
|
||||
in QX11Info.
|
||||
|
||||
Change-Id: Ib5e38703bf11ae08bb283f26a7b7b15f1a5e8671
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
(cherry picked from commit 362b977e7c99d47c9c598cef946273089881fd81)
|
||||
---
|
||||
.../xcbfunctions/qxcbscreenfunctions.h | 56 ++++++++++++++++++++++
|
||||
src/platformheaders/xcbfunctions/xcbfunctions.pri | 3 +-
|
||||
src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 5 ++
|
||||
src/plugins/platforms/xcb/qxcbscreen.cpp | 8 ++++
|
||||
src/plugins/platforms/xcb/qxcbscreen.h | 1 +
|
||||
5 files changed, 72 insertions(+), 1 deletion(-)
|
||||
create mode 100644 src/platformheaders/xcbfunctions/qxcbscreenfunctions.h
|
||||
|
||||
diff --git a/src/platformheaders/xcbfunctions/qxcbscreenfunctions.h b/src/platformheaders/xcbfunctions/qxcbscreenfunctions.h
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7773c275b9d6d6bacbf776d13cbb5a5ccbcf2bbf
|
||||
--- /dev/null
|
||||
+++ b/src/platformheaders/xcbfunctions/qxcbscreenfunctions.h
|
||||
@@ -0,0 +1,56 @@
|
||||
+/****************************************************************************
|
||||
+**
|
||||
+** Copyright (C) 2016 The Qt Company Ltd.
|
||||
+** Contact: http://www.qt.io/licensing/
|
||||
+**
|
||||
+** This file is part of the plugins of the Qt Toolkit.
|
||||
+**
|
||||
+** $QT_BEGIN_LICENSE:LGPL21$
|
||||
+** Commercial License Usage
|
||||
+** Licensees holding valid commercial Qt licenses may use this file in
|
||||
+** accordance with the commercial license agreement provided with the
|
||||
+** Software or, alternatively, in accordance with the terms contained in
|
||||
+** a written agreement between you and The Qt Company. For licensing terms
|
||||
+** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
+** information use the contact form at http://www.qt.io/contact-us.
|
||||
+**
|
||||
+** GNU Lesser General Public License Usage
|
||||
+** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
+** General Public License version 2.1 or version 3 as published by the Free
|
||||
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
+** following information to ensure the GNU Lesser General Public License
|
||||
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
+**
|
||||
+** As a special exception, The Qt Company gives you certain additional
|
||||
+** rights. These rights are described in The Qt Company LGPL Exception
|
||||
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
+**
|
||||
+** $QT_END_LICENSE$
|
||||
+**
|
||||
+****************************************************************************/
|
||||
+
|
||||
+#ifndef QXCBSCREENFUNCTIONS_H
|
||||
+#define QXCBSCREENFUNCTIONS_H
|
||||
+
|
||||
+#include <QtPlatformHeaders/QPlatformHeaderHelper>
|
||||
+
|
||||
+QT_BEGIN_NAMESPACE
|
||||
+
|
||||
+class QScreen;
|
||||
+
|
||||
+class QXcbScreenFunctions
|
||||
+{
|
||||
+public:
|
||||
+ typedef bool (*VirtualDesktopNumber)(const QScreen *screen);
|
||||
+ static const QByteArray virtualDesktopNumberIdentifier() { return QByteArrayLiteral("XcbVirtualDesktopNumber"); }
|
||||
+ static int virtualDesktopNumber(const QScreen *screen)
|
||||
+ {
|
||||
+ return QPlatformHeaderHelper::callPlatformFunction<int, VirtualDesktopNumber, const QScreen *>(virtualDesktopNumberIdentifier(), screen);
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+QT_END_NAMESPACE
|
||||
+
|
||||
+#endif /*QXCBSCREENFUNCTIONS_H*/
|
||||
diff --git a/src/platformheaders/xcbfunctions/xcbfunctions.pri b/src/platformheaders/xcbfunctions/xcbfunctions.pri
|
||||
index 7f611d80bd5518b1e018a4738c0da79d814d2f47..3f2bcb2b34cb23e55ad57898b44ff442d66980e3 100644
|
||||
--- a/src/platformheaders/xcbfunctions/xcbfunctions.pri
|
||||
+++ b/src/platformheaders/xcbfunctions/xcbfunctions.pri
|
||||
@@ -1,3 +1,4 @@
|
||||
HEADERS += \
|
||||
$$PWD/qxcbwindowfunctions.h \
|
||||
- $$PWD/qxcbintegrationfunctions.h
|
||||
+ $$PWD/qxcbintegrationfunctions.h \
|
||||
+ $$PWD/qxcbscreenfunctions.h
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
|
||||
index f6bd878bde4ef1b659fc22d357a691e5ae6bfc71..96239a0f2041d901500fd645d6c699a93ceda5c9 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
|
||||
@@ -48,6 +48,7 @@
|
||||
|
||||
#include <QtPlatformHeaders/qxcbwindowfunctions.h>
|
||||
#include <QtPlatformHeaders/qxcbintegrationfunctions.h>
|
||||
+#include <QtPlatformHeaders/qxcbscreenfunctions.h>
|
||||
|
||||
#ifndef QT_NO_DBUS
|
||||
#include "QtPlatformSupport/private/qdbusmenuconnection_p.h"
|
||||
@@ -367,6 +368,10 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio
|
||||
if (function == QXcbWindowFunctions::visualIdIdentifier()) {
|
||||
return QFunctionPointer(QXcbWindowFunctions::VisualId(QXcbWindow::visualIdStatic));
|
||||
}
|
||||
+
|
||||
+ if (function == QXcbScreenFunctions::virtualDesktopNumberIdentifier())
|
||||
+ return QFunctionPointer(QXcbScreenFunctions::VirtualDesktopNumber(QXcbScreen::virtualDesktopNumberStatic));
|
||||
+
|
||||
return Q_NULLPTR;
|
||||
}
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
index 28b175371264cd445c1bd67a8d33f6de5a8fa219..1a90f824fc454c69f73ac195b1241bc6371d7aed 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
@@ -438,6 +438,14 @@ void QXcbScreen::setOutput(xcb_randr_output_t outputId,
|
||||
// TODO: Send an event to the QScreen instance that the screen changed its name
|
||||
}
|
||||
|
||||
+int QXcbScreen::virtualDesktopNumberStatic(const QScreen *screen)
|
||||
+{
|
||||
+ if (screen && screen->handle())
|
||||
+ return static_cast<const QXcbScreen *>(screen->handle())->screenNumber();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*!
|
||||
\brief handle the XCB screen change event and update properties
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
|
||||
index f4de2b9dfd5e3042f4192b85c8e7b9b79aa04e74..7376ddf35c3b34ef7f5310299039431a9a97d45b 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbscreen.h
|
||||
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
|
||||
@@ -133,6 +133,7 @@ public:
|
||||
bool isPrimary() const { return m_primary; }
|
||||
|
||||
int screenNumber() const { return m_virtualDesktop->number(); }
|
||||
+ static int virtualDesktopNumberStatic(const QScreen *screen);
|
||||
|
||||
xcb_screen_t *screen() const { return m_virtualDesktop->screen(); }
|
||||
xcb_window_t root() const { return screen()->root; }
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,199 +0,0 @@
|
||||
From c44d853fd7e71eff0e1a1d4512c2215a1e701008 Mon Sep 17 00:00:00 2001
|
||||
From: Shawn Rutledge <shawn.rutledge@digia.com>
|
||||
Date: Tue, 8 Mar 2016 15:50:20 +0100
|
||||
Subject: [PATCH 10/16] xcb: mark mouse events from tablet devices as
|
||||
synthesized
|
||||
|
||||
Task-number: QTBUG-51617
|
||||
Change-Id: Ic1d258c56165947ff821b1bf4d044bcf29b41a3b
|
||||
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
|
||||
(cherry picked from commit d7db6c6c1944894737babf3958d0cff1e6222a22)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbconnection.h | 2 +-
|
||||
src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 2 +-
|
||||
src/plugins/platforms/xcb/qxcbwindow.cpp | 39 +++++++++++++++---------
|
||||
src/plugins/platforms/xcb/qxcbwindow.h | 11 ++++---
|
||||
4 files changed, 32 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
|
||||
index 6c2b8583af24e9abd7a087144fb33504ec36fbf8..4d318457e3b05de8c343580aad217cc1bad9072c 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbconnection.h
|
||||
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
|
||||
@@ -348,7 +348,7 @@ public:
|
||||
virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {}
|
||||
virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {}
|
||||
#ifdef XCB_USE_XINPUT22
|
||||
- virtual void handleXIMouseEvent(xcb_ge_event_t *) {}
|
||||
+ virtual void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource = Qt::MouseEventNotSynthesized) {}
|
||||
virtual void handleXIEnterLeave(xcb_ge_event_t *) {}
|
||||
#endif
|
||||
virtual QXcbWindow *toWindow() { return 0; }
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
|
||||
index 0c78c0e0d2bc9d05e9f6768ead72cad4a51d03a7..bf961318a343e56ee4e4a72a854ff757875be534 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
|
||||
@@ -1096,7 +1096,7 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q
|
||||
// Synthesize mouse events since otherwise there are no mouse events from
|
||||
// the pen on the XI 2.2+ path.
|
||||
if (xi2MouseEvents() && eventListener)
|
||||
- eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event));
|
||||
+ eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event), Qt::MouseEventSynthesizedByQt);
|
||||
#else
|
||||
Q_UNUSED(eventListener);
|
||||
#endif
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
index 7eae2d92ab39843d09cb6294f9afd7fc51260ecb..5ed35ec8e2bbc0c29b72fb616a746a352a9df969 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "qxcbwindow.h"
|
||||
|
||||
#include <QtDebug>
|
||||
+#include <QMetaEnum>
|
||||
#include <QScreen>
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtGui/QRegion>
|
||||
@@ -2157,7 +2158,7 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
|
||||
}
|
||||
|
||||
void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y,
|
||||
- int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp)
|
||||
+ int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source)
|
||||
{
|
||||
const bool isWheel = detail >= 4 && detail <= 7;
|
||||
if (!isWheel && window() != QGuiApplication::focusWindow()) {
|
||||
@@ -2193,11 +2194,11 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
|
||||
return;
|
||||
}
|
||||
|
||||
- handleMouseEvent(timestamp, local, global, modifiers);
|
||||
+ handleMouseEvent(timestamp, local, global, modifiers, source);
|
||||
}
|
||||
|
||||
void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y,
|
||||
- int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp)
|
||||
+ int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source)
|
||||
{
|
||||
QPoint local(event_x, event_y);
|
||||
QPoint global(root_x, root_y);
|
||||
@@ -2207,7 +2208,7 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x,
|
||||
return;
|
||||
}
|
||||
|
||||
- handleMouseEvent(timestamp, local, global, modifiers);
|
||||
+ handleMouseEvent(timestamp, local, global, modifiers, source);
|
||||
}
|
||||
|
||||
static bool ignoreLeaveEvent(quint8 mode, quint8 detail)
|
||||
@@ -2290,11 +2291,11 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y,
|
||||
}
|
||||
|
||||
void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y,
|
||||
- Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp)
|
||||
+ Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source)
|
||||
{
|
||||
QPoint local(event_x, event_y);
|
||||
QPoint global(root_x, root_y);
|
||||
- handleMouseEvent(timestamp, local, global, modifiers);
|
||||
+ handleMouseEvent(timestamp, local, global, modifiers, source);
|
||||
}
|
||||
|
||||
// Handlers for plain xcb events. Used only when XI 2.2 or newer is not available.
|
||||
@@ -2325,7 +2326,7 @@ static inline int fixed1616ToInt(FP1616 val)
|
||||
}
|
||||
|
||||
// With XI 2.2+ press/release/motion comes here instead of the above handlers.
|
||||
-void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event)
|
||||
+void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source)
|
||||
{
|
||||
QXcbConnection *conn = connection();
|
||||
xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event);
|
||||
@@ -2345,20 +2346,27 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event)
|
||||
conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i));
|
||||
}
|
||||
|
||||
+ const char *sourceName = nullptr;
|
||||
+ if (lcQpaXInput().isDebugEnabled()) {
|
||||
+ const QMetaObject *metaObject = qt_getEnumMetaObject(source);
|
||||
+ const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(source)));
|
||||
+ sourceName = me.valueToKey(source);
|
||||
+ }
|
||||
+
|
||||
switch (ev->evtype) {
|
||||
case XI_ButtonPress:
|
||||
- qCDebug(lcQpaXInput, "XI2 mouse press, button %d, time %d", button, ev->time);
|
||||
+ qCDebug(lcQpaXInput, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName);
|
||||
conn->setButton(button, true);
|
||||
- handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time);
|
||||
+ handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source);
|
||||
break;
|
||||
case XI_ButtonRelease:
|
||||
- qCDebug(lcQpaXInput, "XI2 mouse release, button %d, time %d", button, ev->time);
|
||||
+ qCDebug(lcQpaXInput, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName);
|
||||
conn->setButton(button, false);
|
||||
- handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time);
|
||||
+ handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source);
|
||||
break;
|
||||
case XI_Motion:
|
||||
- qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d, time %d", event_x, event_y, ev->time);
|
||||
- handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time);
|
||||
+ qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName);
|
||||
+ handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, source);
|
||||
break;
|
||||
default:
|
||||
qWarning() << "Unrecognized XI2 mouse event" << ev->evtype;
|
||||
@@ -2401,10 +2409,11 @@ void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event)
|
||||
|
||||
QXcbWindow *QXcbWindow::toWindow() { return this; }
|
||||
|
||||
-void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers)
|
||||
+void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
|
||||
+ Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source)
|
||||
{
|
||||
connection()->setTime(time);
|
||||
- QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers);
|
||||
+ QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers, source);
|
||||
}
|
||||
|
||||
void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
|
||||
index 69790f29ae098bbfcc5aa6edec75e3d0fea8ea75..4673f3dd33fd5cc9aa12bc1c50244b84ee3e398e 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbwindow.h
|
||||
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
|
||||
@@ -133,13 +133,14 @@ public:
|
||||
void handleFocusOutEvent(const xcb_focus_out_event_t *event) Q_DECL_OVERRIDE;
|
||||
void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) Q_DECL_OVERRIDE;
|
||||
#ifdef XCB_USE_XINPUT22
|
||||
- void handleXIMouseEvent(xcb_ge_event_t *) Q_DECL_OVERRIDE;
|
||||
+ void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) Q_DECL_OVERRIDE;
|
||||
void handleXIEnterLeave(xcb_ge_event_t *) Q_DECL_OVERRIDE;
|
||||
#endif
|
||||
|
||||
QXcbWindow *toWindow() Q_DECL_OVERRIDE;
|
||||
|
||||
- void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers);
|
||||
+ void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
|
||||
+ Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source);
|
||||
|
||||
void updateNetWmUserTime(xcb_timestamp_t timestamp);
|
||||
|
||||
@@ -207,13 +208,13 @@ protected:
|
||||
bool compressExposeEvent(QRegion &exposeRegion);
|
||||
|
||||
void handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y,
|
||||
- int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp);
|
||||
+ int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
|
||||
|
||||
void handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y,
|
||||
- int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp);
|
||||
+ int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
|
||||
|
||||
void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y,
|
||||
- Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp);
|
||||
+ Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
|
||||
|
||||
void handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y,
|
||||
quint8 mode, quint8 detail, xcb_timestamp_t timestamp);
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,142 +0,0 @@
|
||||
From 3c8b9236ed7a0b1284922097da875cc8baa1bb78 Mon Sep 17 00:00:00 2001
|
||||
From: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
Date: Mon, 14 Mar 2016 10:07:20 +0100
|
||||
Subject: [PATCH 11/16] xcb: Initialize all xcb_client_message_event_t members
|
||||
before use
|
||||
|
||||
Change-Id: I01e4b69b138fd19fc7e67751d93adebc1326b2f9
|
||||
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
|
||||
(cherry picked from commit 6c53f2528c86fb72f19951a799f0afaa02ad4490)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbdrag.cpp | 6 ++++++
|
||||
src/plugins/platforms/xcb/qxcbscreen.cpp | 1 +
|
||||
src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp | 2 +-
|
||||
src/plugins/platforms/xcb/qxcbwindow.cpp | 5 +++++
|
||||
4 files changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
|
||||
index aa6445d2da56f09696c98cba76baf6c74e44841c..f5cc87394b941014a1f45e0064d341dc8ad093d0 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
|
||||
@@ -423,6 +423,7 @@ void QXcbDrag::move(const QPoint &globalPos)
|
||||
|
||||
xcb_client_message_event_t enter;
|
||||
enter.response_type = XCB_CLIENT_MESSAGE;
|
||||
+ enter.sequence = 0;
|
||||
enter.window = target;
|
||||
enter.format = 32;
|
||||
enter.type = atom(QXcbAtom::XdndEnter);
|
||||
@@ -451,6 +452,7 @@ void QXcbDrag::move(const QPoint &globalPos)
|
||||
|
||||
xcb_client_message_event_t move;
|
||||
move.response_type = XCB_CLIENT_MESSAGE;
|
||||
+ move.sequence = 0;
|
||||
move.window = target;
|
||||
move.format = 32;
|
||||
move.type = atom(QXcbAtom::XdndPosition);
|
||||
@@ -479,6 +481,7 @@ void QXcbDrag::drop(const QPoint &globalPos)
|
||||
|
||||
xcb_client_message_event_t drop;
|
||||
drop.response_type = XCB_CLIENT_MESSAGE;
|
||||
+ drop.sequence = 0;
|
||||
drop.window = current_target;
|
||||
drop.format = 32;
|
||||
drop.type = atom(QXcbAtom::XdndDrop);
|
||||
@@ -740,6 +743,7 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
|
||||
|
||||
xcb_client_message_event_t response;
|
||||
response.response_type = XCB_CLIENT_MESSAGE;
|
||||
+ response.sequence = 0;
|
||||
response.window = xdnd_dragsource;
|
||||
response.format = 32;
|
||||
response.type = atom(QXcbAtom::XdndStatus);
|
||||
@@ -886,6 +890,7 @@ void QXcbDrag::send_leave()
|
||||
|
||||
xcb_client_message_event_t leave;
|
||||
leave.response_type = XCB_CLIENT_MESSAGE;
|
||||
+ leave.sequence = 0;
|
||||
leave.window = current_target;
|
||||
leave.format = 32;
|
||||
leave.type = atom(QXcbAtom::XdndLeave);
|
||||
@@ -956,6 +961,7 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
|
||||
|
||||
xcb_client_message_event_t finished;
|
||||
finished.response_type = XCB_CLIENT_MESSAGE;
|
||||
+ finished.sequence = 0;
|
||||
finished.window = xdnd_dragsource;
|
||||
finished.format = 32;
|
||||
finished.type = atom(QXcbAtom::XdndFinished);
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
index 1a90f824fc454c69f73ac195b1241bc6371d7aed..f74244e13c852d4a4844bb6e470d037e03a45c84 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
@@ -361,6 +361,7 @@ void QXcbScreen::sendStartupMessage(const QByteArray &message) const
|
||||
ev.response_type = XCB_CLIENT_MESSAGE;
|
||||
ev.format = 8;
|
||||
ev.type = connection()->atom(QXcbAtom::_NET_STARTUP_INFO_BEGIN);
|
||||
+ ev.sequence = 0;
|
||||
ev.window = rootWindow;
|
||||
int sent = 0;
|
||||
int length = message.length() + 1; // include NUL byte
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
|
||||
index 1f217e8de798d5161ec52bf8e88508f7314e6328..49c0440a3c4b48e2abaff5515cc4341257bcbc88 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
|
||||
@@ -94,9 +94,9 @@ xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *conne
|
||||
void QXcbSystemTrayTracker::requestSystemTrayWindowDock(xcb_window_t window) const
|
||||
{
|
||||
xcb_client_message_event_t trayRequest;
|
||||
- memset(&trayRequest, 0, sizeof(trayRequest));
|
||||
trayRequest.response_type = XCB_CLIENT_MESSAGE;
|
||||
trayRequest.format = 32;
|
||||
+ trayRequest.sequence = 0;
|
||||
trayRequest.window = m_trayWindow;
|
||||
trayRequest.type = m_trayAtom;
|
||||
trayRequest.data.data32[0] = XCB_CURRENT_TIME;
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
index 5ed35ec8e2bbc0c29b72fb616a746a352a9df969..1dc066c692d5beaf632ead78784683c928d1c1e4 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
@@ -1224,6 +1224,7 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two)
|
||||
|
||||
event.response_type = XCB_CLIENT_MESSAGE;
|
||||
event.format = 32;
|
||||
+ event.sequence = 0;
|
||||
event.window = m_window;
|
||||
event.type = atom(QXcbAtom::_NET_WM_STATE);
|
||||
event.data.data32[0] = set ? 1 : 0;
|
||||
@@ -1265,6 +1266,7 @@ void QXcbWindow::setWindowState(Qt::WindowState state)
|
||||
|
||||
event.response_type = XCB_CLIENT_MESSAGE;
|
||||
event.format = 32;
|
||||
+ event.sequence = 0;
|
||||
event.window = m_window;
|
||||
event.type = atom(QXcbAtom::WM_CHANGE_STATE);
|
||||
event.data.data32[0] = XCB_WM_STATE_ICONIC;
|
||||
@@ -1660,6 +1662,7 @@ void QXcbWindow::requestActivateWindow()
|
||||
|
||||
event.response_type = XCB_CLIENT_MESSAGE;
|
||||
event.format = 32;
|
||||
+ event.sequence = 0;
|
||||
event.window = m_window;
|
||||
event.type = atom(QXcbAtom::_NET_ACTIVE_WINDOW);
|
||||
event.data.data32[0] = 1;
|
||||
@@ -2607,6 +2610,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
|
||||
xcb_client_message_event_t xev;
|
||||
xev.response_type = XCB_CLIENT_MESSAGE;
|
||||
xev.type = moveResize;
|
||||
+ xev.sequence = 0;
|
||||
xev.window = xcb_window();
|
||||
xev.format = 32;
|
||||
const QPoint globalPos = window()->mapToGlobal(pos);
|
||||
@@ -2635,6 +2639,7 @@ void QXcbWindow::sendXEmbedMessage(xcb_window_t window, quint32 message,
|
||||
|
||||
event.response_type = XCB_CLIENT_MESSAGE;
|
||||
event.format = 32;
|
||||
+ event.sequence = 0;
|
||||
event.window = window;
|
||||
event.type = atom(QXcbAtom::_XEMBED);
|
||||
event.data.data32[0] = connection()->time();
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,71 +0,0 @@
|
||||
From cc32b65569c3cd947a7d012d41379490c9bf80c0 Mon Sep 17 00:00:00 2001
|
||||
From: David Rosca <nowrep@gmail.com>
|
||||
Date: Wed, 16 Mar 2016 08:35:22 +0100
|
||||
Subject: [PATCH 12/16] xcb: Merge _NET_WM_STATE hints instead of overwriting
|
||||
|
||||
This makes possible to set custom _NET_WM_STATE hints before
|
||||
showing the window.
|
||||
|
||||
Change-Id: I86ad3863f7a8b3bb610a31b9af4b02c9d38eb111
|
||||
Task-number: QTBUG-26978
|
||||
Reviewed-by: Ilya Kotov
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
Reviewed-by: Uli Schlachter <psychon@znc.in>
|
||||
(cherry picked from commit e4cea305ed2ba3c9f580bf9d16c59a1048af0e8a)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbwindow.cpp | 32 ++++++++++++++++++++++++--------
|
||||
1 file changed, 24 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
index 1dc066c692d5beaf632ead78784683c928d1c1e4..d2475a8b1329dee1034f5ac5e054e5318ca2ea09 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
@@ -1091,21 +1091,37 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
|
||||
void QXcbWindow::setNetWmStates(NetWmStates states)
|
||||
{
|
||||
QVector<xcb_atom_t> atoms;
|
||||
- if (states & NetWmStateAbove)
|
||||
+
|
||||
+ xcb_get_property_cookie_t get_cookie =
|
||||
+ xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE),
|
||||
+ XCB_ATOM_ATOM, 0, 1024);
|
||||
+
|
||||
+ xcb_get_property_reply_t *reply =
|
||||
+ xcb_get_property_reply(xcb_connection(), get_cookie, NULL);
|
||||
+
|
||||
+ if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) {
|
||||
+ const xcb_atom_t *data = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply));
|
||||
+ atoms.resize(reply->value_len);
|
||||
+ memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t));
|
||||
+ }
|
||||
+
|
||||
+ free(reply);
|
||||
+
|
||||
+ if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE)))
|
||||
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE));
|
||||
- if (states & NetWmStateBelow)
|
||||
+ if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW)))
|
||||
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW));
|
||||
- if (states & NetWmStateFullScreen)
|
||||
+ if (states & NetWmStateFullScreen && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)))
|
||||
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
|
||||
- if (states & NetWmStateMaximizedHorz)
|
||||
+ if (states & NetWmStateMaximizedHorz && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)))
|
||||
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ));
|
||||
- if (states & NetWmStateMaximizedVert)
|
||||
+ if (states & NetWmStateMaximizedVert && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)))
|
||||
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
|
||||
- if (states & NetWmStateModal)
|
||||
+ if (states & NetWmStateModal && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MODAL)))
|
||||
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MODAL));
|
||||
- if (states & NetWmStateStaysOnTop)
|
||||
+ if (states & NetWmStateStaysOnTop && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)))
|
||||
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP));
|
||||
- if (states & NetWmStateDemandsAttention)
|
||||
+ if (states & NetWmStateDemandsAttention && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)))
|
||||
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION));
|
||||
|
||||
if (atoms.isEmpty()) {
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,43 +0,0 @@
|
||||
From a148affea7763395ce503f695ddb6c7b4c1e4b08 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Volkov <a.volkov@rusbitech.ru>
|
||||
Date: Fri, 8 Apr 2016 18:50:15 +0300
|
||||
Subject: [PATCH 13/16] xcb: Fix interpretation of the size from
|
||||
RRCrtcChangeNotify
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The size in RRCrtcChangeNotify is a size of the mode and it is
|
||||
not rotated. At the same time when we call RRGetCrtcInfo, it
|
||||
returns a rotated size, which is then passed to
|
||||
QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation).
|
||||
|
||||
So to pass the expected size to QXcbScreen::updateGeometry()
|
||||
after receiving RRCrtcChangeNotify, we should rotate the size
|
||||
according the screen rotation.
|
||||
|
||||
Change-Id: If5b5b52403b077d3cd64b9a05d938bb9ac00b1e0
|
||||
Reviewed-by: Daniel Vrátil <daniel.vratil@kdab.com>
|
||||
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
|
||||
(cherry picked from commit d8667fde189fa08002295fc66414d67e73b3c67b)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbconnection.cpp | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
|
||||
index aeb730670d62b3ce2239fba48b58ccb4752e912d..9f170b095926501b91a20f401284c6c6149a07ab 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
|
||||
@@ -209,6 +209,9 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
|
||||
// CRTC with node mode could mean that output has been disabled, and we'll
|
||||
// get RRNotifyOutputChange notification for that.
|
||||
if (screen && crtc.mode) {
|
||||
+ if (crtc.rotation == XCB_RANDR_ROTATION_ROTATE_90 ||
|
||||
+ crtc.rotation == XCB_RANDR_ROTATION_ROTATE_270)
|
||||
+ std::swap(crtc.width, crtc.height);
|
||||
screen->updateGeometry(QRect(crtc.x, crtc.y, crtc.width, crtc.height), crtc.rotation);
|
||||
if (screen->mode() != crtc.mode)
|
||||
screen->updateRefreshRate(crtc.mode);
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,206 +0,0 @@
|
||||
From 123a082fd423422412d554a3b5973bcfc78c62a8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= <spaz16@wp.pl>
|
||||
Date: Thu, 14 Apr 2016 17:00:23 +0200
|
||||
Subject: [PATCH 14/16] xcb: Properly process enter/leave events
|
||||
|
||||
Ignore enter/leave events when there is a window under mouse button.
|
||||
Unset window under mouse button if other window is grabbed.
|
||||
Smarter ignoring (un)grab ancestor enter/leave event.
|
||||
Ignore ungrab inferior leave event.
|
||||
|
||||
Amends: b9f76db30d261421e4da58f29053181af04ceb4d
|
||||
|
||||
Task-number: QTBUG-46576
|
||||
Task-number: QTBUG-51573
|
||||
Task-number: QTBUG-52332
|
||||
Task-number: QTBUG-52488
|
||||
Change-Id: I8d926309aa60bb8929728691c31ecf93d1e299ad
|
||||
Reviewed-by: Dmitry Shachnev <mitya57@gmail.com>
|
||||
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
||||
(cherry picked from commit c511466d747d99ee76465cfe90ce594fa1f27469)
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbconnection.cpp | 6 +++
|
||||
src/plugins/platforms/xcb/qxcbconnection.h | 3 ++
|
||||
src/plugins/platforms/xcb/qxcbwindow.cpp | 70 ++++++++++++++++++++++------
|
||||
3 files changed, 64 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
|
||||
index 9f170b095926501b91a20f401284c6c6149a07ab..333a9606f50e9c27bdb7d24c836a3029a635b881 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
|
||||
@@ -560,6 +560,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
||||
, m_buttons(0)
|
||||
, m_focusWindow(0)
|
||||
, m_mouseGrabber(0)
|
||||
+ , m_mousePressWindow(0)
|
||||
, m_clientLeader(0)
|
||||
, m_systemTrayTracker(0)
|
||||
, m_glIntegration(Q_NULLPTR)
|
||||
@@ -1367,6 +1368,11 @@ void QXcbConnection::setFocusWindow(QXcbWindow *w)
|
||||
void QXcbConnection::setMouseGrabber(QXcbWindow *w)
|
||||
{
|
||||
m_mouseGrabber = w;
|
||||
+ m_mousePressWindow = Q_NULLPTR;
|
||||
+}
|
||||
+void QXcbConnection::setMousePressWindow(QXcbWindow *w)
|
||||
+{
|
||||
+ m_mousePressWindow = w;
|
||||
}
|
||||
|
||||
void QXcbConnection::grabServer()
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
|
||||
index 4d318457e3b05de8c343580aad217cc1bad9072c..0c004a86dd286a2c4aaf77d249eef14a2af8ff03 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbconnection.h
|
||||
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
|
||||
@@ -473,6 +473,8 @@ public:
|
||||
void setFocusWindow(QXcbWindow *);
|
||||
QXcbWindow *mouseGrabber() const { return m_mouseGrabber; }
|
||||
void setMouseGrabber(QXcbWindow *);
|
||||
+ QXcbWindow *mousePressWindow() const { return m_mousePressWindow; }
|
||||
+ void setMousePressWindow(QXcbWindow *);
|
||||
|
||||
QByteArray startupId() const { return m_startupId; }
|
||||
void setStartupId(const QByteArray &nextId) { m_startupId = nextId; }
|
||||
@@ -656,6 +658,7 @@ private:
|
||||
|
||||
QXcbWindow *m_focusWindow;
|
||||
QXcbWindow *m_mouseGrabber;
|
||||
+ QXcbWindow *m_mousePressWindow;
|
||||
|
||||
xcb_window_t m_clientLeader;
|
||||
QByteArray m_startupId;
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
index d2475a8b1329dee1034f5ac5e054e5318ca2ea09..e8ad6be82bba983127ecf0fe2c7f0a951d9b5fb3 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
|
||||
@@ -616,8 +616,12 @@ QXcbWindow::~QXcbWindow()
|
||||
{
|
||||
if (window()->type() != Qt::ForeignWindow)
|
||||
destroy();
|
||||
- else if (connection()->mouseGrabber() == this)
|
||||
- connection()->setMouseGrabber(Q_NULLPTR);
|
||||
+ else {
|
||||
+ if (connection()->mouseGrabber() == this)
|
||||
+ connection()->setMouseGrabber(Q_NULLPTR);
|
||||
+ if (connection()->mousePressWindow() == this)
|
||||
+ connection()->setMousePressWindow(Q_NULLPTR);
|
||||
+ }
|
||||
}
|
||||
|
||||
void QXcbWindow::destroy()
|
||||
@@ -875,6 +879,16 @@ void QXcbWindow::hide()
|
||||
|
||||
if (connection()->mouseGrabber() == this)
|
||||
connection()->setMouseGrabber(Q_NULLPTR);
|
||||
+ if (QPlatformWindow *w = connection()->mousePressWindow()) {
|
||||
+ // Unset mousePressWindow when it (or one of its parents) is unmapped
|
||||
+ while (w) {
|
||||
+ if (w == this) {
|
||||
+ connection()->setMousePressWindow(Q_NULLPTR);
|
||||
+ break;
|
||||
+ }
|
||||
+ w = w->parent();
|
||||
+ }
|
||||
+ }
|
||||
|
||||
m_mapped = false;
|
||||
|
||||
@@ -2213,6 +2227,8 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
|
||||
return;
|
||||
}
|
||||
|
||||
+ connection()->setMousePressWindow(this);
|
||||
+
|
||||
handleMouseEvent(timestamp, local, global, modifiers, source);
|
||||
}
|
||||
|
||||
@@ -2227,19 +2243,44 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x,
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (connection()->buttons() == Qt::NoButton)
|
||||
+ connection()->setMousePressWindow(Q_NULLPTR);
|
||||
+
|
||||
handleMouseEvent(timestamp, local, global, modifiers, source);
|
||||
}
|
||||
|
||||
-static bool ignoreLeaveEvent(quint8 mode, quint8 detail)
|
||||
+static inline bool doCheckUnGrabAncestor(QXcbConnection *conn)
|
||||
+{
|
||||
+ /* Checking for XCB_NOTIFY_MODE_GRAB and XCB_NOTIFY_DETAIL_ANCESTOR prevents unwanted
|
||||
+ * enter/leave events on AwesomeWM on mouse button press. It also ignores duplicated
|
||||
+ * enter/leave events on Alt+Tab switching on some WMs with XInput2 events.
|
||||
+ * Without XInput2 events the (Un)grabAncestor cannot be checked when mouse button is
|
||||
+ * not pressed, otherwise (e.g. on Alt+Tab) it can igonre important enter/leave events.
|
||||
+ */
|
||||
+ if (conn) {
|
||||
+ const bool mouseButtonsPressed = (conn->buttons() != Qt::NoButton);
|
||||
+#ifdef XCB_USE_XINPUT22
|
||||
+ return mouseButtonsPressed || (conn->isAtLeastXI22() && conn->xi2MouseEvents());
|
||||
+#else
|
||||
+ return mouseButtonsPressed;
|
||||
+#endif
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn = Q_NULLPTR)
|
||||
{
|
||||
- return (mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM
|
||||
+ return ((doCheckUnGrabAncestor(conn)
|
||||
+ && mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR)
|
||||
+ || (mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_INFERIOR)
|
||||
|| detail == XCB_NOTIFY_DETAIL_VIRTUAL
|
||||
- || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL;
|
||||
+ || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL);
|
||||
}
|
||||
|
||||
-static bool ignoreEnterEvent(quint8 mode, quint8 detail)
|
||||
+static bool ignoreEnterEvent(quint8 mode, quint8 detail, QXcbConnection *conn = Q_NULLPTR)
|
||||
{
|
||||
- return ((mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM
|
||||
+ return ((doCheckUnGrabAncestor(conn)
|
||||
+ && mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR)
|
||||
|| (mode != XCB_NOTIFY_MODE_NORMAL && mode != XCB_NOTIFY_MODE_UNGRAB)
|
||||
|| detail == XCB_NOTIFY_DETAIL_VIRTUAL
|
||||
|| detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL);
|
||||
@@ -2273,9 +2314,7 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in
|
||||
|
||||
const QPoint global = QPoint(root_x, root_y);
|
||||
|
||||
- if (ignoreEnterEvent(mode, detail)
|
||||
- || (connection()->buttons() != Qt::NoButton
|
||||
- && QGuiApplicationPrivate::lastCursorPosition != global))
|
||||
+ if (ignoreEnterEvent(mode, detail, connection()) || connection()->mousePressWindow())
|
||||
return;
|
||||
|
||||
const QPoint local(event_x, event_y);
|
||||
@@ -2287,11 +2326,7 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y,
|
||||
{
|
||||
connection()->setTime(timestamp);
|
||||
|
||||
- const QPoint global(root_x, root_y);
|
||||
-
|
||||
- if (ignoreLeaveEvent(mode, detail)
|
||||
- || (connection()->buttons() != Qt::NoButton
|
||||
- && QGuiApplicationPrivate::lastCursorPosition != global))
|
||||
+ if (ignoreLeaveEvent(mode, detail, connection()) || connection()->mousePressWindow())
|
||||
return;
|
||||
|
||||
EnterEventChecker checker;
|
||||
@@ -2314,6 +2349,11 @@ void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, i
|
||||
{
|
||||
QPoint local(event_x, event_y);
|
||||
QPoint global(root_x, root_y);
|
||||
+
|
||||
+ // "mousePressWindow" can be NULL i.e. if a window will be grabbed or umnapped, so set it again here
|
||||
+ if (connection()->buttons() != Qt::NoButton && connection()->mousePressWindow() == Q_NULLPTR)
|
||||
+ connection()->setMousePressWindow(this);
|
||||
+
|
||||
handleMouseEvent(timestamp, local, global, modifiers, source);
|
||||
}
|
||||
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,149 +0,0 @@
|
||||
From d7be69c973623e76deff3fa00354927946b21c66 Mon Sep 17 00:00:00 2001
|
||||
From: Albert Astals Cid <aacid@kde.org>
|
||||
Date: Thu, 21 Apr 2016 01:39:27 +0200
|
||||
Subject: [PATCH 15/16] Use the state of the key event to process it
|
||||
|
||||
Use the state of the key event instead of the global state.
|
||||
UpdateXKBStateFromState uses xkbModMask, which needs updateXKBMods
|
||||
to be called beforehand.
|
||||
|
||||
Task-number: QTBUG-48795
|
||||
Change-Id: Ic2c545718adb68df41730e5a3bf25adb374ffce3
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbkeyboard.cpp | 72 ++++++++++++++++++------------
|
||||
src/plugins/platforms/xcb/qxcbkeyboard.h | 2 +
|
||||
2 files changed, 46 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
|
||||
index 631dd17908f458533f413409773b6c078b743d98..baba7ec812c16025893bf5267fba545e8b4378bf 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
|
||||
@@ -742,8 +742,7 @@ void QXcbKeyboard::updateKeymap()
|
||||
// update xkb state object
|
||||
xkb_state_unref(xkb_state);
|
||||
xkb_state = new_state;
|
||||
- if (!connection()->hasXKB())
|
||||
- updateXKBMods();
|
||||
+ updateXKBMods();
|
||||
|
||||
checkForLatinLayout();
|
||||
}
|
||||
@@ -768,32 +767,37 @@ void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
|
||||
}
|
||||
#endif
|
||||
|
||||
+void QXcbKeyboard::updateXKBStateFromState(struct xkb_state *kb_state, quint16 state)
|
||||
+{
|
||||
+ const quint32 modsDepressed = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_DEPRESSED);
|
||||
+ const quint32 modsLatched = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LATCHED);
|
||||
+ const quint32 modsLocked = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LOCKED);
|
||||
+ const quint32 xkbMask = xkbModMask(state);
|
||||
+
|
||||
+ const quint32 latched = modsLatched & xkbMask;
|
||||
+ const quint32 locked = modsLocked & xkbMask;
|
||||
+ quint32 depressed = modsDepressed & xkbMask;
|
||||
+ // set modifiers in depressed if they don't appear in any of the final masks
|
||||
+ depressed |= ~(depressed | latched | locked) & xkbMask;
|
||||
+
|
||||
+ const xkb_state_component newState
|
||||
+ = xkb_state_update_mask(kb_state,
|
||||
+ depressed,
|
||||
+ latched,
|
||||
+ locked,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ (state >> 13) & 3); // bits 13 and 14 report the state keyboard group
|
||||
+
|
||||
+ if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) {
|
||||
+ //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
|
||||
{
|
||||
if (m_config && !connection()->hasXKB()) {
|
||||
- const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED);
|
||||
- const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED);
|
||||
- const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED);
|
||||
- const quint32 xkbMask = xkbModMask(state);
|
||||
-
|
||||
- const quint32 latched = modsLatched & xkbMask;
|
||||
- const quint32 locked = modsLocked & xkbMask;
|
||||
- quint32 depressed = modsDepressed & xkbMask;
|
||||
- // set modifiers in depressed if they don't appear in any of the final masks
|
||||
- depressed |= ~(depressed | latched | locked) & xkbMask;
|
||||
-
|
||||
- const xkb_state_component newState
|
||||
- = xkb_state_update_mask(xkb_state,
|
||||
- depressed,
|
||||
- latched,
|
||||
- locked,
|
||||
- 0,
|
||||
- 0,
|
||||
- (state >> 13) & 3); // bits 13 and 14 report the state keyboard group
|
||||
-
|
||||
- if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) {
|
||||
- //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
|
||||
- }
|
||||
+ updateXKBStateFromState(xkb_state, state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1445,7 +1449,16 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
|
||||
if (type == QEvent::KeyPress)
|
||||
targetWindow->updateNetWmUserTime(time);
|
||||
|
||||
- xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code);
|
||||
+ // Have a temporary keyboard state filled in from state
|
||||
+ // this way we allow for synthetic events to have different state
|
||||
+ // from the current state i.e. you can have Alt+Ctrl pressed
|
||||
+ // and receive a synthetic key event that has neither Alt nor Ctrl pressed
|
||||
+ struct xkb_state *kb_state = xkb_state_new(xkb_keymap);
|
||||
+ if (!kb_state)
|
||||
+ return;
|
||||
+ updateXKBStateFromState(kb_state, state);
|
||||
+
|
||||
+ xcb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, code);
|
||||
|
||||
QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
|
||||
QMetaMethod method;
|
||||
@@ -1464,11 +1477,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
|
||||
Q_ARG(uint, code),
|
||||
Q_ARG(uint, state),
|
||||
Q_ARG(bool, type == QEvent::KeyPress));
|
||||
- if (retval)
|
||||
+ if (retval) {
|
||||
+ xkb_state_unref(kb_state);
|
||||
return;
|
||||
+ }
|
||||
}
|
||||
|
||||
- QString string = lookupString(xkb_state, code);
|
||||
+ QString string = lookupString(kb_state, code);
|
||||
|
||||
// Ιf control modifier is set we should prefer latin character, this is
|
||||
// used for standard shortcuts in checks like "key == QKeySequence::Copy",
|
||||
@@ -1537,6 +1552,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
|
||||
QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers,
|
||||
code, sym, state, string, isAutoRepeat);
|
||||
}
|
||||
+ xkb_state_unref(kb_state);
|
||||
}
|
||||
|
||||
QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
|
||||
index 457a27affb166e2a3e54c78761361ff3713a4d18..dc27511b56e98bfc0f642e03c0b3aa8b2f4778e9 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
|
||||
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
|
||||
@@ -98,6 +98,8 @@ protected:
|
||||
void checkForLatinLayout();
|
||||
|
||||
private:
|
||||
+ void updateXKBStateFromState(struct xkb_state *kb_state, quint16 state);
|
||||
+
|
||||
bool m_config;
|
||||
xcb_keycode_t m_autorepeat_code;
|
||||
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,92 +0,0 @@
|
||||
From 7c3b3375b2d54ef1965c32131123a9becfa27f98 Mon Sep 17 00:00:00 2001
|
||||
From: Urs Fleisch <ufleisch@users.sourceforge.net>
|
||||
Date: Fri, 26 Feb 2016 17:46:09 +0100
|
||||
Subject: [PATCH 16/16] xcb: Fix drag and drop to applications like Emacs and
|
||||
Chromium.
|
||||
|
||||
Drops without matching time stamp do not work. I have fixed the issue by
|
||||
reanimating the findXdndAwareParent() function (adapted to XCB) and
|
||||
using it to find a matching transaction if all else fails.
|
||||
|
||||
Task-number: QTBUG-45812
|
||||
Change-Id: Ibca15bbab02ccf2f25280418e9edf36972ebf9a0
|
||||
---
|
||||
src/plugins/platforms/xcb/qxcbdrag.cpp | 55 +++++++++++++++++++++++++++-------
|
||||
1 file changed, 44 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
|
||||
index f5cc87394b941014a1f45e0064d341dc8ad093d0..f1428d0a9632bd692ceaa130be58992f282d3081 100644
|
||||
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
|
||||
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
|
||||
@@ -1072,6 +1072,40 @@ void QXcbDrag::cancel()
|
||||
send_leave();
|
||||
}
|
||||
|
||||
+// find an ancestor with XdndAware on it
|
||||
+static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window)
|
||||
+{
|
||||
+ xcb_window_t target = 0;
|
||||
+ forever {
|
||||
+ // check if window has XdndAware
|
||||
+ xcb_get_property_cookie_t gpCookie = Q_XCB_CALL(
|
||||
+ xcb_get_property(c->xcb_connection(), false, window,
|
||||
+ c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
|
||||
+ xcb_get_property_reply_t *gpReply = xcb_get_property_reply(
|
||||
+ c->xcb_connection(), gpCookie, 0);
|
||||
+ bool aware = gpReply && gpReply->type != XCB_NONE;
|
||||
+ free(gpReply);
|
||||
+ if (aware) {
|
||||
+ target = window;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ // try window's parent
|
||||
+ xcb_query_tree_cookie_t qtCookie = Q_XCB_CALL(
|
||||
+ xcb_query_tree_unchecked(c->xcb_connection(), window));
|
||||
+ xcb_query_tree_reply_t *qtReply = xcb_query_tree_reply(
|
||||
+ c->xcb_connection(), qtCookie, NULL);
|
||||
+ if (!qtReply)
|
||||
+ break;
|
||||
+ xcb_window_t root = qtReply->root;
|
||||
+ xcb_window_t parent = qtReply->parent;
|
||||
+ free(qtReply);
|
||||
+ if (window == root)
|
||||
+ break;
|
||||
+ window = parent;
|
||||
+ }
|
||||
+ return target;
|
||||
+}
|
||||
|
||||
void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event)
|
||||
{
|
||||
@@ -1099,17 +1133,16 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
|
||||
// xcb_convert_selection() that we sent the XdndDrop event to.
|
||||
at = findTransactionByWindow(event->requestor);
|
||||
}
|
||||
-// if (at == -1 && event->time == XCB_CURRENT_TIME) {
|
||||
-// // previous Qt versions always requested the data on a child of the target window
|
||||
-// // using CurrentTime... but it could be asking for either drop data or the current drag's data
|
||||
-// Window target = findXdndAwareParent(event->requestor);
|
||||
-// if (target) {
|
||||
-// if (current_target && current_target == target)
|
||||
-// at = -2;
|
||||
-// else
|
||||
-// at = findXdndDropTransactionByWindow(target);
|
||||
-// }
|
||||
-// }
|
||||
+
|
||||
+ if (at == -1 && event->time == XCB_CURRENT_TIME) {
|
||||
+ xcb_window_t target = findXdndAwareParent(connection(), event->requestor);
|
||||
+ if (target) {
|
||||
+ if (current_target == target)
|
||||
+ at = -2;
|
||||
+ else
|
||||
+ at = findTransactionByWindow(target);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
QDrag *transactionDrag = 0;
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,124 +0,0 @@
|
||||
From f328f0cd2eb6be2a0a0d148bd769d51eae42bdc6 Mon Sep 17 00:00:00 2001
|
||||
From: Thiago Macieira <thiago.macieira@intel.com>
|
||||
Date: Tue, 15 Mar 2016 11:00:20 -0700
|
||||
Subject: [PATCH] Fix QtDBus deadlock inside kded/kiod
|
||||
|
||||
Whenever a message spy was installed, we failed to actually process
|
||||
looped-back messages by queueing them for processing by the spy. That
|
||||
had as a consequence that the caller got an error reply and the message,
|
||||
later, we attempted to deliver the message. Since that message still was
|
||||
isLocal==true, bad things happened inside the manager thread.
|
||||
|
||||
The correct solution is not to queue the message for the filter. If the
|
||||
message is local, then simply deliver directly, as we're still in the
|
||||
user's thread. This used to be the behavior in Qt 5.5.
|
||||
|
||||
Task-number: QTBUG-51676
|
||||
Change-Id: I1dc112894cde7121e8ce302ae51b438ade1ff612
|
||||
---
|
||||
src/dbus/qdbusintegrator.cpp | 42 ++++++++++++++++++++++++++++++++----------
|
||||
src/dbus/qdbusintegrator_p.h | 1 +
|
||||
2 files changed, 33 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
|
||||
index cd44861..478a2c4 100644
|
||||
--- a/src/dbus/qdbusintegrator.cpp
|
||||
+++ b/src/dbus/qdbusintegrator.cpp
|
||||
@@ -481,6 +481,11 @@ QDBusSpyCallEvent::~QDBusSpyCallEvent()
|
||||
|
||||
void QDBusSpyCallEvent::placeMetaCall(QObject *)
|
||||
{
|
||||
+ invokeSpyHooks(msg, hooks, hookCount);
|
||||
+}
|
||||
+
|
||||
+inline void QDBusSpyCallEvent::invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount)
|
||||
+{
|
||||
// call the spy hook list
|
||||
for (int i = 0; i < hookCount; ++i)
|
||||
hooks[i](msg);
|
||||
@@ -509,7 +514,12 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
|
||||
{
|
||||
if (!ref.load())
|
||||
return false;
|
||||
- if (!dispatchEnabled && !QDBusMessagePrivate::isLocal(amsg)) {
|
||||
+
|
||||
+ // local message are always delivered, regardless of filtering
|
||||
+ // or whether the dispatcher is enabled
|
||||
+ bool isLocal = QDBusMessagePrivate::isLocal(amsg);
|
||||
+
|
||||
+ if (!dispatchEnabled && !isLocal) {
|
||||
// queue messages only, we'll handle them later
|
||||
qDBusDebug() << this << "delivery is suspended";
|
||||
pendingMessages << amsg;
|
||||
@@ -523,13 +533,23 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
|
||||
// let them see the signal too
|
||||
return false;
|
||||
case QDBusMessage::MethodCallMessage:
|
||||
- // run it through the spy filters (if any) before the regular processing
|
||||
+ // run it through the spy filters (if any) before the regular processing:
|
||||
+ // a) if it's a local message, we're in the caller's thread, so invoke the filter directly
|
||||
+ // b) if it's an external message, post to the main thread
|
||||
if (Q_UNLIKELY(qDBusSpyHookList.exists()) && qApp) {
|
||||
const QDBusSpyHookList &list = *qDBusSpyHookList;
|
||||
- qDBusDebug() << this << "invoking message spies";
|
||||
- QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this),
|
||||
- amsg, list.constData(), list.size()));
|
||||
- return true;
|
||||
+ if (isLocal) {
|
||||
+ Q_ASSERT(QThread::currentThread() != thread());
|
||||
+ qDBusDebug() << this << "invoking message spies directly";
|
||||
+ QDBusSpyCallEvent::invokeSpyHooks(amsg, list.constData(), list.size());
|
||||
+ } else {
|
||||
+ qDBusDebug() << this << "invoking message spies via event";
|
||||
+ QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this),
|
||||
+ amsg, list.constData(), list.size()));
|
||||
+
|
||||
+ // we'll be called back, so return
|
||||
+ return true;
|
||||
+ }
|
||||
}
|
||||
|
||||
handleObjectCall(amsg);
|
||||
@@ -1451,9 +1471,9 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
|
||||
// that means the dispatchLock mutex is locked
|
||||
// must not call out to user code in that case
|
||||
//
|
||||
- // however, if the message is internal, handleMessage was called
|
||||
- // directly and no lock is in place. We can therefore call out to
|
||||
- // user code, if necessary
|
||||
+ // however, if the message is internal, handleMessage was called directly
|
||||
+ // (user's thread) and no lock is in place. We can therefore call out to
|
||||
+ // user code, if necessary.
|
||||
ObjectTreeNode result;
|
||||
int usedLength;
|
||||
QThread *objThread = 0;
|
||||
@@ -1492,12 +1512,14 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
|
||||
usedLength, msg));
|
||||
return;
|
||||
} else if (objThread != QThread::currentThread()) {
|
||||
- // synchronize with other thread
|
||||
+ // looped-back message, targeting another thread:
|
||||
+ // synchronize with it
|
||||
postEventToThread(HandleObjectCallPostEventAction, result.obj,
|
||||
new QDBusActivateObjectEvent(QDBusConnection(this), this, result,
|
||||
usedLength, msg, &sem));
|
||||
semWait = true;
|
||||
} else {
|
||||
+ // looped-back message, targeting current thread
|
||||
semWait = false;
|
||||
}
|
||||
} // release the lock
|
||||
diff --git a/src/dbus/qdbusintegrator_p.h b/src/dbus/qdbusintegrator_p.h
|
||||
index 2bbebdf..c0d9c22 100644
|
||||
--- a/src/dbus/qdbusintegrator_p.h
|
||||
+++ b/src/dbus/qdbusintegrator_p.h
|
||||
@@ -145,6 +145,7 @@ public:
|
||||
{}
|
||||
~QDBusSpyCallEvent();
|
||||
void placeMetaCall(QObject *) Q_DECL_OVERRIDE;
|
||||
+ static inline void invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount);
|
||||
|
||||
QDBusConnection conn; // keeps the refcount in QDBusConnectionPrivate up
|
||||
QDBusMessage msg;
|
||||
--
|
||||
2.6.2.2.g1b5ffa3
|
@ -1,87 +0,0 @@
|
||||
From b024fbe83863fc57364a52c717d5b43d654bdb5d Mon Sep 17 00:00:00 2001
|
||||
From: Weng Xuetian <wengxt@gmail.com>
|
||||
Date: Sat, 5 Mar 2016 12:23:21 -0800
|
||||
Subject: [PATCH] QtDBus: clean up signal hooks and object tree in
|
||||
closeConnection
|
||||
|
||||
If a QObject is added or passed as receiver to QDBusConnection::connect()
|
||||
and it is managed by Q_GLOBAL_STATIC or similar mechanism, it is
|
||||
possible that when that its destructor is called after the dbus daemon
|
||||
thread ends. In that case, QObject::destroyed connected via
|
||||
Qt::BlockingQueuedConnection to QDBusConnectionPrivate will cause dead
|
||||
lock since the thread is no longer processing events.
|
||||
|
||||
Task-number: QTBUG-51648
|
||||
Change-Id: I1a1810a6d6d0234af0269d5f3fc1f54101bf1547
|
||||
---
|
||||
src/dbus/qdbusconnection_p.h | 1 +
|
||||
src/dbus/qdbusintegrator.cpp | 28 +++++++++++++++++++++++++++-
|
||||
2 files changed, 28 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
|
||||
index c77daf7..565eb83 100644
|
||||
--- a/src/dbus/qdbusconnection_p.h
|
||||
+++ b/src/dbus/qdbusconnection_p.h
|
||||
@@ -254,6 +254,7 @@ private:
|
||||
const QVector<int> &metaTypes, int slotIdx);
|
||||
|
||||
SignalHookHash::Iterator removeSignalHookNoLock(SignalHookHash::Iterator it);
|
||||
+ void disconnectObjectTree(ObjectTreeNode &node);
|
||||
|
||||
bool isServiceRegisteredByThread(const QString &serviceName);
|
||||
|
||||
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
|
||||
index cd44861..a3cd47b 100644
|
||||
--- a/src/dbus/qdbusintegrator.cpp
|
||||
+++ b/src/dbus/qdbusintegrator.cpp
|
||||
@@ -1030,7 +1030,6 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate()
|
||||
qPrintable(name));
|
||||
|
||||
closeConnection();
|
||||
- rootNode.children.clear(); // free resources
|
||||
qDeleteAll(cachedMetaObjects);
|
||||
|
||||
if (mode == ClientMode || mode == PeerMode) {
|
||||
@@ -1052,6 +1051,20 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate()
|
||||
}
|
||||
}
|
||||
|
||||
+void QDBusConnectionPrivate::disconnectObjectTree(QDBusConnectionPrivate::ObjectTreeNode &haystack)
|
||||
+{
|
||||
+ QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = haystack.children.begin();
|
||||
+
|
||||
+ while (it != haystack.children.end()) {
|
||||
+ disconnectObjectTree(*it);
|
||||
+ it++;
|
||||
+ }
|
||||
+
|
||||
+ if (haystack.obj) {
|
||||
+ haystack.obj->disconnect(this);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void QDBusConnectionPrivate::closeConnection()
|
||||
{
|
||||
QDBusWriteLocker locker(CloseConnectionAction, this);
|
||||
@@ -1075,6 +1088,19 @@ void QDBusConnectionPrivate::closeConnection()
|
||||
}
|
||||
|
||||
qDeleteAll(pendingCalls);
|
||||
+
|
||||
+ // clean up all signal hook and object tree, to avoid QObject::destroyed
|
||||
+ // being activated to dbus daemon thread which already quits.
|
||||
+ // dbus connection is already closed, so there is nothing we could do be clean
|
||||
+ // up everything here.
|
||||
+ SignalHookHash::iterator sit = signalHooks.begin();
|
||||
+ while (sit != signalHooks.end()) {
|
||||
+ sit.value().obj->disconnect(this);
|
||||
+ sit++;
|
||||
+ }
|
||||
+
|
||||
+ disconnectObjectTree(rootNode);
|
||||
+ rootNode.children.clear(); // free resources
|
||||
}
|
||||
|
||||
void QDBusConnectionPrivate::checkThread()
|
||||
--
|
||||
2.6.2.2.g1b5ffa3
|
@ -1,158 +0,0 @@
|
||||
From acde2e69df5dedc624674107596f276125e22864 Mon Sep 17 00:00:00 2001
|
||||
From: Weng Xuetian <wengxt@gmail.com>
|
||||
Date: Thu, 3 Mar 2016 21:56:53 -0800
|
||||
Subject: [PATCH] QtDBus: finish all pending call with error if disconnected
|
||||
|
||||
libdbus will send a local signal if connection gets disconnected. When
|
||||
this happens, end all pending calls with QDBusError::Disconnected.
|
||||
|
||||
Task-number: QTBUG-51649
|
||||
Change-Id: I5c7d2a468bb5da746d0c0e53e458c1e376f186a9
|
||||
---
|
||||
src/dbus/dbus_minimal_p.h | 2 ++
|
||||
src/dbus/qdbusintegrator.cpp | 26 +++++++++++++++++-----
|
||||
src/dbus/qdbusutil_p.h | 6 +++++
|
||||
.../dbus/qdbusconnection/tst_qdbusconnection.cpp | 22 ++++++++++++++++++
|
||||
.../dbus/qdbusconnection/tst_qdbusconnection.h | 1 +
|
||||
5 files changed, 51 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/dbus/dbus_minimal_p.h b/src/dbus/dbus_minimal_p.h
|
||||
index f0a2954..8f25b24 100644
|
||||
--- a/src/dbus/dbus_minimal_p.h
|
||||
+++ b/src/dbus/dbus_minimal_p.h
|
||||
@@ -99,9 +99,11 @@ typedef dbus_uint32_t dbus_bool_t;
|
||||
/* dbus-shared.h */
|
||||
#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
|
||||
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
|
||||
+#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local"
|
||||
#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
|
||||
#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable"
|
||||
#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
|
||||
+#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local"
|
||||
|
||||
#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */
|
||||
#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */
|
||||
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
|
||||
index cd44861..320419f 100644
|
||||
--- a/src/dbus/qdbusintegrator.cpp
|
||||
+++ b/src/dbus/qdbusintegrator.cpp
|
||||
@@ -519,6 +519,14 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
|
||||
switch (amsg.type()) {
|
||||
case QDBusMessage::SignalMessage:
|
||||
handleSignal(amsg);
|
||||
+ // Check local disconnected signal from libdbus
|
||||
+ if (amsg.interface() == QDBusUtil::dbusInterfaceLocal()
|
||||
+ && amsg.path() == QDBusUtil::dbusPathLocal()
|
||||
+ && amsg.member() == QDBusUtil::disconnected()
|
||||
+ && !QDBusMessagePrivate::isLocal(amsg)) {
|
||||
+ while (!pendingCalls.isEmpty())
|
||||
+ processFinishedCall(pendingCalls.first());
|
||||
+ }
|
||||
// if there are any other filters in this DBusConnection,
|
||||
// let them see the signal too
|
||||
return false;
|
||||
@@ -1767,10 +1775,16 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
|
||||
|
||||
QDBusMessage &msg = call->replyMessage;
|
||||
if (call->pending) {
|
||||
- // decode the message
|
||||
- DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
|
||||
- msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities);
|
||||
- q_dbus_message_unref(reply);
|
||||
+ // when processFinishedCall is called and pending call is not completed,
|
||||
+ // it means we received disconnected signal from libdbus
|
||||
+ if (q_dbus_pending_call_get_completed(call->pending)) {
|
||||
+ // decode the message
|
||||
+ DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
|
||||
+ msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities);
|
||||
+ q_dbus_message_unref(reply);
|
||||
+ } else {
|
||||
+ msg = QDBusMessage::createError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage());
|
||||
+ }
|
||||
}
|
||||
qDBusDebug() << connection << "got message reply:" << msg;
|
||||
|
||||
@@ -2070,8 +2084,8 @@ void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall, void *
|
||||
pcall->pending = pending;
|
||||
q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0);
|
||||
|
||||
- // DBus won't notify us when a peer disconnects so we need to track these ourselves
|
||||
- if (mode == QDBusConnectionPrivate::PeerMode)
|
||||
+ // DBus won't notify us when a peer disconnects or server terminates so we need to track these ourselves
|
||||
+ if (mode == QDBusConnectionPrivate::PeerMode || mode == QDBusConnectionPrivate::ClientMode)
|
||||
pendingCalls.append(pcall);
|
||||
|
||||
return;
|
||||
diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h
|
||||
index 8f5ae92..ca70ff9 100644
|
||||
--- a/src/dbus/qdbusutil_p.h
|
||||
+++ b/src/dbus/qdbusutil_p.h
|
||||
@@ -155,6 +155,8 @@ namespace QDBusUtil
|
||||
{ return QStringLiteral(DBUS_SERVICE_DBUS); }
|
||||
inline QString dbusPath()
|
||||
{ return QStringLiteral(DBUS_PATH_DBUS); }
|
||||
+ inline QString dbusPathLocal()
|
||||
+ { return QStringLiteral(DBUS_PATH_LOCAL); }
|
||||
inline QString dbusInterface()
|
||||
{
|
||||
// it's the same string, but just be sure
|
||||
@@ -165,8 +167,12 @@ namespace QDBusUtil
|
||||
{ return QStringLiteral(DBUS_INTERFACE_PROPERTIES); }
|
||||
inline QString dbusInterfaceIntrospectable()
|
||||
{ return QStringLiteral(DBUS_INTERFACE_INTROSPECTABLE); }
|
||||
+ inline QString dbusInterfaceLocal()
|
||||
+ { return QStringLiteral(DBUS_INTERFACE_LOCAL); }
|
||||
inline QString nameOwnerChanged()
|
||||
{ return QStringLiteral("NameOwnerChanged"); }
|
||||
+ inline QString disconnected()
|
||||
+ { return QStringLiteral("Disconnected"); }
|
||||
inline QString disconnectedErrorMessage()
|
||||
{ return QStringLiteral("Not connected to D-Bus server"); }
|
||||
}
|
||||
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
|
||||
index e91f87d..6c7e6b1 100644
|
||||
--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
|
||||
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
|
||||
@@ -1218,6 +1218,28 @@ void tst_QDBusConnection::callVirtualObjectLocal()
|
||||
QCOMPARE(obj.replyArguments, subPathReply.arguments());
|
||||
}
|
||||
|
||||
+void tst_QDBusConnection::pendingCallWhenDisconnected()
|
||||
+{
|
||||
+ QDBusServer *server = new QDBusServer;
|
||||
+ QDBusConnection con = QDBusConnection::connectToPeer(server->address(), "disconnect");
|
||||
+ QTestEventLoop::instance().enterLoop(2);
|
||||
+ QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
+ QVERIFY(con.isConnected());
|
||||
+
|
||||
+ delete server;
|
||||
+
|
||||
+ // Make sure we call the method before we know it is disconnected.
|
||||
+ QVERIFY(con.isConnected());
|
||||
+ QDBusMessage message = QDBusMessage::createMethodCall("", "/", QString(), "method");
|
||||
+ QDBusPendingCall reply = con.asyncCall(message);
|
||||
+
|
||||
+ QTestEventLoop::instance().enterLoop(2);
|
||||
+ QVERIFY(!con.isConnected());
|
||||
+ QVERIFY(reply.isFinished());
|
||||
+ QVERIFY(reply.isError());
|
||||
+ QVERIFY(reply.error().type() == QDBusError::Disconnected);
|
||||
+}
|
||||
+
|
||||
QString MyObject::path;
|
||||
QString MyObjectWithoutInterface::path;
|
||||
QString MyObjectWithoutInterface::interface;
|
||||
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
|
||||
index a53ba32..720e484 100644
|
||||
--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
|
||||
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
|
||||
@@ -121,6 +121,7 @@ private slots:
|
||||
void registerVirtualObject();
|
||||
void callVirtualObject();
|
||||
void callVirtualObjectLocal();
|
||||
+ void pendingCallWhenDisconnected();
|
||||
|
||||
public:
|
||||
QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; }
|
||||
--
|
||||
2.6.2.2.g1b5ffa3
|
@ -2,20 +2,13 @@ Index: qtbase-opensource-src-5.5.1/src/network/ssl/qsslsocket_openssl.cpp
|
||||
===================================================================
|
||||
--- qtbase-opensource-src-5.5.1.orig/src/network/ssl/qsslsocket_openssl.cpp
|
||||
+++ qtbase-opensource-src-5.5.1/src/network/ssl/qsslsocket_openssl.cpp
|
||||
@@ -662,10 +662,13 @@ void QSslSocketPrivate::resetDefaultCiph
|
||||
// Unconditionally exclude ADH and AECDH ciphers since they offer no MITM protection
|
||||
if (!ciph.name().toLower().startsWith(QLatin1String("adh")) &&
|
||||
!ciph.name().toLower().startsWith(QLatin1String("exp-adh")) &&
|
||||
- !ciph.name().toLower().startsWith(QLatin1String("aecdh")))
|
||||
+ !ciph.name().toLower().startsWith(QLatin1String("aecdh"))) {
|
||||
@@ -645,7 +645,8 @@ void QSslSocketPrivate::resetDefaultCiph
|
||||
!ciph.name().toLower().startsWith(QLatin1String("aecdh"))) {
|
||||
ciphers << ciph;
|
||||
- if (ciph.usedBits() >= 128)
|
||||
- defaultCiphers << ciph;
|
||||
+
|
||||
|
||||
- if (ciph.usedBits() >= 128)
|
||||
+ if (ciph.usedBits() >= 128 &&
|
||||
+ !ciph.encryptionMethod().toLower().startsWith(QLatin1String("rc4")))
|
||||
+ defaultCiphers << ciph;
|
||||
+ }
|
||||
defaultCiphers << ciph;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,30 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Jun 8 14:15:14 UTC 2016 - hrvoje.senjan@gmail.com
|
||||
|
||||
- Update to 5.6.1
|
||||
* For more details please see:
|
||||
http://blog.qt.io/blog/2016/06/08/qt-5-6-1-released/
|
||||
- Drop upstreamed patches:
|
||||
0005-xcb-Properly-initialize-available-geometry-when-XRan.patch
|
||||
Fix-QtDBus-deadlock-inside-kded-kiod.patch
|
||||
0007-xcb-Deliver-mouse-enter-event-to-window-when-closing.patch
|
||||
0009-Expose-the-number-of-X-screen-through-the-QXcbScreen.patch
|
||||
0001-xcb-XInput2-fixes-enter-leave-event-fixes.patch
|
||||
0002-xcb-Correct-enter-leave-event-handling-when-mouse-bu.patch
|
||||
0015-Use-the-state-of-the-key-event-to-process-it.patch
|
||||
0012-xcb-Merge-_NET_WM_STATE-hints-instead-of-overwriting.patch
|
||||
0004-xcb-Fix-drag-and-drop-between-xcb-screens.patch
|
||||
QtDBus-finish-all-pending-call-with-error-if-disconnected.patch
|
||||
0010-xcb-mark-mouse-events-from-tablet-devices-as-synthes.patch
|
||||
0011-xcb-Initialize-all-xcb_client_message_event_t-member.patch
|
||||
0008-xcb-resourceType-names-must-have-only-small-letters.patch
|
||||
0016-xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch
|
||||
0013-xcb-Fix-interpretation-of-the-size-from-RRCrtcChange.patch
|
||||
0006-xcb-properly-initialize-size-in-millimeters-if-XRand.patch
|
||||
0003-xcb-Fix-not-delivering-focusIn-event-on-hide-show.patch
|
||||
QtDBus-clean-up-signal-hooks-and-object-tree-in-closeConnection.patch
|
||||
0014-xcb-Properly-process-enter-leave-events.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sat Apr 23 18:04:33 UTC 2016 - hrvoje.senjan@gmail.com
|
||||
|
||||
|
@ -26,15 +26,15 @@
|
||||
%endif
|
||||
|
||||
Name: libqt5-qtbase
|
||||
Version: 5.6.0
|
||||
Version: 5.6.1
|
||||
Release: 0
|
||||
Summary: C++ Program Library, Core Components
|
||||
License: GPL-3.0 or SUSE-LGPL-2.1-with-digia-exception-1.1
|
||||
Group: System/Libraries
|
||||
Url: http://qt.digia.com
|
||||
%define base_name libqt5
|
||||
%define real_version 5.6.0
|
||||
%define so_version 5.6.0
|
||||
%define real_version 5.6.1
|
||||
%define so_version 5.6.1
|
||||
%define tar_version qtbase-opensource-src-%{real_version}
|
||||
Source: %{tar_version}.tar.xz
|
||||
# to get mtime of file:
|
||||
@ -53,26 +53,7 @@ Patch5: libqt5-do-not-use-shm-if-display-name-doesnt-look-local.patch
|
||||
Patch6: disable-rc4-ciphers-bnc865241.diff
|
||||
Patch7: tell-the-truth-about-private-api.patch
|
||||
# patches 1000-2000 and above from upstream 5.6 branch #
|
||||
Patch1000: 0001-xcb-XInput2-fixes-enter-leave-event-fixes.patch
|
||||
Patch1001: 0002-xcb-Correct-enter-leave-event-handling-when-mouse-bu.patch
|
||||
Patch1002: 0003-xcb-Fix-not-delivering-focusIn-event-on-hide-show.patch
|
||||
Patch1003: 0004-xcb-Fix-drag-and-drop-between-xcb-screens.patch
|
||||
Patch1004: 0005-xcb-Properly-initialize-available-geometry-when-XRan.patch
|
||||
Patch1005: 0006-xcb-properly-initialize-size-in-millimeters-if-XRand.patch
|
||||
Patch1006: 0007-xcb-Deliver-mouse-enter-event-to-window-when-closing.patch
|
||||
Patch1007: 0008-xcb-resourceType-names-must-have-only-small-letters.patch
|
||||
Patch1008: 0009-Expose-the-number-of-X-screen-through-the-QXcbScreen.patch
|
||||
Patch1009: 0010-xcb-mark-mouse-events-from-tablet-devices-as-synthes.patch
|
||||
Patch1010: 0011-xcb-Initialize-all-xcb_client_message_event_t-member.patch
|
||||
Patch1011: 0012-xcb-Merge-_NET_WM_STATE-hints-instead-of-overwriting.patch
|
||||
Patch1012: 0013-xcb-Fix-interpretation-of-the-size-from-RRCrtcChange.patch
|
||||
Patch1013: 0014-xcb-Properly-process-enter-leave-events.patch
|
||||
# patches 2000-3000 and above from upstream 5.7 branch #
|
||||
Patch3000: Fix-QtDBus-deadlock-inside-kded-kiod.patch
|
||||
Patch3001: QtDBus-clean-up-signal-hooks-and-object-tree-in-closeConnection.patch
|
||||
Patch3002: QtDBus-finish-all-pending-call-with-error-if-disconnected.patch
|
||||
Patch3003: 0015-Use-the-state-of-the-key-event-to-process-it.patch
|
||||
Patch3004: 0016-xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch
|
||||
BuildRequires: alsa-devel
|
||||
BuildRequires: cups-devel
|
||||
BuildRequires: gcc-c++
|
||||
@ -156,25 +137,6 @@ handling.
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch1000 -p1
|
||||
%patch1001 -p1
|
||||
%patch1002 -p1
|
||||
%patch1003 -p1
|
||||
%patch1004 -p1
|
||||
%patch1005 -p1
|
||||
%patch1006 -p1
|
||||
%patch1007 -p1
|
||||
%patch1008 -p1
|
||||
%patch1009 -p1
|
||||
%patch1010 -p1
|
||||
%patch1011 -p1
|
||||
%patch1012 -p1
|
||||
%patch1013 -p1
|
||||
%patch3000 -p1
|
||||
%patch3001 -p1
|
||||
%patch3002 -p1
|
||||
%patch3003 -p1
|
||||
%patch3004 -p1
|
||||
|
||||
# be sure not to use them
|
||||
rm -r src/3rdparty/{libjpeg,freetype,libpng,zlib}
|
||||
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6efa8a5c559e92b2e526d48034e858023d5fd3c39115ac1bfd3bb65834dbd67a
|
||||
size 46757096
|
3
qtbase-opensource-src-5.6.1.tar.xz
Normal file
3
qtbase-opensource-src-5.6.1.tar.xz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d01cc1ee2be9ecdb169be3aea9dc9fc019c1c6d0bb87e0c88bb95b5b3dce7264
|
||||
size 46791688
|
@ -2,13 +2,11 @@ diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
|
||||
index aefd3ae..53a3f60 100644
|
||||
--- a/mkspecs/features/qt_module.prf
|
||||
+++ b/mkspecs/features/qt_module.prf
|
||||
@@ -195,16 +195,18 @@
|
||||
|
||||
!header_module:unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!no_linker_version_script:!static {
|
||||
@@ -196,12 +196,14 @@ android: CONFIG += qt_android_deps no_li
|
||||
verscript = $${TARGET}.version
|
||||
QMAKE_LFLAGS += $${QMAKE_LFLAGS_VERSION_SCRIPT}$$verscript
|
||||
|
||||
+ private_api_headers = $$SYNCQT.PRIVATE_HEADER_FILES $$SYNCQT.QPA_HEADER_FILES
|
||||
+ private_api_headers = $$SYNCQT.PRIVATE_HEADER_FILES $$SYNCQT.QPA_HEADER_FILES
|
||||
+
|
||||
internal_module {
|
||||
- verscript_content = "Qt_$${QT_MAJOR_VERSION}_PRIVATE_API { *; };"
|
||||
@ -22,11 +20,7 @@ index aefd3ae..53a3f60 100644
|
||||
verscript_content += " @FILE:$${_PRO_FILE_PWD_}/$$header@"
|
||||
verscript_content += "};"
|
||||
|
||||
current = Qt_$$QT_MAJOR_VERSION
|
||||
verscript_content += "$$current { *; };"
|
||||
@@ -221,11 +223,11 @@
|
||||
# Add a post-processing step to replace the @FILE:filename@
|
||||
verscript_in = $${verscript}.in
|
||||
@@ -222,7 +224,7 @@ android: CONFIG += qt_android_deps no_li
|
||||
verscriptprocess.name = linker version script ${QMAKE_FILE_BASE}
|
||||
verscriptprocess.input = verscript_in
|
||||
verscriptprocess.CONFIG += no_link target_predeps
|
||||
@ -35,5 +29,3 @@ index aefd3ae..53a3f60 100644
|
||||
verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header
|
||||
verscriptprocess.output = $$verscript
|
||||
verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < ${QMAKE_FILE_IN} > $@
|
||||
silent:verscriptprocess.commands = @echo creating linker version script ${QMAKE_FILE_BASE} && $$verscriptprocess.commands
|
||||
QMAKE_EXTRA_COMPILERS += verscriptprocess
|
||||
|
Loading…
Reference in New Issue
Block a user