同步X桌面环境显示参数至lightdm用户下登录环境

This commit is contained in:
yangmin100 2023-12-28 11:04:21 +08:00
parent 3e34ea70bc
commit 4baa356b2c
8 changed files with 324 additions and 11 deletions

View File

@ -106,6 +106,8 @@ set(dialog_SRC
dbusifs/biometrichelper.cpp
dbusifs/freedesktophelper.cpp
dbusifs/giodbus.cpp
common/configuration.cpp
common/displayservice.cpp
)
add_executable(ukui-screensaver-dialog ${dialog_SRC})
add_definitions(-DAPP_API_MAJOR=0 -DAPP_API_MINOR=11 -DAPP_API_FUNC=0)

View File

@ -0,0 +1,238 @@
/* displayservice.cpp
* Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301, USA.
**/
#include "displayservice.h"
#include <QException>
#include <QDebug>
#include <QProcess>
#include <QStandardPaths>
DisplayService* DisplayService::m_instance = nullptr;
DisplayService::DisplayService(QObject *parent) : QObject(parent)
{
// 使用usd设置显示参数
m_strSaveParamPath = QStandardPaths::findExecutable("save-param");
}
DisplayService* DisplayService::instance(QObject *parent)
{
if(m_instance == nullptr)
m_instance = new DisplayService(parent);
return m_instance;
}
bool DisplayService::switchDisplayMode(DisplayMode targetMode)
{
if (m_strSaveParamPath.isEmpty() || m_strUserName.isEmpty()) {
//获取显示器列表
getMonitors();
//如果当前只有一个显示器就什么也不做
if(monitors.keys().size() < 2) {
qDebug() << "only one monitor, doNothing";
return false;
}
QProcess subProcess;
//模式切换
try {
switch(targetMode){
case DISPLAY_MODE_ORI:
{
QString XRANDR_ORIONLY = "xrandr --output " + monitorNames[0] + " --auto";
for(int i = 1; i < monitorNames.size(); i++)
XRANDR_ORIONLY = XRANDR_ORIONLY + " --output " + monitorNames[i] + " --off";
qDebug() << "XRANDR_ORIONLY: " << XRANDR_ORIONLY;
subProcess.start(XRANDR_ORIONLY, QIODevice::NotOpen);
break;
}
case DISPLAY_MODE_CLONE:
{
//查找最佳克隆分辨率
QString BEST_CLONE_MODE;
bool find = false;
for(auto & mode_0 : monitors[monitorNames[0]]) {
for(auto & mode_1 : monitors[monitorNames[1]]) {
if(mode_0 == mode_1) {
BEST_CLONE_MODE = mode_0;
find = true;
break;
}
}
if(find)
break;
}
QString XRANDR_CLONE = "xrandr --output " + monitorNames[0] + " --mode " + BEST_CLONE_MODE;
for(int i = 1; i < monitorNames.size(); i++)
XRANDR_CLONE = XRANDR_CLONE + " --output " + monitorNames[i] + " --mode " + BEST_CLONE_MODE + " --same-as " + monitorNames[0];
qDebug() << "XRANDR_CLONE: " << XRANDR_CLONE;
subProcess.start(XRANDR_CLONE, QIODevice::NotOpen);
break;
}
case DISPLAY_MODE_EXTEND:
{
QString XRANDR_EXTEND = "xrandr --output " + monitorNames[0] + " --auto";
for(int i = 1; i < monitorNames.size(); i++)
XRANDR_EXTEND = XRANDR_EXTEND + " --output " + monitorNames[i] + " --right-of " + monitorNames[i-1] + " --auto";
qDebug() << "XRANDR_EXTEND: " << XRANDR_EXTEND;
subProcess.start(XRANDR_EXTEND, QIODevice::NotOpen);
break;
}
case DISPLAY_MODE_ONLY_OUT:
{
QString XRANDR_OUTONLY = "xrandr --output " + monitorNames[0] + " --off --output " + monitorNames[1] + " --auto";
qDebug() << "XRANDR_OUTONLY: " << XRANDR_OUTONLY;
subProcess.start(XRANDR_OUTONLY, QIODevice::NotOpen);
break;
}
}
subProcess.waitForFinished();
return true;
} catch(const QException &e) {
qWarning() << e.what();
return false;
}
} else {
QProcess subProcess;
try {
QString usdSaveParam = m_strSaveParamPath + " -u " +m_strUserName;
qDebug() << "usdSaveParam: " << usdSaveParam;
subProcess.start(usdSaveParam, QIODevice::NotOpen);
subProcess.waitForFinished();
return true;
} catch(const QException &e) {
qWarning() << e.what();
return false;
}
}
}
void DisplayService::setOneDisplayMode()
{
//组装第一个设备名显示命令
QProcess subProcess;
try {
QString oneXrandrCmd = "";
if (m_strSaveParamPath.isEmpty() || m_strUserName.isEmpty()) {
//获取显示器列表
getMonitors();
if (monitorNames.size() <= 0) {
return ;
}
oneXrandrCmd = "xrandr --output " + monitorNames[0] + " --auto";
} else {
oneXrandrCmd = m_strSaveParamPath + " -u " +m_strUserName;
}
qDebug() << "setOneDisplayMode: " << oneXrandrCmd;
subProcess.start(oneXrandrCmd);
subProcess.waitForFinished();
return;
} catch(const QException &e) {
qWarning() << e.what();
return;
}
}
void DisplayService::setCurUserName(QString strUserName)
{
m_strUserName = strUserName;
if (!m_strSaveParamPath.isEmpty()) {
QProcess subProcess;
try {
QString usdSaveParam = m_strSaveParamPath + " -u " +m_strUserName;
qDebug() << "setCurUserName usdSaveParam: " << usdSaveParam;
subProcess.start(usdSaveParam);
subProcess.waitForFinished();
} catch(const QException &e) {
qWarning() << e.what();
}
}
}
bool DisplayService::isSaveParamInUsed()
{
return !(m_strSaveParamPath.isEmpty());
}
void DisplayService::getMonitors()
{
QProcess subProcess;
subProcess.setProgram(QStandardPaths::findExecutable("xrandr"));
subProcess.setArguments({"-q"});
subProcess.start(QIODevice::ReadOnly);
subProcess.waitForFinished();
QString outputs = subProcess.readAll();
QStringList lines = outputs.split('\n');
QString name;
QVector<QString> modes;
bool find = false;
QString lastName;
monitorNames.clear();
monitors.clear();
for(auto & line : lines) {
if(line.indexOf(" connected") != -1) { //找显示器名称
name = line.left(line.indexOf(' '));
monitorNames.push_back(name);
if(find) //又找到了一个显示器将上一个显示器的信息存到map
monitors[lastName] = modes;
find = true;
lastName = name;
modes.clear();
} else {
if(line.startsWith(' ')) { //获取分辨率
QString mode = line.trimmed().split(' ').at(0);
modes.push_back(mode);
}
}
}
monitors[name] = modes; //将最后一个显示器的信息存储到map
qDebug() << "find motinors: " << monitorNames;
}
int DisplayService::isJJW7200()
{
static int ret = -1;
char *pAck = NULL;
char CmdAck[256] = "";
FILE *pPipe = NULL;
if (ret != -1) {
return ret;
}
pPipe = popen("lspci | grep -i VGA |grep 7200", "r");
if (pPipe) {
pAck = fgets(CmdAck, sizeof(CmdAck)-1, pPipe);
if (strlen(CmdAck) > 3) {
ret = 1;
} else{
ret = 0;
}
pclose(pPipe);
} else {
ret = 0;
}
return ret;
}

View File

@ -0,0 +1,57 @@
/* displayservice.h
* Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301, USA.
**/
#ifndef DISPLAYSERVICE_H
#define DISPLAYSERVICE_H
#include <QObject>
#include <QVector>
#include <QMap>
enum DisplayMode{
DISPLAY_MODE_ORI = 1,
DISPLAY_MODE_CLONE = 2,
DISPLAY_MODE_EXTEND = 3,
DISPLAY_MODE_ONLY_OUT = 4
};
class DisplayService : public QObject
{
Q_OBJECT
private:
explicit DisplayService(QObject *parent = nullptr);
public:
static DisplayService *instance(QObject *parent = nullptr);
bool switchDisplayMode(DisplayMode targetMode);
void setOneDisplayMode();//单屏模式设置
void setCurUserName(QString strUserName);
bool isSaveParamInUsed();
int isJJW7200();
private:
void getMonitors();
QMap<QString, QVector<QString>> monitors;
QStringList monitorNames;
QString m_strSaveParamPath = "";
QString m_strUserName = "";
static DisplayService *m_instance;
};
#endif // DISPLAYSERVICE_H

View File

@ -56,10 +56,10 @@ void DbusUpperInterface::initData()
{
m_bLockState = false;
m_bSlpState = false;
m_accountsHelper = new AccountsHelper(this);
m_lightDmHelper = new LightDMHelper(m_accountsHelper, this);
m_login1Helper = new Login1Helper(this);
m_config = new Configuration(this);
m_accountsHelper = new AccountsHelper(this);
m_lightDmHelper = new LightDMHelper(m_accountsHelper, m_config, this);
m_login1Helper = new Login1Helper(this);
m_gsettingsHelper = new GSettingsHelper(this);
m_bioAuth = new BioAuthenticate(this);
m_pamAuth = new PamAuthenticate(m_lightDmHelper, this);

View File

@ -28,12 +28,13 @@
#include <QDBusMessage>
#include <QVariantMap>
LightDMHelper::LightDMHelper(AccountsHelper *accountHelper, QObject *parent)
LightDMHelper::LightDMHelper(AccountsHelper *accountHelper, Configuration *config, QObject *parent)
: QLightDM::Greeter(parent)
, m_sessionsModel(nullptr)
, m_secUser(SecurityUser::instance())
, m_strCurUserName("")
, m_accountServiceHelper(accountHelper)
, m_configuration(config)
, m_ldmSessions(new QMap<QString, std::shared_ptr<LightDMSessionInfo>>())
, m_mapUsers(new QMap<QString, UserInfoPtr>())
, m_dbusIfsLDM(nullptr)
@ -96,8 +97,13 @@ QList<QString> LightDMHelper::getSessionsInfo()
void LightDMHelper::startSession()
{
if(isAuthenticated())
Q_EMIT authenticationSucess(authenticationUser());
if(isAuthenticated()) {
if (m_configuration) {
m_configuration->saveLastLoginUser(m_strCurUserName);
m_configuration->saveLastLoginUser1(m_strCurUserName);
}
Q_EMIT authenticationSucess(m_strCurUserName);
}
if(!startSessionSync(m_strSession)) {

View File

@ -26,6 +26,7 @@
#include <QModelIndex>
#include <QDBusInterface>
#include "userinfo.h"
#include "configuration.h"
class SecurityUser;
class UsersModel;
@ -44,7 +45,7 @@ public:
*
* @param parent
*/
explicit LightDMHelper(AccountsHelper *accountHelper, QObject *parent = nullptr);
explicit LightDMHelper(AccountsHelper *accountHelper, Configuration *config, QObject *parent = nullptr);
public:
/**
@ -180,6 +181,7 @@ private:
AccountsHelper *m_accountServiceHelper = nullptr;
QMap<QString, std::shared_ptr<LightDMSessionInfo>> *m_ldmSessions;
QDBusInterface *m_dbusIfsLDM;
Configuration *m_configuration = nullptr;
};
class LightDMSessionInfo : public QObject

View File

@ -43,6 +43,7 @@
#include "pluginsloader.h"
#include "msysdbus.h"
#include "languagesetting.h"
#include "displayservice.h"
FullBackgroundWidget *window = nullptr;
@ -71,11 +72,19 @@ int main(int argc, char *argv[])
// 屏蔽输入法
qunsetenv("QT_IM_MODULE");
LockDialogModel *lockDialogModel = new LockDialogModel();
LockDialogPerformer *performer = new LockDialogPerformer(lockDialogModel);
if (isGreeterMode())
DisplayService::instance(lockDialogModel)->setCurUserName(lockDialogModel->defaultUserName());
QString id = QString("ukui-screensaver-dialog"+QLatin1String(getenv("DISPLAY")));
QtSingleApplication app(id, argc, argv);
if (app.isRunning()) {
QString strArguments = QApplication::arguments().join(",");
app.sendMessage(strArguments);
delete lockDialogModel;
lockDialogModel = nullptr;
qInfo()<<"ukui screensaver dialog is running!";
return EXIT_SUCCESS;
}
@ -87,9 +96,6 @@ int main(int argc, char *argv[])
QApplication::setSetuidAllowed(true);
LockDialogModel *lockDialogModel = new LockDialogModel();
LockDialogPerformer *performer = new LockDialogPerformer(lockDialogModel);
QObject::connect(lockDialogModel, &LockDialogModel::requestUnlockSession, [=]() {
if (window) {
window->onCloseScreensaver();

View File

@ -43,6 +43,7 @@
#include "commonfunc.h"
#include "screensavermode.h"
#include "screensaverwidget.h"
#include "displayservice.h"
FullBackgroundWidget::FullBackgroundWidget(LockDialogModel *model, QWidget *parent)
: QWidget(parent)
@ -635,7 +636,8 @@ bool FullBackgroundWidget::nativeEventFilter(const QByteArray &eventType, void *
void FullBackgroundWidget::onCurUserChanged(const QString &strUserName)
{
if (isGreeterMode())
DisplayService::instance(m_modelLockDialog)->setCurUserName(strUserName);
}
void FullBackgroundWidget::onAuthSucceed(QString strUserName)