Skip to content

Commit

Permalink
Prevent infinite loop when two ContextActive toggle each other
Browse files Browse the repository at this point in the history
  • Loading branch information
houmain committed Jul 18, 2024
1 parent d802a36 commit 602c047
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
8 changes: 6 additions & 2 deletions src/server/ServerState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ bool ServerState::flush_send_buffer() {

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

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

if (is_virtual_key(event.key)) {
if (event.state == KeyState::Down)
toggle_virtual_key(event.key);
if (event.state == KeyState::Down) {
// prevent infinite loop (when two ContextActive toggle each other)
if (++toggled_virtual_keys < 10)
toggle_virtual_key(event.key);
}
continue;
}

Expand Down
36 changes: 35 additions & 1 deletion src/test/test4_Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ TEST_CASE("Minimal configuration", "[Server]") {
CHECK(state.apply_input("-A") == "-B");
}


//--------------------------------------------------------------------

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

//--------------------------------------------------------------------

TEST_CASE("Modifier filter toggled in ContextActive", "[Server]") {
auto state = create_state(R"(
X >> Virtual1
[modifier = Virtual1]
ContextActive >> A Virtual1
)");
CHECK(state.apply_input("+X") == "+A -A");
CHECK(state.apply_input("-X") == "");
CHECK(state.apply_input("+X") == "+A -A");
CHECK(state.apply_input("-X") == "");
}

//--------------------------------------------------------------------

TEST_CASE("Modifier filter toggled in two ContextActive (prevent infinite loop)", "[Server]") {
auto state = create_state(R"(
C >> Virtual1
[modifier = Virtual1]
ContextActive >> A Virtual1
[modifier = "!Virtual1"]
ContextActive >> B Virtual1
)", false);
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");
CHECK(state.apply_input("+A -A") == "+A -A");
CHECK(state.apply_input("+B -B") == "+B -B");
CHECK(state.apply_input("+C") == "+B -B +A -A +B -B +A -A +B -B +A -A +B -B +A -A +B -B");
CHECK(state.apply_input("+A -A") == "+A -A");
CHECK(state.apply_input("+B -B") == "+B -B");
}

//--------------------------------------------------------------------

TEST_CASE("Trigger Not Timeout", "[Server]") {
auto state = create_state(R"(
ShiftLeft{!200ms} >> B
Expand Down

0 comments on commit 602c047

Please sign in to comment.