From 9a4c98e55659b32db984612e6247ac193812a502 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 4 Nov 2020 10:29:13 +0100 Subject: xcb: support xrandr(1.5) monitor setup More information about monitor in xrandr 1.5, see https://keithp.com/blogs/MST-monitors/ Since this change, screen is logical instead of physical. If xrandr 1.5 and later is installed, Qt screen info will get from xrandr monitor object instead of xrandr output if only have 1.2 to 1.4. Users can manipulate monitor as they want, for example, a combination for two physical screens, half of one screen and etc. Didn't have chance to access MST monitors, but it should work if xrandr monitor object was created automatically. [ChangeLog][xcb] Qt screen info will get from xrandr monitor object if 1.5 is installed. Fixes: QTBUG-65457 Change-Id: Iad339cc0d4293b2403b4ef6bf6eb770feb3e685f Reviewed-by: Shawn Rutledge --- tests/manual/CMakeLists.txt | 1 + tests/manual/manual.pro | 1 + tests/manual/qscreen_xrandr/CMakeLists.txt | 14 +++ tests/manual/qscreen_xrandr/qscreen_xrandr.pro | 6 ++ tests/manual/qscreen_xrandr/tst_qscreen_xrandr.cpp | 110 +++++++++++++++++++++ 5 files changed, 132 insertions(+) create mode 100644 tests/manual/qscreen_xrandr/CMakeLists.txt create mode 100644 tests/manual/qscreen_xrandr/qscreen_xrandr.pro create mode 100644 tests/manual/qscreen_xrandr/tst_qscreen_xrandr.cpp (limited to 'tests/manual') diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt index f9eb23cd5f..6dee2e7448 100644 --- a/tests/manual/CMakeLists.txt +++ b/tests/manual/CMakeLists.txt @@ -39,6 +39,7 @@ endif() #special case end add_subdirectory(qstorageinfo) add_subdirectory(qscreen) +add_subdirectory(qscreen_xrandr) add_subdirectory(qsslsocket) add_subdirectory(qsysinfo) add_subdirectory(qtabletevent) diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 2ef802c8f3..8ad5882234 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -27,6 +27,7 @@ qnetworkaccessmanager/qget \ qnetworkreply \ qstorageinfo \ qscreen \ +qscreen_xrandr \ qssloptions \ qsslsocket \ qsysinfo \ diff --git a/tests/manual/qscreen_xrandr/CMakeLists.txt b/tests/manual/qscreen_xrandr/CMakeLists.txt new file mode 100644 index 0000000000..095948b070 --- /dev/null +++ b/tests/manual/qscreen_xrandr/CMakeLists.txt @@ -0,0 +1,14 @@ +# Generated from qscreen_xrandr.pro. + +##################################################################### +## tst_qscreen2 Test: +##################################################################### + +qt_internal_add_test(tst_qscreen_xrandr + SOURCES + tst_qscreen_xrandr.cpp + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate +) diff --git a/tests/manual/qscreen_xrandr/qscreen_xrandr.pro b/tests/manual/qscreen_xrandr/qscreen_xrandr.pro new file mode 100644 index 0000000000..61132f63c2 --- /dev/null +++ b/tests/manual/qscreen_xrandr/qscreen_xrandr.pro @@ -0,0 +1,6 @@ +CONFIG += testcase +TARGET = tst_qscreen_xrandr + +QT += core-private gui-private testlib + +SOURCES += tst_qscreen_xrandr.cpp diff --git a/tests/manual/qscreen_xrandr/tst_qscreen_xrandr.cpp b/tests/manual/qscreen_xrandr/tst_qscreen_xrandr.cpp new file mode 100644 index 0000000000..f7611fc95a --- /dev/null +++ b/tests/manual/qscreen_xrandr/tst_qscreen_xrandr.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include + +class tst_QScreen_Xrandr: public QObject +{ + Q_OBJECT + +private slots: + void xrandr_15(); +}; + +// this test requires an X11 desktop with at least two screens +void tst_QScreen_Xrandr::xrandr_15() +{ + QStringList originalScreenNames; + QStringList mergedScreenNames; + { + QList screens = QGuiApplication::screens(); + QVERIFY(screens.size() >= 2); + qDebug() << "initial set of screens:" << screens.size(); + for (QScreen *s : screens) { + qDebug() << "screen: " << s->name(); + originalScreenNames << s->name(); + if (mergedScreenNames.size() < 2) + mergedScreenNames << s->name(); + } + } + + QSignalSpy addedSpy(qApp, &QGuiApplication::screenAdded); + QSignalSpy removedSpy(qApp, &QGuiApplication::screenRemoved); + + // combine the first two screens into one monitor + // e.g. "xrandr --setmonitor Qt-merged auto eDP,HDMI-0" + QString prog1 = "xrandr"; + QStringList args1; + args1 << "--setmonitor" << "Qt-merged" << "auto" << mergedScreenNames.join(','); + qDebug() << prog1 << args1; + QProcess *myProcess1 = new QProcess(this); + myProcess1->start(prog1, args1); + QVERIFY(myProcess1->waitForFinished()); + + QTRY_COMPARE(removedSpy.count(), 2); + QVERIFY(QGuiApplication::screens().size() != originalScreenNames.size()); + auto combinedScreens = QGuiApplication::screens(); + qDebug() << "added" << addedSpy.count() << "removed" << removedSpy.count() << "combined screen(s):" << combinedScreens.size(); + QScreen *merged = nullptr; + for (QScreen *s : combinedScreens) { + qDebug() << "screen: " << s->name(); + if (s->name() == QLatin1String("Qt-merged")) + merged = s; + } + // the screen that we created must be in the list now + QVERIFY(merged); + QCOMPARE(QGuiApplication::screens().size(), originalScreenNames.size() - 1); + addedSpy.clear(); + removedSpy.clear(); + + // "xrandr --delmonitor Qt-merged" + QString prog2 = "xrandr"; + QStringList args2; + args2 << "--delmonitor" << "Qt-merged"; + QProcess *myProcess2 = new QProcess(this); + myProcess2->start(prog2, args2); + QVERIFY(myProcess2->waitForFinished()); + + QTRY_COMPARE(removedSpy.count(), 1); + QVERIFY(QGuiApplication::screens().size() != combinedScreens.size()); + auto separatedScreens = QGuiApplication::screens(); + qDebug() << "added" << addedSpy.count() << "removed" << removedSpy.count() << "separated screen(s):" << separatedScreens.size(); + for (QScreen *s : separatedScreens) + qDebug() << "screen: " << s->name(); + + QCOMPARE(QGuiApplication::screens().size(), originalScreenNames.size()); +} + +#include +QTEST_MAIN(tst_QScreen_Xrandr); -- cgit v1.2.3