summaryrefslogtreecommitdiffstats
path: root/src/x.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/x.cpp')
-rw-r--r--src/x.cpp55
1 files changed, 34 insertions, 21 deletions
diff --git a/src/x.cpp b/src/x.cpp
index df257bb..73662c5 100644
--- a/src/x.cpp
+++ b/src/x.cpp
@@ -40,7 +40,9 @@ ScreenInfo::ScreenInfo(const OutputInfo *oi, const ModeMap &om)
if (om.contains(oi->output->modes[i])) {
auto m = om.value(oi->output->modes[i]);
const QSize size(int(m->width), int(m->height));
- modes.append(size);
+ if (!modes.contains(size)) {
+ modes.append(size);
+ }
if (i == 0 && oi->output->npreferred > 0) {
preferredResolution = size;
}
@@ -415,12 +417,12 @@ static QSize getTotalSizeHorz(const QList<QSize> &list)
return ret;
}
-void ScreenSetup::setOutputResolution(OutputInfo *oi, int x, int y, const QSize &size, bool dryRun)
+bool ScreenSetup::setOutputResolution(OutputInfo *oi, int x, int y, const QSize &size, bool dryRun)
{
RRMode mode = getOutputModeForResolution(oi->output, size);
if (mode == None) {
if (oi->output->nmode == 0)
- return;
+ return false;
qDebug() << oi->outputName << "doesn't support" << size << "- falling back to its default";
mode = oi->output->modes[0];
}
@@ -434,18 +436,27 @@ void ScreenSetup::setOutputResolution(OutputInfo *oi, int x, int y, const QSize
&oi->id, 1);
}
qDebug() << "Set" << oi->outputName << "to" << _modeMap[mode]->width << "x" << _modeMap[mode]->height << "-- offset" << x << "/" << y;
+ return true;
}
ScreenMode ScreenSetup::getCurrentMode()
{
- if (_outputMap.size() == 1)
- return ScreenMode::Single;
- if (_outputMap.size() > 2)
- return ScreenMode::Advanced;
+ int numConnected = 0;
+ bool notAtOrigin = false;
for (auto oi : _outputMap) {
- if (oi->crtc->x != 0 || oi->crtc->y != 0)
- return ScreenMode::Dual;
+ if (oi->mode != nullptr) {
+ ++numConnected;
+ if (oi->crtc->x != 0 || oi->crtc->y != 0) {
+ notAtOrigin = true;
+ }
+ }
}
+ if (numConnected == 1)
+ return ScreenMode::Single;
+ if (numConnected > 2)
+ return ScreenMode::Advanced;
+ if (notAtOrigin)
+ return ScreenMode::Dual;
return ScreenMode::Clone;
}
@@ -471,6 +482,7 @@ ScreenMode ScreenSetup::setDefaultMode(bool dryRun)
return ScreenMode::Advanced; // Dunno lol
QSize screenSize = getTotalSizeHorz(outputSizes);
if (!dryRun) {
+ XGrabServer(_display);
disconnectAllCrtcs();
// Set new screen size
setScreenSize(screenSize);
@@ -489,7 +501,10 @@ ScreenMode ScreenSetup::setDefaultMode(bool dryRun)
}
offset += size.width();
}
- XSync(_display, False);
+ if (!dryRun) {
+ XUngrabServer(_display);
+ XSync(_display, False);
+ }
updateScreenResources(); // Re-Read
if (outputSizes.size() == 1) // One output size, at least 2 outputs in total -- clone mode
return ScreenMode::Clone;
@@ -661,16 +676,14 @@ void ScreenSetup::createCrtcBackup()
bool ScreenSetup::setClone(const QSize &resolution)
{
createCrtcBackup();
+ XGrabServer(_display);
disconnectAllCrtcs();
setScreenSize(resolution);
bool ok = false;
for (auto oi : _outputMap) {
- RRMode mode = getOutputModeForResolution(oi->output, resolution);
- if (mode != None) {
- XRRSetCrtcConfig(_display, _screenResources, oi->output->crtc, CurrentTime, 0, 0, mode, RR_Rotate_0, &oi->id, 1);
- ok = true;
- }
+ ok = setOutputResolution(oi, 0, 0, resolution) || ok;
}
+ XUngrabServer(_display);
XSync(_display, False);
return ok;
}
@@ -685,6 +698,7 @@ bool ScreenSetup::setCustom(const QList<QPair<QSize, QList<QString>>> &list)
auto screenSize = getTotalSizeHorz(sizes);
if (screenSize.isEmpty())
return false;
+ XGrabServer(_display);
disconnectAllCrtcs();
setScreenSize(screenSize);
int x = 0;
@@ -695,15 +709,12 @@ bool ScreenSetup::setCustom(const QList<QPair<QSize, QList<QString>>> &list)
for (auto oi : _outputMap) {
if (oi->outputName != outputName)
continue;
- RRMode mode = getOutputModeForResolution(oi->output, res);
- if (mode == None)
- continue;
- XRRSetCrtcConfig(_display, _screenResources, oi->output->crtc, CurrentTime, x, 0, mode, RR_Rotate_0, &oi->id, 1);
- ok = true;
+ ok = setOutputResolution(oi, x, 0, res) || ok;
}
}
x += res.width();
}
+ XUngrabServer(_display);
XSync(_display, False);
return ok;
}
@@ -713,6 +724,7 @@ void ScreenSetup::revertChanges()
if (_crtcBackup.isEmpty())
return;
qDebug() << "Starting revert";
+ XGrabServer(_display);
disconnectAllCrtcs();
QSize screenSize;
for (auto e : _crtcBackup) {
@@ -727,7 +739,8 @@ void ScreenSetup::revertChanges()
XRRSetCrtcConfig(_display, _screenResources, it.key(), CurrentTime,
e->x, e->y, e->mode, e->rotation, e->outputs, e->noutput);
}
- XSync (_display, False);
+ XUngrabServer(_display);
+ XSync(_display, False);
}
static bool modeBiggerThan(const QSize &a, const QSize &b)