Skip to content

Commit f1e02d0

Browse files
committed
add tests for rebinds
1 parent bfbc0be commit f1e02d0

12 files changed

Lines changed: 1153 additions & 6 deletions

File tree

CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ endif()
651651
set(TOOLSCREEN_GUI_INTEGRATION_SUITE_FILES
652652
${CMAKE_CURRENT_SOURCE_DIR}/tests/gui_integration_tests.cpp
653653
${CMAKE_CURRENT_SOURCE_DIR}/tests/gui_integration/config_tests.inl
654+
${CMAKE_CURRENT_SOURCE_DIR}/tests/gui_integration/rebind_tests.inl
654655
${CMAKE_CURRENT_SOURCE_DIR}/tests/gui_integration/render_tests.inl
655656
${CMAKE_CURRENT_SOURCE_DIR}/tests/gui_integration/ui_and_log_tests.inl
656657
${CMAKE_CURRENT_SOURCE_DIR}/tests/gui_integration/runner.inl
@@ -678,6 +679,7 @@ target_compile_definitions(toolscreen_gui_integration_tests PRIVATE
678679
CMAKE_BUILD
679680
GLEW_STATIC
680681
NOMINMAX
682+
TOOLSCREEN_GUI_INTEGRATION_TESTS
681683
UNICODE
682684
_UNICODE
683685
)
@@ -761,6 +763,21 @@ set(TOOLSCREEN_GUI_INTEGRATION_TEST_CASES
761763
config-load-key-rebind-escaped-unicode-string-parsed
762764
config-load-key-rebind-hex-unicode-string-parsed
763765
config-load-key-rebind-invalid-unicode-defaulted
766+
config-load-key-rebind-shift-layer-caps-lock-parsed
767+
config-load-key-rebind-shift-layer-caps-lock-defaulted
768+
key-rebind-runtime-full-forwarding
769+
key-rebind-runtime-split-vk-output
770+
key-rebind-runtime-split-unicode-output
771+
key-rebind-runtime-shift-layer-shift-activated
772+
key-rebind-runtime-shift-layer-caps-lock-activated
773+
key-rebind-runtime-full-caps-lock-honored
774+
key-rebind-runtime-split-caps-lock-ignored
775+
key-rebind-runtime-non-typable-trigger-consumes-char
776+
key-rebind-runtime-mouse-source-emits-key-and-char
777+
key-rebind-runtime-disabled-rebind-ignored
778+
key-rebind-gui-keyboard-layout-full-bind-and-trigger
779+
key-rebind-gui-keyboard-layout-split-bind-and-trigger
780+
key-rebind-gui-keyboard-layout-mouse-source-bind-and-trigger
764781
config-load-fullscreen-stretch-repaired
765782
config-load-preemptive-sync-existing-mode
766783
config-load-thin-min-width-enforced

lang/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@
298298
"inputs.tooltip.rebind_triggers": "Changes the game keybind this key triggers, including non-text actions like Backspace or Home.",
299299
"inputs.tooltip.rebind_types": "Changes what this key types in chat, search boxes, and other in-game text fields.",
300300
"inputs.tooltip.rebind_types_shift": "Changes what this key types while Shift is held in in-game text fields. Leave it unchanged to inherit Types.",
301+
"inputs.tooltip.rebind_types_shift_caps_lock": "When enabled, Caps Lock also activates this key's Shift layer in split rebind mode.",
301302
"inputs.tooltip.rebind_toggle_hotkey": "Toggles key rebinding ACTIVE/DISABLED at runtime.",
302303
"inputs.tooltip.resolve_rebind_targets": "When enabled, hotkeys can match the rebind target key for the pressed source key. Disable to only match the actual pressed key.",
303304
"inputs.tooltip.right_click_to_configure": "Right-click to configure rebinds.",
@@ -307,6 +308,7 @@
307308
"inputs.triggers_format": "Triggers: {}",
308309
"inputs.triggers_label": "Triggers:",
309310
"inputs.shift_layer_label": "Shift layer",
311+
"inputs.shift_layer_caps_lock_label": "Caps Lock triggers shift layer",
310312
"inputs.shift_layer_output_shifted_label": "Type uppercase / symbol",
311313
"inputs.types_shift_inherits_format": "Same as Types ({})",
312314
"inputs.types_shift_format": "Types (Shift): {}",

lang/zh_CN.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@
298298
"inputs.tooltip.rebind_triggers": "更改此按键触发的游戏按键绑定,包括 Backspace 或 Home 之类的非文本动作。",
299299
"inputs.tooltip.rebind_types": "更改此按键在聊天、搜索框和其他游戏文本输入中实际输入的内容。",
300300
"inputs.tooltip.rebind_types_shift": "更改按住 Shift 时,此按键在游戏文本输入中实际输入的内容。留空时会继承“类型”设置。",
301+
"inputs.tooltip.rebind_types_shift_caps_lock": "启用后,在拆分重绑定模式下,Caps Lock 也会触发该按键的 Shift 层。",
301302
"inputs.tooltip.rebind_toggle_hotkey": "在运行时切换按键重绑定的激活/禁用状态。",
302303
"inputs.tooltip.resolve_rebind_targets": "启用后,快捷键可以匹配按下源键的重绑定目标键。禁用以仅匹配实际按下的键。",
303304
"inputs.tooltip.right_click_to_configure": "右键单击以配置重绑定。",
@@ -307,6 +308,7 @@
307308
"inputs.triggers_format": "触发器:{}",
308309
"inputs.triggers_label": "触发器:",
309310
"inputs.shift_layer_label": "Shift 层",
311+
"inputs.shift_layer_caps_lock_label": "Caps Lock 触发 Shift 层",
310312
"inputs.shift_layer_output_shifted_label": "输入大写 / 符号",
311313
"inputs.types_shift_inherits_format": "与类型相同({})",
312314
"inputs.types_shift_format": "类型(Shift):{}",

src/config/config_defaults.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ constexpr DWORD KEY_REBIND_CUSTOM_OUTPUT_UNICODE = 0;
182182
constexpr DWORD KEY_REBIND_CUSTOM_OUTPUT_SCANCODE = 0;
183183
constexpr bool KEY_REBIND_BASE_OUTPUT_SHIFTED = false;
184184
constexpr bool KEY_REBIND_SHIFT_LAYER_ENABLED = false;
185+
constexpr bool KEY_REBIND_SHIFT_LAYER_USES_CAPS_LOCK = false;
185186
constexpr DWORD KEY_REBIND_SHIFT_LAYER_OUTPUT_VK = 0;
186187
constexpr DWORD KEY_REBIND_SHIFT_LAYER_OUTPUT_UNICODE = 0;
187188
constexpr bool KEY_REBIND_SHIFT_LAYER_OUTPUT_SHIFTED = false;

src/config/config_toml.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,6 +1702,7 @@ void KeyRebindToToml(const KeyRebind& cfg, toml::table& out) {
17021702
out.insert("customOutputScanCode", static_cast<int64_t>(cfg.customOutputScanCode));
17031703
out.insert("baseOutputShifted", cfg.baseOutputShifted);
17041704
out.insert("shiftLayerEnabled", cfg.shiftLayerEnabled);
1705+
out.insert("shiftLayerUsesCapsLock", cfg.shiftLayerUsesCapsLock);
17051706
out.insert("shiftLayerOutputVK", static_cast<int64_t>(cfg.shiftLayerOutputVK));
17061707
out.insert("shiftLayerOutputUnicode", static_cast<int64_t>(cfg.shiftLayerOutputUnicode));
17071708
out.insert("shiftLayerOutputShifted", cfg.shiftLayerOutputShifted);
@@ -1809,6 +1810,8 @@ void KeyRebindFromToml(const toml::table& tbl, KeyRebind& cfg) {
18091810
static_cast<DWORD>(GetOr<int64_t>(tbl, "customOutputScanCode", ConfigDefaults::KEY_REBIND_CUSTOM_OUTPUT_SCANCODE));
18101811
cfg.baseOutputShifted = GetOr(tbl, "baseOutputShifted", ConfigDefaults::KEY_REBIND_BASE_OUTPUT_SHIFTED);
18111812
cfg.shiftLayerEnabled = GetOr(tbl, "shiftLayerEnabled", ConfigDefaults::KEY_REBIND_SHIFT_LAYER_ENABLED);
1813+
cfg.shiftLayerUsesCapsLock =
1814+
GetOr(tbl, "shiftLayerUsesCapsLock", ConfigDefaults::KEY_REBIND_SHIFT_LAYER_USES_CAPS_LOCK);
18121815
cfg.shiftLayerOutputVK =
18131816
static_cast<DWORD>(GetOr<int64_t>(tbl, "shiftLayerOutputVK", ConfigDefaults::KEY_REBIND_SHIFT_LAYER_OUTPUT_VK));
18141817
cfg.shiftLayerOutputUnicode = ConfigDefaults::KEY_REBIND_SHIFT_LAYER_OUTPUT_UNICODE;

src/gui/gui.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,70 @@ namespace {
7474
const char* s_forcedSettingsTopTabLabel = nullptr;
7575
const char* s_forcedSettingsInputsSubTabLabel = nullptr;
7676

77+
#ifdef TOOLSCREEN_GUI_INTEGRATION_TESTS
78+
std::unordered_map<std::string, GuiTestInteractionRect> s_guiTestInteractionRects;
79+
bool s_guiTestOpenKeyboardLayoutRequested = false;
80+
DWORD s_guiTestOpenKeyboardLayoutContextVk = 0;
81+
int s_guiTestKeyboardLayoutSplitModeRequest = -1;
82+
GuiTestKeyboardLayoutBindTarget s_guiTestKeyboardLayoutBindTargetRequest = GuiTestKeyboardLayoutBindTarget::None;
83+
int s_guiTestKeyboardLayoutShiftUppercaseRequest = -1;
84+
int s_guiTestKeyboardLayoutShiftCapsLockRequest = -1;
85+
86+
void RecordGuiTestInteractionRect(const char* id, const ImVec2& min, const ImVec2& max) {
87+
if (id == nullptr) {
88+
return;
89+
}
90+
91+
s_guiTestInteractionRects[std::string(id)] = GuiTestInteractionRect{ min.x, min.y, max.x, max.y };
92+
}
93+
94+
void RecordGuiTestInteractionRect(const std::string& id, const ImVec2& min, const ImVec2& max) {
95+
RecordGuiTestInteractionRect(id.c_str(), min, max);
96+
}
97+
98+
void RecordGuiTestKeyboardLayoutKeyRect(DWORD vk, const ImVec2& min, const ImVec2& max) {
99+
char id[96] = {};
100+
sprintf_s(id, "inputs.keyboard_layout.key.%u", static_cast<unsigned>(vk));
101+
RecordGuiTestInteractionRect(id, min, max);
102+
}
103+
104+
bool ConsumeGuiTestOpenKeyboardLayoutRequest() {
105+
const bool requested = s_guiTestOpenKeyboardLayoutRequested;
106+
s_guiTestOpenKeyboardLayoutRequested = false;
107+
return requested;
108+
}
109+
110+
DWORD ConsumeGuiTestOpenKeyboardLayoutContextRequest() {
111+
const DWORD vk = s_guiTestOpenKeyboardLayoutContextVk;
112+
s_guiTestOpenKeyboardLayoutContextVk = 0;
113+
return vk;
114+
}
115+
116+
int ConsumeGuiTestKeyboardLayoutSplitModeRequest() {
117+
const int request = s_guiTestKeyboardLayoutSplitModeRequest;
118+
s_guiTestKeyboardLayoutSplitModeRequest = -1;
119+
return request;
120+
}
121+
122+
GuiTestKeyboardLayoutBindTarget ConsumeGuiTestKeyboardLayoutBindTargetRequest() {
123+
const GuiTestKeyboardLayoutBindTarget request = s_guiTestKeyboardLayoutBindTargetRequest;
124+
s_guiTestKeyboardLayoutBindTargetRequest = GuiTestKeyboardLayoutBindTarget::None;
125+
return request;
126+
}
127+
128+
int ConsumeGuiTestKeyboardLayoutShiftUppercaseRequest() {
129+
const int request = s_guiTestKeyboardLayoutShiftUppercaseRequest;
130+
s_guiTestKeyboardLayoutShiftUppercaseRequest = -1;
131+
return request;
132+
}
133+
134+
int ConsumeGuiTestKeyboardLayoutShiftCapsLockRequest() {
135+
const int request = s_guiTestKeyboardLayoutShiftCapsLockRequest;
136+
s_guiTestKeyboardLayoutShiftCapsLockRequest = -1;
137+
return request;
138+
}
139+
#endif
140+
77141
bool BeginSelectableSettingsTopTabItem(const char* label) {
78142
ImGuiTabItemFlags flags = ImGuiTabItemFlags_None;
79143
if (s_forcedSettingsTopTabLabel != nullptr && std::strcmp(s_forcedSettingsTopTabLabel, label) == 0) {
@@ -132,6 +196,50 @@ void CloseSettingsGuiWindow() {
132196

133197
}
134198

199+
#ifdef TOOLSCREEN_GUI_INTEGRATION_TESTS
200+
void ResetGuiTestInteractionRects() {
201+
s_guiTestInteractionRects.clear();
202+
}
203+
204+
bool GetGuiTestInteractionRect(const char* id, GuiTestInteractionRect& outRect) {
205+
if (id == nullptr) {
206+
return false;
207+
}
208+
209+
const auto found = s_guiTestInteractionRects.find(id);
210+
if (found == s_guiTestInteractionRects.end()) {
211+
return false;
212+
}
213+
214+
outRect = found->second;
215+
return true;
216+
}
217+
218+
void RequestGuiTestOpenKeyboardLayout() {
219+
s_guiTestOpenKeyboardLayoutRequested = true;
220+
}
221+
222+
void RequestGuiTestOpenKeyboardLayoutContext(DWORD vk) {
223+
s_guiTestOpenKeyboardLayoutContextVk = vk;
224+
}
225+
226+
void RequestGuiTestKeyboardLayoutSetSplitMode(bool splitMode) {
227+
s_guiTestKeyboardLayoutSplitModeRequest = splitMode ? 1 : 0;
228+
}
229+
230+
void RequestGuiTestKeyboardLayoutBeginBind(GuiTestKeyboardLayoutBindTarget target) {
231+
s_guiTestKeyboardLayoutBindTargetRequest = target;
232+
}
233+
234+
void RequestGuiTestKeyboardLayoutSetShiftLayerUppercase(bool enabled) {
235+
s_guiTestKeyboardLayoutShiftUppercaseRequest = enabled ? 1 : 0;
236+
}
237+
238+
void RequestGuiTestKeyboardLayoutSetShiftLayerUsesCapsLock(bool enabled) {
239+
s_guiTestKeyboardLayoutShiftCapsLockRequest = enabled ? 1 : 0;
240+
}
241+
#endif
242+
135243
void SetGuiTabSelectionOverride(const char* topLevelTabLabel, const char* inputsSubTabLabel) {
136244
s_forcedSettingsTopTabLabel = topLevelTabLabel;
137245
s_forcedSettingsInputsSubTabLabel = inputsSubTabLabel;
@@ -210,6 +318,10 @@ void RenderConfigErrorGUI() {
210318
void RenderSettingsGUI() {
211319
ResetTransientBindingUiState();
212320

321+
#ifdef TOOLSCREEN_GUI_INTEGRATION_TESTS
322+
ResetGuiTestInteractionRects();
323+
#endif
324+
213325
static const std::vector<std::pair<const char*, const char*>>
214326
relativeToOptions = {
215327
{"topLeftViewport", trc("position.top_left_viewport")},

src/gui/gui.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,32 @@ void ApplyDynamicGuiFontRefresh();
6666
void RequestKeyboardLayoutFontRefresh(const ImVec2& windowSize, float keyHeight, float keyboardScale, bool forceRefresh = false);
6767
void ApplyPendingKeyboardLayoutFontRefresh();
6868

69+
#ifdef TOOLSCREEN_GUI_INTEGRATION_TESTS
70+
struct GuiTestInteractionRect {
71+
float minX = 0.0f;
72+
float minY = 0.0f;
73+
float maxX = 0.0f;
74+
float maxY = 0.0f;
75+
};
76+
77+
enum class GuiTestKeyboardLayoutBindTarget {
78+
None,
79+
FullOutputVk,
80+
TypesVk,
81+
TypesVkShift,
82+
TriggersVk,
83+
};
84+
85+
void ResetGuiTestInteractionRects();
86+
bool GetGuiTestInteractionRect(const char* id, GuiTestInteractionRect& outRect);
87+
void RequestGuiTestOpenKeyboardLayout();
88+
void RequestGuiTestOpenKeyboardLayoutContext(DWORD vk);
89+
void RequestGuiTestKeyboardLayoutSetSplitMode(bool splitMode);
90+
void RequestGuiTestKeyboardLayoutBeginBind(GuiTestKeyboardLayoutBindTarget target);
91+
void RequestGuiTestKeyboardLayoutSetShiftLayerUppercase(bool enabled);
92+
void RequestGuiTestKeyboardLayoutSetShiftLayerUsesCapsLock(bool enabled);
93+
#endif
94+
6995
extern ImFont* g_keyboardLayoutPrimaryFont;
7096
extern ImFont* g_keyboardLayoutSecondaryFont;
7197

@@ -474,6 +500,7 @@ struct KeyRebind {
474500
DWORD customOutputScanCode = 0;
475501
bool baseOutputShifted = false;
476502
bool shiftLayerEnabled = false;
503+
bool shiftLayerUsesCapsLock = false;
477504
DWORD shiftLayerOutputVK = 0;
478505
DWORD shiftLayerOutputUnicode = 0;
479506
bool shiftLayerOutputShifted = false;

0 commit comments

Comments
 (0)