dde-session-shell icon indicating copy to clipboard operation
dde-session-shell copied to clipboard

fix: greeter could not enter the password after setting a special key…

Open yixinshark opened this issue 8 months ago • 2 comments

…board layout

无法输入是因为密码输入限制输入字符。而密码输入需要字母,数字,符号等,禁止其他字符,如藏文。 1.检测到设置特殊键盘布局后,修改称us键盘布局 2.认证成功后,恢复原先键盘布局。

Log: as title Pms: BUG-317167

yixinshark avatar May 22 '25 05:05 yixinshark

deepin pr auto review

关键摘要:

  • getCurrentKBLayout 函数中使用了 QProcess 来获取键盘布局,可能会影响性能,建议使用更高效的方法。
  • setKBLayout 函数中直接执行 QProcess::execute,没有错误处理机制,建议添加错误处理逻辑。
  • m_originalKBLayout 成员变量在 LockContent 类中声明,但没有对应的析构函数处理,可能会导致资源泄露。
  • init 函数中新增的键盘布局处理逻辑,没有对 m_originalKBLayout 的初始化处理,可能会导致未定义行为。

是否建议立即修改: 是

deepin-ci-robot avatar Aug 14 '25 03:08 deepin-ci-robot

[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.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment Approvers can cancel approval by writing /approve cancel in a comment

deepin-ci-robot avatar Aug 14 '25 03:08 deepin-ci-robot

这样是不是影响最小呢,比如不影响网络的输入呢,但更复杂,还是设计大小写转换,还有特殊字符,需要测试。 #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(); }

yixinshark avatar Aug 14 '25 03:08 yixinshark