diff options
Diffstat (limited to 'src/widget.cpp')
-rw-r--r-- | src/widget.cpp | 182 |
1 files changed, 124 insertions, 58 deletions
diff --git a/src/widget.cpp b/src/widget.cpp index bc4869f..49e5285 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -68,6 +68,9 @@ static void addBoldListener(QComboBox *combo) }); } +static const QString resetButtonStyle("padding: 2px; margin: 0 0 1px 1px;"); +static const QString resetButtonHotStyle(resetButtonStyle + "background-color: #f99;"); + /* * Main widget */ @@ -77,64 +80,92 @@ Widget::Widget(QWidget *parent) : _ui(new Ui::Widget), _popupCount(0), _iProjector(QIcon(":projector")), - _iScreen(QIcon(":screen")) + _iScreen(QIcon(":screen")), + _lastScreenCount(0), + _isDbus(true) { _ui->setupUi(this); + // Add refresh button + _ui->btnReload->setStyleSheet(resetButtonStyle); + _ui->tabWidget->setCornerWidget(_ui->btnReload); + connect(_ui->btnReload, &QPushButton::clicked, [=](bool) { + _ui->btnReload->setStyleSheet(resetButtonStyle); + ScreenSetup::inst()->initModes(); + initControls(); + }); setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); QTimer *top = new QTimer(this); connect(top, &QTimer::timeout, [=]() { + if (this->isHidden()) + return; // Move window to current screen - QRect win = this->geometry(); - QPoint cursor = QCursor::pos(); - const QScreen *winScreen = nullptr, *mouseScreen = nullptr; - //qDebug() << "Mouse at" << cursor << " window at" << win; - for (auto screen : _qtScreens) { - QRect geo = screen->geometry(); - if (geo.contains(win)) { - winScreen = screen; - //qDebug() << "Window on screen" << geo; - } - if (geo.contains(cursor)) { - mouseScreen = screen; - //qDebug() << "Mouse on screen" << geo; - } - } - if (mouseScreen != nullptr && mouseScreen != winScreen) { - QPoint offset = mouseScreen->geometry().topLeft(); - QSize spacing = (mouseScreen->size() - this->size()) / 2; - offset.rx() += spacing.width(); - offset.ry() += spacing.height(); - this->move(offset); + if (qApp->mouseButtons() == Qt::NoButton) { + updateWindowPlacement(); } // Raise window if appropriate - if (_popupCount > 0) - return; - auto combos = this->findChildren<QComboBox*>(); - for (auto combo : combos) { - if (combo->view()->isVisible()) - return; + if (_popupCount == 0) { + bool ok = true; + auto combos = this->findChildren<QComboBox*>(); + for (auto combo : combos) { + if (combo->view()->isVisible()) { + ok = false; + break; + } + } + if (ok) { + raise(); + } } - raise(); }); top->start(1000); addBoldListener(_ui->cboCloneResolution); addBoldListener(_ui->cboDualLeft); addBoldListener(_ui->cboDualRight); connectButtons(); - auto fun = [this](const QScreen *scrn) { - qDebug() << "QT SEES SCREEN" << scrn->geometry(); - _qtScreens.append(scrn); - /* - connect(scrn, &QScreen::geometryChanged, [this](const QRect &geom) { - - }); - */ + // Handle screens on Qt level + // Timer + QTimer *t = new QTimer(this); + t->setSingleShot(true); + // Worked fine + connect(t, &QTimer::timeout, [=]() { + int currentCount = ScreenSetup::inst()->queryCurrentOutputCount(); + qDebug() << "Timeout. Dbus:" << _isDbus << "old count:" << _lastScreenCount << "new count:" << currentCount; + if (_isDbus && _lastScreenCount >= currentCount) + return; // Ignore dbus events if the screen count didn't change (or decreased) + if (this->isHidden()) { + ScreenSetup::inst()->initModes(); + _isDbus = true; + this->show(); + } else { + if (currentCount > _lastScreenCount) { + ScreenSetup::inst()->initModes(); + initControls(); + } else { + _ui->btnReload->setStyleSheet(resetButtonHotStyle); + } + } + }); + auto popupGui = [=]() { + if (this->isHidden()) { + t->start(1000); + } else { + _ui->btnReload->setStyleSheet(resetButtonHotStyle); + } }; for (auto scrn : QGuiApplication::screens()) { - fun(scrn); + _qtScreens.append(scrn); } - connect(qApp, &QGuiApplication::screenAdded, fun); - connect(qApp, &QGuiApplication::screenRemoved, [this](const QScreen *scrn) { + connect(qApp, &QGuiApplication::screenAdded, [=](const QScreen *scrn) { + qDebug() << "QT SEES SCREEN" << scrn->geometry(); + _qtScreens.append(scrn); + if (CommandLine::backgroundMode()) { + qDebug() << "Qt setting FALSE"; + _isDbus = false; + popupGui(); + } + }); + connect(qApp, &QGuiApplication::screenRemoved, [=](const QScreen *scrn) { + qDebug() << "Qt lost screen" << scrn->geometry(); _qtScreens.removeAll(scrn); }); _ui->btnExit->setVisible(CommandLine::backgroundMode()); @@ -144,28 +175,23 @@ Widget::Widget(QWidget *parent) : qDebug() << "WARNING: CANNOT CONNECT TO DBUS FOR LISTENING"; // TODO: GUI feedback } else { - // Worked fine - // Timer - QTimer *t = new QTimer(this); - t->setSingleShot(true); - connect(t, &QTimer::timeout, [=]() { - if (this->isHidden()) { - ScreenSetup::inst()->initModes(); - this->show(); - } else { - // TODO: Flash button - } - }); // GUI popup logic connect(Bus::inst(), &Bus::serviceConnected, [=]() { qDebug() << "\\o/ Received DBus connect notification \\o/"; - if (this->isHidden()) { - t->start(1500); - } else { - // TODO: Flash button - } + popupGui(); }); } + // Xlib + connect(ScreenSetup::inst(), &ScreenSetup::outputConfigChanged, [=](ConnectionEvent type) { + if (type == ConnectionEvent::Disconnected) { + if (!this->isHidden()) { + _ui->btnReload->setStyleSheet(resetButtonHotStyle); + } + } else { + _isDbus = false; + popupGui(); + } + }); } } @@ -178,6 +204,7 @@ void Widget::showEvent(QShowEvent *event) { QWidget::showEvent(event); initControls(true); + updateWindowPlacement(true); } static void fillCombo(QComboBox *combo, const ResolutionVector &resolutions, const QSize &preselected, const QSize &preferred = QSize()) @@ -223,6 +250,8 @@ void Widget::comboBold(int index) void Widget::initControls(bool jumpToTab) { + _lastScreenCount = ScreenSetup::inst()->getOutputCount(); + _ui->btnReload->setStyleSheet(resetButtonStyle); // ScreenMode currentOpMode = ScreenSetup::inst()->getCurrentMode(); _ui->tabWidget->setTabEnabled(1, CommandLine::testMode() || ScreenSetup::inst()->getOutputCount() == 2 || currentOpMode == ScreenMode::Dual); @@ -265,13 +294,24 @@ void Widget::initControls(bool jumpToTab) QSize preferredClone; for (auto screen : screenList) { if (!screen.preferredResolution.isEmpty()) { - preferredClone = screen.preferredResolution; + if (screen.isProjector // Projector always overrides + || preferredClone.isEmpty() // Have no preferred yet + || screen.preferredResolution.width() < preferredClone.width() // For normal screens, + || screen.preferredResolution.height() < preferredClone.height()) { // smallest wins + preferredClone = screen.preferredResolution; + } if (screen.isProjector) break; } } fillCombo(_ui->cboCloneResolution, modes, screenList[0].currentResolution, preferredClone); // Dual + _ui->dualContainer->takeAt(0); + _ui->dualContainer->takeAt(1); + _ui->dualContainer->takeAt(2); + _ui->dualContainer->addLayout(_ui->dualLeft); + _ui->dualContainer->addWidget(_ui->btnDualSwap); + _ui->dualContainer->addLayout(_ui->dualRight); if (screenList.size() >= 2) { auto lists = QList<QComboBox*>({_ui->cboDualLeft, _ui->cboDualRight}); int j = 0; @@ -575,4 +615,30 @@ void Widget::connectButtons() { } +void Widget::updateWindowPlacement(bool force) +{ + QRect win = this->geometry(); + QPoint cursor = QCursor::pos(); + const QScreen *winScreen = nullptr, *mouseScreen = nullptr; + //qDebug() << "Mouse at" << cursor << " window at" << win; + for (auto screen : _qtScreens) { + QRect geo = screen->geometry(); + if (geo.contains(win)) { + winScreen = screen; + //qDebug() << "Window on screen" << geo; + } + if (geo.contains(cursor)) { + mouseScreen = screen; + //qDebug() << "Mouse on screen" << geo; + } + } + if (mouseScreen != nullptr && (force || mouseScreen != winScreen)) { + QPoint offset = mouseScreen->geometry().topLeft(); + QSize spacing = (mouseScreen->size() - this->size()) / 2; + offset.rx() += spacing.width(); + offset.ry() += spacing.height(); + this->move(offset); + } +} + //////////////////////////////////////////////////////////////////////////////// |