summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main.cpp82
-rw-r--r--src/xprivate.cpp2
2 files changed, 82 insertions, 2 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 59c886b..eac930b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -7,9 +7,10 @@
#include <QLibraryInfo>
#include <QTranslator>
#include <QCommandLineParser>
+#include <QScreen>
namespace {
-bool _testMode, _autoSetup, _showGui, _backgroundMode, _wakeup, _center;
+bool _testMode, _autoSetup, _showGui, _backgroundMode, _wakeup, _center, _dumpScreens;
}
namespace CommandLine
@@ -20,10 +21,13 @@ bool showGui() { return _showGui; }
bool backgroundMode() { return _backgroundMode; }
bool wakeup() { return _wakeup; }
bool center() { return _center; }
+bool dumpScreens() { return _dumpScreens; }
}
static void parseCommandLine(const QCoreApplication &a);
+static void dumpScreens();
+
int main(int argc, char *argv[])
{
QCoreApplication *a;
@@ -54,6 +58,10 @@ int main(int argc, char *argv[])
if (CommandLine::wakeup()) {
return Bus::inst()->registerService() ? 0 : 1;
}
+ if (CommandLine::dumpScreens()) {
+ dumpScreens();
+ return 0;
+ }
ScreenSetup::inst()->addMissingEdidResolutions();
ScreenSetup::inst()->initModes();
@@ -110,6 +118,10 @@ static void parseCommandLine(const QCoreApplication &a)
QCommandLineOption oCenter(QStringList() << "c" << "center",
QCoreApplication::translate("main", "Set all outputs to clone mode. If size differs, center outputs according to largest output."));
parser.addOption(oCenter);
+ // Dump all screens, non-overlapping (ie. exclude clones)
+ QCommandLineOption oDumpScreens(QStringList() << "d" << "dump",
+ QCoreApplication::translate("main", "Dump all non-overlapping screens."));
+ parser.addOption(oDumpScreens);
// PARSE
parser.process(a);
_testMode = parser.isSet(oTest);
@@ -118,5 +130,73 @@ static void parseCommandLine(const QCoreApplication &a)
_backgroundMode = parser.isSet(oBackground);
_wakeup = parser.isSet(oWakeup);
_center = parser.isSet(oCenter);
+ _dumpScreens = parser.isSet(oDumpScreens);
}
+QTextStream& qStdOut()
+{
+ static QTextStream ts(stdout);
+ return ts;
+}
+
+static int findConfig(QVector<QRect> &list)
+{
+ int area = 0;
+ bool overlap = false;
+ struct {
+ QVector<QRect> list;
+ int area = 0;
+ } best;
+ for (int i = 0; i < list.size(); ++i) {
+ const QRect &first = list[i];
+ for (int j = i + 1; j < list.size(); ++j) {
+ if (!list[j].intersects(first))
+ continue;
+ overlap = true;
+ QVector<QRect> copy1 = list, copy2 = list;
+ copy1.remove(i);
+ copy2.remove(j);
+ int a1 = findConfig(copy1);
+ int a2 = findConfig(copy2);
+ if (a1 > best.area && a1 > a2) {
+ best.area = a1;
+ best.list = copy1;
+ } else if (a2 > best.area) {
+ best.area = a2;
+ best.list = copy2;
+ }
+ }
+ area += first.width() * first.height();
+ }
+ if (!overlap)
+ return area;
+ list = best.list;
+ return best.area;
+}
+
+static void dumpScreens()
+{
+ QVector<QRect> list;
+ for (auto *scr : QGuiApplication::screens()) {
+ list.append(scr->geometry());
+ }
+ findConfig(list);
+ qSort(list.begin(), list.end(), [](const QRect &one, const QRect &other) -> bool {
+ return one.y() < other.y() || (one.y() == other.y() && one.x() < other.x());
+ });
+ int nextX = 0;
+ int lastY = 0;
+ qStdOut() << "# x y width height" << endl;
+ for (const auto &geo : list) {
+ if (geo.x() != nextX) {
+ qStdOut() << "# Warning: Next screen has gap to previous one" << endl;
+ }
+ qStdOut() << geo.x() << ' ' << geo.y() << ' ' << geo.width() << ' ' << geo.height() << endl;
+ if (lastY == geo.y()) {
+ nextX += geo.width();
+ } else {
+ lastY = 0;
+ }
+ lastY = geo.y();
+ }
+}
diff --git a/src/xprivate.cpp b/src/xprivate.cpp
index 01f265f..c8a45b2 100644
--- a/src/xprivate.cpp
+++ b/src/xprivate.cpp
@@ -488,7 +488,7 @@ QList<RRMode> XPrivate::getOutputModeForResolution(const XRROutputInfo *output,
}
}
// Sort others descending by dotClock
- qSort(others.begin(), others.end(), [](const XRRModeInfo *a, const XRRModeInfo *b) {
+ qSort(others.begin(), others.end(), [](const XRRModeInfo *a, const XRRModeInfo *b) -> bool {
if ((a->modeFlags & RR_DoubleScan) != (b->modeFlags & RR_DoubleScan))
return (a->modeFlags & RR_DoubleScan) == 0; // Prefer non-interlaced resolutions
return toVertRefresh(a) > toVertRefresh(b);