diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizer.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizer.swift index a29eb9b..a368c34 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizer.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizer.swift @@ -178,7 +178,7 @@ private extension KeyboardVisualizer { updateGroup: { group, items in self.visualizerWindow.updateGroup(group, with: items) } ) self.collapseActiveRepeatIfNeeded(group) - if keystroke.type == .keyUp, keystroke.modifierFlags.intersection(Self.trackedModifierFlags).isEmpty { + if keystroke.type == .keyUp { self.finalizeGroupIfNeeded(group) } } diff --git a/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Keyboard/Keycaps/KeyboardVisualizerTests.swift b/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Keyboard/Keycaps/KeyboardVisualizerTests.swift index 64b3375..78b320f 100644 --- a/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Keyboard/Keycaps/KeyboardVisualizerTests.swift +++ b/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Keyboard/Keycaps/KeyboardVisualizerTests.swift @@ -190,6 +190,34 @@ final class KeyboardVisualizerTests: XCTestCase { XCTAssertEqual(self.visualizer.visibleGroupCount, 1) } + func testCollapseRepeatedGroupsReusesChordWhileModifierRemainsPressed() { + self.settings.collapseRepeatedGroups = true + self.settings.onlyShowModifiedKeystrokes = true + self.visualizer.isPresentationActive = true + + let command: NSEvent.ModifierFlags = .recorded([.command]) + self.visualizer.display(.modifierStateChanged(command)) + + self.pressAndReleaseKey(.k, modifiers: command, character: "k") + self.pressAndReleaseKey(.k, modifiers: command, character: "k") + + XCTAssertEqual(self.visualizer.visibleGroupCount, 1) + } + + func testCollapseRepeatedGroupsEnforcesHistoryLimitWhileModifierRemainsPressed() { + self.settings.collapseRepeatedGroups = true + self.settings.onlyShowModifiedKeystrokes = true + self.visualizer.isPresentationActive = true + + let command: NSEvent.ModifierFlags = .recorded([.command]) + self.visualizer.display(.modifierStateChanged(command)) + + for (keyCode, character) in [(KeyboardKeyCode.a, "a"), (.k, "k"), (.a, "a"), (.k, "k")] { + self.pressAndReleaseKey(keyCode, modifiers: command, character: character) + XCTAssertEqual(self.visualizer.visibleGroupCount, 1) + } + } + private func pressAndReleaseA() { self.visualizer.display(.keystroke(.stub( keyCode: .a, @@ -223,4 +251,25 @@ final class KeyboardVisualizerTests: XCTestCase { ))) self.visualizer.display(.modifierStateChanged([])) } + + private func pressAndReleaseKey( + _ keyCode: KeyboardKeyCode, + modifiers: NSEvent.ModifierFlags, + character: String + ) { + self.visualizer.display(.keystroke(.stub( + keyCode: keyCode, + type: .keyDown, + modifiers: modifiers, + characters: character, + charactersIgnoringModifiers: character + ))) + self.visualizer.display(.keystroke(.stub( + keyCode: keyCode, + type: .keyUp, + modifiers: modifiers, + characters: character, + charactersIgnoringModifiers: character + ))) + } }