diff options
author | Simon Rettberg | 2020-02-17 08:24:24 +0100 |
---|---|---|
committer | Simon Rettberg | 2020-02-17 08:24:24 +0100 |
commit | 19033eebd821813bc1b1ad54094bfcea673bc0ac (patch) | |
tree | 6b3d97d6e3b4af775d60f82fb4d3ef25f9c03cda | |
parent | Fix xrandr command line for positioning... (diff) | |
download | beamergui-19033eebd821813bc1b1ad54094bfcea673bc0ac.tar.gz beamergui-19033eebd821813bc1b1ad54094bfcea673bc0ac.tar.xz beamergui-19033eebd821813bc1b1ad54094bfcea673bc0ac.zip |
Add -d to dump all screen geometry
This ignores cloned outputs and overlapping screens.
In case of overlapping screens it will remove those
screens from the list that cause the least decrease
in total screen size (in pixels).
-rw-r--r-- | src/main.cpp | 82 | ||||
-rw-r--r-- | src/xprivate.cpp | 2 |
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); |