Skip to content

Commit b0f0b9e

Browse files
sync: from linuxdeepin/dde-session-shell
Synchronize source files from linuxdeepin/dde-session-shell. Source-pull-request: linuxdeepin/dde-session-shell#10
1 parent ea24f05 commit b0f0b9e

File tree

3 files changed

+111
-7
lines changed

3 files changed

+111
-7
lines changed

src/session-widgets/lockcontent.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ void LockContent::init(SessionBaseModel *model)
112112
}
113113

114114
DConfigHelper::instance()->bind(this, SHOW_MEDIA_WIDGET, &LockContent::OnDConfigPropertyChanged);
115+
116+
if (m_model->appType() == AuthCommon::Login && keyboardLayoutHasSpecialSetting()) {
117+
m_originalKBLayout = getCurrentKBLayoutAndVariant();
118+
qCInfo(DDE_SHELL) << "Original keyboard layout:" << m_originalKBLayout;
119+
// 如果是登录界面且键盘布局有特殊设置,则切换到英文键盘布局
120+
setKBLayoutAndVariant("us");
121+
}
115122
}
116123

117124
void LockContent::initUI()
@@ -184,8 +191,13 @@ void LockContent::initConnections()
184191
connect(m_model, &SessionBaseModel::userListChanged, this, &LockContent::onUserListChanged);
185192
connect(m_model, &SessionBaseModel::userListLoginedChanged, this, &LockContent::onUserListChanged);
186193
connect(m_model, &SessionBaseModel::authFinished, this, [this](bool successful) {
187-
if (successful)
194+
if (successful) {
188195
setVisible(false);
196+
if (!m_originalKBLayout.isEmpty()) {
197+
// 切换回原来的键盘布局
198+
setKBLayoutAndVariant(m_originalKBLayout);
199+
}
200+
}
189201
restoreMode();
190202
});
191203
connect(m_model, &SessionBaseModel::MFAFlagChanged, this, [this](const bool isMFA) {
@@ -985,3 +997,53 @@ void LockContent::showShutdown()
985997
m_model->setCurrentModeState(SessionBaseModel::ModeStatus::ShutDownMode);
986998
m_model->setVisible(true);
987999
}
1000+
1001+
// 判断键盘布局是否有特殊设置,如XKBVARIANT=tib(藏文键盘布局),这个配置文件可通过安装器后配置键盘布局修改
1002+
// 如果设置特殊键盘布局,则在greeter阶段会导致无法输入的问题,密码输入框等设置过滤规则(如大小写,数字,符号等)
1003+
bool LockContent::keyboardLayoutHasSpecialSetting() const
1004+
{
1005+
QFile file("/etc/default/keyboard");
1006+
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
1007+
return false;
1008+
1009+
QTextStream in(&file);
1010+
while (!in.atEnd()) {
1011+
QString line = in.readLine().trimmed();
1012+
if (line.startsWith("XKBVARIANT=")) {
1013+
QString val = line.section('=', 1).trimmed();
1014+
if (val.startsWith('"') && val.endsWith('"'))
1015+
val = val.mid(1, val.length() - 2); // Remove quotes
1016+
return !val.trimmed().isEmpty();
1017+
}
1018+
}
1019+
1020+
return false;
1021+
}
1022+
1023+
QString LockContent::getCurrentKBLayoutAndVariant() const
1024+
{
1025+
QProcess p;
1026+
p.start("/usr/bin/setxkbmap", {"-query"});
1027+
p.waitForFinished();
1028+
QString layout, variant;
1029+
1030+
const QString output = QString::fromUtf8(p.readAllStandardOutput());
1031+
for (const QString &line : output.split('\n')) {
1032+
if (line.startsWith("layout:"))
1033+
layout = line.section(':', 1).trimmed();
1034+
else if (line.startsWith("variant:"))
1035+
variant = line.section(':', 1).trimmed();
1036+
}
1037+
1038+
return variant.isEmpty() ? layout : layout + "+" + variant;
1039+
}
1040+
1041+
void LockContent::setKBLayoutAndVariant(const QString &layoutVariant)
1042+
{
1043+
qCInfo(DDE_SHELL) << "Set keyboard layout and variant: " << layoutVariant;
1044+
const QStringList parts = layoutVariant.split('+');
1045+
if (parts.size() == 2)
1046+
QProcess::execute("/usr/bin/setxkbmap", {parts[0], "-variant", parts[1]});
1047+
else if (parts.size() == 1)
1048+
QProcess::execute("/usr/bin/setxkbmap", {parts[0]});
1049+
}

src/session-widgets/lockcontent.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ public slots:
101101
void initFMAWidget();
102102
void initUserListWidget();
103103
void enableSystemShortcut(const QStringList &shortcuts, bool enabled, bool isPersistent);
104+
bool keyboardLayoutHasSpecialSetting() const;
105+
QString getCurrentKBLayoutAndVariant() const;
106+
void setKBLayoutAndVariant(const QString &layoutVariant);
104107

105108
protected:
106109
SessionBaseModel *m_model = nullptr;
@@ -133,6 +136,8 @@ public slots:
133136
bool m_MPRISEnable = false;
134137
bool m_showMediaWidget = false;
135138
bool m_hasResetPasswordDialog = false;
139+
140+
QString m_originalKBLayout;
136141
};
137142

138143
#endif // LOCKCONTENT_H

src/widgets/inhibitwarnview.cpp

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,22 @@
1010
#include <DLabel>
1111
#include <DToolTip>
1212

13+
#ifdef ENABLE_DSS_SNIPE
14+
#include <DSGApplication>
15+
#include <DUtil>
16+
#include <DDBusSender>
17+
#endif
18+
1319
#include <QHBoxLayout>
1420

1521
DWIDGET_USE_NAMESPACE
1622

23+
#ifdef ENABLE_DSS_SNIPE
24+
#define AMDBUS_SERVICE "org.desktopspec.ApplicationManager1"
25+
#define AMDBUS_PATH_APP_PREFIX "/org/desktopspec/ApplicationManager1"
26+
#define AMDBUS_APP_INTERFACE "org.desktopspec.ApplicationManager1.Application"
27+
#endif
28+
1729
const int ButtonWidth = 200;
1830
const int ButtonHeight = 64;
1931
const int FIXED_INHIBITOR_WIDTH = 328;
@@ -86,16 +98,41 @@ void InhibitWarnView::setInhibitorList(const QList<InhibitorData> &list)
8698
for (const InhibitorData &inhibitor : list) {
8799
QIcon icon;
88100

89-
if (inhibitor.icon.isEmpty() && inhibitor.pid) {
101+
if (inhibitor.icon.isEmpty()) {
102+
QString iconName;
103+
#ifdef ENABLE_DSS_SNIPE
104+
do {
105+
const auto appId = Dtk::Core::DSGApplication::getId(inhibitor.pid);
106+
if (appId.isEmpty())
107+
break;
108+
const auto amDBusAppPath = QString("%1/%2").arg(AMDBUS_PATH_APP_PREFIX, DUtil::escapeToObjectPath(appId));
109+
QDBusReply<QDBusVariant> reply = DDBusSender()
110+
.service(AMDBUS_SERVICE)
111+
.path(amDBusAppPath)
112+
.interface(AMDBUS_APP_INTERFACE)
113+
.property("Icons")
114+
.get();
115+
if (reply.isValid()) {
116+
auto ret = qdbus_cast<QMap<QString, QString>>(reply.value().variant());
117+
iconName = ret.value("Desktop Entry");
118+
} else {
119+
qCWarning(DDE_SHELL) << "Get icon error:" << reply.error().message();
120+
break;
121+
}
122+
} while(0);
123+
#endif
124+
125+
if (iconName.isEmpty() && inhibitor.pid) {
90126
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
91-
QFileInfo executable_info(QFile::symLinkTarget(QString("/proc/%1/exe").arg(inhibitor.pid)));
127+
QFileInfo executable_info(QFile::symLinkTarget(QString("/proc/%1/exe").arg(inhibitor.pid)));
92128
#else
93-
QFileInfo executable_info(QFile::readLink(QString("/proc/%1/exe").arg(inhibitor.pid)));
129+
QFileInfo executable_info(QFile::readLink(QString("/proc/%1/exe").arg(inhibitor.pid)));
94130
#endif
95-
96-
if (executable_info.exists()) {
97-
icon = QIcon::fromTheme(executable_info.fileName());
131+
// 玲珑应用的exe指向的路径是容器内的路径,在容器外无法访问,因此不能判断文件是否存在
132+
QString iconName = executable_info.fileName();
98133
}
134+
135+
icon = QIcon::fromTheme(iconName);
99136
} else {
100137
icon = QIcon::fromTheme(inhibitor.icon, QIcon::fromTheme("application-x-desktop"));
101138
}

0 commit comments

Comments
 (0)