summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp44
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h6
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp44
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h36
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.cpp10
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.h4
8 files changed, 92 insertions, 56 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index f0cd4c8484..3d65b789a4 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -143,7 +143,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)
{
@@ -156,10 +156,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)
@@ -179,15 +179,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;
@@ -200,8 +196,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;
@@ -218,9 +214,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;
@@ -248,7 +243,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));
@@ -299,14 +294,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;
@@ -376,7 +372,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;
@@ -411,8 +407,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;
@@ -583,6 +580,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
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index f479c1bc80..91547dd697 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;
@@ -494,12 +495,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);
@@ -564,6 +565,7 @@ private:
const xcb_setup_t *m_setup;
bool m_canGrabServer;
+ QList<QXcbVirtualDesktop *> m_virtualDesktops;
QList<QXcbScreen *> m_screens;
int m_primaryScreenNumber;
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index 8dd27ec9c5..e30cc26313 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);
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/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 6f1fc08167..fcf70f3c51 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;
@@ -496,7 +516,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) {
@@ -707,11 +727,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..6b60ea9bb1 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; }
@@ -126,7 +146,7 @@ private:
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 +163,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 +176,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/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);