Skip to content

Commit 947b8d1

Browse files
committed
Create a window per screen
A big window for all screens may hit hardware limits and it often has a bad alignment as reported by #265. Creating a window per screen doesn't suffer from these problems and, as a nice side effects, it helps the Wayland port. [ChangeLog][Greeter][Behavioral Change] Create a window per screen.
1 parent 622b4d8 commit 947b8d1

File tree

3 files changed

+72
-30
lines changed

3 files changed

+72
-30
lines changed

src/greeter/GreeterApp.cpp

Lines changed: 62 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/***************************************************************************
2+
* Copyright (c) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
23
* Copyright (c) 2013 Abdurrahman AVCI <abdurrahmanavci@gmail.com>
34
*
45
* This program is free software; you can redistribute it and/or modify
@@ -70,16 +71,10 @@ namespace SDDM {
7071
QString socket = parameter(arguments(), "--socket", "");
7172

7273
// get theme path
73-
QString themePath = parameter(arguments(), "--theme", "");
74-
75-
// create view
76-
m_view = new QQuickView();
77-
m_view->setResizeMode(QQuickView::SizeRootObjectToView);
78-
79-
m_view->engine()->addImportPath(IMPORTS_INSTALL_DIR);
74+
m_themePath = parameter(arguments(), "--theme", "");
8075

8176
// read theme metadata
82-
m_metadata = new ThemeMetadata(QString("%1/metadata.desktop").arg(themePath));
77+
m_metadata = new ThemeMetadata(QString("%1/metadata.desktop").arg(m_themePath));
8378

8479
// Translations
8580
// Components translation
@@ -90,11 +85,11 @@ namespace SDDM {
9085
// Theme specific translation
9186
m_theme_translator = new QTranslator();
9287
if (m_theme_translator->load(QLocale::system(), "", "",
93-
QString("%1/%2/").arg(themePath, m_metadata->translationsDirectory())))
88+
QString("%1/%2/").arg(m_themePath, m_metadata->translationsDirectory())))
9489
installTranslator(m_theme_translator);
9590

9691
// get theme config file
97-
QString configFile = QString("%1/%2").arg(themePath).arg(m_metadata->configFile());
92+
QString configFile = QString("%1/%2").arg(m_themePath).arg(m_metadata->configFile());
9893

9994
// read theme config
10095
m_themeConfig = new ThemeConfig(configFile);
@@ -134,35 +129,74 @@ namespace SDDM {
134129

135130
m_proxy->setSessionModel(m_sessionModel);
136131

132+
// create views
133+
Q_FOREACH (QScreen *screen, screens())
134+
addViewForScreen(screen);
135+
136+
// handle screens
137+
connect(this, &GreeterApp::screenAdded, this, &GreeterApp::addViewForScreen);
138+
}
139+
140+
void GreeterApp::addViewForScreen(QScreen *screen) {
141+
// heuristic to detect clone mode, in that case only add a view for the primary screen
142+
if (screen->virtualGeometry() == primaryScreen()->geometry() && screen != primaryScreen())
143+
return;
144+
145+
// create view
146+
QQuickView *view = new QQuickView();
147+
view->setScreen(screen);
148+
view->setResizeMode(QQuickView::SizeRootObjectToView);
149+
view->setGeometry(QRect(QPoint(0, 0), screen->availableGeometry().size()));
150+
151+
// remove the view when the screen is removed, but we
152+
// need to be careful here since Qt will move the view to
153+
// another screen before this signal is emitted so we
154+
// pass a pointer to the view to our slot
155+
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
156+
connect(this, &GreeterApp::screenRemoved, this, [view, this](QScreen *) {
157+
removeViewForScreen(view);
158+
});
159+
#else
160+
connect(view, &QQuickView::screenChanged, this, [view, this](QScreen *screen) {
161+
if (screen == Q_NULLPTR)
162+
removeViewForScreen(view);
163+
});
164+
#endif
165+
166+
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
167+
// always resize when the screen geometry changes
168+
connect(screen, &QScreen::availableGeometryChanged, this, [view](const QRect &r) {
169+
view->setGeometry(QRect(QPoint(0, 0), r.size()));
170+
});
171+
#endif
172+
173+
view->engine()->addImportPath(IMPORTS_INSTALL_DIR);
174+
137175
// connect proxy signals
138-
QObject::connect(m_proxy, SIGNAL(loginSucceeded()), m_view, SLOT(close()));
176+
connect(m_proxy, SIGNAL(loginSucceeded()), view, SLOT(close()));
139177

140178
// set context properties
141-
m_view->rootContext()->setContextProperty("sessionModel", m_sessionModel);
142-
m_view->rootContext()->setContextProperty("screenModel", m_screenModel);
143-
m_view->rootContext()->setContextProperty("userModel", m_userModel);
144-
m_view->rootContext()->setContextProperty("config", *m_themeConfig);
145-
m_view->rootContext()->setContextProperty("sddm", m_proxy);
146-
m_view->rootContext()->setContextProperty("keyboard", m_keyboard);
179+
view->rootContext()->setContextProperty("sessionModel", m_sessionModel);
180+
view->rootContext()->setContextProperty("screenModel", m_screenModel);
181+
view->rootContext()->setContextProperty("userModel", m_userModel);
182+
view->rootContext()->setContextProperty("config", *m_themeConfig);
183+
view->rootContext()->setContextProperty("sddm", m_proxy);
184+
view->rootContext()->setContextProperty("keyboard", m_keyboard);
147185

148186
// get theme main script
149-
QString mainScript = QString("%1/%2").arg(themePath).arg(m_metadata->mainScript());
187+
QString mainScript = QString("%1/%2").arg(m_themePath).arg(m_metadata->mainScript());
150188

151189
// set main script as source
152-
m_view->setSource(QUrl::fromLocalFile(mainScript));
190+
view->setSource(QUrl::fromLocalFile(mainScript));
153191

154-
// connect screen update signals
155-
connect(m_screenModel, SIGNAL(primaryChanged()), this, SLOT(show()));
156-
157-
show();
192+
// show
193+
view->show();
158194
}
159195

160-
void GreeterApp::show() {
161-
m_view->setGeometry(m_screenModel->geometry());
162-
m_view->show();
163-
m_view->requestActivate();
196+
void GreeterApp::removeViewForScreen(QQuickView *view) {
197+
m_views.removeOne(view);
198+
view->deleteLater();
164199
}
165-
166200
}
167201

168202
int main(int argc, char **argv) {

src/greeter/GreeterApp.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/***************************************************************************
2+
* Copyright (c) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
23
* Copyright (c) 2013 Nikita Mikhaylov <nslqqq@gmail.com>
34
*
45
* This program is free software; you can redistribute it and/or modify
@@ -21,6 +22,7 @@
2122
#define GREETERAPP_H
2223

2324
#include <QGuiApplication>
25+
#include <QScreen>
2426
#include <QQuickView>
2527

2628
class QTranslator;
@@ -47,15 +49,17 @@ namespace SDDM {
4749
static GreeterApp *instance() { return self; }
4850

4951
private slots:
50-
void show();
52+
void addViewForScreen(QScreen *screen);
53+
void removeViewForScreen(QQuickView *view);
5154

5255
private:
5356
static GreeterApp *self;
5457

55-
QQuickView *m_view { nullptr };
58+
QList<QQuickView *> m_views;
5659
QTranslator *m_theme_translator { nullptr },
5760
*m_components_tranlator { nullptr };
5861

62+
QString m_themePath;
5963
ThemeMetadata *m_metadata { nullptr };
6064
ThemeConfig *m_themeConfig { nullptr };
6165
SessionModel *m_sessionModel { nullptr };

src/greeter/ScreenModel.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,13 @@ namespace SDDM {
120120
return;
121121
#endif
122122

123+
QScreen *primaryScreen = QGuiApplication::primaryScreen();
123124
QList<QScreen *> screens = QGuiApplication::screens();
124125
for (int i = 0; i < screens.size(); ++i) {
125126
QScreen *screen = screens.at(i);
127+
// heuristic to detect clone mode, in that case only consider the primary screen
128+
if (screen->virtualGeometry() == primaryScreen->geometry() && screen != primaryScreen)
129+
continue;
126130
// add to the screens list
127131
d->screens << ScreenPtr { new Screen { QString("Screen %1").arg(i + 1), screen->geometry() } };
128132
// extend available geometry

0 commit comments

Comments
 (0)