diff --git a/Sources/AppDelegate.swift b/Sources/AppDelegate.swift index 23197bba..cfb30cd4 100644 --- a/Sources/AppDelegate.swift +++ b/Sources/AppDelegate.swift @@ -118,21 +118,21 @@ func browserZoomShortcutAction( .intersection(.deviceIndependentFlagsMask) .subtracting([.numericPad, .function]) let key = chars.lowercased() + let hasCommand = normalizedFlags.contains(.command) + let hasOnlyCommandAndOptionalShift = hasCommand && normalizedFlags.isDisjoint(with: [.control, .option]) - if normalizedFlags == [.command] { - if key == "=" || keyCode == 24 || keyCode == 69 { // kVK_ANSI_Equal / kVK_ANSI_KeypadPlus - return .zoomIn - } - if key == "-" || keyCode == 27 || keyCode == 78 { // kVK_ANSI_Minus / kVK_ANSI_KeypadMinus - return .zoomOut - } - if key == "0" || keyCode == 29 || keyCode == 82 { // kVK_ANSI_0 / kVK_ANSI_Keypad0 - return .reset - } + guard hasOnlyCommandAndOptionalShift else { return nil } + + if key == "=" || key == "+" || keyCode == 24 || keyCode == 69 { // kVK_ANSI_Equal / kVK_ANSI_KeypadPlus + return .zoomIn } - if normalizedFlags == [.command, .shift] && (key == "=" || key == "+" || keyCode == 24 || keyCode == 69) { - return .zoomIn + if key == "-" || key == "_" || keyCode == 27 || keyCode == 78 { // kVK_ANSI_Minus / kVK_ANSI_KeypadMinus + return .zoomOut + } + + if key == "0" || keyCode == 29 || keyCode == 82 { // kVK_ANSI_0 / kVK_ANSI_Keypad0 + return .reset } return nil diff --git a/cmuxTests/CmuxWebViewKeyEquivalentTests.swift b/cmuxTests/CmuxWebViewKeyEquivalentTests.swift index cc8f5395..d66de4b7 100644 --- a/cmuxTests/CmuxWebViewKeyEquivalentTests.swift +++ b/cmuxTests/CmuxWebViewKeyEquivalentTests.swift @@ -680,6 +680,47 @@ final class BrowserOmnibarCommandNavigationTests: XCTestCase { } } +final class BrowserZoomShortcutActionTests: XCTestCase { + func testZoomInSupportsEqualsAndPlusVariants() { + XCTAssertEqual( + browserZoomShortcutAction(flags: [.command], chars: "=", keyCode: 24), + .zoomIn + ) + XCTAssertEqual( + browserZoomShortcutAction(flags: [.command], chars: "+", keyCode: 24), + .zoomIn + ) + XCTAssertEqual( + browserZoomShortcutAction(flags: [.command, .shift], chars: "+", keyCode: 24), + .zoomIn + ) + } + + func testZoomOutSupportsMinusAndUnderscoreVariants() { + XCTAssertEqual( + browserZoomShortcutAction(flags: [.command], chars: "-", keyCode: 27), + .zoomOut + ) + XCTAssertEqual( + browserZoomShortcutAction(flags: [.command, .shift], chars: "_", keyCode: 27), + .zoomOut + ) + } + + func testZoomRequiresCommandWithoutOptionOrControl() { + XCTAssertNil(browserZoomShortcutAction(flags: [], chars: "=", keyCode: 24)) + XCTAssertNil(browserZoomShortcutAction(flags: [.command, .option], chars: "=", keyCode: 24)) + XCTAssertNil(browserZoomShortcutAction(flags: [.command, .control], chars: "-", keyCode: 27)) + } + + func testResetSupportsCommandZero() { + XCTAssertEqual( + browserZoomShortcutAction(flags: [.command], chars: "0", keyCode: 29), + .reset + ) + } +} + final class SidebarCommandHintPolicyTests: XCTestCase { func testCommandHintRequiresCommandOnlyModifier() { XCTAssertTrue(SidebarCommandHintPolicy.shouldShowHints(for: [.command]))