Skip to content

Commit 602c047

Browse files
committed
Prevent infinite loop when two ContextActive toggle each other
1 parent d802a36 commit 602c047

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

src/server/ServerState.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ bool ServerState::flush_send_buffer() {
271271

272272
auto succeeded = true;
273273
auto i = size_t{ };
274+
auto toggled_virtual_keys = 0;
274275
for (; i < m_send_buffer.size(); ++i) {
275276
const auto& event = m_send_buffer[i];
276277

@@ -282,8 +283,11 @@ bool ServerState::flush_send_buffer() {
282283
}
283284

284285
if (is_virtual_key(event.key)) {
285-
if (event.state == KeyState::Down)
286-
toggle_virtual_key(event.key);
286+
if (event.state == KeyState::Down) {
287+
// prevent infinite loop (when two ContextActive toggle each other)
288+
if (++toggled_virtual_keys < 10)
289+
toggle_virtual_key(event.key);
290+
}
287291
continue;
288292
}
289293

src/test/test4_Server.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ TEST_CASE("Minimal configuration", "[Server]") {
152152
CHECK(state.apply_input("-A") == "-B");
153153
}
154154

155-
156155
//--------------------------------------------------------------------
157156

158157
TEST_CASE("Modifier filter and no might match (infinite loop bug)", "[Server]") {
@@ -170,6 +169,41 @@ TEST_CASE("Modifier filter and no might match (infinite loop bug)", "[Server]")
170169

171170
//--------------------------------------------------------------------
172171

172+
TEST_CASE("Modifier filter toggled in ContextActive", "[Server]") {
173+
auto state = create_state(R"(
174+
X >> Virtual1
175+
176+
[modifier = Virtual1]
177+
ContextActive >> A Virtual1
178+
)");
179+
CHECK(state.apply_input("+X") == "+A -A");
180+
CHECK(state.apply_input("-X") == "");
181+
CHECK(state.apply_input("+X") == "+A -A");
182+
CHECK(state.apply_input("-X") == "");
183+
}
184+
185+
//--------------------------------------------------------------------
186+
187+
TEST_CASE("Modifier filter toggled in two ContextActive (prevent infinite loop)", "[Server]") {
188+
auto state = create_state(R"(
189+
C >> Virtual1
190+
191+
[modifier = Virtual1]
192+
ContextActive >> A Virtual1
193+
194+
[modifier = "!Virtual1"]
195+
ContextActive >> B Virtual1
196+
)", false);
197+
CHECK(state.set_active_contexts({ 0, 1, 2 }) == "+B -B +A -A +B -B +A -A +B -B +A -A +B -B +A -A +B -B +A -A");
198+
CHECK(state.apply_input("+A -A") == "+A -A");
199+
CHECK(state.apply_input("+B -B") == "+B -B");
200+
CHECK(state.apply_input("+C") == "+B -B +A -A +B -B +A -A +B -B +A -A +B -B +A -A +B -B");
201+
CHECK(state.apply_input("+A -A") == "+A -A");
202+
CHECK(state.apply_input("+B -B") == "+B -B");
203+
}
204+
205+
//--------------------------------------------------------------------
206+
173207
TEST_CASE("Trigger Not Timeout", "[Server]") {
174208
auto state = create_state(R"(
175209
ShiftLeft{!200ms} >> B

0 commit comments

Comments
 (0)