summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-10-14 15:45:35 +0200
committerLiang Qi <liang.qi@theqtcompany.com>2015-10-14 15:45:35 +0200
commit4456984da780b14572e1ec0f079a4d349ab299bd (patch)
treef586a281a81c57c91c49e83a5d3ec6c7eece0578 /src/plugins/platforms/xcb
parente824abd987d77efaa085fe1f9fb514d270798d55 (diff)
parent281121697340084f7d385eab530f41916789b94d (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: tests/auto/corelib/io/qfile/tst_qfile.cpp tests/auto/corelib/io/qprocess/tst_qprocess.cpp tests/auto/corelib/tools/qversionnumber/qversionnumber.pro Change-Id: Ia93ce500349d96a2fbf0b4a37b73f088cc505c6e
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp45
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp43
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp11
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp20
9 files changed, 73 insertions, 57 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index c35b019f7e..13d73c7194 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -476,7 +476,7 @@ void QXcbConnection::initializeScreens()
// Push the screens to QApplication
QXcbIntegration *integration = QXcbIntegration::instance();
foreach (QXcbScreen* screen, m_screens) {
- qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ")";
+ qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ')';
integration->screenAdded(screen, screen->isPrimary());
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 6ee32bf600..fb5b941fff 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -376,8 +376,10 @@ public:
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
+ const QList<QXcbVirtualDesktop *> &virtualDesktops() const { return m_virtualDesktops; }
const QList<QXcbScreen *> &screens() const { return m_screens; }
int primaryScreenNumber() const { return m_primaryScreenNumber; }
+ QXcbVirtualDesktop *primaryVirtualDesktop() const { return m_virtualDesktops.value(m_primaryScreenNumber); }
QXcbScreen *primaryScreen() const;
inline xcb_atom_t atom(QXcbAtom::Atom atom) const { return m_allAtoms[atom]; }
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index 0cd9159052..b321ed95dc 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -607,30 +607,33 @@ xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor)
}
#endif
-void QXcbCursor::queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint *pos, int *keybMask)
+void QXcbCursor::queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDesktop, QPoint *pos, int *keybMask)
{
if (pos)
*pos = QPoint();
- xcb_screen_iterator_t it = xcb_setup_roots_iterator(c->setup());
- while (it.rem) {
- xcb_window_t root = it.data->root;
- xcb_query_pointer_cookie_t cookie = xcb_query_pointer(c->xcb_connection(), root);
- xcb_generic_error_t *err = 0;
- xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(c->xcb_connection(), cookie, &err);
- if (!err && reply) {
- if (pos)
- *pos = QPoint(reply->root_x, reply->root_y);
- if (rootWin)
- *rootWin = root;
- if (keybMask)
- *keybMask = reply->mask;
- free(reply);
- return;
+
+ xcb_window_t root = c->primaryVirtualDesktop()->root();
+ xcb_query_pointer_cookie_t cookie = xcb_query_pointer(c->xcb_connection(), root);
+ xcb_generic_error_t *err = 0;
+ xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(c->xcb_connection(), cookie, &err);
+ if (!err && reply) {
+ if (virtualDesktop) {
+ foreach (QXcbVirtualDesktop *vd, c->virtualDesktops()) {
+ if (vd->root() == reply->root) {
+ *virtualDesktop = vd;
+ break;
+ }
+ }
}
- free(err);
+ if (pos)
+ *pos = QPoint(reply->root_x, reply->root_y);
+ if (keybMask)
+ *keybMask = reply->mask;
free(reply);
- xcb_screen_next(&it);
+ return;
}
+ free(err);
+ free(reply);
}
QPoint QXcbCursor::pos() const
@@ -642,9 +645,9 @@ QPoint QXcbCursor::pos() const
void QXcbCursor::setPos(const QPoint &pos)
{
- xcb_window_t root = 0;
- queryPointer(connection(), &root, 0);
- xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, pos.x(), pos.y());
+ QXcbVirtualDesktop *virtualDesktop = Q_NULLPTR;
+ queryPointer(connection(), &virtualDesktop, 0);
+ xcb_warp_pointer(xcb_connection(), XCB_NONE, virtualDesktop->root(), 0, 0, 0, 0, pos.x(), pos.y());
xcb_flush(xcb_connection());
}
diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h
index f4f6e61706..3c6dece1f2 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.h
+++ b/src/plugins/platforms/xcb/qxcbcursor.h
@@ -75,7 +75,7 @@ public:
QPoint pos() const Q_DECL_OVERRIDE;
void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
- static void queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint *pos, int *keybMask = 0);
+ static void queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDesktop, QPoint *pos, int *keybMask = 0);
private:
#ifndef QT_NO_CURSOR
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index de23c59a63..f9c3aa7fed 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -39,6 +39,7 @@
#include "qxcbwindow.h"
#include "qxcbscreen.h"
#include "qwindow.h"
+#include "qxcbcursor.h"
#include <private/qdnd_p.h>
#include <qdebug.h>
#include <qevent.h>
@@ -160,7 +161,7 @@ void QXcbDrag::init()
source_time = XCB_CURRENT_TIME;
target_time = XCB_CURRENT_TIME;
- current_screen = 0;
+ QXcbCursor::queryPointer(connection(), &current_virtual_desktop, 0);
drag_types.clear();
}
@@ -308,38 +309,20 @@ void QXcbDrag::move(const QPoint &globalPos)
if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid())
return;
- const QList<QXcbScreen *> &screens = connection()->screens();
- QXcbScreen *screen = connection()->primaryScreen();
- for (int i = 0; i < screens.size(); ++i) {
- if (screens.at(i)->geometry().contains(globalPos)) {
- screen = screens.at(i);
- break;
- }
- }
+ QXcbVirtualDesktop *virtualDesktop = Q_NULLPTR;
+ QPoint cursorPos;
+ QXcbCursor::queryPointer(connection(), &virtualDesktop, &cursorPos);
+ QXcbScreen *screen = virtualDesktop->screenAt(cursorPos);
+ QPoint deviceIndependentPos = QHighDpiScaling::mapPositionFromNative(globalPos, screen);
- QBasicDrag::moveShapedPixmapWindow(QHighDpiScaling::mapPositionFromNative(globalPos, screen));
-
- if (screen != current_screen) {
- // ### need to recreate the shaped pixmap window?
-// int screen = QCursor::x11Screen();
-// if ((qt_xdnd_current_screen == -1 && screen != X11->defaultScreen) || (screen != qt_xdnd_current_screen)) {
-// // recreate the pixmap on the new screen...
-// delete xdnd_data.deco;
-// QWidget* parent = object->source()->window()->x11Info().screen() == screen
-// ? object->source()->window() : QApplication::desktop()->screen(screen);
-// xdnd_data.deco = new QShapedPixmapWidget(parent);
-// if (!QWidget::mouseGrabber()) {
-// updatePixmap();
-// xdnd_data.deco->grabMouse();
-// }
-// }
-// xdnd_data.deco->move(QCursor::pos() - xdnd_data.deco->pm_hot);
- current_screen = screen;
+ if (virtualDesktop != current_virtual_desktop) {
+ recreateShapedPixmapWindow(static_cast<QPlatformScreen*>(screen)->screen(), deviceIndependentPos);
+ current_virtual_desktop = virtualDesktop;
+ } else {
+ QBasicDrag::moveShapedPixmapWindow(deviceIndependentPos);
}
-
-// qt_xdnd_current_screen = screen;
- xcb_window_t rootwin = current_screen->root();
+ xcb_window_t rootwin = current_virtual_desktop->root();
xcb_translate_coordinates_reply_t *translate =
::translateCoordinates(connection(), rootwin, rootwin, globalPos.x(), globalPos.y());
if (!translate)
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index 9584c04238..c9d257906f 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -133,7 +133,7 @@ private:
// window to send events to (always valid if current_target)
xcb_window_t current_proxy_target;
- QXcbScreen *current_screen;
+ QXcbVirtualDesktop *current_virtual_desktop;
// 10 minute timer used to discard old XdndDrop transactions
enum { XdndDropTransactionTimeout = 600000 };
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 82cd1b86c9..da4db5edcb 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -61,6 +61,15 @@ QXcbVirtualDesktop::~QXcbVirtualDesktop()
delete m_xSettings;
}
+QXcbScreen *QXcbVirtualDesktop::screenAt(const QPoint &pos) const
+{
+ foreach (QXcbScreen *screen, connection()->screens()) {
+ if (screen->virtualDesktop() == this && screen->nativeGeometry().contains(pos))
+ return screen;
+ }
+ return Q_NULLPTR;
+}
+
QXcbXSettings *QXcbVirtualDesktop::xSettings() const
{
if (!m_xSettings) {
@@ -724,7 +733,7 @@ QDebug operator<<(QDebug debug, const QXcbScreen *screen)
formatSizeF(debug, screen->physicalSize());
// TODO 5.6 if (debug.verbosity() > 2) {
debug << ", screenNumber=" << screen->screenNumber();
- debug << ", virtualSize=" << screen->virtualSize().width() << "x" << screen->virtualSize().height() << " (";
+ debug << ", virtualSize=" << screen->virtualSize().width() << 'x' << screen->virtualSize().height() << " (";
formatSizeF(debug, screen->virtualSize());
debug << "), nativeGeometry=";
formatRect(debug, screen->nativeGeometry());
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index cbb6307d6e..d8d63608e7 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -64,6 +64,8 @@ public:
int number() const { return m_number; }
QSize size() const { return QSize(m_screen->width_in_pixels, m_screen->height_in_pixels); }
QSize physicalSize() const { return QSize(m_screen->width_in_millimeters, m_screen->height_in_millimeters); }
+ xcb_window_t root() const { return m_screen->root; }
+ QXcbScreen *screenAt(const QPoint &pos) const;
QXcbXSettings *xSettings() const;
@@ -104,6 +106,7 @@ public:
void setVirtualSiblings(QList<QPlatformScreen *> sl) { m_siblings = sl; }
void removeVirtualSibling(QPlatformScreen *s) { m_siblings.removeOne(s); }
void addVirtualSibling(QPlatformScreen *s) { ((QXcbScreen *) s)->isPrimary() ? m_siblings.prepend(s) : m_siblings.append(s); }
+ QXcbVirtualDesktop *virtualDesktop() const { return m_virtualDesktop; }
void setPrimary(bool primary) { m_primary = primary; }
bool isPrimary() const { return m_primary; }
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index d751c6d48a..e7f5bbf0e9 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -775,6 +775,13 @@ void QXcbWindow::setVisible(bool visible)
hide();
}
+static inline bool testShowWithoutActivating(const QWindow *window)
+{
+ // QWidget-attribute Qt::WA_ShowWithoutActivating.
+ const QVariant showWithoutActivating = window->property("_q_showWithoutActivating");
+ return showWithoutActivating.isValid() && showWithoutActivating.toBool();
+}
+
void QXcbWindow::show()
{
if (window()->isTopLevel()) {
@@ -822,7 +829,9 @@ void QXcbWindow::show()
updateNetWmStateBeforeMap();
}
- if (connection()->time() != XCB_TIME_CURRENT_TIME)
+ if (testShowWithoutActivating(window()))
+ updateNetWmUserTime(0);
+ else if (connection()->time() != XCB_TIME_CURRENT_TIME)
updateNetWmUserTime(connection()->time());
if (window()->objectName() == QLatin1String("QSystemTrayIconSysWindow"))
@@ -1112,6 +1121,9 @@ void QXcbWindow::setMotifWindowFlags(Qt::WindowFlags flags)
mwmhints.flags |= MWM_HINTS_DECORATIONS;
bool customize = flags & Qt::CustomizeWindowHint;
+ if (type == Qt::Window && !customize)
+ flags |= Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint;
+
if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
mwmhints.decorations |= MWM_DECOR_BORDER;
mwmhints.decorations |= MWM_DECOR_RESIZEH;
@@ -1326,7 +1338,11 @@ void QXcbWindow::updateNetWmStateBeforeMap()
void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
{
xcb_window_t wid = m_window;
- connection()->setNetWmUserTime(timestamp);
+ // If timestamp == 0, then it means that the window should not be
+ // initially activated. Don't update global user time for this
+ // special case.
+ if (timestamp != 0)
+ connection()->setNetWmUserTime(timestamp);
const bool isSupportedByWM = connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW));
if (m_netWmUserTimeWindow || isSupportedByWM) {