fix: greeter could not enter the password after setting a special key…
…board layout
无法输入是因为密码输入限制输入字符。而密码输入需要字母,数字,符号等,禁止其他字符,如藏文。 1.检测到设置特殊键盘布局后,修改称us键盘布局 2.认证成功后,恢复原先键盘布局。
Log: as title Pms: BUG-317167
deepin pr auto review
关键摘要:
-
getCurrentKBLayout函数中使用了QProcess来获取键盘布局,可能会影响性能,建议使用更高效的方法。 -
setKBLayout函数中直接执行QProcess::execute,没有错误处理机制,建议添加错误处理逻辑。 -
m_originalKBLayout成员变量在LockContent类中声明,但没有对应的析构函数处理,可能会导致资源泄露。 -
init函数中新增的键盘布局处理逻辑,没有对m_originalKBLayout的初始化处理,可能会导致未定义行为。
是否建议立即修改: 是
[APPROVALNOTIFIER] This PR is NOT APPROVED
This pull-request has been approved by: robertkill, yixinshark
The full list of commands accepted by this bot can be found here.
Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment
这样是不是影响最小呢,比如不影响网络的输入呢,但更复杂,还是设计大小写转换,还有特殊字符,需要测试。 #include <QApplication> #include <QLineEdit> #include <QKeyEvent> #include <QHash> #include <QSet> #include <QDebug>
class USPasswordEdit : public QLineEdit { public: USPasswordEdit(QWidget* parent = nullptr) : QLineEdit(parent) { setPlaceholderText("US 强制键位解析(支持符号 @#$% 等)"); setEchoMode(QLineEdit::Password); }
protected: void keyPressEvent(QKeyEvent* e) override { // 放行带 Ctrl 的组合键(复制/粘贴/游标跳转等) if (e->modifiers() & Qt::ControlModifier) { QLineEdit::keyPressEvent(e); return; }
// 维护 CapsLock 状态(Qt 没有直接 API,靠收到的 CapsLock 按键翻转)
if (e->key() == Qt::Key_CapsLock) {
capsOn_ = !capsOn_;
e->accept();
return;
}
const quint32 sc = e->nativeScanCode(); // 关键:使用原生扫描码绕过系统布局
const bool shift = (e->modifiers() & Qt::ShiftModifier);
// 一些非字符键:用默认处理
switch (e->key()) {
case Qt::Key_Backspace:
case Qt::Key_Delete:
case Qt::Key_Left:
case Qt::Key_Right:
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_Home:
case Qt::Key_End:
case Qt::Key_Tab:
case Qt::Key_Escape:
QLineEdit::keyPressEvent(e);
return;
case Qt::Key_Return:
case Qt::Key_Enter:
QLineEdit::keyPressEvent(e);
return;
default:
break;
}
// 若拿不到扫描码(Wayland 常见),退回默认(会受系统布局影响)
if (sc == 0) {
QLineEdit::keyPressEvent(e);
return;
}
// === US 键盘映射(evdev 扫描码) ===
// 字母键(用小写,稍后按 Shift ⊕ CapsLock 决定大小写)
static const QHash<quint32, QChar> letterMap = {
{16,'q'},{17,'w'},{18,'e'},{19,'r'},{20,'t'},{21,'y'},{22,'u'},{23,'i'},{24,'o'},{25,'p'},
{30,'a'},{31,'s'},{32,'d'},{33,'f'},{34,'g'},{35,'h'},{36,'j'},{37,'k'},{38,'l'},
{44,'z'},{45,'x'},{46,'c'},{47,'v'},{48,'b'},{49,'n'},{50,'m'}
};
static const QSet<quint32> letterSet = QSet<quint32>(letterMap.keyBegin(), letterMap.keyEnd());
// 数字排及符号(非字母),用 normal/shifted 两套
struct Pair { QChar normal; QChar shifted; };
static const QHash<quint32, Pair> symMap = {
// 数字行(上排)
{ 2, {'1','!'} }, { 3, {'2','@'} }, { 4, {'3','#'} }, { 5, {'4','$'} }, { 6, {'5','%'} },
{ 7, {'6','^'} }, { 8, {'7','&'} }, { 9, {'8','*'} }, {10, {'9','('} }, {11, {'0',')'} },
{12, {'-','_'} }, {13, {'=','+'} },
// 右侧区(中排/边角)
{26, {'[','{'} }, {27, {']','}'} },
{39, {';',':'} }, {40, {'\'','"'} },
{41, {'`','~'} },
{43, {'\\','|'} },
{51, {',','<'} }, {52, {'.','>'} }, {53, {'/','?'} },
// 空格
{57, {' ',' '} },
// 小键盘(NumLock 开启时常用)
{71, {'7','7'} }, {72, {'8','8'} }, {73, {'9','9'} },
{75, {'4','4'} }, {76, {'5','5'} }, {77, {'6','6'} },
{79, {'1','1'} }, {80, {'2','2'} }, {81, {'3','3'} },
{82, {'0','0'} }, {83, {'.','.'} }
};
// 先处理字母
if (letterSet.contains(sc)) {
QChar ch = letterMap.value(sc);
const bool upper = shift ^ capsOn_; // Shift 与 CapsLock 异或决定大小写
if (upper) ch = ch.toUpper();
insert(QString(ch));
e->accept();
return;
}
// 再处理符号/数字
if (symMap.contains(sc)) {
const Pair p = symMap.value(sc);
const QChar ch = shift ? p.shifted : p.normal;
insert(QString(ch));
e->accept();
return;
}
// 其他未知键:走默认
QLineEdit::keyPressEvent(e);
}
private: bool capsOn_ = false; };
int main(int argc, char* argv[]) { QApplication app(argc, argv); USPasswordEdit edit; edit.resize(420, 40); edit.show(); return app.exec(); }