summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2018-09-11 17:50:33 +0200
committerSimon Rettberg2018-09-11 17:50:33 +0200
commit193daa35e13865d72ad25acb881108b5e8b7ff36 (patch)
treed9c42a866c8faa037e1552a38144c5c05840dae9
parentChange popup logic yet again (diff)
downloadbeamergui-193daa35e13865d72ad25acb881108b5e8b7ff36.tar.gz
beamergui-193daa35e13865d72ad25acb881108b5e8b7ff36.tar.xz
beamergui-193daa35e13865d72ad25acb881108b5e8b7ff36.zip
Keep revert state in separate class ti handle interleaving mode changes
-rw-r--r--src/main.cpp3
-rw-r--r--src/timeoutdialog.cpp35
-rw-r--r--src/timeoutdialog.h1
-rw-r--r--src/widget.cpp26
-rw-r--r--src/xprivate.cpp31
-rw-r--r--src/xprivate.h3
-rw-r--r--src/xx.cpp268
-rw-r--r--src/xx.h30
8 files changed, 273 insertions, 124 deletions
diff --git a/src/main.cpp b/src/main.cpp
index fabf36c..317383d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -60,7 +60,8 @@ int main(int argc, char *argv[])
if (CommandLine::center()) {
ScreenSetup::inst()->setCenteredClone();
} else if (CommandLine::autoSetup()) {
- ScreenSetup::inst()->setDefaultMode(CommandLine::testMode());
+ ScreenMode mode;
+ ScreenSetup::inst()->setDefaultMode(CommandLine::testMode(), mode);
} else {
ScreenSetup::inst()->getCurrentMode();
}
diff --git a/src/timeoutdialog.cpp b/src/timeoutdialog.cpp
index 6f12ca2..9eefc42 100644
--- a/src/timeoutdialog.cpp
+++ b/src/timeoutdialog.cpp
@@ -6,22 +6,26 @@
#include <QProgressBar>
#include <QDebug>
#include <QPushButton>
+#include <QKeyEvent>
TimeOutDialog::TimeOutDialog(int time, QWidget *parent)
: QDialog(parent), _ui(new Ui::TimeOutDialog), _time(time)
{
_ui->setupUi(this);
+ this->installEventFilter(this);
+ _ui->buttonBox->installEventFilter(this);
+ for (auto b : _ui->buttonBox->buttons()) {
+ b->installEventFilter(this);
+ b->setFocusPolicy(Qt::NoFocus);
+ }
+ this->setFocus();
QObject::connect(&_timer, &QTimer::timeout, this, &TimeOutDialog::update);
QObject::connect(_ui->buttonBox, &QDialogButtonBox::clicked, [this](QAbstractButton *button) {
_timer.stop();
if (button == _ui->buttonBox->button(QDialogButtonBox::Discard)) {
_time = 0;
}
- });
- QObject::connect(_ui->buttonBox, &QDialogButtonBox::rejected, [this]() {
- _timer.stop();
- _time = 0; // So wasCanceled() returns true
- });
+ });
// QProgressDialog takes ownership of QProgressBar
_ui->progressBar->setMaximum(_time);
@@ -37,6 +41,27 @@ void TimeOutDialog::hideEvent(QHideEvent *e)
_timer.stop();
}
+bool TimeOutDialog::eventFilter(QObject *, QEvent *event)
+{
+ if (event->type() != QEvent::KeyPress)
+ return false;
+ if (!_timer.isActive())
+ return false;
+ QKeyEvent *e = static_cast<QKeyEvent *>(event);
+ if (e->key() == Qt::Key_Escape) {
+ // Handle as discard
+ _time = 0;
+ _timer.stop();
+ return true;
+ }
+ if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
+ // Handle as accept
+ _timer.stop();
+ return true;
+ }
+ return false;
+}
+
void TimeOutDialog::update()
{
--_time;
diff --git a/src/timeoutdialog.h b/src/timeoutdialog.h
index b70f753..d80de1c 100644
--- a/src/timeoutdialog.h
+++ b/src/timeoutdialog.h
@@ -27,6 +27,7 @@ private:
protected:
void hideEvent(QHideEvent *event) override;
+ bool eventFilter(QObject *object, QEvent *event) override;
private slots:
void update();
diff --git a/src/widget.cpp b/src/widget.cpp
index fba46a7..069e8db 100644
--- a/src/widget.cpp
+++ b/src/widget.cpp
@@ -139,10 +139,12 @@ Widget::Widget(QWidget *parent) :
if (currentCount == _lastScreenCount) {
// Nothing seems to have changed. This might happen when another tool changes the screen config. Let's not interfere.
} else if (currentCount > _lastScreenCount) { // Screen count increased - auto setup
+ _lastScreenCount = currentCount;
ScreenSetup::inst()->initModes();
- ScreenSetup::inst()->setDefaultMode(CommandLine::testMode());
- if (!keepResolution()) {
- ScreenSetup::inst()->revertChanges();
+ ScreenMode mode;
+ auto ret = ScreenSetup::inst()->setDefaultMode(CommandLine::testMode(), mode);
+ if (!ret.ok() || !keepResolution()) {
+ ret.revert();
}
} else { // Screen count decreased - pop up GUI and don't just deconfig the screen
this->show();
@@ -569,8 +571,7 @@ bool Widget::keepResolution()
//______________________________________________________________________________
void Widget::connectButtons() {
-
- // Swap dualscreen
+ // Swap dualscreen
connect(_ui->btnDualSwap, &QPushButton::clicked, [=](bool) {
_ui->dualContainer->addItem(_ui->dualContainer->takeAt(1));
_ui->dualContainer->addItem(_ui->dualContainer->takeAt(0));
@@ -578,9 +579,10 @@ void Widget::connectButtons() {
// Apply CLONE
connect(_ui->btnCloneApply, &QPushButton::clicked, [=](bool) {
- if (!ScreenSetup::inst()->setClone(_ui->cboCloneResolution->currentData().toSize()) || !keepResolution()) {
+ auto ret = ScreenSetup::inst()->setClone(_ui->cboCloneResolution->currentData().toSize());
+ if (!ret.ok() || !keepResolution()) {
qDebug() << "reverting clone";
- ScreenSetup::inst()->revertChanges();
+ ret.revert();
}
ScreenSetup::inst()->updateScreenResources();
initControls();
@@ -593,9 +595,10 @@ void Widget::connectButtons() {
if (_ui->btnDualSwap->isChecked()) {
qSwap(left, right);
}
- if (!ScreenSetup::inst()->setCustom({left, right}) || !keepResolution()) {
+ auto ret = ScreenSetup::inst()->setCustom({left, right});
+ if (!ret.ok() || !keepResolution()) {
qDebug() << "reverting dualhead";
- ScreenSetup::inst()->revertChanges();
+ ret.revert();
}
ScreenSetup::inst()->updateScreenResources();
initControls();
@@ -613,9 +616,10 @@ void Widget::connectButtons() {
continue;
list[index].second.append(e->info.output);
}
- if (!ScreenSetup::inst()->setCustom(list) || !keepResolution()) {
+ auto ret = ScreenSetup::inst()->setCustom(list);
+ if (!ret.ok() || !keepResolution()) {
qDebug() << "reverting custom";
- ScreenSetup::inst()->revertChanges();
+ ret.revert();
}
ScreenSetup::inst()->updateScreenResources();
initControls();
diff --git a/src/xprivate.cpp b/src/xprivate.cpp
index 0233f5b..70c1a3f 100644
--- a/src/xprivate.cpp
+++ b/src/xprivate.cpp
@@ -60,7 +60,6 @@ XPrivate::~XPrivate()
void XPrivate::freeResources()
{
- freeCrtcBackup();
// Clear the modemap (nothing to be freed, stored in screenResources)
_modeMap.clear();
_resolutions.clear();
@@ -292,36 +291,6 @@ void XPrivate::disconnectAllCrtcs()
}
}
-void XPrivate::freeCrtcBackup()
-{
- for (auto entry : _crtcBackup) {
- free(entry->outputs);
- free(entry);
- }
- _crtcBackup.clear();
- qDebug() << "CRTC freed";
-}
-
-void XPrivate::createCrtcBackup()
-{
- freeCrtcBackup();
- for (CrtcMap::iterator it = _crtcMap.begin(); it != _crtcMap.end(); ++it) {
- const auto src = it.value();
- XRRCrtcInfo *copy = static_cast<XRRCrtcInfo*>(calloc(1, sizeof(XRRCrtcInfo)));
- copy->outputs = static_cast<RROutput*>(calloc(size_t(src->noutput), sizeof(RROutput)));
- copy->x = src->x;
- copy->y = src->y;
- copy->mode = src->mode;
- copy->rotation = src->rotation;
- copy->noutput = src->noutput;
- for (int i = 0; i < src->noutput; ++i) {
- copy->outputs[i] = src->outputs[i];
- }
- _crtcBackup[it.key()] = copy;
- }
- qDebug() << "Created CRTC backup with entries:" << _crtcBackup.size();
-}
-
/**
* Copy first "num" modes from output to all other outputs if they
* dont have a suitable mode yet.
diff --git a/src/xprivate.h b/src/xprivate.h
index fd0e9f3..d3e9129 100644
--- a/src/xprivate.h
+++ b/src/xprivate.h
@@ -45,8 +45,6 @@ public:
void freeResources();
void updateScreenResources();
bool readEdid(OutputInfo* output);
- void createCrtcBackup();
- void freeCrtcBackup();
void disconnectAllCrtcs();
XRRModeInfo* getPreferredMode(OutputInfo *oi, XRRModeInfo *fallback = nullptr) const;
void setScreenSize(const QSize &size);
@@ -62,7 +60,6 @@ public:
XRRScreenResources* _screenResources;
ModeMap _modeMap;
CrtcMap _crtcMap;
- CrtcMap _crtcBackup;
OutputMap _outputMap;
ResolutionVector _resolutions;
};
diff --git a/src/xx.cpp b/src/xx.cpp
index a5f9d92..d0b6a3d 100644
--- a/src/xx.cpp
+++ b/src/xx.cpp
@@ -4,9 +4,137 @@
#include <QDebug>
#include <QSocketNotifier>
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * This clusterfuck exists because there are name clashes between X11/Xrandr headers
+ * and Qt classes. Hence the split into xx.* and xprivate.* as well as those idiotic
+ * matrjoschka classes. Or I'm just stupid.
+ */
+
+class BackupInternalInternal
+{
+private:
+ XPrivate *x;
+public:
+ CrtcMap map;
+ BackupInternalInternal() : x(nullptr) {
+ qDebug() << "new BackupInternalInternal";
+ }
+ ~BackupInternalInternal() {
+ qDebug() << "delete BackupInternalInternal";
+ freeBackup();
+ }
+ void createBackup(XPrivate *x) {
+ this->x = x;
+ freeBackup();
+ for (CrtcMap::iterator it = x->_crtcMap.begin(); it != x->_crtcMap.end(); ++it) {
+ const auto src = it.value();
+ XRRCrtcInfo *copy = static_cast<XRRCrtcInfo*>(calloc(1, sizeof(XRRCrtcInfo)));
+ copy->outputs = static_cast<RROutput*>(calloc(size_t(src->noutput), sizeof(RROutput)));
+ copy->x = src->x;
+ copy->y = src->y;
+ copy->mode = src->mode;
+ copy->rotation = src->rotation;
+ copy->noutput = src->noutput;
+ for (int i = 0; i < src->noutput; ++i) {
+ copy->outputs[i] = src->outputs[i];
+ }
+ map[it.key()] = copy;
+ }
+ qDebug() << "Created CRTC backup with entries:" << map.size();
+ }
+ void freeBackup() {
+ for (auto i : map) {
+ free(i->outputs);
+ free(i);
+ }
+ map.clear();
+ }
+ void revertChanges()
+ {
+ if (map.isEmpty())
+ return;
+ qDebug() << "Starting revert";
+ XGrabServer(x->_display);
+ x->disconnectAllCrtcs();
+ QSize screenSize;
+ for (auto e : map) {
+ if (e->mode == None || !x->_modeMap.contains(e->mode))
+ continue;
+ screenSize = screenSize.expandedTo(QSize(e->x + int(x->_modeMap[e->mode]->width), e->y + int(x->_modeMap[e->mode]->height)));
+ }
+ x->setScreenSize(screenSize);
+ for (CrtcMap::iterator it = map.begin(); it != map.end(); ++it) {
+ auto e = it.value();
+ if (e->mode == None)
+ continue;
+ XRRSetCrtcConfig(x->_display, x->_screenResources, it.key(), CurrentTime,
+ e->x, e->y, e->mode, e->rotation, e->outputs, e->noutput);
+ }
+ XUngrabServer(x->_display);
+ XSync(x->_display, False);
+ freeBackup();
+ }
+};
+
+class BackupInternal
+{
+public:
+ BackupInternal() {
+ qDebug() << "new BackupInternal";
+ }
+ ~BackupInternal() {
+ qDebug() << "delete BackupInternal";
+ }
+ QSharedPointer<BackupInternalInternal> backup;
+};
+
+ConfigBackup::ConfigBackup()
+{
+ _ok = false;
+ a = new BackupInternal;
+}
+
+ConfigBackup::ConfigBackup(XPrivate *x)
+{
+ _ok = false;
+ a = new BackupInternal;
+ a->backup = QSharedPointer<BackupInternalInternal>(new BackupInternalInternal);
+ a->backup->createBackup(x);
+}
+
+ConfigBackup::~ConfigBackup()
+{
+ delete a;
+}
+
+ConfigBackup& ConfigBackup::operator=(const ConfigBackup &other)
+{
+ if (this == &other)
+ return *this;
+ delete a;
+ _ok = other._ok;
+ a = new BackupInternal;
+ a->backup = other.a->backup;
+ return *this;
+}
+
+ConfigBackup::ConfigBackup(const ConfigBackup &other)
+{
+ _ok = other._ok;
+ a = new BackupInternal;
+ a->backup = other.a->backup;
+}
+
+void ConfigBackup::revert()
+{
+ a->backup->revertChanges();
+}
+
+static QWeakPointer<BackupInternalInternal> currentBackup;
+
+/*
+ * Slightly more normal code starts here
+ */
static ScreenInfo initScreenInfo(const OutputInfo *oi, const ModeMap &om)
@@ -183,10 +311,14 @@ ScreenMode ScreenSetup::getCurrentMode()
return ScreenMode::Clone;
}
-ScreenMode ScreenSetup::setDefaultMode(bool dryRun)
+ConfigBackup ScreenSetup::setDefaultMode(bool dryRun, ScreenMode &mode)
{
- if (a->_outputMap.size() == 1) // Only one output exists, do nothing
- return ScreenMode::Single;
+ ConfigBackup retval;
+ if (a->_outputMap.size() == 1) { // Only one output exists, do nothing
+ retval._ok = (a->_outputMap.begin().value()->mode != nullptr);
+ mode = ScreenMode::Single;
+ return retval;
+ }
QMap<QString, OutputInfo*> screenMap;
QMap<QString, OutputInfo*> projectorMap;
for (auto o : a->_outputMap) {
@@ -201,11 +333,13 @@ ScreenMode ScreenSetup::setDefaultMode(bool dryRun)
auto screens = screenMap.values();
qDebug() << projectors.size() << "projectors," << screens.size() << "screens.";
QList<QSize> outputSizes = a->getTotalSize(projectors, screens);
- if (outputSizes.isEmpty())
- return ScreenMode::Advanced; // Dunno lol
+ if (outputSizes.isEmpty()) {
+ mode = ScreenMode::Advanced; // Dunno lol
+ return retval;
+ }
QSize screenSize = getTotalSizeHorz(outputSizes);
if (!dryRun) {
- a->createCrtcBackup();
+ retval = createCrtcBackup();
XGrabServer(a->_display);
a->disconnectAllCrtcs();
// Set new screen size
@@ -216,25 +350,34 @@ ScreenMode ScreenSetup::setDefaultMode(bool dryRun)
int offset = 0;
for (int i = 0; i < outputSizes.size(); ++i) {
+ bool ok = false;
const QSize &size = outputSizes.at(i);
if (i < projectors.size()) {
- a->setOutputResolution(projectors.at(i), offset, 0, size, dryRun);
+ ok = a->setOutputResolution(projectors.at(i), offset, 0, size, dryRun) || ok;
}
if (i < screens.size()) {
- a->setOutputResolution(screens.at(i), offset, 0, size, dryRun);
+ ok = a->setOutputResolution(screens.at(i), offset, 0, size, dryRun) || ok;
}
offset += size.width();
+ if (ok) {
+ retval._ok = true;
+ }
}
if (!dryRun) {
XUngrabServer(a->_display);
XSync(a->_display, False);
}
updateScreenResources(); // Re-Read
- if (outputSizes.size() == 1) // One output size, at least 2 outputs in total -- clone mode
- return ScreenMode::Clone;
- if (outputSizes.size() == 2 && a->_outputMap.size() == 2) // Two outputs, two sizes -- extended
- return ScreenMode::Dual;
- return ScreenMode::Advanced; // Must be more than 2 outputs -> something more involved
+ if (outputSizes.size() == 1) {
+ // One output size, at least 2 outputs in total -- clone mode
+ mode = ScreenMode::Clone;
+ } else if (outputSizes.size() == 2 && a->_outputMap.size() == 2) {
+ // Two outputs, two sizes -- extended
+ mode = ScreenMode::Dual;
+ } else {
+ mode = ScreenMode::Advanced; // Must be more than 2 outputs -> something more involved
+ }
+ return retval;
}
//___________________________________________________________________________
@@ -282,9 +425,9 @@ ScreenSetup::~ScreenSetup()
delete a;
}
-bool ScreenSetup::setCenteredClone()
+ConfigBackup ScreenSetup::setCenteredClone()
{
- a->createCrtcBackup();
+ ConfigBackup retval = createCrtcBackup();
XRRModeInfo *fallback = nullptr;
for (auto m : a->_modeMap) {
if (m->width == 1024 && m->height == 768) {
@@ -294,46 +437,48 @@ bool ScreenSetup::setCenteredClone()
}
XGrabServer(a->_display);
a->disconnectAllCrtcs();
- QSize screenSize;
- bool ok = false;
+ QSize screenSize;
for (auto oi : a->_outputMap) {
auto mode = a->getPreferredMode(oi, fallback);
if (mode != nullptr) {
if (int(mode->width) > screenSize.width()) {
- screenSize.setWidth(mode->width);
+ screenSize.setWidth(int(mode->width));
}
if (int(mode->height) > screenSize.height()) {
- screenSize.setHeight(mode->height);
- }
- // TODO: CENTER
- const int x = (screenSize.width() - mode->width) / 2;
- const int y = (screenSize.height() - mode->height) / 2;
- ok = a->setOutputResolution(oi, x, y, QSize(int(mode->width), int(mode->height))) || ok;
+ screenSize.setHeight(int(mode->height));
+ }
+ const int x = (screenSize.width() - int(mode->width)) / 2;
+ const int y = (screenSize.height() - int(mode->height)) / 2;
+ if (a->setOutputResolution(oi, x, y, QSize(int(mode->width), int(mode->height)))) {
+ retval._ok = true;
+ }
}
}
a->setScreenSize(screenSize);
XUngrabServer(a->_display);
XSync(a->_display, False);
- return ok;
+ return retval;
}
-bool ScreenSetup::setClone(const QSize &resolution)
+ConfigBackup ScreenSetup::setClone(const QSize &resolution)
{
- a->createCrtcBackup();
+ ConfigBackup retval = createCrtcBackup();
XGrabServer(a->_display);
a->disconnectAllCrtcs();
- a->setScreenSize(resolution);
- bool ok = false;
+ a->setScreenSize(resolution);
for (auto oi : a->_outputMap) {
- ok = a->setOutputResolution(oi, 0, 0, resolution) || ok;
+ if (a->setOutputResolution(oi, 0, 0, resolution)) {
+ retval._ok = true;
+ }
}
XUngrabServer(a->_display);
XSync(a->_display, False);
- return ok;
+ return retval;
}
-bool ScreenSetup::setCustom(const QList<QPair<QSize, QList<QString>>> &list)
+ConfigBackup ScreenSetup::setCustom(const QList<QPair<QSize, QList<QString>>> &list)
{
+ ConfigBackup retval;
QList<QSize> sizes;
for (auto e : list) {
if (e.second.isEmpty())
@@ -341,16 +486,15 @@ bool ScreenSetup::setCustom(const QList<QPair<QSize, QList<QString>>> &list)
sizes.append(e.first);
}
if (sizes.isEmpty())
- return false;
- a->createCrtcBackup();
+ return retval;
+ retval = createCrtcBackup();
auto screenSize = getTotalSizeHorz(sizes);
if (screenSize.isEmpty())
- return false;
+ return retval;
XGrabServer(a->_display);
a->disconnectAllCrtcs();
a->setScreenSize(screenSize);
- int x = 0;
- bool ok = false;
+ int x = 0;
for (auto e : list) {
if (e.second.isEmpty())
continue;
@@ -359,39 +503,16 @@ bool ScreenSetup::setCustom(const QList<QPair<QSize, QList<QString>>> &list)
for (auto oi : a->_outputMap) {
if (oi->outputName != outputName)
continue;
- ok = a->setOutputResolution(oi, x, 0, res) || ok;
+ if (a->setOutputResolution(oi, x, 0, res)) {
+ retval._ok = true;
+ }
}
}
x += res.width();
}
XUngrabServer(a->_display);
XSync(a->_display, False);
- return ok;
-}
-
-void ScreenSetup::revertChanges()
-{
- if (a->_crtcBackup.isEmpty())
- return;
- qDebug() << "Starting revert";
- XGrabServer(a->_display);
- a->disconnectAllCrtcs();
- QSize screenSize;
- for (auto e : a->_crtcBackup) {
- if (e->mode == None || !a->_modeMap.contains(e->mode))
- continue;
- screenSize = screenSize.expandedTo(QSize(e->x + int(a->_modeMap[e->mode]->width), e->y + int(a->_modeMap[e->mode]->height)));
- }
- a->setScreenSize(screenSize);
- for (CrtcMap::iterator it = a->_crtcBackup.begin(); it != a->_crtcBackup.end(); ++it) {
- auto e = it.value();
- if (e->mode == None)
- continue;
- XRRSetCrtcConfig(a->_display, a->_screenResources, it.key(), CurrentTime,
- e->x, e->y, e->mode, e->rotation, e->outputs, e->noutput);
- }
- XUngrabServer(a->_display);
- XSync(a->_display, False);
+ return retval;
}
static bool modeBiggerThan(const QSize &a, const QSize &b)
@@ -423,6 +544,19 @@ ResolutionVector ScreenSetup::getCommonModes() const
return ret;
}
+ConfigBackup ScreenSetup::createCrtcBackup()
+{
+ auto bd = currentBackup.toStrongRef();
+ if (bd.data() != nullptr && !bd->map.isEmpty()) {
+ ConfigBackup backup;
+ backup.a->backup = bd;
+ return backup;
+ }
+ ConfigBackup backup(a);
+ currentBackup = backup.a->backup.toWeakRef();
+ return backup;
+}
+
/**
* Return number of connected (no active) outputs according to last query
*/
diff --git a/src/xx.h b/src/xx.h
index 2e2e3f2..de52db3 100644
--- a/src/xx.h
+++ b/src/xx.h
@@ -8,6 +8,7 @@
struct ScreenInfo;
class XPrivate;
class QSocketNotifier;
+class BackupInternal;
typedef QVector<QSize> ResolutionVector;
@@ -39,6 +40,23 @@ enum class ConnectionEvent
Unknown,
};
+class ConfigBackup
+{
+ friend class ScreenSetup;
+protected:
+ explicit ConfigBackup(XPrivate*);
+ explicit ConfigBackup();
+private:
+ bool _ok;
+ BackupInternal* a;
+ ConfigBackup& operator=(const ConfigBackup &other);
+public:
+ ConfigBackup(const ConfigBackup &other);
+ ~ConfigBackup();
+ bool ok() const { return _ok; }
+ void revert();
+};
+
class ScreenSetup : public QObject
{
Q_OBJECT
@@ -46,12 +64,11 @@ public:
void updateScreenResources();
void initModes();
ScreenMode getCurrentMode();
- ScreenMode setDefaultMode(bool dryRun = false);
- bool createMode(unsigned int resX, unsigned int resY, float refresh, QString name);
- void revertChanges();
- bool setCenteredClone();
- bool setClone(const QSize &resolution);
- bool setCustom(const QList<QPair<QSize, QList<QString>>> &list);
+ ConfigBackup setDefaultMode(bool dryRun, ScreenMode &mode);
+ bool createMode(unsigned int resX, unsigned int resY, float refresh, QString name);
+ ConfigBackup setCenteredClone();
+ ConfigBackup setClone(const QSize &resolution);
+ ConfigBackup setCustom(const QList<QPair<QSize, QList<QString>>> &list);
ResolutionVector getCommonModes() const;
int getOutputCount() const;
int queryCurrentOutputCount() const;
@@ -67,6 +84,7 @@ public:
private:
ScreenSetup();
~ScreenSetup();
+ ConfigBackup createCrtcBackup();
static ScreenSetup * _instance;
XPrivate *a;