summaryrefslogtreecommitdiffstats
path: root/src/widget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widget.cpp')
-rw-r--r--src/widget.cpp141
1 files changed, 122 insertions, 19 deletions
diff --git a/src/widget.cpp b/src/widget.cpp
index a5f32fa..34684b5 100644
--- a/src/widget.cpp
+++ b/src/widget.cpp
@@ -7,6 +7,8 @@
#include <QDebug>
#include <QtWidgets/QAction>
#include <QAbstractItemView>
+#include <QScreen>
+#include <QThread>
class ScreenWidget : public QWidget
{
@@ -16,6 +18,10 @@ public:
QWidget::setStyleSheet(".QWidget { border-radius: 3px;border: 2px solid black; }");
QWidget::setLayout(new QVBoxLayout(this));
}
+ void setScaling(float scale)
+ {
+ this->scale = scale;
+ }
protected:
float scale;
void resizeEvent(QResizeEvent *event) override
@@ -59,12 +65,39 @@ static void addBoldListener(QComboBox *combo)
//______________________________________________________________________________
Widget::Widget(QWidget *parent) :
QWidget(parent),
- _ui(new Ui::Widget)
+ _ui(new Ui::Widget),
+ _popupCount(0)
{
_ui->setupUi(this);
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
QTimer *top = new QTimer(this);
connect(top, &QTimer::timeout, [=]() {
+ // 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);
+ }
+ // Raise window if appropriate
+ if (_popupCount > 0)
+ return;
auto combos = this->findChildren<QComboBox*>();
for (auto combo : combos) {
if (combo->view()->isVisible())
@@ -77,6 +110,22 @@ Widget::Widget(QWidget *parent) :
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) {
+
+ });
+ */
+ };
+ for (auto scrn : QGuiApplication::screens()) {
+ fun(scrn);
+ }
+ connect(qApp, &QGuiApplication::screenAdded, fun);
+ connect(qApp, &QGuiApplication::screenRemoved, [this](const QScreen *scrn) {
+ _qtScreens.removeAll(scrn);
+ });
}
//______________________________________________________________________________
@@ -178,7 +227,14 @@ void Widget::initControls()
auto lists = QList<QComboBox*>({_ui->cboDualLeft, _ui->cboDualRight});
int j = 0;
for (int i = 0; i < screenList.size() && j < 2; ++i) {
- fillCombo(lists[j], screenList[i].modes, screenList[i].currentResolution, screenList[i].preferredResolution);
+ QSize selected;
+ if (ScreenSetup::inst()->getCurrentMode() == ScreenMode::Dual) {
+ // When we're not in dualhead mode, pre-select the preferred solution, so in case the user wants
+ // to switch to dualhead, they just need to switch to the "dual" tab and hit apply to get
+ // each screen configured to its preferred resolution.
+ selected = screenList[i].currentResolution;
+ }
+ fillCombo(lists[j], screenList[i].modes, selected, screenList[i].preferredResolution);
lists[j]->setProperty("output", screenList[i].output);
QLabel *sl = ( j == 0 ? _ui->lblDualLeft : _ui->lblDualRight );
sl->setText(screenList[i].output + "\n" + screenList[i].name);
@@ -225,7 +281,7 @@ void Widget::initControls()
res = QSize(16, 9);
}
AdvancedScreen *a = new AdvancedScreen();
- a->screen = new ScreenWidget(float(res.width()) / float(res.height()));
+ a->screen = new ScreenWidget(res.isEmpty() ? 1.33f : float(res.width()) / float(res.height()));
a->desiredResolution = res;
a->cboResolution = new QComboBox();
_ui->advancedContainer->addWidget(a->screen);
@@ -233,12 +289,19 @@ void Widget::initControls()
a->screen->layout()->addWidget(a->cboResolution);
a->screen->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
positionList.append(QString::number(_advancedScreens.size()));
- connect(a->cboResolution, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index) {
+ connect(a->cboResolution, QOverload<int>::of(&QComboBox::currentIndexChanged), [a, this](int index) {
if (!_ignoreResolutionChange) {
a->desiredResolution = a->cboResolution->itemData(index).toSize();
}
});
addBoldListener(a->cboResolution);
+ connect(a->cboResolution, QOverload<int>::of(&QComboBox::currentIndexChanged), [a, this](int index) {
+ if (index < 0)
+ return;
+ QSize res = a->cboResolution->itemData(index).toSize();
+ a->screen->setScaling(res.isEmpty() ? 1.33f : float(res.width()) / float(res.height()));
+ _ui->advancedContainer->update();
+ });
}
// Header
_ui->advancedCombos->addWidget(new QLabel(tr("Output")), 0, 0);
@@ -262,10 +325,10 @@ void Widget::initControls()
// Logic
cbo->addItems(positionList);
// TODO Signal
- connect(cbo, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index) {
+ connect(cbo, QOverload<int>::of(&QComboBox::currentIndexChanged), [a, this](int index) {
a->info.position = index - 1;
if (a->assignmentLabel->layout() != nullptr) {
- a->assignmentLabel->layout()->removeWidget(cbo);
+ a->assignmentLabel->layout()->removeWidget(a->cboPosition);
}
if (index > 0) {
_advancedScreens[index - 1]->screen->layout()->addWidget(a->assignmentLabel);
@@ -318,23 +381,63 @@ void Widget::initControls()
bool Widget::keepResolution()
{
- // Show a dialog asking if the res should be kept
- TimeOutDialog keepDialog(15, this);
- keepDialog.setWindowModality(Qt::ApplicationModal);
- keepDialog.setWindowTitle(" ");
- keepDialog.setLabelText(trUtf8("Do you want to keep this resolution?"));
- keepDialog.setCancelButtonText(trUtf8("Keep"));
- /*
- keepDialog.move(monitorMode->width/2 - this->width()/2,
- monitorMode->height/2 - this->height());
- */
- keepDialog.show();
+ _popupCount += 1;
+ // Qt needs some time to notice the screen setup has changed
+ QCoreApplication::processEvents();
+ QThread::msleep(10);
+ QCoreApplication::processEvents();
+ QList<TimeOutDialog*> list;
+ this->setDisabled(true);
+ for (auto screen : _qtScreens) {
+ QRect geo = screen->geometry();
+ bool skip = false;
+ // See if it overlaps with an existing screen
+ for (auto other : _qtScreens) {
+ if (other == screen)
+ break;
+ if (other->geometry().intersects(geo)) {
+ skip = true;
+ break;
+ }
+ }
+ if (skip)
+ continue;
+ // Show a dialog asking if the res should be kept
+ TimeOutDialog *keepDialog = new TimeOutDialog(15, this);
+ //keepDialog->setWindowModality(Qt::WindowModal);
+ keepDialog->setWindowTitle(" ");
+ keepDialog->setLabelText(trUtf8("Do you want to keep this resolution?"));
+ keepDialog->setCancelButtonText(trUtf8("Keep"));
+ keepDialog->setWindowFlag(Qt::WindowStaysOnTopHint, true);
+ QSize s = (geo.size() - keepDialog->size()) / 2;
+ QPoint tl = geo.topLeft();
+ tl.rx() += s.width();
+ tl.ry() += s.height();
+ keepDialog->move(tl);
+ keepDialog->show();
+ list.append(keepDialog);
+ }
+ bool wasCanceled = false;
+ bool active;
do {
+ active = true;
QCoreApplication::processEvents();
- } while (keepDialog.isActive());
+ for (auto win : list) {
+ active = active && win->isActive();
+ wasCanceled = wasCanceled || win->wasCanceled();
+ }
+ } while (active && !wasCanceled);
+
+ for (auto win : list) {
+ win->deleteLater();
+ }
+
+ this->setDisabled(false);
+
+ _popupCount -= 1;
- return keepDialog.wasCanceled();
+ return wasCanceled;
}
//______________________________________________________________________________