summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2020-02-17 08:24:24 +0100
committerSimon Rettberg2020-02-17 08:24:24 +0100
commit19033eebd821813bc1b1ad54094bfcea673bc0ac (patch)
tree6b3d97d6e3b4af775d60f82fb4d3ef25f9c03cda
parentFix xrandr command line for positioning... (diff)
downloadbeamergui-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.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);