Skip to content

feat(wlroots): key modifiers#1215

Merged
MistEO merged 4 commits intoMaaXYZ:mainfrom
heipiao233:feat/wlroots-key-modifiers
Mar 21, 2026
Merged

feat(wlroots): key modifiers#1215
MistEO merged 4 commits intoMaaXYZ:mainfrom
heipiao233:feat/wlroots-key-modifiers

Conversation

@heipiao233
Copy link
Copy Markdown
Contributor

@heipiao233 heipiao233 commented Mar 18, 2026

增加 wlroots 控制器下 Ctrl、Shift、Meta 、CapsLock 和 NumLock 等按键的支持,补充相关文档

Summary by Sourcery

为 wlroots 虚拟键盘客户端添加修饰键状态处理,并更新相关文档。

新功能:

  • 支持通过 wlroots 虚拟键盘客户端追踪并发送 Ctrl、Shift、Alt/Meta、CapsLock 和 NumLock 的修饰键状态。

增强:

  • 引入辅助工具,用于在 Wayland 客户端中将 Linux 输入键码映射为按下(depressed)和锁定(locked)的修饰键掩码。

文档:

  • 更新中文文档,以反映 wlroots 控制器对修饰键的新支持。
Original summary in English

Summary by Sourcery

Add modifier key state handling to the wlroots virtual keyboard client and update related documentation.

New Features:

  • Support tracking and sending Ctrl, Shift, Alt/Meta, CapsLock, and NumLock modifier states through the wlroots virtual keyboard client.

Enhancements:

  • Introduce helper utilities to map Linux input key codes to depressed and locked modifier masks within the Wayland client.

Documentation:

  • Update Chinese documentation to reflect new wlroots controller modifier key support.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:

  • WaylandHelper::depressed_key_modifiers/locked_key_modifiers 中硬编码的修饰键位掩码值 (1, 2, 4, 8, 16, 64),如果通过具名的 enum 或与 WaylandClient 共享的 constexpr 位掩码常量来表达,会更清晰也更不容易出错。
  • input_key 的修饰键处理目前会忽略 EventPhase::Moved;如果按设计键盘事件不会出现这个 phase,建议增加断言/日志,或者在文档中说明这一假设,以避免出现静默的 no-op。
  • 在按键按下时使用 current_locked_modifiers_ ^= locked_modifier 的逻辑假定所有锁定键都是“切换”行为;如果未来新增其他类似锁定行为的按键,这里可能会比较脆弱——建议将切换语义集中到一个地方处理,或者明确只限制在 Caps Lock / Num Lock 上,从而让行为更清晰。
给 AI 代理的提示
请根据本次代码评审中的评论进行修改:

## 总体评论
-`WaylandHelper::depressed_key_modifiers`/`locked_key_modifiers` 中硬编码的修饰键位掩码值 (1, 2, 4, 8, 16, 64),如果通过具名的 enum 或与 `WaylandClient` 共享的 `constexpr` 位掩码常量来表达,会更清晰也更不容易出错。
- `input_key` 的修饰键处理目前会忽略 `EventPhase::Moved`;如果按设计键盘事件不会出现这个 phase,建议增加断言/日志,或者在文档中说明这一假设,以避免出现静默的 no-op。
- 在按键按下时使用 `current_locked_modifiers_ ^= locked_modifier` 的逻辑假定所有锁定键都是“切换”行为;如果未来新增其他类似锁定行为的按键,这里可能会比较脆弱——建议将切换语义集中到一个地方处理,或者明确只限制在 Caps Lock / Num Lock 上,从而让行为更清晰。

## 具体评论

### 评论 1
<location path="source/MaaWlRootsControlUnit/Client/WaylandHelper.cpp" line_range="45-54" />
<code_context>
     }
 }

+int WaylandHelper::depressed_key_modifiers(int key) {
+    switch (key) {
+        case KEY_LEFTSHIFT:
+        case KEY_RIGHTSHIFT:
+            return 1;
+        case KEY_CAPSLOCK:
+            return 2;
+        case KEY_LEFTCTRL:
+        case KEY_RIGHTCTRL:
+            return 4;
+        case KEY_LEFTALT:
+        case KEY_RIGHTALT:
+            return 8; // Mod1
+        case KEY_NUMLOCK:
+            return 16; // Mod2
+        case KEY_LEFTMETA:
+        case KEY_RIGHTMETA:
+            return 64; // Mod4
+        default:
+            return 0;
</code_context>
<issue_to_address>
**suggestion:** 使用具名常量或强类型 enum/位掩码来替代魔法数字形式的修饰键位掩码值。

硬编码的位值 (1, 2, 4, 8, 16, 64) 会掩盖各自对应的逻辑修饰键含义,也让对齐 xkb/common 的检查更困难。请引入 `constexpr` 具名常量或作为位掩码使用的 scoped enum(例如 Shift、Lock、Control、Mod1、Mod2、Mod4),并在此处改用这些常量,这样未来如果需要新增 Mod3/Mod5 或调整位位置,会更容易也更安全。

建议实现如下:

```cpp
}
}

namespace {
constexpr int MOD_SHIFT   = 1;
constexpr int MOD_LOCK    = 2;
constexpr int MOD_CONTROL = 4;
constexpr int MOD1        = 8;   // Typically Alt
constexpr int MOD2        = 16;  // Typically NumLock
constexpr int MOD4        = 64;  // Typically Meta/Super
}

int WaylandHelper::depressed_key_modifiers(int key) {

```

```cpp
int WaylandHelper::depressed_key_modifiers(int key) {
    switch (key) {
        case KEY_LEFTSHIFT:
        case KEY_RIGHTSHIFT:
            return MOD_SHIFT;
        case KEY_CAPSLOCK:
            return MOD_LOCK;
        case KEY_LEFTCTRL:
        case KEY_RIGHTCTRL:
            return MOD_CONTROL;
        case KEY_LEFTALT:
        case KEY_RIGHTALT:
            return MOD1;  // Mod1 (Alt)
        case KEY_NUMLOCK:
            return MOD2;  // Mod2 (NumLock)
        case KEY_LEFTMETA:
        case KEY_RIGHTMETA:
            return MOD4;  // Mod4 (Meta/Super)
        default:
            return 0;
    }
}

```

```cpp
int WaylandHelper::locked_key_modifiers(int key) {
    switch (key) {
        case KEY_CAPSLOCK:
            return MOD_LOCK;
        case KEY_NUMLOCK:
            return MOD2; // Mod2 (NumLock)
        default:

```
</issue_to_address>

Sourcery 对开源项目免费——如果你喜欢我们的评审,请考虑帮我们分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据反馈改进后续评审。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • The hardcoded modifier bit values (1, 2, 4, 8, 16, 64) in WaylandHelper::depressed_key_modifiers/locked_key_modifiers would be clearer and less error-prone if expressed via a named enum or constexpr bitmask constants shared with WaylandClient.
  • The input_key modifier handling currently ignores EventPhase::Moved; if this phase is not expected for key events, consider asserting/logging, or otherwise documenting the assumption to avoid silent no-ops.
  • The logic current_locked_modifiers_ ^= locked_modifier on key press assumes all lock keys toggle; if additional lock-like keys are added later this might be fragile—consider centralizing the toggle semantics or restricting it explicitly to caps/num lock to make the behavior clearer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The hardcoded modifier bit values (1, 2, 4, 8, 16, 64) in `WaylandHelper::depressed_key_modifiers`/`locked_key_modifiers` would be clearer and less error-prone if expressed via a named enum or `constexpr` bitmask constants shared with `WaylandClient`.
- The `input_key` modifier handling currently ignores `EventPhase::Moved`; if this phase is not expected for key events, consider asserting/logging, or otherwise documenting the assumption to avoid silent no-ops.
- The logic `current_locked_modifiers_ ^= locked_modifier` on key press assumes all lock keys toggle; if additional lock-like keys are added later this might be fragile—consider centralizing the toggle semantics or restricting it explicitly to caps/num lock to make the behavior clearer.

## Individual Comments

### Comment 1
<location path="source/MaaWlRootsControlUnit/Client/WaylandHelper.cpp" line_range="45-54" />
<code_context>
     }
 }

+int WaylandHelper::depressed_key_modifiers(int key) {
+    switch (key) {
+        case KEY_LEFTSHIFT:
+        case KEY_RIGHTSHIFT:
+            return 1;
+        case KEY_CAPSLOCK:
+            return 2;
+        case KEY_LEFTCTRL:
+        case KEY_RIGHTCTRL:
+            return 4;
+        case KEY_LEFTALT:
+        case KEY_RIGHTALT:
+            return 8; // Mod1
+        case KEY_NUMLOCK:
+            return 16; // Mod2
+        case KEY_LEFTMETA:
+        case KEY_RIGHTMETA:
+            return 64; // Mod4
+        default:
+            return 0;
</code_context>
<issue_to_address>
**suggestion:** Replace magic modifier bit values with named constants or a strongly-typed enum/bitmask.

The hard-coded bit values (1, 2, 4, 8, 16, 64) obscure which logical modifier each represents and make it harder to check alignment with xkb/common. Please introduce `constexpr` named constants or a scoped enum used as a bitmask (e.g., Shift, Lock, Control, Mod1, Mod2, Mod4) and use those instead, so future changes (adding Mod3/Mod5 or adjusting bit positions) are easier and safer.

Suggested implementation:

```cpp
}
}

namespace {
constexpr int MOD_SHIFT   = 1;
constexpr int MOD_LOCK    = 2;
constexpr int MOD_CONTROL = 4;
constexpr int MOD1        = 8;   // Typically Alt
constexpr int MOD2        = 16;  // Typically NumLock
constexpr int MOD4        = 64;  // Typically Meta/Super
}

int WaylandHelper::depressed_key_modifiers(int key) {

```

```cpp
int WaylandHelper::depressed_key_modifiers(int key) {
    switch (key) {
        case KEY_LEFTSHIFT:
        case KEY_RIGHTSHIFT:
            return MOD_SHIFT;
        case KEY_CAPSLOCK:
            return MOD_LOCK;
        case KEY_LEFTCTRL:
        case KEY_RIGHTCTRL:
            return MOD_CONTROL;
        case KEY_LEFTALT:
        case KEY_RIGHTALT:
            return MOD1;  // Mod1 (Alt)
        case KEY_NUMLOCK:
            return MOD2;  // Mod2 (NumLock)
        case KEY_LEFTMETA:
        case KEY_RIGHTMETA:
            return MOD4;  // Mod4 (Meta/Super)
        default:
            return 0;
    }
}

```

```cpp
int WaylandHelper::locked_key_modifiers(int key) {
    switch (key) {
        case KEY_CAPSLOCK:
            return MOD_LOCK;
        case KEY_NUMLOCK:
            return MOD2; // Mod2 (NumLock)
        default:

```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +45 to +54
int WaylandHelper::depressed_key_modifiers(int key) {
switch (key) {
case KEY_LEFTSHIFT:
case KEY_RIGHTSHIFT:
return 1;
case KEY_CAPSLOCK:
return 2;
case KEY_LEFTCTRL:
case KEY_RIGHTCTRL:
return 4;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: 使用具名常量或强类型 enum/位掩码来替代魔法数字形式的修饰键位掩码值。

硬编码的位值 (1, 2, 4, 8, 16, 64) 会掩盖各自对应的逻辑修饰键含义,也让对齐 xkb/common 的检查更困难。请引入 constexpr 具名常量或作为位掩码使用的 scoped enum(例如 Shift、Lock、Control、Mod1、Mod2、Mod4),并在此处改用这些常量,这样未来如果需要新增 Mod3/Mod5 或调整位位置,会更容易也更安全。

建议实现如下:

}
}

namespace {
constexpr int MOD_SHIFT   = 1;
constexpr int MOD_LOCK    = 2;
constexpr int MOD_CONTROL = 4;
constexpr int MOD1        = 8;   // Typically Alt
constexpr int MOD2        = 16;  // Typically NumLock
constexpr int MOD4        = 64;  // Typically Meta/Super
}

int WaylandHelper::depressed_key_modifiers(int key) {
int WaylandHelper::depressed_key_modifiers(int key) {
    switch (key) {
        case KEY_LEFTSHIFT:
        case KEY_RIGHTSHIFT:
            return MOD_SHIFT;
        case KEY_CAPSLOCK:
            return MOD_LOCK;
        case KEY_LEFTCTRL:
        case KEY_RIGHTCTRL:
            return MOD_CONTROL;
        case KEY_LEFTALT:
        case KEY_RIGHTALT:
            return MOD1;  // Mod1 (Alt)
        case KEY_NUMLOCK:
            return MOD2;  // Mod2 (NumLock)
        case KEY_LEFTMETA:
        case KEY_RIGHTMETA:
            return MOD4;  // Mod4 (Meta/Super)
        default:
            return 0;
    }
}
int WaylandHelper::locked_key_modifiers(int key) {
    switch (key) {
        case KEY_CAPSLOCK:
            return MOD_LOCK;
        case KEY_NUMLOCK:
            return MOD2; // Mod2 (NumLock)
        default:
Original comment in English

suggestion: Replace magic modifier bit values with named constants or a strongly-typed enum/bitmask.

The hard-coded bit values (1, 2, 4, 8, 16, 64) obscure which logical modifier each represents and make it harder to check alignment with xkb/common. Please introduce constexpr named constants or a scoped enum used as a bitmask (e.g., Shift, Lock, Control, Mod1, Mod2, Mod4) and use those instead, so future changes (adding Mod3/Mod5 or adjusting bit positions) are easier and safer.

Suggested implementation:

}
}

namespace {
constexpr int MOD_SHIFT   = 1;
constexpr int MOD_LOCK    = 2;
constexpr int MOD_CONTROL = 4;
constexpr int MOD1        = 8;   // Typically Alt
constexpr int MOD2        = 16;  // Typically NumLock
constexpr int MOD4        = 64;  // Typically Meta/Super
}

int WaylandHelper::depressed_key_modifiers(int key) {
int WaylandHelper::depressed_key_modifiers(int key) {
    switch (key) {
        case KEY_LEFTSHIFT:
        case KEY_RIGHTSHIFT:
            return MOD_SHIFT;
        case KEY_CAPSLOCK:
            return MOD_LOCK;
        case KEY_LEFTCTRL:
        case KEY_RIGHTCTRL:
            return MOD_CONTROL;
        case KEY_LEFTALT:
        case KEY_RIGHTALT:
            return MOD1;  // Mod1 (Alt)
        case KEY_NUMLOCK:
            return MOD2;  // Mod2 (NumLock)
        case KEY_LEFTMETA:
        case KEY_RIGHTMETA:
            return MOD4;  // Mod4 (Meta/Super)
        default:
            return 0;
    }
}
int WaylandHelper::locked_key_modifiers(int key) {
    switch (key) {
        case KEY_CAPSLOCK:
            return MOD_LOCK;
        case KEY_NUMLOCK:
            return MOD2; // Mod2 (NumLock)
        default:

@MistEO MistEO merged commit 907ee9b into MaaXYZ:main Mar 21, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants