summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-04-22 09:04:29 +0200
committerLiang Qi <liang.qi@theqtcompany.com>2015-04-22 09:25:54 +0200
commitaed5a7168354c6ae47687d20b4bd3f0adcc14f8e (patch)
treed2060479a7c12fdba8c1955e5d363754feffabb8 /src/plugins/platforms/xcb
parentd3d10cf23d61f4a011f1a7e9abdee1a92717e80f (diff)
parent628fa13ea4d6ff0e2e2ee76c9adfc78676de3c59 (diff)
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts: src/corelib/statemachine/qstatemachine.cpp src/corelib/statemachine/qstatemachine_p.h src/gui/painting/qdrawhelper.cpp src/plugins/platforms/xcb/qxcbnativeinterface.cpp src/plugins/platforms/xcb/qxcbwindow.cpp src/plugins/platforms/xcb/qxcbwindow.h src/testlib/qtestblacklist.cpp src/tools/qdoc/node.cpp src/tools/qdoc/node.h tests/auto/gui/painting/qcolor/tst_qcolor.cpp Change-Id: I6c78b7b162001712d5774293f501b06b4ff32684
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp74
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h15
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp9
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp11
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp95
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h41
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp226
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h12
-rw-r--r--src/plugins/platforms/xcb/qxcbwmsupport.cpp12
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.cpp10
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.h4
16 files changed, 365 insertions, 157 deletions
diff --git a/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri b/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri
index 8c60268e0d..e859865687 100644
--- a/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri
+++ b/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri
@@ -29,8 +29,8 @@ CONFIG += qpa/genericunixfontdatabase
contains(QT_CONFIG, xcb-qt) {
DEFINES += XCB_USE_RENDER
- XCB_DIR = ../../../3rdparty/xcb
- INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude
+ XCB_DIR = $$clean_path($$PWD/../../../../3rdparty/xcb)
+ INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude
LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static
} else {
LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 706b9c8e48..8500aa1ffa 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -66,6 +66,7 @@
#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>
#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
#endif
#if defined(XCB_USE_XINPUT2)
@@ -83,6 +84,12 @@ Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input")
Q_LOGGING_CATEGORY(lcQpaXInputDevices, "qt.qpa.input.devices")
Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen")
+// this event type was added in libxcb 1.10,
+// but we support also older version
+#ifndef XCB_GE_GENERIC
+#define XCB_GE_GENERIC 35
+#endif
+
#ifdef XCB_USE_XLIB
static const char * const xcbConnectionErrors[] = {
"No error", /* Error 0 */
@@ -137,7 +144,7 @@ QXcbScreen* QXcbConnection::findScreenForOutput(xcb_window_t rootWindow, xcb_ran
return 0;
}
-QXcbScreen* QXcbConnection::createScreen(int screenNumber, xcb_screen_t* xcbScreen,
+QXcbScreen* QXcbConnection::createScreen(QXcbVirtualDesktop* virtualDesktop,
xcb_randr_output_t outputId,
xcb_randr_get_output_info_reply_t *output)
{
@@ -150,10 +157,10 @@ QXcbScreen* QXcbConnection::createScreen(int screenNumber, xcb_screen_t* xcbScre
int dotPos = displayName.lastIndexOf('.');
if (dotPos != -1)
displayName.truncate(dotPos);
- name = QString::fromLocal8Bit(displayName) + QLatin1Char('.') + QString::number(screenNumber);
+ name = QString::fromLocal8Bit(displayName) + QLatin1Char('.') + QString::number(virtualDesktop->number());
}
- return new QXcbScreen(this, xcbScreen, outputId, output, name, screenNumber);
+ return new QXcbScreen(this, virtualDesktop, outputId, output, name);
}
bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output)
@@ -173,15 +180,11 @@ bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_out
return isPrimary;
}
-xcb_screen_t* QXcbConnection::xcbScreenForRootWindow(xcb_window_t rootWindow, int *xcbScreenNumber)
+QXcbVirtualDesktop* QXcbConnection::virtualDesktopForRootWindow(xcb_window_t rootWindow)
{
- xcb_screen_iterator_t xcbScreenIter = xcb_setup_roots_iterator(m_setup);
- for (; xcbScreenIter.rem; xcb_screen_next(&xcbScreenIter)) {
- if (xcbScreenIter.data->root == rootWindow) {
- if (xcbScreenNumber)
- *xcbScreenNumber = xcb_setup_roots_length(m_setup) - xcbScreenIter.rem;
- return xcbScreenIter.data;
- }
+ foreach (QXcbVirtualDesktop *virtualDesktop, m_virtualDesktops) {
+ if (virtualDesktop->screen()->root == rootWindow)
+ return virtualDesktop;
}
return 0;
@@ -194,8 +197,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
{
if (event->subCode == XCB_RANDR_NOTIFY_CRTC_CHANGE) {
xcb_randr_crtc_change_t crtc = event->u.cc;
- xcb_screen_t *xcbScreen = xcbScreenForRootWindow(crtc.window);
- if (!xcbScreen)
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(crtc.window);
+ if (!virtualDesktop)
// Not for us
return;
@@ -212,9 +215,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
} else if (event->subCode == XCB_RANDR_NOTIFY_OUTPUT_CHANGE) {
xcb_randr_output_change_t output = event->u.oc;
- int xcbScreenNumber = 0;
- xcb_screen_t *xcbScreen = xcbScreenForRootWindow(output.window, &xcbScreenNumber);
- if (!xcbScreen)
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(output.window);
+ if (!virtualDesktop)
// Not for us
return;
@@ -242,7 +244,7 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo(
xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL));
- screen = createScreen(xcbScreenNumber, xcbScreen, output.output, outputInfo.data());
+ screen = createScreen(virtualDesktop, output.output, outputInfo.data());
qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled";
screen->setPrimary(checkOutputIsPrimary(output.window, output.output));
@@ -293,14 +295,15 @@ void QXcbConnection::initializeScreens()
xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);
int xcbScreenNumber = 0; // screen number in the xcb sense
QXcbScreen* primaryScreen = Q_NULLPTR;
- xcb_screen_t *xcbScreen = Q_NULLPTR;
bool hasOutputs = false;
while (it.rem) {
// Each "screen" in xcb terminology is a virtual desktop,
// potentially a collection of separate juxtaposed monitors.
// But we want a separate QScreen for each output (e.g. DVI-I-1, VGA-1, etc.)
// which will become virtual siblings.
- xcbScreen = it.data;
+ xcb_screen_t *xcbScreen = it.data;
+ QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber);
+ m_virtualDesktops.append(virtualDesktop);
QList<QPlatformScreen *> siblings;
int outputCount = 0;
int connectedOutputCount = 0;
@@ -370,7 +373,7 @@ void QXcbConnection::initializeScreens()
continue;
}
- QXcbScreen *screen = createScreen(xcbScreenNumber, xcbScreen, outputs[i], output.data());
+ QXcbScreen *screen = createScreen(virtualDesktop, outputs[i], output.data());
siblings << screen;
++connectedOutputCount;
hasOutputs = true;
@@ -405,8 +408,9 @@ void QXcbConnection::initializeScreens()
// but the dimensions are known anyway, and we don't already have any lingering
// (possibly disconnected) screens, then showing windows should be possible,
// so create one screen. (QTBUG-31389)
- if (xcbScreen && !hasOutputs && xcbScreen->width_in_pixels > 0 && xcbScreen->height_in_pixels > 0 && m_screens.isEmpty()) {
- QXcbScreen *screen = createScreen(0, xcbScreen, 0, Q_NULLPTR);
+ QXcbVirtualDesktop *virtualDesktop = m_virtualDesktops.value(0);
+ if (virtualDesktop && !hasOutputs && !virtualDesktop->size().isEmpty() && m_screens.isEmpty()) {
+ QXcbScreen *screen = createScreen(virtualDesktop, 0, Q_NULLPTR);
screen->setVirtualSiblings(QList<QPlatformScreen *>() << screen);
m_screens << screen;
primaryScreen = screen;
@@ -434,9 +438,10 @@ void QXcbConnection::initializeScreens()
qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name();
}
-QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName)
+QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName)
: m_connection(0)
, m_canGrabServer(canGrabServer)
+ , m_defaultVisualId(defaultVisualId)
, m_primaryScreenNumber(0)
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
, m_nativeInterface(nativeInterface)
@@ -577,6 +582,9 @@ QXcbConnection::~QXcbConnection()
while (!m_screens.isEmpty())
integration->destroyScreen(m_screens.takeLast());
+ while (!m_virtualDesktops.isEmpty())
+ delete m_virtualDesktops.takeLast();
+
delete m_glIntegration;
#ifdef XCB_USE_XLIB
@@ -666,6 +674,7 @@ void printXcbEvent(const char *message, xcb_generic_event_t *event)
PRINT_XCB_EVENT(XCB_KEYMAP_NOTIFY);
PRINT_XCB_EVENT(XCB_EXPOSE);
PRINT_XCB_EVENT(XCB_GRAPHICS_EXPOSURE);
+ PRINT_XCB_EVENT(XCB_NO_EXPOSURE);
PRINT_XCB_EVENT(XCB_VISIBILITY_NOTIFY);
PRINT_XCB_EVENT(XCB_CREATE_NOTIFY);
PRINT_XCB_EVENT(XCB_DESTROY_NOTIFY);
@@ -685,6 +694,8 @@ void printXcbEvent(const char *message, xcb_generic_event_t *event)
PRINT_XCB_EVENT(XCB_SELECTION_NOTIFY);
PRINT_XCB_EVENT(XCB_COLORMAP_NOTIFY);
PRINT_XCB_EVENT(XCB_CLIENT_MESSAGE);
+ PRINT_XCB_EVENT(XCB_MAPPING_NOTIFY);
+ PRINT_XCB_EVENT(XCB_GE_GENERIC);
default:
qDebug("QXcbConnection: %s: unknown event - response_type: %d - sequence: %d", message, int(event->response_type & ~0x80), int(event->sequence));
}
@@ -1080,7 +1091,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
break;
#if defined(XCB_USE_XINPUT2)
- case GenericEvent:
+ case XCB_GE_GENERIC:
if (m_xi2Enabled)
xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
break;
@@ -1342,6 +1353,21 @@ void *QXcbConnection::xlib_display() const
{
return m_xlib_display;
}
+
+void *QXcbConnection::createVisualInfoForDefaultVisualId() const
+{
+ if (m_defaultVisualId == UINT_MAX)
+ return 0;
+ XVisualInfo info;
+ memset(&info, 0, sizeof info);
+ info.visualid = m_defaultVisualId;
+
+ int count = 0;
+ XVisualInfo *retVisual = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &info, &count);
+ Q_ASSERT(count < 2);
+ return retVisual;
+}
+
#endif
void QXcbConnection::processXcbEvents()
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 1190e7c2b0..466492ce42 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -80,6 +80,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaXInput)
Q_DECLARE_LOGGING_CATEGORY(lcQpaXInputDevices)
Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen)
+class QXcbVirtualDesktop;
class QXcbScreen;
class QXcbWindow;
class QXcbDrag;
@@ -369,7 +370,7 @@ class Q_XCB_EXPORT QXcbConnection : public QObject
{
Q_OBJECT
public:
- QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName = 0);
+ QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName = 0);
~QXcbConnection();
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
@@ -399,8 +400,13 @@ public:
QXcbWMSupport *wmSupport() const { return m_wmSupport.data(); }
xcb_window_t rootWindow();
+
+ bool hasDefaultVisualId() const { return m_defaultVisualId != UINT_MAX; }
+ xcb_visualid_t defaultVisualId() const { return m_defaultVisualId; }
+
#ifdef XCB_USE_XLIB
void *xlib_display() const;
+ void *createVisualInfoForDefaultVisualId() const;
#endif
#if defined(XCB_USE_XINPUT2)
@@ -497,12 +503,12 @@ private:
void initializeXShape();
void initializeXKB();
void handleClientMessageEvent(const xcb_client_message_event_t *event);
- QXcbScreen* createScreen(int screenNumber, xcb_screen_t* xcbScreen,
+ QXcbScreen* createScreen(QXcbVirtualDesktop *virtualDesktop,
xcb_randr_output_t outputId = XCB_NONE,
xcb_randr_get_output_info_reply_t *output = 0);
QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc);
QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output);
- xcb_screen_t* xcbScreenForRootWindow(xcb_window_t rootWindow, int *xcbScreenNumber = 0);
+ QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow);
bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output);
void initializeScreens();
void updateScreens(const xcb_randr_notify_event_t *event);
@@ -566,7 +572,9 @@ private:
xcb_connection_t *m_connection;
const xcb_setup_t *m_setup;
bool m_canGrabServer;
+ xcb_visualid_t m_defaultVisualId;
+ QList<QXcbVirtualDesktop *> m_virtualDesktops;
QList<QXcbScreen *> m_screens;
int m_primaryScreenNumber;
@@ -633,6 +641,7 @@ private:
};
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
+#define CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(object) ((XVisualInfo *)(object->connection()->createVisualInfoForDefaultVisualId()))
template<typename T>
xcb_generic_event_t *QXcbConnection::checkEvent(T &checker)
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index 8dd27ec9c5..e51ab85e30 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -502,7 +502,7 @@ bool updateCursorTheme(void *dpy, const QByteArray &theme) {
return setTheme;
}
- void QXcbCursor::cursorThemePropertyChanged(QXcbScreen *screen, const QByteArray &name, const QVariant &property, void *handle)
+ void QXcbCursor::cursorThemePropertyChanged(QXcbVirtualDesktop *screen, const QByteArray &name, const QVariant &property, void *handle)
{
Q_UNUSED(screen);
Q_UNUSED(name);
@@ -633,18 +633,17 @@ void QXcbCursor::queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint *
QPoint QXcbCursor::pos() const
{
- const int dpr = int(m_screen->devicePixelRatio());
QPoint p;
queryPointer(connection(), 0, &p);
- return p / dpr;
+ return m_screen->mapFromNative(p);
}
void QXcbCursor::setPos(const QPoint &pos)
{
- const int dpr = int(m_screen->devicePixelRatio());
+ const QPoint xPos = m_screen->mapToNative(pos);
xcb_window_t root = 0;
queryPointer(connection(), &root, 0);
- xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, pos.x()*dpr, pos.y()*dpr);
+ xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, xPos.x(), xPos.y());
xcb_flush(xcb_connection());
}
diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h
index 1280c7e042..7e5cdc6870 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.h
+++ b/src/plugins/platforms/xcb/qxcbcursor.h
@@ -91,7 +91,7 @@ private:
CursorHash m_cursorHash;
#endif
#ifdef XCB_USE_XLIB
- static void cursorThemePropertyChanged(QXcbScreen *screen,
+ static void cursorThemePropertyChanged(QXcbVirtualDesktop *screen,
const QByteArray &name,
const QVariant &property,
void *handle);
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 2547e537a7..fc06f1a7b0 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -116,6 +116,7 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
: m_services(new QGenericUnixServices)
, m_instanceName(0)
, m_canGrab(true)
+ , m_defaultVisualId(UINT_MAX)
{
m_instance = this;
@@ -143,6 +144,12 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
noGrabArg = true;
else if (arg == "-dograb")
doGrabArg = true;
+ else if (arg == "-visual" && i < argc - 1) {
+ bool ok = false;
+ m_defaultVisualId = QByteArray(argv[++i]).toUInt(&ok, 0);
+ if (!ok)
+ m_defaultVisualId = UINT_MAX;
+ }
else
argv[j++] = argv[i];
}
@@ -167,12 +174,12 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
if (canNotGrabEnv)
m_canGrab = false;
- m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, displayName);
+ m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName);
for (int i = 0; i < parameters.size() - 1; i += 2) {
qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1);
- m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, display.toLatin1().constData());
+ m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData());
}
m_fontDatabase.reset(new QGenericUnixFontDatabase());
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 4212d53810..4e2a3c2bbd 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -39,6 +39,8 @@
#include "qxcbexport.h"
+#include <xcb/xcb.h>
+
QT_BEGIN_NAMESPACE
class QXcbConnection;
@@ -123,6 +125,7 @@ private:
mutable QByteArray m_wmClass;
const char *m_instanceName;
bool m_canGrab;
+ xcb_visualid_t m_defaultVisualId;
static QXcbIntegration *m_instance;
};
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 6c80c1b30e..5a7c2cef83 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -437,6 +437,7 @@ static const unsigned int KeyTbl[] = {
XF86XK_AudioPrev, Qt::Key_MediaPrevious,
XF86XK_AudioNext, Qt::Key_MediaNext,
XF86XK_AudioRecord, Qt::Key_MediaRecord,
+ XF86XK_AudioPause, Qt::Key_MediaPause,
XF86XK_Mail, Qt::Key_LaunchMail,
XF86XK_MyComputer, Qt::Key_Launch0, // ### Qt 6: remap properly
XF86XK_Calculator, Qt::Key_Launch1,
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 75ffaa37bb..1629f3013c 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -361,6 +361,9 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio
if (function == QXcbIntegrationFunctions::xEmbedSystemTrayVisualHasAlphaChannelIdentifier())
return QFunctionPointer(QXcbIntegrationFunctions::XEmbedSystemTrayVisualHasAlphaChannel(QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel));
+ if (function == QXcbWindowFunctions::visualIdIdentifier()) {
+ return QFunctionPointer(QXcbWindowFunctions::VisualId(QXcbWindow::visualIdStatic));
+ }
return Q_NULLPTR;
}
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 383adf9734..a0d6d88d11 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -47,11 +47,33 @@
QT_BEGIN_NAMESPACE
-QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
+QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t *screen, int number)
+ : QXcbObject(connection)
+ , m_screen(screen)
+ , m_number(number)
+ , m_xSettings(Q_NULLPTR)
+{
+}
+
+QXcbVirtualDesktop::~QXcbVirtualDesktop()
+{
+ delete m_xSettings;
+}
+
+QXcbXSettings *QXcbVirtualDesktop::xSettings() const
+{
+ if (!m_xSettings) {
+ QXcbVirtualDesktop *self = const_cast<QXcbVirtualDesktop *>(this);
+ self->m_xSettings = new QXcbXSettings(self);
+ }
+ return m_xSettings;
+}
+
+QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop,
xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output,
- QString outputName, int number)
+ QString outputName)
: QXcbObject(connection)
- , m_screen(scr)
+ , m_virtualDesktop(virtualDesktop)
, m_output(outputId)
, m_crtc(output ? output->crtc : 0)
, m_mode(XCB_NONE)
@@ -59,10 +81,9 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
, m_rotation(XCB_RANDR_ROTATION_ROTATE_0)
, m_outputName(outputName)
, m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize())
- , m_virtualSize(scr->width_in_pixels, scr->height_in_pixels)
- , m_virtualSizeMillimeters(scr->width_in_millimeters, scr->height_in_millimeters)
+ , m_virtualSize(virtualDesktop->size())
+ , m_virtualSizeMillimeters(virtualDesktop->physicalSize())
, m_orientation(Qt::PrimaryOrientation)
- , m_number(number)
, m_refreshRate(60)
, m_forcedDpi(-1)
, m_devicePixelRatio(1)
@@ -70,7 +91,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
, m_noFontHinting(false)
, m_subpixelType(QFontEngine::SubpixelAntialiasingType(-1))
, m_antialiasingEnabled(-1)
- , m_xSettings(0)
{
if (connection->hasXRandr()) {
xcb_randr_select_input(xcb_connection(), screen()->root, true);
@@ -215,7 +235,7 @@ QXcbScreen::~QXcbScreen()
QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
{
- xcb_window_t root = m_screen->root;
+ xcb_window_t root = screen()->root;
int dpr = int(devicePixelRatio());
int x = p.x() / dpr;
@@ -253,6 +273,31 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
return 0;
}
+
+QPoint QXcbScreen::mapToNative(const QPoint &pos) const
+{
+ const int dpr = int(devicePixelRatio());
+ return (pos - m_geometry.topLeft()) * dpr + m_nativeGeometry.topLeft();
+}
+
+QPoint QXcbScreen::mapFromNative(const QPoint &pos) const
+{
+ const int dpr = int(devicePixelRatio());
+ return (pos - m_nativeGeometry.topLeft()) / dpr + m_geometry.topLeft();
+}
+
+QRect QXcbScreen::mapToNative(const QRect &rect) const
+{
+ const int dpr = int(devicePixelRatio());
+ return QRect(mapToNative(rect.topLeft()), rect.size() * dpr);
+}
+
+QRect QXcbScreen::mapFromNative(const QRect &rect) const
+{
+ const int dpr = int(devicePixelRatio());
+ return QRect(mapFromNative(rect.topLeft()), rect.size() / dpr);
+}
+
void QXcbScreen::windowShown(QXcbWindow *window)
{
// Freedesktop.org Startup Notification
@@ -310,19 +355,16 @@ QImage::Format QXcbScreen::format() const
QDpi QXcbScreen::logicalDpi() const
{
- int dpr = int(devicePixelRatio());
-
- if (m_forcedDpi > 0)
- return QDpi(m_forcedDpi/dpr, m_forcedDpi/dpr);
+ static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI");
+ if (overrideDpi)
+ return QDpi(overrideDpi, overrideDpi);
- static const bool auto_dpr = qgetenv("QT_DEVICE_PIXEL_RATIO").toLower() == "auto";
- if (auto_dpr) {
- return QDpi(Q_MM_PER_INCH * m_geometry.width() / m_sizeMillimeters.width(),
- Q_MM_PER_INCH * m_geometry.height() / m_sizeMillimeters.height());
- } else {
- return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width() / dpr,
- Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height() / dpr);
+ if (m_forcedDpi > 0) {
+ int primaryDpr = int(connection()->screens().at(0)->devicePixelRatio());
+ return QDpi(m_forcedDpi/primaryDpr, m_forcedDpi/primaryDpr);
}
+ return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(),
+ Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height());
}
@@ -426,6 +468,9 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan
void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
{
+ if (!connection()->hasXRandr())
+ return;
+
xcb_randr_get_crtc_info_cookie_t crtcCookie =
xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, timestamp);
xcb_randr_get_crtc_info_reply_t *crtc =
@@ -482,9 +527,9 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation)
qreal dpi = xGeometry.width() / physicalSize().width() * qreal(25.4);
m_devicePixelRatio = qRound(dpi/96);
const int dpr = int(devicePixelRatio()); // we may override m_devicePixelRatio
- m_geometry = QRect(xGeometry.topLeft()/dpr, xGeometry.size()/dpr);
+ m_geometry = QRect(xGeometry.topLeft(), xGeometry.size()/dpr);
m_nativeGeometry = QRect(xGeometry.topLeft(), xGeometry.size());
- m_availableGeometry = QRect(xAvailableGeometry.topLeft()/dpr, xAvailableGeometry.size()/dpr);
+ m_availableGeometry = QRect(mapFromNative(xAvailableGeometry.topLeft()), xAvailableGeometry.size()/dpr);
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);
}
@@ -499,7 +544,7 @@ void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode)
// we can safely use get_screen_resources_current here, because in order to
// get here, we must have called get_screen_resources before
xcb_randr_get_screen_resources_current_cookie_t resourcesCookie =
- xcb_randr_get_screen_resources_current_unchecked(xcb_connection(), m_screen->root);
+ xcb_randr_get_screen_resources_current_unchecked(xcb_connection(), screen()->root);
xcb_randr_get_screen_resources_current_reply_t *resources =
xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, NULL);
if (resources) {
@@ -710,11 +755,7 @@ void QXcbScreen::readXResources()
QXcbXSettings *QXcbScreen::xSettings() const
{
- if (!m_xSettings) {
- QXcbScreen *self = const_cast<QXcbScreen *>(this);
- self->m_xSettings = new QXcbXSettings(self);
- }
- return m_xSettings;
+ return m_virtualDesktop->xSettings();
}
static inline void formatRect(QDebug &debug, const QRect r)
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index 3f228465f2..a29efc1e79 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -54,12 +54,32 @@ class QXcbXSettings;
class QDebug;
#endif
+class QXcbVirtualDesktop : public QXcbObject
+{
+public:
+ QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t *screen, int number);
+ ~QXcbVirtualDesktop();
+
+ xcb_screen_t *screen() const { return m_screen; }
+ 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); }
+
+ QXcbXSettings *xSettings() const;
+
+private:
+ xcb_screen_t *m_screen;
+ int m_number;
+
+ QXcbXSettings *m_xSettings;
+};
+
class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen
{
public:
- QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen,
+ QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop,
xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output,
- QString outputName, int number);
+ QString outputName);
~QXcbScreen();
QPixmap grabWindow(WId window, int x, int y, int width, int height) const Q_DECL_OVERRIDE;
@@ -69,7 +89,7 @@ public:
QRect geometry() const Q_DECL_OVERRIDE { return m_geometry; }
QRect nativeGeometry() const { return m_nativeGeometry; }
QRect availableGeometry() const Q_DECL_OVERRIDE {return m_availableGeometry;}
- int depth() const Q_DECL_OVERRIDE { return m_screen->root_depth; }
+ int depth() const Q_DECL_OVERRIDE { return screen()->root_depth; }
QImage::Format format() const Q_DECL_OVERRIDE;
QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_sizeMillimeters; }
QSize virtualSize() const { return m_virtualSize; }
@@ -87,10 +107,10 @@ public:
void setPrimary(bool primary) { m_primary = primary; }
bool isPrimary() const { return m_primary; }
- int screenNumber() const { return m_number; }
+ int screenNumber() const { return m_virtualDesktop->number(); }
- xcb_screen_t *screen() const { return m_screen; }
- xcb_window_t root() const { return m_screen->root; }
+ xcb_screen_t *screen() const { return m_virtualDesktop->screen(); }
+ xcb_window_t root() const { return screen()->root; }
xcb_randr_output_t output() const { return m_output; }
xcb_randr_crtc_t crtc() const { return m_crtc; }
xcb_randr_mode_t mode() const { return m_mode; }
@@ -120,13 +140,18 @@ public:
QXcbXSettings *xSettings() const;
+ QPoint mapToNative(const QPoint &pos) const;
+ QPoint mapFromNative(const QPoint &pos) const;
+ QRect mapToNative(const QRect &rect) const;
+ QRect mapFromNative(const QRect &rect) const;
+
private:
static bool xResource(const QByteArray &identifier,
const QByteArray &expectedIdentifier,
QByteArray &stringValue);
void sendStartupMessage(const QByteArray &message) const;
- xcb_screen_t *m_screen;
+ QXcbVirtualDesktop *m_virtualDesktop;
xcb_randr_output_t m_output;
xcb_randr_crtc_t m_crtc;
xcb_randr_mode_t m_mode;
@@ -143,7 +168,6 @@ private:
QSizeF m_virtualSizeMillimeters;
QList<QPlatformScreen *> m_siblings;
Qt::ScreenOrientation m_orientation;
- int m_number;
QString m_windowManagerName;
bool m_syncRequestSupported;
xcb_window_t m_clientLeader;
@@ -157,7 +181,6 @@ private:
bool m_noFontHinting;
QFontEngine::SubpixelAntialiasingType m_subpixelType;
int m_antialiasingEnabled;
- QXcbXSettings *m_xSettings;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index ceb95a1515..076cc1aa80 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -139,7 +139,7 @@ enum QX11EmbedMessageType {
const quint32 XEMBED_VERSION = 0;
-static inline QRect mapToNative(const QRect &qtRect, int dpr)
+static inline QRect mapLocalGeometryToNative(const QRect &qtRect, int dpr)
{
return QRect(qtRect.x() * dpr, qtRect.y() * dpr, qtRect.width() * dpr, qtRect.height() * dpr);
}
@@ -167,11 +167,45 @@ static inline QRect mapExposeFromNative(const QRect &xRect, int dpr)
return QRect(dpr_floor(xRect.topLeft(), dpr), dpr_ceil(xRect.bottomRight(), dpr));
}
-static inline QRect mapGeometryFromNative(const QRect &xRect, int dpr)
+static inline QRect mapLocalGeometryFromNative(const QRect &xRect, int dpr)
{
return QRect(xRect.topLeft() / dpr, dpr_ceil(xRect.size(), dpr));
}
+QXcbScreen *QXcbWindow::parentScreen()
+{
+ return parent() ? static_cast<QXcbWindow*>(parent())->parentScreen() : m_xcbScreen;
+}
+
+QPoint QXcbWindow::mapToNative(const QPoint &pos, const QXcbScreen *screen) const
+{
+ if (parent())
+ return pos * int(screen->devicePixelRatio());
+ else
+ return screen->mapToNative(pos);
+}
+QPoint QXcbWindow::mapFromNative(const QPoint &pos, const QXcbScreen *screen) const
+{
+ if (parent())
+ return pos / int(screen->devicePixelRatio());
+ else
+ return screen->mapFromNative(pos);
+}
+QRect QXcbWindow::mapToNative(const QRect &rect, const QXcbScreen *screen) const
+{
+ if (parent())
+ return mapLocalGeometryToNative(rect, int(screen->devicePixelRatio()));
+ else
+ return screen->mapToNative(rect);
+}
+QRect QXcbWindow::mapFromNative(const QRect &rect, const QXcbScreen *screen) const
+{
+ if (parent())
+ return mapLocalGeometryFromNative(rect, int(screen->devicePixelRatio()));
+ else
+ return screen->mapFromNative(rect);
+}
+
// Returns \c true if we should set WM_TRANSIENT_FOR on \a w
static inline bool isTransient(const QWindow *w)
{
@@ -292,6 +326,7 @@ static const char *wm_window_type_property_id = "_q_xcb_wm_window_type";
QXcbWindow::QXcbWindow(QWindow *window)
: QPlatformWindow(window)
, m_window(0)
+ , m_xcbScreen(0)
, m_syncCounter(0)
, m_gravity(XCB_GRAVITY_STATIC)
, m_mapped(false)
@@ -345,13 +380,25 @@ void QXcbWindow::create()
Qt::WindowType type = window()->type();
- QXcbScreen *platformScreen = xcbScreen();
+ QXcbScreen *currentScreen = xcbScreen();
+ QRect rect = window()->geometry();
+ QXcbScreen *platformScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect));
+ m_xcbScreen = platformScreen;
if (type == Qt::Desktop) {
m_window = platformScreen->root();
m_depth = platformScreen->screen()->root_depth;
m_visualId = platformScreen->screen()->root_visual;
- const xcb_visualtype_t *visual = platformScreen->visualForId(m_visualId);
+ const xcb_visualtype_t *visual = 0;
+ if (connection()->hasDefaultVisualId()) {
+ visual = platformScreen->visualForId(connection()->defaultVisualId());
+ if (visual)
+ m_visualId = connection()->defaultVisualId();
+ if (!visual)
+ qWarning() << "Could not use default visual id. Falling back to root_visual for screen.";
+ }
+ if (!visual)
+ visual = platformScreen->visualForId(m_visualId);
m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
connection()->addWindowEventListener(m_window, this);
return;
@@ -372,13 +419,10 @@ void QXcbWindow::create()
// Parameters to XCreateWindow() are frame corner + inner size.
// This fits in case position policy is frame inclusive. There is
// currently no way to implement it for frame-exclusive geometries.
- QRect rect = window()->geometry();
QPlatformWindow::setGeometry(rect);
- QXcbScreen *currentScreen = xcbScreen();
- QPlatformScreen *newScreen = screenForGeometry(rect);
- if (newScreen != currentScreen)
- QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
+ if (platformScreen != currentScreen)
+ QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen());
const int dpr = int(devicePixelRatio());
@@ -408,7 +452,12 @@ void QXcbWindow::create()
#ifdef XCB_USE_XLIB
if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
- XVisualInfo *visualInfo = static_cast<XVisualInfo *>(createVisual());
+ XVisualInfo *visualInfo = Q_NULLPTR;
+ if (connection()->hasDefaultVisualId())
+ visualInfo = CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(this);
+ if (!visualInfo)
+ visualInfo = static_cast<XVisualInfo *>(createVisual());
+
if (!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface)
qFatal("Could not initialize OpenGL");
@@ -429,7 +478,7 @@ void QXcbWindow::create()
m_visualId = visualInfo->visualid;
- const QRect xRect = mapToNative(rect, dpr);
+ const QRect xRect = mapToNative(rect, platformScreen);
m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, xRect.x(), xRect.y(), xRect.width(), xRect.height(),
0, visualInfo->depth, InputOutput, visualInfo->visual,
@@ -443,45 +492,60 @@ void QXcbWindow::create()
if (!m_window)
{
m_window = xcb_generate_id(xcb_connection());
- m_visualId = platformScreen->screen()->root_visual;
+ m_visualId = UINT_MAX;
+ const xcb_visualtype_t *visual = Q_NULLPTR;
m_depth = platformScreen->screen()->root_depth;
uint32_t mask = 0;
uint32_t values[3];
- if (m_format.alphaBufferSize() == 8) {
- xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(platformScreen->screen());
- while (depthIter.rem) {
- if (depthIter.data->depth == 32) {
- xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data);
- if (visualIter.rem) {
- m_visualId = visualIter.data->visual_id;
- m_depth = 32;
- uint32_t colormap = xcb_generate_id(xcb_connection());
- xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap,
- xcb_parent_id, m_visualId);
- mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP;
- values[0] = platformScreen->screen()->white_pixel;
- values[1] = platformScreen->screen()->black_pixel;
- values[2] = colormap;
- break;
+ if (connection()->hasDefaultVisualId()) {
+ m_visualId = connection()->defaultVisualId();
+ visual = platformScreen->visualForId(m_visualId);
+ }
+
+ if (!visual) {
+ if (connection()->hasDefaultVisualId())
+ qWarning("Failed to use default visual id. Falling back to using screens root_visual");
+
+ m_visualId = platformScreen->screen()->root_visual;
+
+ if (m_format.alphaBufferSize() == 8) {
+ xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(platformScreen->screen());
+ while (depthIter.rem) {
+ if (depthIter.data->depth == 32) {
+ xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data);
+ if (visualIter.rem) {
+ m_visualId = visualIter.data->visual_id;
+ m_depth = 32;
+ uint32_t colormap = xcb_generate_id(xcb_connection());
+ xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap,
+ xcb_parent_id, m_visualId);
+ mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP;
+ values[0] = platformScreen->screen()->white_pixel;
+ values[1] = platformScreen->screen()->black_pixel;
+ values[2] = colormap;
+ break;
+ }
}
+ xcb_depth_next(&depthIter);
}
- xcb_depth_next(&depthIter);
}
+
+ visual = platformScreen->visualForId(m_visualId);
}
- const xcb_visualtype_t *visual = platformScreen->visualForId(m_visualId);
m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
+ const QRect xRect = mapToNative(rect, platformScreen);
Q_XCB_CALL(xcb_create_window(xcb_connection(),
m_depth,
m_window, // window id
xcb_parent_id, // parent window id
- rect.x(),
- rect.y(),
- rect.width(),
- rect.height(),
+ xRect.x(),
+ xRect.y(),
+ xRect.width(),
+ xRect.height(),
0, // border width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
m_visualId, // visual
@@ -632,7 +696,7 @@ void QXcbWindow::destroy()
void QXcbWindow::maybeSetScreen(QXcbScreen *screen)
{
- if (!window()->screen() && screen->geometry().contains(geometry().topLeft() * int(devicePixelRatio()))) {
+ if (!window()->screen() && screen->geometry().contains(geometry().topLeft())) {
QWindowSystemInterface::handleWindowScreenChanged(window(), static_cast<QPlatformScreen *>(screen)->screen());
QWindowSystemInterface::handleExposeEvent(window(), QRegion(QRect(QPoint(0, 0), window()->size())));
}
@@ -645,16 +709,17 @@ void QXcbWindow::setGeometry(const QRect &rect)
propagateSizeHints();
QXcbScreen *currentScreen = xcbScreen();
- QPlatformScreen *newScreen = screenForGeometry(rect);
+ QXcbScreen *newScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect));
+
if (!newScreen)
newScreen = currentScreen;
- const QRect xRect = mapToNative(rect, int(newScreen->devicePixelRatio()));
+ m_xcbScreen = newScreen;
+ const QRect xRect = mapToNative(rect, newScreen);
const QRect wmGeometry = windowToWmGeometry(xRect);
-
if (newScreen != currentScreen)
- QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
+ QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
if (qt_window_private(window())->positionAutomatic) {
const quint32 mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
@@ -1161,6 +1226,8 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two)
event.data.data32[3] = 0;
event.data.data32[4] = 0;
+ if (!xcbScreen())
+ return;
Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, xcbScreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
}
@@ -1567,7 +1634,7 @@ void QXcbWindow::propagateSizeHints()
memset(&hints, 0, sizeof(hints));
const int dpr = int(devicePixelRatio());
- const QRect xRect = mapToNative(windowToWmGeometry(geometry()), dpr);
+ const QRect xRect = windowToWmGeometry(mapToNative(geometry(), xcbScreen()));
QWindow *win = window();
@@ -1660,6 +1727,13 @@ void QXcbWindow::setWindowIconTextStatic(QWindow *window, const QString &text)
static_cast<QXcbWindow *>(window->handle())->setWindowIconText(text);
}
+uint QXcbWindow::visualIdStatic(QWindow *window)
+{
+ if (window && window->handle())
+ return static_cast<QXcbWindow *>(window->handle())->visualId();
+ return UINT_MAX;
+}
+
QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const
{
QXcbWindowFunctions::WmWindowTypes result(0);
@@ -1953,20 +2027,21 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
}
}
-// Temporary workaround for bug in QPlatformScreen::screenForNativeGeometry
+// Temporary workaround for bug in QPlatformScreen::screenForGeometry
// we need the native geometries to detect our screen, but that's not
// available in cross-platform code. Will be fixed properly when highDPI
// support is refactored to expose the native coordinate system.
-QPlatformScreen *QXcbWindow::screenForNativeGeometry(const QRect &newGeometry) const
+QXcbScreen *QXcbWindow::screenForNativeGeometry(const QRect &newGeometry) const
{
- QXcbScreen *currentScreen = static_cast<QXcbScreen*>(screen());
+ QXcbScreen *currentScreen = xcbScreen();
if (!currentScreen && QGuiApplication::primaryScreen())
currentScreen = static_cast<QXcbScreen*>(QGuiApplication::primaryScreen()->handle());
if (currentScreen && !parent() && !currentScreen->nativeGeometry().intersects(newGeometry)) {
Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) {
- if (static_cast<QXcbScreen*>(screen)->nativeGeometry().intersects(newGeometry))
- return screen;
+ QXcbScreen *xcbScreen = static_cast<QXcbScreen*>(screen);
+ if (xcbScreen->nativeGeometry().intersects(newGeometry))
+ return xcbScreen;
}
}
return currentScreen;
@@ -1988,23 +2063,19 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
}
}
- const int dpr = devicePixelRatio();
const QRect nativeRect = QRect(pos, QSize(event->width, event->height));
- const QRect rect = mapGeometryFromNative(nativeRect, dpr);
+ QXcbScreen *newScreen = parent() ? parentScreen() : screenForNativeGeometry(nativeRect);
+
+ QXcbScreen *currentScreen = m_xcbScreen;
+ m_xcbScreen = newScreen;
+ if (!newScreen)
+ return;
+ const QRect rect = mapFromNative(nativeRect, newScreen);
QPlatformWindow::setGeometry(rect);
QWindowSystemInterface::handleGeometryChange(window(), rect);
- QPlatformScreen *newScreen = screenForNativeGeometry(nativeRect);
- if (newScreen != screen()) {
- if (newScreen)
- QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
- int newDpr = newScreen->devicePixelRatio();
- if (newDpr != dpr) {
- QRect newRect = mapGeometryFromNative(nativeRect, newDpr);
- QPlatformWindow::setGeometry(newRect);
- QWindowSystemInterface::handleGeometryChange(window(), newRect);
- }
- }
+ if (newScreen != currentScreen)
+ QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
m_configureNotifyPending = false;
@@ -2045,12 +2116,12 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const
xcb_translate_coordinates_reply_t *reply =
xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
if (reply) {
- ret.setX(reply->dst_x / dpr);
- ret.setY(reply->dst_y / dpr);
+ ret.setX(reply->dst_x);
+ ret.setY(reply->dst_y);
free(reply);
}
- return ret;
+ return mapFromNative(ret, xcbScreen());
}
QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const
@@ -2060,9 +2131,10 @@ QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const
const int dpr = int(devicePixelRatio());
QPoint ret;
+ QPoint xPos = mapToNative(pos, xcbScreen());
xcb_translate_coordinates_cookie_t cookie =
xcb_translate_coordinates(xcb_connection(), xcbScreen()->root(), xcb_window(),
- pos.x() *dpr, pos.y() * dpr);
+ xPos.x(), xPos.y());
xcb_translate_coordinates_reply_t *reply =
xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
if (reply) {
@@ -2116,7 +2188,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
}
const int dpr = int(devicePixelRatio());
QPoint local(event->event_x/dpr, event->event_y/dpr);
- QPoint global(event->root_x/dpr, event->root_y/dpr);
+ QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y));
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
@@ -2141,7 +2213,7 @@ void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *even
{
const int dpr = int(devicePixelRatio());
QPoint local(event->event_x/dpr, event->event_y/dpr);
- QPoint global(event->root_x/dpr, event->root_y/dpr);
+ QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y));
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
if (event->detail >= 4 && event->detail <= 7) {
@@ -2156,7 +2228,9 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
{
const int dpr = int(devicePixelRatio());
QPoint local(event->event_x/dpr, event->event_y/dpr);
- QPoint global(event->root_x/dpr, event->root_y/dpr);
+ if (!xcbScreen())
+ return;
+ QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y));
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
handleMouseEvent(event->time, local, global, modifiers);
@@ -2213,7 +2287,9 @@ void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
const int dpr = int(devicePixelRatio());
const QPoint local(event->event_x/dpr, event->event_y/dpr);
- const QPoint global(event->root_x/dpr, event->root_y/dpr);
+ if (!xcbScreen())
+ return;
+ QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y));
QWindowSystemInterface::handleEnterEvent(window(), local, global);
}
@@ -2231,7 +2307,9 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
if (enterWindow) {
const int dpr = int(devicePixelRatio());
QPoint local(enter->event_x/dpr, enter->event_y/dpr);
- QPoint global(enter->root_x/dpr, enter->root_y/dpr);
+ if (!xcbScreen())
+ return;
+ QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y));
QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global);
} else {
@@ -2246,6 +2324,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
connection()->setTime(event->time);
const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
+ if (!xcbScreen())
+ return;
if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) {
if (propertyDeleted)
@@ -2394,7 +2474,6 @@ void QXcbWindow::windowEvent(QEvent *event)
bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
{
- const int dpr = int(devicePixelRatio());
const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE);
if (!connection()->wmSupport()->isSupportedByWM(moveResize))
return false;
@@ -2403,7 +2482,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
xev.type = moveResize;
xev.window = xcb_window();
xev.format = 32;
- const QPoint globalPos = window()->mapToGlobal(pos) * dpr;
+ const QPoint globalPos = mapToNative(window()->mapToGlobal(pos), xcbScreen());
xev.data.data32[0] = globalPos.x();
xev.data.data32[1] = globalPos.y();
const bool bottom = corner == Qt::BottomRightCorner || corner == Qt::BottomLeftCorner;
@@ -2532,7 +2611,7 @@ void QXcbWindow::setMask(const QRegion &region)
const int dpr = devicePixelRatio();
QVector<xcb_rectangle_t> rects;
foreach (const QRect &r, region.rects())
- rects.push_back(qRectToXCBRectangle(mapToNative(r, dpr)));
+ rects.push_back(qRectToXCBRectangle(mapLocalGeometryToNative(r, dpr)));
xcb_shape_rectangles(connection()->xcb_connection(), XCB_SHAPE_SO_SET,
XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
xcb_window(), 0, 0, rects.size(), &rects[0]);
@@ -2549,6 +2628,11 @@ void QXcbWindow::setAlertState(bool enabled)
changeNetWmState(enabled, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION));
}
+uint QXcbWindow::visualId() const
+{
+ return m_visualId;
+}
+
bool QXcbWindow::needsSync() const
{
return m_syncState == SyncAndConfigureReceived;
@@ -2556,6 +2640,8 @@ bool QXcbWindow::needsSync() const
void QXcbWindow::postSyncWindowRequest()
{
+ if (!xcbScreen())
+ return;
if (!m_pendingSyncRequest) {
QXcbSyncWindowRequest *e = new QXcbSyncWindowRequest(this);
m_pendingSyncRequest = e;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 2442e6c4e3..52e8ac1459 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -140,6 +140,7 @@ public:
void updateNetWmUserTime(xcb_timestamp_t timestamp);
static void setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes);
+ static uint visualIdStatic(QWindow *window);
QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const;
void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types);
@@ -154,6 +155,7 @@ public:
static QRect systemTrayWindowGlobalGeometryStatic(const QWindow *window);
QRect systemTrayWindowGlobalGeometry() const;
+ uint visualId() const;
bool needsSync() const;
@@ -167,7 +169,7 @@ public:
virtual void create();
virtual void destroy();
void maybeSetScreen(QXcbScreen *screen);
- QPlatformScreen *screenForNativeGeometry(const QRect &newGeometry) const;
+ QXcbScreen *screenForNativeGeometry(const QRect &newGeometry) const;
public Q_SLOTS:
void updateSyncRequestCounter();
@@ -177,6 +179,12 @@ protected:
virtual void *createVisual() { return Q_NULLPTR; }
virtual bool supportsSyncProtocol() { return !window()->supportsOpenGL(); }
+ QPoint mapToNative(const QPoint &pos, const QXcbScreen *screen) const;
+ QPoint mapFromNative(const QPoint &pos, const QXcbScreen *screen) const;
+ QRect mapToNative(const QRect &rect, const QXcbScreen *screen) const;
+ QRect mapFromNative(const QRect &rect, const QXcbScreen *screen) const;
+ QXcbScreen *parentScreen();
+
void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0);
NetWmStates netWmStates();
void setNetWmStates(NetWmStates);
@@ -204,6 +212,8 @@ protected:
xcb_window_t m_window;
+ QXcbScreen *m_xcbScreen;
+
uint m_depth;
QImage::Format m_imageFormat;
bool m_imageRgbSwap;
diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.cpp b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
index bcdfde2ef9..7d31ac7118 100644
--- a/src/plugins/platforms/xcb/qxcbwmsupport.cpp
+++ b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
@@ -68,7 +68,7 @@ void QXcbWMSupport::updateNetWMAtoms()
remaining = 0;
if (reply->type == XCB_ATOM_ATOM && reply->format == 32) {
- int len = xcb_get_property_value_length(reply)/4;
+ int len = xcb_get_property_value_length(reply)/sizeof(xcb_atom_t);
xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply);
int s = net_wm_atoms.size();
net_wm_atoms.resize(s + len);
@@ -102,11 +102,11 @@ void QXcbWMSupport::updateVirtualRoots()
remaining = 0;
if (reply->type == XCB_ATOM_ATOM && reply->format == 32) {
- int len = xcb_get_property_value_length(reply)/4;
- xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply);
- int s = net_wm_atoms.size();
- net_wm_atoms.resize(s + len);
- memcpy(net_wm_atoms.data() + s, atoms, len*sizeof(xcb_atom_t));
+ int len = xcb_get_property_value_length(reply)/sizeof(xcb_window_t);
+ xcb_window_t *roots = (xcb_window_t *)xcb_get_property_value(reply);
+ int s = net_virtual_roots.size();
+ net_virtual_roots.resize(s + len);
+ memcpy(net_virtual_roots.data() + s, roots, len*sizeof(xcb_window_t));
remaining = reply->bytes_after;
offset += len;
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp
index c83edd506d..46cee5d6d0 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.cpp
+++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp
@@ -63,7 +63,7 @@ public:
: last_change_serial(-1)
{}
- void updateValue(QXcbScreen *screen, const QByteArray &name, const QVariant &value, int last_change_serial)
+ void updateValue(QXcbVirtualDesktop *screen, const QByteArray &name, const QVariant &value, int last_change_serial)
{
if (last_change_serial <= this->last_change_serial)
return;
@@ -92,7 +92,7 @@ public:
class QXcbXSettingsPrivate
{
public:
- QXcbXSettingsPrivate(QXcbScreen *screen)
+ QXcbXSettingsPrivate(QXcbVirtualDesktop *screen)
: screen(screen)
, initialized(false)
{
@@ -217,18 +217,18 @@ public:
}
#endif //XCB_USE_XLIB
- QXcbScreen *screen;
+ QXcbVirtualDesktop *screen;
xcb_window_t x_settings_window;
QMap<QByteArray, QXcbXSettingsPropertyValue> settings;
bool initialized;
};
-QXcbXSettings::QXcbXSettings(QXcbScreen *screen)
+QXcbXSettings::QXcbXSettings(QXcbVirtualDesktop *screen)
: d_ptr(new QXcbXSettingsPrivate(screen))
{
QByteArray settings_atom_for_screen("_XSETTINGS_S");
- settings_atom_for_screen.append(QByteArray::number(screen->screenNumber()));
+ settings_atom_for_screen.append(QByteArray::number(screen->number()));
xcb_intern_atom_cookie_t atom_cookie = xcb_intern_atom(screen->xcb_connection(),
true,
settings_atom_for_screen.length(),
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.h b/src/plugins/platforms/xcb/qxcbxsettings.h
index 4022f0a2c4..3f1d175336 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.h
+++ b/src/plugins/platforms/xcb/qxcbxsettings.h
@@ -44,13 +44,13 @@ class QXcbXSettings : public QXcbWindowEventListener
{
Q_DECLARE_PRIVATE(QXcbXSettings)
public:
- QXcbXSettings(QXcbScreen *screen);
+ QXcbXSettings(QXcbVirtualDesktop *screen);
~QXcbXSettings();
bool initialized() const;
QVariant setting(const QByteArray &property) const;
- typedef void (*PropertyChangeFunc)(QXcbScreen *screen, const QByteArray &name, const QVariant &property, void *handle);
+ typedef void (*PropertyChangeFunc)(QXcbVirtualDesktop *screen, const QByteArray &name, const QVariant &property, void *handle);
void registerCallbackForProperty(const QByteArray &property, PropertyChangeFunc func, void *handle);
void removeCallbackForHandle(const QByteArray &property, void *handle);
void removeCallbackForHandle(void *handle);