From 1a0bb4e833f4a6dbef65f4f4641f9920c13a04fc Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 11 Aug 2017 15:00:33 +0200 Subject: Move code to src/, tweak CMakeLists.txt --- CMakeLists.txt | 17 ++-- loginform.cpp | 197 --------------------------------------- loginform.h | 64 ------------- loginform.ui | 267 ----------------------------------------------------- main.cpp | 57 ------------ mainwindow.cpp | 126 ------------------------- mainwindow.h | 41 -------- settings.cpp | 21 ----- settings.h | 41 -------- src/loginform.cpp | 197 +++++++++++++++++++++++++++++++++++++++ src/loginform.h | 64 +++++++++++++ src/loginform.ui | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 57 ++++++++++++ src/mainwindow.cpp | 126 +++++++++++++++++++++++++ src/mainwindow.h | 41 ++++++++ src/settings.cpp | 21 +++++ src/settings.h | 41 ++++++++ 17 files changed, 824 insertions(+), 821 deletions(-) delete mode 100644 loginform.cpp delete mode 100644 loginform.h delete mode 100644 loginform.ui delete mode 100644 main.cpp delete mode 100644 mainwindow.cpp delete mode 100644 mainwindow.h delete mode 100644 settings.cpp delete mode 100644 settings.h create mode 100644 src/loginform.cpp create mode 100644 src/loginform.h create mode 100644 src/loginform.ui create mode 100644 src/main.cpp create mode 100644 src/mainwindow.cpp create mode 100644 src/mainwindow.h create mode 100644 src/settings.cpp create mode 100644 src/settings.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d217c7..2fd0179 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,20 +1,23 @@ cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) -set(PROJECT qt-lightdm-greeter) -project(${PROJECT}) + +PROJECT(qt-lightdm-greeter) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_BUILD_TYPE Debug) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) -file(GLOB SRCS *.cpp *ui *moc) -message(STATUS "SRCS ${SRCS}") +file(GLOB_RECURSE SRCS src/*.cpp) +file(GLOB_RECURSE UIS src/*.ui) +#message(STATUS "SRCS ${SRCS}") find_package(Qt5Widgets REQUIRED) find_package(Qt5Svg REQUIRED) -#find_package(Qt5X11Extras REQUIRED QUIET) QT5_ADD_RESOURCES(RSCS qt-lightdm-greeter.qrc) -QT5_WRAP_UI(loginform_UI loginform.ui) +QT5_WRAP_UI(UI_HEADERS ${UIS}) include(FindPkgConfig) pkg_check_modules(LIGHTDM_QT liblightdm-qt5-3) @@ -24,7 +27,7 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ${LIGHTDM_QT_INCLUDE_DIRS} ) -add_executable ( qt-lightdm-greeter ${SRCS} ${RSCS}) +add_executable ( qt-lightdm-greeter ${SRCS} ${RSCS} ${UI_HEADERS} ) target_link_libraries ( qt-lightdm-greeter Qt5::Widgets Qt5::Svg ${LIGHTDM_QT_LIBRARIES} ) diff --git a/loginform.cpp b/loginform.cpp deleted file mode 100644 index 3f40e81..0000000 --- a/loginform.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* -* Copyright (c) 2012-2015 Christian Surlykke -* -* This file is part of qt-lightdm-greeter -* It is distributed under the LGPL 2.1 or later license. -* Please refer to the LICENSE file for a copy of the license. -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "loginform.h" -#include "ui_loginform.h" -#include "settings.h" - -const int KeyRole = QLightDM::SessionsModel::KeyRole; - -int rows(QAbstractItemModel& model) { - return model.rowCount(QModelIndex()); -} - -QString displayData(QAbstractItemModel& model, int row, int role) -{ - QModelIndex modelIndex = model.index(row, 0); - return model.data(modelIndex, role).toString(); -} - -LoginForm::LoginForm(QWidget *parent) : - QWidget(parent), - ui(new Ui::LoginForm), - m_Greeter(), - power(this), - sessionsModel() -{ - if (!m_Greeter.connectSync()) { - close(); - } - - ui->setupUi(this); - initialize(); -} - -LoginForm::~LoginForm() -{ - delete ui; -} - -void LoginForm::setFocus(Qt::FocusReason reason) -{ - if (ui->userInput->text().isEmpty()) { - ui->userInput->setFocus(reason); - } else { - ui->passwordInput->setFocus(reason); - } -} - - -void LoginForm::initialize() -{ - QPixmap icon(":/resources/rqt-2.png"); // This project came from Razor-qt - ui->iconLabel->setPixmap(icon.scaled(ui->iconLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); - ui->hostnameLabel->setText(m_Greeter.hostname()); - - ui->sessionCombo->setModel(&sessionsModel); - - addLeaveEntry(power.canShutdown(), "system-shutdown", tr("Shutdown"), "shutdown"); - addLeaveEntry(power.canRestart(), "system-reboot", tr("Restart"), "restart"); - addLeaveEntry(power.canHibernate(), "system-suspend-hibernate", tr("Hibernate"), "hibernate"); - addLeaveEntry(power.canSuspend(), "system-suspend", tr("Suspend"), "suspend"); - ui->leaveComboBox->setDisabled(ui->leaveComboBox->count() <= 1); - - ui->sessionCombo->setCurrentIndex(0); - setCurrentSession(m_Greeter.defaultSessionHint()); - - connect(ui->userInput, SIGNAL(editingFinished()), this, SLOT(userChanged())); - connect(ui->leaveComboBox, SIGNAL(activated(int)), this, SLOT(leaveDropDownActivated(int))); - connect(&m_Greeter, SIGNAL(showPrompt(QString, QLightDM::Greeter::PromptType)), this, SLOT(onPrompt(QString, QLightDM::Greeter::PromptType))); - connect(&m_Greeter, SIGNAL(authenticationComplete()), this, SLOT(authenticationComplete())); - - ui->passwordInput->setEnabled(false); - ui->passwordInput->clear(); - - if (! m_Greeter.hideUsersHint()) { - QStringList knownUsers; - QLightDM::UsersModel usersModel; - for (int i = 0; i < usersModel.rowCount(QModelIndex()); i++) { - knownUsers << usersModel.data(usersModel.index(i, 0), QLightDM::UsersModel::NameRole).toString(); - } - ui->userInput->setCompleter(new QCompleter(knownUsers)); - ui->userInput->completer()->setCompletionMode(QCompleter::InlineCompletion); - } - - QString user = Cache().getLastUser(); - if (user.isEmpty()) { - user = m_Greeter.selectUserHint(); - } - ui->userInput->setText(user); - userChanged(); -} - -void LoginForm::userChanged() -{ - setCurrentSession(Cache().getLastSession(ui->userInput->text())); - - if (m_Greeter.inAuthentication()) { - m_Greeter.cancelAuthentication(); - } - if (! ui->userInput->text().isEmpty()) { - m_Greeter.authenticate(ui->userInput->text()); - ui->passwordInput->setFocus(); - } - else { - ui->userInput->setFocus(); - } -} - -void LoginForm::leaveDropDownActivated(int index) -{ - QString actionName = ui->leaveComboBox->itemData(index).toString(); - if (actionName == "shutdown") power.shutdown(); - else if (actionName == "restart") power.restart(); - else if (actionName == "hibernate") power.hibernate(); - else if (actionName == "suspend") power.suspend(); -} - -void LoginForm::respond() -{ - m_Greeter.respond(ui->passwordInput->text().trimmed()); - ui->passwordInput->clear(); - ui->passwordInput->setEnabled(false); -} - -void LoginForm::onPrompt(QString prompt, QLightDM::Greeter::PromptType promptType) -{ - ui->passwordInput->setEnabled(true); - ui->passwordInput->setFocus(); -} - - -void LoginForm::addLeaveEntry(bool canDo, QString iconName, QString text, QString actionName) -{ - if (canDo) { - ui->leaveComboBox->addItem(QIcon::fromTheme(iconName), text, actionName); - } -} - -QString LoginForm::currentSession() -{ - QModelIndex index = sessionsModel.index(ui->sessionCombo->currentIndex(), 0, QModelIndex()); - return sessionsModel.data(index, QLightDM::SessionsModel::KeyRole).toString(); -} - -void LoginForm::setCurrentSession(QString session) -{ - for (int i = 0; i < ui->sessionCombo->count(); i++) { - if (session == sessionsModel.data(sessionsModel.index(i, 0), KeyRole).toString()) { - ui->sessionCombo->setCurrentIndex(i); - return; - } - } -} - - -void LoginForm::authenticationComplete() -{ - if (m_Greeter.isAuthenticated()) { - Cache().setLastUser(ui->userInput->text()); - Cache().setLastSession(ui->userInput->text(), currentSession()); - Cache().sync(); - m_Greeter.startSessionSync(currentSession()); - } - else { - ui->passwordInput->clear(); - userChanged(); - } -} - -void LoginForm::keyPressEvent(QKeyEvent *event) -{ - if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { - respond(); - } - else { - QWidget::keyPressEvent(event); - } -} - diff --git a/loginform.h b/loginform.h deleted file mode 100644 index 8346a58..0000000 --- a/loginform.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* Copyright (c) 2012-2015 Christian Surlykke -* -* This file is part of qt-lightdm-greeter -* It is distributed under the LGPL 2.1 or later license. -* Please refer to the LICENSE file for a copy of the license. -*/ -#ifndef LOGINFORM_H -#define LOGINFORM_H - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -namespace Ui -{ -class LoginForm; -} - -class LoginForm : public QWidget -{ - Q_OBJECT - -friend class DecoratedUsersModel; - -public: - explicit LoginForm(QWidget *parent = 0); - ~LoginForm(); - virtual void setFocus(Qt::FocusReason reason); - -public slots: - void userChanged(); - void leaveDropDownActivated(int index); - void respond(); - void onPrompt(QString prompt, QLightDM::Greeter::PromptType promptType); - void authenticationComplete(); - -protected: - virtual void keyPressEvent(QKeyEvent *event); - -private: - void initialize(); - void addLeaveEntry(bool canDo, QString iconName, QString text, QString actionName); - QString currentSession(); - void setCurrentSession(QString session); - - Ui::LoginForm *ui; - - QLightDM::Greeter m_Greeter; - QLightDM::PowerInterface power; - QLightDM::SessionsModel sessionsModel; - - QMap powerSlots; -}; - -#endif // LOGINFORM_H diff --git a/loginform.ui b/loginform.ui deleted file mode 100644 index 3525a9d..0000000 --- a/loginform.ui +++ /dev/null @@ -1,267 +0,0 @@ - - - LoginForm - - - - 0 - 0 - 350 - 325 - - - - - Andale Mono - 12 - - - - LoginForm - - - QWidget { - border-radius: 5px; -} - -#hostnameLabel { - color: white; -} - -#formFrame { - background-color: rgba(80,80,80, 180); - border-radius: 10px; -} - -QComboBox, -QPushButton { - border: 1px solid silver; - background-color: rgb(200, 200, 200); -} - -QComboBox::drop-down { - border: none; - width: 24px; - text-align: center; -} - -QComboBox::down-arrow { - image: url(:/resources/dropdown.svg); -} - - - - - - - - 0 - 0 - - - - - 25 - - - 8 - - - - - - 0 - 60 - - - - - 10000 - 60 - - - - - Bitstream Vera Sans - 14 - 50 - true - false - - - - Hostname - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 0 - - - 10 - - - - - - - - 50 - 50 - - - - - 50 - 50 - - - - - - - :/resources/rqt-2.png - - - true - - - Qt::AlignCenter - - - - - - - - 200 - 60 - - - - - 10000 - 60 - - - - - Bitstream Vera Sans - 50 - false - - - - QLineEdit::Normal - - - user id - - - - - - - - 0 - 60 - - - - - 10000 - 60 - - - - - Bitstream Vera Sans - 50 - false - - - - - - - QLineEdit::Password - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - password - - - 0 - - - 10 - - - - - - - - 200 - 60 - - - - - 10000 - 60 - - - - - Bitstream Vera Sans - 50 - false - - - - QComboBox::AdjustToContents - - - true - - - - - - - - 80 - 60 - - - - - 80 - 60 - - - - - - - - - :/resources/leaveIcon.svg:/resources/leaveIcon.svg - - - - - - - - - - - - - - diff --git a/main.cpp b/main.cpp deleted file mode 100644 index c0ce7bc..0000000 --- a/main.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* -* Copyright (c) 2012-2015 Christian Surlykke, Petr Vanek -* -* This file is part of qt-lightdm-greeter -* It is distributed under the LGPL 2.1 or later license. -* Please refer to the LICENSE file for a copy of the license. -*/ -#include -#include -#include -#include -#include -#include - -#include - -#include "settings.h" -#include "mainwindow.h" - -QFile logfile; -QTextStream ts; - -void messageHandler(QtMsgType type, const QMessageLogContext&, const QString& msg) -{ - std::cerr << type << ": " << msg.toLatin1().data() << "\n"; -} - -int main(int argc, char *argv[]) -{ - // I have no idea why, but Qt's stock qDebug() output never makes it - // to /var/log/lightdm/x-0-greeter.log, so we use std::cerr instead.. - qInstallMessageHandler(messageHandler); - Cache::prepare(); - - QApplication a(argc, argv); - - if (! Settings().iconThemeName().isEmpty()) { - QIcon::setThemeName(Settings().iconThemeName()); - } - - MainWindow *focusWindow = 0; - for (int i = 0; i < QApplication::desktop()->screenCount(); ++i) { - MainWindow *w = new MainWindow(i); - w->show(); - if (w->showLoginForm()) - focusWindow = w; - } - - // Ensure we set the primary screen's widget as active when there - // are more screens - if (focusWindow) { - focusWindow->setFocus(Qt::OtherFocusReason); - focusWindow->activateWindow(); - } - - return a.exec(); -} diff --git a/mainwindow.cpp b/mainwindow.cpp deleted file mode 100644 index a8dbd21..0000000 --- a/mainwindow.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* -* Copyright (c) 2012-2015 Christian Surlykke, Petr Vanek -* -* This file is part of qt-lightdm-greeter -* It is distributed under the LGPL 2.1 or later license. -* Please refer to the LICENSE file for a copy of the license. -*/ -#include -#include -#include -#include -#include -#include - -#include "mainwindow.h" -#include "loginform.h" -#include "settings.h" - -MainWindow::MainWindow(int screen, QWidget *parent) : - QWidget(parent), - m_Screen(screen) -{ - setObjectName(QString("MainWindow_%1").arg(screen)); - - - QRect screenRect = QApplication::desktop()->screenGeometry(screen); - setGeometry(screenRect); - - setBackground(); - - // display login dialog only in the main screen - - if (showLoginForm()) { - m_LoginForm = new LoginForm(this); - - int maxX = screenRect.width() - m_LoginForm->width(); - int maxY = screenRect.height() - m_LoginForm->height(); - int defaultX = 10*maxX/100; - int defaultY = 50*maxY/100; - int offsetX = getOffset(Settings().offsetX(), maxX, defaultX); - int offsetY = getOffset(Settings().offsetY(), maxY, defaultY); - - m_LoginForm->move(offsetX, offsetY); - m_LoginForm->show(); - - // This hack ensures that the primary screen will have focus - // if there are more screens (move the mouse cursor in the center - // of primary screen - not in the center of all X area). It - // won't affect single-screen environments. - int centerX = screenRect.width()/2 + screenRect.x(); - int centerY = screenRect.height()/2 + screenRect.y(); - QCursor::setPos(centerX, centerY); - } -} - -MainWindow::~MainWindow() -{ -} - -bool MainWindow::showLoginForm() -{ - return m_Screen == QApplication::desktop()->primaryScreen(); -} - -void MainWindow::setFocus(Qt::FocusReason reason) -{ - if (m_LoginForm) { - m_LoginForm->setFocus(reason); - } - else { - QWidget::setFocus(reason); - } -} - -int MainWindow::getOffset(QString settingsOffset, int maxVal, int defaultVal) -{ - - int offset = defaultVal > maxVal ? maxVal : defaultVal; - - if (! settingsOffset.isEmpty()) { - if (QRegExp("^\\d+px$", Qt::CaseInsensitive).exactMatch(settingsOffset)) { - offset = settingsOffset.left(settingsOffset.size() - 2).toInt(); - if (offset > maxVal) offset = maxVal; - } - else if (QRegExp("^\\d+%$", Qt::CaseInsensitive).exactMatch(settingsOffset)) { - int offsetPct = settingsOffset.left(settingsOffset.size() -1).toInt(); - if (offsetPct > 100) offsetPct = 100; - offset = (maxVal * offsetPct)/100; - } - else { - qWarning() << "Could not understand" << settingsOffset - << "- must be of form px or %, e.g. 35px or 25%" ; - } - } - - return offset; -} - -void MainWindow::setBackground() -{ - QImage backgroundImage; - QSettings greeterSettings(CONFIG_FILE, QSettings::IniFormat); - - if (greeterSettings.contains(BACKGROUND_IMAGE_KEY)) { - QString pathToBackgroundImage = greeterSettings.value(BACKGROUND_IMAGE_KEY).toString(); - - backgroundImage = QImage(pathToBackgroundImage); - if (backgroundImage.isNull()) { - qWarning() << "Not able to read" << pathToBackgroundImage << "as image"; - } - - } - - QPalette palette; - QRect rect = QApplication::desktop()->screenGeometry(m_Screen); - if (backgroundImage.isNull()) { - palette.setColor(QPalette::Background, Qt::black); - } - else { - QBrush brush(backgroundImage.scaled(rect.width(), rect.height())); - palette.setBrush(this->backgroundRole(), brush); - } - this->setPalette(palette); -} - - diff --git a/mainwindow.h b/mainwindow.h deleted file mode 100644 index 738d423..0000000 --- a/mainwindow.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -* Copyright (c) 2012-2015 Christian Surlykke, Petr Vanek -* -* This file is part of qt-lightdm-greeter -* It is distributed under the LGPL 2.1 or later license. -* Please refer to the LICENSE file for a copy of the license. -*/ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include - -#include - -#include "loginform.h" - -namespace Ui { - class MainWindow; -} - -class MainWindow : public QWidget -{ - Q_OBJECT - -public: - explicit MainWindow(int screen, QWidget *parent = 0); - ~MainWindow(); - - void setFocus(Qt::FocusReason reason); - - bool showLoginForm(); - - LoginForm* loginForm() { return m_LoginForm;} -private: - int getOffset(QString offset, int maxVal, int defaultVal); - void setBackground(); - int m_Screen; - LoginForm* m_LoginForm; -}; - -#endif // MAINWINDOW_H diff --git a/settings.cpp b/settings.cpp deleted file mode 100644 index 0c37166..0000000 --- a/settings.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include "settings.h" - -#define BACKGROUND_IMAGE_KEY "greeter-background-image" -#define LOGINFORM_OFFSETX_KEY "loginform-offset-x" -#define LOGINFORM_OFFSETY_KEY "loginform-offset-y" -#define LOGFILE_PATH_KEY "logfile-path" - -const QString Cache::GREETER_DATA_DIR_PATH = "/var/lib/lightdm/qt-lightdm-greeter"; - -void Cache::prepare() -{ - QDir dir(GREETER_DATA_DIR_PATH); - if (!dir.exists()) { - if (!dir.mkpath(GREETER_DATA_DIR_PATH)) { - qWarning() << "Unable to create dir" << GREETER_DATA_DIR_PATH; - } - } -} - diff --git a/settings.h b/settings.h deleted file mode 100644 index 7f2b135..0000000 --- a/settings.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef SETTINGS_H -#define SETTINGS_H - -#include - - - - -class Cache : public QSettings -{ -public: - static const QString GREETER_DATA_DIR_PATH; - static void prepare(); - - Cache() : QSettings(GREETER_DATA_DIR_PATH + "/state", QSettings::NativeFormat) {} - QString getLastUser() { return value("last-user").toString(); } - void setLastUser(QString userId) { setValue("last-user", userId); } - QString getLastSession(QString userId) { return value(userId + "/last-session").toString(); } - void setLastSession(QString userId, QString session) { setValue(userId + "/last-session", session); } -}; - -#define CONFIG_FILE "/etc/lightdm/qt-lightdm-greeter.conf" -#define BACKGROUND_IMAGE_KEY "greeter-background-image" -#define LOGINFORM_OFFSETX_KEY "loginform-offset-x" -#define LOGINFORM_OFFSETY_KEY "loginform-offset-y" - - -class Settings : public QSettings -{ -public: - Settings() : QSettings(QString("/etc/lightdm/qt-lightdm-greeter.conf"), QSettings::NativeFormat) {} - QString iconThemeName() { return value("greeter-icon-theme").toString(); } - QString backgrundImagePath() { return value("greeter-background-image").toString(); } - QString offsetX() { return value("loginform-offset-x").toString(); } - QString offsetY() { return value("loginform-offset-y").toString(); } -}; - - - - -#endif // SETTINGS_H diff --git a/src/loginform.cpp b/src/loginform.cpp new file mode 100644 index 0000000..3f40e81 --- /dev/null +++ b/src/loginform.cpp @@ -0,0 +1,197 @@ +/* +* Copyright (c) 2012-2015 Christian Surlykke +* +* This file is part of qt-lightdm-greeter +* It is distributed under the LGPL 2.1 or later license. +* Please refer to the LICENSE file for a copy of the license. +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "loginform.h" +#include "ui_loginform.h" +#include "settings.h" + +const int KeyRole = QLightDM::SessionsModel::KeyRole; + +int rows(QAbstractItemModel& model) { + return model.rowCount(QModelIndex()); +} + +QString displayData(QAbstractItemModel& model, int row, int role) +{ + QModelIndex modelIndex = model.index(row, 0); + return model.data(modelIndex, role).toString(); +} + +LoginForm::LoginForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LoginForm), + m_Greeter(), + power(this), + sessionsModel() +{ + if (!m_Greeter.connectSync()) { + close(); + } + + ui->setupUi(this); + initialize(); +} + +LoginForm::~LoginForm() +{ + delete ui; +} + +void LoginForm::setFocus(Qt::FocusReason reason) +{ + if (ui->userInput->text().isEmpty()) { + ui->userInput->setFocus(reason); + } else { + ui->passwordInput->setFocus(reason); + } +} + + +void LoginForm::initialize() +{ + QPixmap icon(":/resources/rqt-2.png"); // This project came from Razor-qt + ui->iconLabel->setPixmap(icon.scaled(ui->iconLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + ui->hostnameLabel->setText(m_Greeter.hostname()); + + ui->sessionCombo->setModel(&sessionsModel); + + addLeaveEntry(power.canShutdown(), "system-shutdown", tr("Shutdown"), "shutdown"); + addLeaveEntry(power.canRestart(), "system-reboot", tr("Restart"), "restart"); + addLeaveEntry(power.canHibernate(), "system-suspend-hibernate", tr("Hibernate"), "hibernate"); + addLeaveEntry(power.canSuspend(), "system-suspend", tr("Suspend"), "suspend"); + ui->leaveComboBox->setDisabled(ui->leaveComboBox->count() <= 1); + + ui->sessionCombo->setCurrentIndex(0); + setCurrentSession(m_Greeter.defaultSessionHint()); + + connect(ui->userInput, SIGNAL(editingFinished()), this, SLOT(userChanged())); + connect(ui->leaveComboBox, SIGNAL(activated(int)), this, SLOT(leaveDropDownActivated(int))); + connect(&m_Greeter, SIGNAL(showPrompt(QString, QLightDM::Greeter::PromptType)), this, SLOT(onPrompt(QString, QLightDM::Greeter::PromptType))); + connect(&m_Greeter, SIGNAL(authenticationComplete()), this, SLOT(authenticationComplete())); + + ui->passwordInput->setEnabled(false); + ui->passwordInput->clear(); + + if (! m_Greeter.hideUsersHint()) { + QStringList knownUsers; + QLightDM::UsersModel usersModel; + for (int i = 0; i < usersModel.rowCount(QModelIndex()); i++) { + knownUsers << usersModel.data(usersModel.index(i, 0), QLightDM::UsersModel::NameRole).toString(); + } + ui->userInput->setCompleter(new QCompleter(knownUsers)); + ui->userInput->completer()->setCompletionMode(QCompleter::InlineCompletion); + } + + QString user = Cache().getLastUser(); + if (user.isEmpty()) { + user = m_Greeter.selectUserHint(); + } + ui->userInput->setText(user); + userChanged(); +} + +void LoginForm::userChanged() +{ + setCurrentSession(Cache().getLastSession(ui->userInput->text())); + + if (m_Greeter.inAuthentication()) { + m_Greeter.cancelAuthentication(); + } + if (! ui->userInput->text().isEmpty()) { + m_Greeter.authenticate(ui->userInput->text()); + ui->passwordInput->setFocus(); + } + else { + ui->userInput->setFocus(); + } +} + +void LoginForm::leaveDropDownActivated(int index) +{ + QString actionName = ui->leaveComboBox->itemData(index).toString(); + if (actionName == "shutdown") power.shutdown(); + else if (actionName == "restart") power.restart(); + else if (actionName == "hibernate") power.hibernate(); + else if (actionName == "suspend") power.suspend(); +} + +void LoginForm::respond() +{ + m_Greeter.respond(ui->passwordInput->text().trimmed()); + ui->passwordInput->clear(); + ui->passwordInput->setEnabled(false); +} + +void LoginForm::onPrompt(QString prompt, QLightDM::Greeter::PromptType promptType) +{ + ui->passwordInput->setEnabled(true); + ui->passwordInput->setFocus(); +} + + +void LoginForm::addLeaveEntry(bool canDo, QString iconName, QString text, QString actionName) +{ + if (canDo) { + ui->leaveComboBox->addItem(QIcon::fromTheme(iconName), text, actionName); + } +} + +QString LoginForm::currentSession() +{ + QModelIndex index = sessionsModel.index(ui->sessionCombo->currentIndex(), 0, QModelIndex()); + return sessionsModel.data(index, QLightDM::SessionsModel::KeyRole).toString(); +} + +void LoginForm::setCurrentSession(QString session) +{ + for (int i = 0; i < ui->sessionCombo->count(); i++) { + if (session == sessionsModel.data(sessionsModel.index(i, 0), KeyRole).toString()) { + ui->sessionCombo->setCurrentIndex(i); + return; + } + } +} + + +void LoginForm::authenticationComplete() +{ + if (m_Greeter.isAuthenticated()) { + Cache().setLastUser(ui->userInput->text()); + Cache().setLastSession(ui->userInput->text(), currentSession()); + Cache().sync(); + m_Greeter.startSessionSync(currentSession()); + } + else { + ui->passwordInput->clear(); + userChanged(); + } +} + +void LoginForm::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { + respond(); + } + else { + QWidget::keyPressEvent(event); + } +} + diff --git a/src/loginform.h b/src/loginform.h new file mode 100644 index 0000000..8346a58 --- /dev/null +++ b/src/loginform.h @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2012-2015 Christian Surlykke +* +* This file is part of qt-lightdm-greeter +* It is distributed under the LGPL 2.1 or later license. +* Please refer to the LICENSE file for a copy of the license. +*/ +#ifndef LOGINFORM_H +#define LOGINFORM_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +namespace Ui +{ +class LoginForm; +} + +class LoginForm : public QWidget +{ + Q_OBJECT + +friend class DecoratedUsersModel; + +public: + explicit LoginForm(QWidget *parent = 0); + ~LoginForm(); + virtual void setFocus(Qt::FocusReason reason); + +public slots: + void userChanged(); + void leaveDropDownActivated(int index); + void respond(); + void onPrompt(QString prompt, QLightDM::Greeter::PromptType promptType); + void authenticationComplete(); + +protected: + virtual void keyPressEvent(QKeyEvent *event); + +private: + void initialize(); + void addLeaveEntry(bool canDo, QString iconName, QString text, QString actionName); + QString currentSession(); + void setCurrentSession(QString session); + + Ui::LoginForm *ui; + + QLightDM::Greeter m_Greeter; + QLightDM::PowerInterface power; + QLightDM::SessionsModel sessionsModel; + + QMap powerSlots; +}; + +#endif // LOGINFORM_H diff --git a/src/loginform.ui b/src/loginform.ui new file mode 100644 index 0000000..3525a9d --- /dev/null +++ b/src/loginform.ui @@ -0,0 +1,267 @@ + + + LoginForm + + + + 0 + 0 + 350 + 325 + + + + + Andale Mono + 12 + + + + LoginForm + + + QWidget { + border-radius: 5px; +} + +#hostnameLabel { + color: white; +} + +#formFrame { + background-color: rgba(80,80,80, 180); + border-radius: 10px; +} + +QComboBox, +QPushButton { + border: 1px solid silver; + background-color: rgb(200, 200, 200); +} + +QComboBox::drop-down { + border: none; + width: 24px; + text-align: center; +} + +QComboBox::down-arrow { + image: url(:/resources/dropdown.svg); +} + + + + + + + + 0 + 0 + + + + + 25 + + + 8 + + + + + + 0 + 60 + + + + + 10000 + 60 + + + + + Bitstream Vera Sans + 14 + 50 + true + false + + + + Hostname + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 0 + + + 10 + + + + + + + + 50 + 50 + + + + + 50 + 50 + + + + + + + :/resources/rqt-2.png + + + true + + + Qt::AlignCenter + + + + + + + + 200 + 60 + + + + + 10000 + 60 + + + + + Bitstream Vera Sans + 50 + false + + + + QLineEdit::Normal + + + user id + + + + + + + + 0 + 60 + + + + + 10000 + 60 + + + + + Bitstream Vera Sans + 50 + false + + + + + + + QLineEdit::Password + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + password + + + 0 + + + 10 + + + + + + + + 200 + 60 + + + + + 10000 + 60 + + + + + Bitstream Vera Sans + 50 + false + + + + QComboBox::AdjustToContents + + + true + + + + + + + + 80 + 60 + + + + + 80 + 60 + + + + + + + + + :/resources/leaveIcon.svg:/resources/leaveIcon.svg + + + + + + + + + + + + + + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c0ce7bc --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2012-2015 Christian Surlykke, Petr Vanek +* +* This file is part of qt-lightdm-greeter +* It is distributed under the LGPL 2.1 or later license. +* Please refer to the LICENSE file for a copy of the license. +*/ +#include +#include +#include +#include +#include +#include + +#include + +#include "settings.h" +#include "mainwindow.h" + +QFile logfile; +QTextStream ts; + +void messageHandler(QtMsgType type, const QMessageLogContext&, const QString& msg) +{ + std::cerr << type << ": " << msg.toLatin1().data() << "\n"; +} + +int main(int argc, char *argv[]) +{ + // I have no idea why, but Qt's stock qDebug() output never makes it + // to /var/log/lightdm/x-0-greeter.log, so we use std::cerr instead.. + qInstallMessageHandler(messageHandler); + Cache::prepare(); + + QApplication a(argc, argv); + + if (! Settings().iconThemeName().isEmpty()) { + QIcon::setThemeName(Settings().iconThemeName()); + } + + MainWindow *focusWindow = 0; + for (int i = 0; i < QApplication::desktop()->screenCount(); ++i) { + MainWindow *w = new MainWindow(i); + w->show(); + if (w->showLoginForm()) + focusWindow = w; + } + + // Ensure we set the primary screen's widget as active when there + // are more screens + if (focusWindow) { + focusWindow->setFocus(Qt::OtherFocusReason); + focusWindow->activateWindow(); + } + + return a.exec(); +} diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp new file mode 100644 index 0000000..a8dbd21 --- /dev/null +++ b/src/mainwindow.cpp @@ -0,0 +1,126 @@ +/* +* Copyright (c) 2012-2015 Christian Surlykke, Petr Vanek +* +* This file is part of qt-lightdm-greeter +* It is distributed under the LGPL 2.1 or later license. +* Please refer to the LICENSE file for a copy of the license. +*/ +#include +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "loginform.h" +#include "settings.h" + +MainWindow::MainWindow(int screen, QWidget *parent) : + QWidget(parent), + m_Screen(screen) +{ + setObjectName(QString("MainWindow_%1").arg(screen)); + + + QRect screenRect = QApplication::desktop()->screenGeometry(screen); + setGeometry(screenRect); + + setBackground(); + + // display login dialog only in the main screen + + if (showLoginForm()) { + m_LoginForm = new LoginForm(this); + + int maxX = screenRect.width() - m_LoginForm->width(); + int maxY = screenRect.height() - m_LoginForm->height(); + int defaultX = 10*maxX/100; + int defaultY = 50*maxY/100; + int offsetX = getOffset(Settings().offsetX(), maxX, defaultX); + int offsetY = getOffset(Settings().offsetY(), maxY, defaultY); + + m_LoginForm->move(offsetX, offsetY); + m_LoginForm->show(); + + // This hack ensures that the primary screen will have focus + // if there are more screens (move the mouse cursor in the center + // of primary screen - not in the center of all X area). It + // won't affect single-screen environments. + int centerX = screenRect.width()/2 + screenRect.x(); + int centerY = screenRect.height()/2 + screenRect.y(); + QCursor::setPos(centerX, centerY); + } +} + +MainWindow::~MainWindow() +{ +} + +bool MainWindow::showLoginForm() +{ + return m_Screen == QApplication::desktop()->primaryScreen(); +} + +void MainWindow::setFocus(Qt::FocusReason reason) +{ + if (m_LoginForm) { + m_LoginForm->setFocus(reason); + } + else { + QWidget::setFocus(reason); + } +} + +int MainWindow::getOffset(QString settingsOffset, int maxVal, int defaultVal) +{ + + int offset = defaultVal > maxVal ? maxVal : defaultVal; + + if (! settingsOffset.isEmpty()) { + if (QRegExp("^\\d+px$", Qt::CaseInsensitive).exactMatch(settingsOffset)) { + offset = settingsOffset.left(settingsOffset.size() - 2).toInt(); + if (offset > maxVal) offset = maxVal; + } + else if (QRegExp("^\\d+%$", Qt::CaseInsensitive).exactMatch(settingsOffset)) { + int offsetPct = settingsOffset.left(settingsOffset.size() -1).toInt(); + if (offsetPct > 100) offsetPct = 100; + offset = (maxVal * offsetPct)/100; + } + else { + qWarning() << "Could not understand" << settingsOffset + << "- must be of form px or %, e.g. 35px or 25%" ; + } + } + + return offset; +} + +void MainWindow::setBackground() +{ + QImage backgroundImage; + QSettings greeterSettings(CONFIG_FILE, QSettings::IniFormat); + + if (greeterSettings.contains(BACKGROUND_IMAGE_KEY)) { + QString pathToBackgroundImage = greeterSettings.value(BACKGROUND_IMAGE_KEY).toString(); + + backgroundImage = QImage(pathToBackgroundImage); + if (backgroundImage.isNull()) { + qWarning() << "Not able to read" << pathToBackgroundImage << "as image"; + } + + } + + QPalette palette; + QRect rect = QApplication::desktop()->screenGeometry(m_Screen); + if (backgroundImage.isNull()) { + palette.setColor(QPalette::Background, Qt::black); + } + else { + QBrush brush(backgroundImage.scaled(rect.width(), rect.height())); + palette.setBrush(this->backgroundRole(), brush); + } + this->setPalette(palette); +} + + diff --git a/src/mainwindow.h b/src/mainwindow.h new file mode 100644 index 0000000..738d423 --- /dev/null +++ b/src/mainwindow.h @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2012-2015 Christian Surlykke, Petr Vanek +* +* This file is part of qt-lightdm-greeter +* It is distributed under the LGPL 2.1 or later license. +* Please refer to the LICENSE file for a copy of the license. +*/ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +#include + +#include "loginform.h" + +namespace Ui { + class MainWindow; +} + +class MainWindow : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindow(int screen, QWidget *parent = 0); + ~MainWindow(); + + void setFocus(Qt::FocusReason reason); + + bool showLoginForm(); + + LoginForm* loginForm() { return m_LoginForm;} +private: + int getOffset(QString offset, int maxVal, int defaultVal); + void setBackground(); + int m_Screen; + LoginForm* m_LoginForm; +}; + +#endif // MAINWINDOW_H diff --git a/src/settings.cpp b/src/settings.cpp new file mode 100644 index 0000000..0c37166 --- /dev/null +++ b/src/settings.cpp @@ -0,0 +1,21 @@ +#include +#include +#include "settings.h" + +#define BACKGROUND_IMAGE_KEY "greeter-background-image" +#define LOGINFORM_OFFSETX_KEY "loginform-offset-x" +#define LOGINFORM_OFFSETY_KEY "loginform-offset-y" +#define LOGFILE_PATH_KEY "logfile-path" + +const QString Cache::GREETER_DATA_DIR_PATH = "/var/lib/lightdm/qt-lightdm-greeter"; + +void Cache::prepare() +{ + QDir dir(GREETER_DATA_DIR_PATH); + if (!dir.exists()) { + if (!dir.mkpath(GREETER_DATA_DIR_PATH)) { + qWarning() << "Unable to create dir" << GREETER_DATA_DIR_PATH; + } + } +} + diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 0000000..7f2b135 --- /dev/null +++ b/src/settings.h @@ -0,0 +1,41 @@ +#ifndef SETTINGS_H +#define SETTINGS_H + +#include + + + + +class Cache : public QSettings +{ +public: + static const QString GREETER_DATA_DIR_PATH; + static void prepare(); + + Cache() : QSettings(GREETER_DATA_DIR_PATH + "/state", QSettings::NativeFormat) {} + QString getLastUser() { return value("last-user").toString(); } + void setLastUser(QString userId) { setValue("last-user", userId); } + QString getLastSession(QString userId) { return value(userId + "/last-session").toString(); } + void setLastSession(QString userId, QString session) { setValue(userId + "/last-session", session); } +}; + +#define CONFIG_FILE "/etc/lightdm/qt-lightdm-greeter.conf" +#define BACKGROUND_IMAGE_KEY "greeter-background-image" +#define LOGINFORM_OFFSETX_KEY "loginform-offset-x" +#define LOGINFORM_OFFSETY_KEY "loginform-offset-y" + + +class Settings : public QSettings +{ +public: + Settings() : QSettings(QString("/etc/lightdm/qt-lightdm-greeter.conf"), QSettings::NativeFormat) {} + QString iconThemeName() { return value("greeter-icon-theme").toString(); } + QString backgrundImagePath() { return value("greeter-background-image").toString(); } + QString offsetX() { return value("loginform-offset-x").toString(); } + QString offsetY() { return value("loginform-offset-y").toString(); } +}; + + + + +#endif // SETTINGS_H -- cgit v1.2.3-55-g7522