feat: warn tahoe users of shortcut conflict with macos game-overlay
closes #5018
This commit is contained in:
1 parent
36ded28ce4
commit
911aad42cc
4 files changed
+114
-42
No files matched your search
@@ -301,6 +301,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Open Screen Recording Settings…" = "Open Screen Recording Settings…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Open System Settings to confirm, and continue" = "Open System Settings to confirm, and continue";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Open Trackpad Settings…" = "Open Trackpad Settings…";
|
||||
|
||||
@@ -503,7 +506,10 @@
|
||||
"The application needs to restart to apply the language change." = "The application needs to restart to apply the language change.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"The ⎋ (escape) key is reserved by some macOS shortcuts (e.g. ⌘⌥⎋ will show the Force Quit Applications window).\n\nIf you want to use ⎋, make sure that Hold modifiers are neither: ⌘⌥, ⌘⌥⇧, or ⌘⌥⇧⌃" = "The ⎋ (escape) key is reserved by some macOS shortcuts (e.g. ⌘⌥⎋ will show the Force Quit Applications window).\n\nIf you want to use ⎋, make sure that Hold modifiers are neither: ⌘⌥, ⌘⌥⇧, or ⌘⌥⇧⌃";
|
||||
"The ⌘⎋ (command+escape) shortcut may be used by macOS for GameOverlay.\n\nYour change would assign it to: %@.\n\nIf you want to continue, make sure that the GameOverlay shortcut is disabled.\nAlso note that macOS has reported bugs where the shortcut may still interfere while disabled." = "The ⌘⎋ (command+escape) shortcut may be used by macOS for GameOverlay.\n\nYour change would assign it to: %@.\n\nIf you want to continue, make sure that the GameOverlay shortcut is disabled.\nAlso note that macOS has reported bugs where the shortcut may still interfere while disabled.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"The ⎋ (escape) key is reserved by some macOS shortcuts (e.g. ⌘⌥⎋ will show the Force Quit Applications window).\n\nYour change would assign it to: %@.\n\nIf you want to use ⎋, make sure that Hold modifiers are neither: ⌘⌥, ⌘⌥⇧, or ⌘⌥⇧⌃" = "The ⎋ (escape) key is reserved by some macOS shortcuts (e.g. ⌘⌥⎋ will show the Force Quit Applications window).\n\nYour change would assign it to: %@.\n\nIf you want to use ⎋, make sure that Hold modifiers are neither: ⌘⌥, ⌘⌥⇧, or ⌘⌥⇧⌃";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Theme";
|
||||
|
||||
@@ -37,7 +37,7 @@ class CustomRecorderControl: RecorderControl {
|
||||
set(allowedModifierFlags: CustomRecorderControl.allowedModifiers.subtracting(restrictedModifiers), requiredModifierFlags: [], allowsEmptyModifierFlags: true)
|
||||
}
|
||||
|
||||
func alertIfSameShortcutAlreadyAssigned(_ candidateId: String, _ candidateShortcut: Shortcut, _ shortcutAlreadyAssigned: String) {
|
||||
func alertIfSameShortcutAlreadyAssigned(_ candidateShortcut: Shortcut, _ shortcutAlreadyAssigned: String) {
|
||||
let isArrowKeys = ["←", "→", "↑", "↓"].contains(shortcutAlreadyAssigned)
|
||||
let isVimKeys = shortcutAlreadyAssigned.starts(with: "vimCycle")
|
||||
let existingShortcut = ControlsTab.shortcutControls[shortcutAlreadyAssigned]!
|
||||
@@ -46,16 +46,16 @@ class CustomRecorderControl: RecorderControl {
|
||||
alert.messageText = NSLocalizedString("Conflicting shortcut", comment: "")
|
||||
alert.informativeText = String(format: NSLocalizedString("Shortcut already assigned to another action: %@", comment: ""),
|
||||
(isArrowKeys ? "Arrow keys" : (isVimKeys ? "Vim keys" : existingShortcut.1)).replacingOccurrences(of: " ", with: "\u{00A0}"))
|
||||
if !candidateId.starts(with: "holdShortcut") {
|
||||
if !id.starts(with: "holdShortcut") {
|
||||
alert.addButton(withTitle: NSLocalizedString("Unassign existing shortcut and continue", comment: "")).setAccessibilityFocused(true)
|
||||
}
|
||||
let cancelButton = alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
|
||||
cancelButton.keyEquivalent = "\u{1b}"
|
||||
if candidateId.starts(with: "holdShortcut") {
|
||||
if id.starts(with: "holdShortcut") {
|
||||
cancelButton.setAccessibilityFocused(true)
|
||||
}
|
||||
let userChoice = alert.runModal()
|
||||
if !candidateId.starts(with: "holdShortcut") && userChoice == .alertFirstButtonReturn {
|
||||
if !id.starts(with: "holdShortcut") && userChoice == .alertFirstButtonReturn {
|
||||
if isArrowKeys {
|
||||
ControlsTab.arrowKeysCheckbox.state = .off
|
||||
ControlsTab.arrowKeysEnabledCallback(ControlsTab.arrowKeysCheckbox)
|
||||
@@ -65,46 +65,70 @@ class CustomRecorderControl: RecorderControl {
|
||||
ControlsTab.vimKeysEnabledCallback(ControlsTab.vimKeysCheckbox)
|
||||
LabelAndControl.controlWasChanged(ControlsTab.vimKeysCheckbox, nil)
|
||||
} else {
|
||||
existingShortcut.0.objectValue = nil
|
||||
ControlsTab.shortcutChangedCallback(existingShortcut.0)
|
||||
LabelAndControl.controlWasChanged(existingShortcut.0, shortcutAlreadyAssigned)
|
||||
updateShortcut(existingShortcut.0, nil, existingShortcut.0, shortcutAlreadyAssigned)
|
||||
}
|
||||
ControlsTab.shortcutControls[candidateId]!.0.objectValue = candidateShortcut
|
||||
ControlsTab.shortcutChangedCallback(self)
|
||||
LabelAndControl.controlWasChanged(self, candidateId)
|
||||
updateShortcut(ControlsTab.shortcutControls[id]!.0, candidateShortcut, self, id)
|
||||
}
|
||||
}
|
||||
|
||||
func alertIfShortcutReservedByMacos(_ candidateId: String, _ candidateShortcut: Shortcut, _ shortcutUsingEscape: String) {
|
||||
func updateShortcut(_ control: CustomRecorderControl, _ objectValue: Shortcut?, _ senderControl: NSControl, _ id: String) {
|
||||
control.objectValue = objectValue
|
||||
LabelAndControl.controlWasChanged(senderControl, id)
|
||||
ControlsTab.shortcutChangedCallback(senderControl)
|
||||
}
|
||||
|
||||
func alertIfShortcutReservedByMacos(_ candidateShortcut: Shortcut, _ shortcutReservedByMacos: String) {
|
||||
let existingShortcutLabel = ControlsTab.shortcutControls[shortcutReservedByMacos]!.1
|
||||
let alert = NSAlert()
|
||||
alert.alertStyle = .warning
|
||||
alert.messageText = NSLocalizedString("Conflicting shortcut", comment: "")
|
||||
alert.informativeText = NSLocalizedString("The ⎋ (escape) key is reserved by some macOS shortcuts (e.g. ⌘⌥⎋ will show the Force Quit Applications window).\n\nIf you want to use ⎋, make sure that Hold modifiers are neither: ⌘⌥, ⌘⌥⇧, or ⌘⌥⇧⌃", comment: "")
|
||||
alert.informativeText = String(format: NSLocalizedString("The ⎋ (escape) key is reserved by some macOS shortcuts (e.g. ⌘⌥⎋ will show the Force Quit Applications window).\n\nYour change would assign it to: %@.\n\nIf you want to use ⎋, make sure that Hold modifiers are neither: ⌘⌥, ⌘⌥⇧, or ⌘⌥⇧⌃", comment: ""), existingShortcutLabel)
|
||||
alert.addButton(withTitle: NSLocalizedString("Unassign existing shortcut and continue", comment: ""))
|
||||
let cancelButton = alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
|
||||
cancelButton.keyEquivalent = "\u{1b}"
|
||||
cancelButton.setAccessibilityFocused(true)
|
||||
let userChoice = alert.runModal()
|
||||
if userChoice == .alertFirstButtonReturn {
|
||||
guard candidateId != shortcutUsingEscape else { return }
|
||||
let existingShortcut = ControlsTab.shortcutControls[shortcutUsingEscape]!
|
||||
existingShortcut.0.objectValue = nil
|
||||
ControlsTab.shortcutChangedCallback(existingShortcut.0)
|
||||
LabelAndControl.controlWasChanged(existingShortcut.0, shortcutUsingEscape)
|
||||
ControlsTab.shortcutControls[candidateId]!.0.objectValue = candidateShortcut
|
||||
ControlsTab.shortcutChangedCallback(self)
|
||||
LabelAndControl.controlWasChanged(self, candidateId)
|
||||
guard id != shortcutReservedByMacos else { return }
|
||||
let existingShortcut = ControlsTab.shortcutControls[shortcutReservedByMacos]!
|
||||
updateShortcut(existingShortcut.0, nil, existingShortcut.0, shortcutReservedByMacos)
|
||||
updateShortcut(ControlsTab.shortcutControls[id]!.0, candidateShortcut, self, id)
|
||||
}
|
||||
}
|
||||
|
||||
// @available(macOS 26.0, *)
|
||||
func alertIfShortcutUsedByGameOverlay(_ candidateShortcut: Shortcut, _ shortcutUsingGameOverlay: String) {
|
||||
let existingShortcutLabel = ControlsTab.shortcutControls[shortcutUsingGameOverlay]!.1
|
||||
let alert = NSAlert()
|
||||
alert.alertStyle = .warning
|
||||
alert.messageText = NSLocalizedString("Conflicting shortcut", comment: "")
|
||||
alert.informativeText = String(format: NSLocalizedString("The ⌘⎋ (command+escape) shortcut may be used by macOS for GameOverlay.\n\nYour change would assign it to: %@.\n\nIf you want to continue, make sure that the GameOverlay shortcut is disabled.\nAlso note that macOS has reported bugs where the shortcut may still interfere while disabled.", comment: ""), existingShortcutLabel)
|
||||
alert.addButton(withTitle: NSLocalizedString("Open System Settings to confirm, and continue", comment: ""))
|
||||
let cancelButton = alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
|
||||
cancelButton.keyEquivalent = "\u{1b}"
|
||||
cancelButton.setAccessibilityFocused(true)
|
||||
let userChoice = alert.runModal()
|
||||
if userChoice == .alertFirstButtonReturn {
|
||||
NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.keyboard?Shortcuts")!)
|
||||
updateShortcut(ControlsTab.shortcutControls[id]!.0, candidateShortcut, self, id)
|
||||
}
|
||||
}
|
||||
|
||||
func save(_ candidateShortcut: Shortcut) {
|
||||
LabelAndControl.controlWasChanged(self, id)
|
||||
// shortcutChangedCallback is called automatically here
|
||||
// setting objectValue also happens automatically
|
||||
}
|
||||
}
|
||||
|
||||
extension CustomRecorderControl: RecorderControlDelegate {
|
||||
func recorderControl(_ control: RecorderControl, canRecord shortcut: Shortcut) -> Bool {
|
||||
switch CustomRecorderControlTestable.isShortcutAcceptable(id, shortcut) {
|
||||
case .accepted: return true
|
||||
case .accepted: save(shortcut)
|
||||
case .modifiersOnlyButContainsKeycode: return false
|
||||
case .conflictWithExistingShortcut(let s): alertIfSameShortcutAlreadyAssigned(id, shortcut, s)
|
||||
case .reservedByMacos(let s): alertIfShortcutReservedByMacos(id, shortcut, s)
|
||||
case .conflictWithExistingShortcut(let s): alertIfSameShortcutAlreadyAssigned(shortcut, s)
|
||||
case .reservedByMacos(let s): alertIfShortcutReservedByMacos(shortcut, s)
|
||||
case .usedByGameOverlay(let s): alertIfShortcutUsedByGameOverlay(shortcut, s)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -4,6 +4,10 @@ import ShortcutRecorder
|
||||
|
||||
class CustomRecorderControlTestable {
|
||||
static func isShortcutAcceptable(_ candidateId: String, _ candidateShortcut: Shortcut) -> ShortcutAcceptance {
|
||||
if let currentShortcutWithSameId = ControlsTab.shortcuts[candidateId]?.shortcut,
|
||||
candidateShortcut.carbonKeyCode == currentShortcutWithSameId.carbonKeyCode && candidateShortcut.carbonModifierFlags == currentShortcutWithSameId.carbonModifierFlags {
|
||||
return .accepted
|
||||
}
|
||||
if candidateId.starts(with: "holdShortcut") && candidateShortcut.keyCode != .none {
|
||||
return .modifiersOnlyButContainsKeycode
|
||||
}
|
||||
@@ -17,6 +21,9 @@ class CustomRecorderControlTestable {
|
||||
if let shortcutUsingEscape = isReservedByMacos(newCombos) {
|
||||
return .reservedByMacos(shortcutUsingEscape: shortcutUsingEscape)
|
||||
}
|
||||
if let shortcutUsingGameOverlay = isUsedByGameOverlay(newCombos) {
|
||||
return .usedByGameOverlay(shortcutUsingGameOverlay: shortcutUsingGameOverlay)
|
||||
}
|
||||
return .accepted
|
||||
}
|
||||
|
||||
@@ -42,8 +49,8 @@ class CustomRecorderControlTestable {
|
||||
}
|
||||
// candidate is a local shortcut
|
||||
} else {
|
||||
// combine with everything except a nextWindowShortcut
|
||||
if !atShortcut.id.starts(with: "nextWindowShortcut") {
|
||||
// combine with every holdShortcut
|
||||
if atShortcut.id.starts(with: "holdShortcut") {
|
||||
combos.append((candidateId, Shortcut(code: candidateShortcut.keyCode, modifierFlags: [candidateShortcut.modifierFlags, atShortcut.shortcut.modifierFlags], characters: nil, charactersIgnoringModifiers: nil)))
|
||||
}
|
||||
}
|
||||
@@ -73,6 +80,18 @@ class CustomRecorderControlTestable {
|
||||
return combos
|
||||
}
|
||||
|
||||
static func isUsedByGameOverlay(_ newCombinationsFromCandidate: [(String, Shortcut)] ) -> String? {
|
||||
if #available(macOS 26.0, *) {
|
||||
let go = MacOsShortcuts.gameOverlay
|
||||
for c in newCombinationsFromCandidate {
|
||||
if c.1.carbonKeyCode == go.carbonKeyCode && c.1.carbonModifierFlags == go.carbonModifierFlags {
|
||||
return c.0
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
static func isReservedByMacos(_ newCombinationsFromCandidate: [(String, Shortcut)] ) -> String? {
|
||||
for r in (ReservedMacosShortcut.allCases.map { $0.basicShortcut }) {
|
||||
for c in newCombinationsFromCandidate {
|
||||
@@ -116,12 +135,14 @@ enum ShortcutAcceptance: Equatable {
|
||||
case modifiersOnlyButContainsKeycode
|
||||
case conflictWithExistingShortcut(shortcutAlreadyAssigned: String)
|
||||
case reservedByMacos(shortcutUsingEscape: String)
|
||||
case usedByGameOverlay(shortcutUsingGameOverlay: String)
|
||||
|
||||
static func == (lhs: ShortcutAcceptance, rhs: ShortcutAcceptance) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case (.accepted, .accepted),
|
||||
(.modifiersOnlyButContainsKeycode, .modifiersOnlyButContainsKeycode),
|
||||
(.reservedByMacos, .reservedByMacos),
|
||||
(.usedByGameOverlay, .usedByGameOverlay),
|
||||
(.conflictWithExistingShortcut, .conflictWithExistingShortcut):
|
||||
return true
|
||||
default:
|
||||
@@ -129,6 +150,14 @@ enum ShortcutAcceptance: Equatable {
|
||||
}
|
||||
}
|
||||
}
|
||||
struct MacOsShortcuts {
|
||||
// Introduced in macOS 26. Can be toggled in System Settings
|
||||
static let gameOverlay = Shortcut(code: KeyCode.escape, modifierFlags: [.command], characters: nil, charactersIgnoringModifiers: nil)
|
||||
// Ancient shortcuts. Hard-set by the OS; can't be toggled by the user
|
||||
static let forceQuitApplicationsDialog = Shortcut(code: KeyCode.escape, modifierFlags: [.command, .option], characters: nil, charactersIgnoringModifiers: nil)
|
||||
static let forceQuitActiveApp = Shortcut(code: KeyCode.escape, modifierFlags: [.command, .option, .shift], characters: nil, charactersIgnoringModifiers: nil)
|
||||
static let reservedForUnknownReason = Shortcut(code: KeyCode.escape, modifierFlags: [.command, .option, .shift, .control], characters: nil, charactersIgnoringModifiers: nil)
|
||||
}
|
||||
|
||||
enum ReservedMacosShortcut: CaseIterable {
|
||||
case forceQuitApplicationsDialog
|
||||
@@ -137,9 +166,9 @@ enum ReservedMacosShortcut: CaseIterable {
|
||||
|
||||
var basicShortcut: Shortcut {
|
||||
switch self {
|
||||
case .forceQuitApplicationsDialog: return Shortcut(code: KeyCode.escape, modifierFlags: [.command, .option], characters: nil, charactersIgnoringModifiers: nil)
|
||||
case .forceQuitActiveApp: return Shortcut(code: KeyCode.escape, modifierFlags: [.command, .option, .shift], characters: nil, charactersIgnoringModifiers: nil)
|
||||
case .reservedForUnknownReason: return Shortcut(code: KeyCode.escape, modifierFlags: [.command, .option, .shift, .control], characters: nil, charactersIgnoringModifiers: nil)
|
||||
case .forceQuitApplicationsDialog: return MacOsShortcuts.forceQuitApplicationsDialog
|
||||
case .forceQuitActiveApp: return MacOsShortcuts.forceQuitActiveApp
|
||||
case .reservedForUnknownReason: return MacOsShortcuts.reservedForUnknownReason
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,32 @@ import XCTest
|
||||
import ShortcutRecorder
|
||||
|
||||
final class CustomRecorderControlTests: XCTestCase {
|
||||
func testIsShortcutAcceptable() {
|
||||
// .accepted
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("holdShortcut", Shortcut(keyEquivalent: "⌘")!), .accepted)
|
||||
func testIsShortcutAcceptable_accepted() {
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("previousWindowShortcut", Shortcut(keyEquivalent: "⇧⇥")!), .accepted)
|
||||
ControlsTab.shortcuts["holdShortcut"] = ATShortcut(Shortcut(keyEquivalent: "⌘⌥")!, "holdShortcut", .global, .up)
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("holdShortcut", Shortcut(keyEquivalent: "⌥")!), .accepted)
|
||||
ControlsTab.shortcuts = ControlsTab.defaultShortcuts
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("holdShortcut", Shortcut(keyEquivalent: "⌥")!), .accepted)
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("previousWindowShortcut", Shortcut(keyEquivalent: "⇧")!), .accepted)
|
||||
ControlsTab.shortcuts["previousWindowShortcut"] = nil
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("previousWindowShortcut", Shortcut(keyEquivalent: "⇧")!), .accepted)
|
||||
ControlsTab.shortcuts = ControlsTab.defaultShortcuts
|
||||
}
|
||||
|
||||
// .modifiersOnlyButContainsKeycode
|
||||
func testIsShortcutAcceptable_modifiersOnlyButContainsKeycode() {
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("holdShortcut", Shortcut(keyEquivalent: "⌘⇧")!), .accepted)
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("holdShortcut", Shortcut(keyEquivalent: "⌘e")!), .modifiersOnlyButContainsKeycode)
|
||||
}
|
||||
|
||||
// .reservedByMacos
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("holdShortcut", Shortcut(keyEquivalent: "⌘")!), .accepted) // ⌘⎋
|
||||
func testIsShortcutAcceptable_conflictWithExistingShortcut() {
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("vimCycleRight", Shortcut(keyEquivalent: "l")!), .accepted)
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("nextWindowShortcut2", Shortcut(keyEquivalent: "⇧⇥")!), .accepted)
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("vimCycleLeft", Shortcut(keyEquivalent: "h")!), .conflictWithExistingShortcut(shortcutAlreadyAssigned: "hideShowAppShortcut"))
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("nextWindowShortcut2", Shortcut(keyEquivalent: "⇥")!), .conflictWithExistingShortcut(shortcutAlreadyAssigned: "nextWindowShortcut"))
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("nextWindowShortcut", Shortcut(keyEquivalent: "⇧")!), .conflictWithExistingShortcut(shortcutAlreadyAssigned: "previousWindowShortcut"))
|
||||
}
|
||||
|
||||
func testIsShortcutAcceptable_reservedByMacos() {
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("previousWindowShortcut", Shortcut(keyEquivalent: "⌘⇧")!), .accepted) // ⌘⎋
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("previousWindowShortcut", Shortcut(keyEquivalent: "⌘⌃⇧")!), .accepted) // ⌘⎋
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("holdShortcut", Shortcut(keyEquivalent: "⌘⌥")!), .reservedByMacos(shortcutUsingEscape: "cancelShortcut")) // ⌘⌥⎋
|
||||
@@ -25,13 +37,6 @@ final class CustomRecorderControlTests: XCTestCase {
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("cancelShortcut", Shortcut(keyEquivalent: "⌘⇧⌃⎋")!), .reservedByMacos(shortcutUsingEscape: "cancelShortcut")) // ⌘⌥⇧⌃⎋
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("cancelShortcut", Shortcut(keyEquivalent: "⌘⎋")!), .reservedByMacos(shortcutUsingEscape: "cancelShortcut")) // ⌘⌥⎋
|
||||
|
||||
// .conflictWithExistingShortcut
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("vimCycleRight", Shortcut(keyEquivalent: "l")!), .accepted)
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("nextWindowShortcut2", Shortcut(keyEquivalent: "⇧⇥")!), .accepted)
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("vimCycleLeft", Shortcut(keyEquivalent: "h")!), .conflictWithExistingShortcut(shortcutAlreadyAssigned: "hideShowAppShortcut"))
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("nextWindowShortcut2", Shortcut(keyEquivalent: "⇥")!), .conflictWithExistingShortcut(shortcutAlreadyAssigned: "nextWindowShortcut"))
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("nextWindowShortcut", Shortcut(keyEquivalent: "⇧")!), .conflictWithExistingShortcut(shortcutAlreadyAssigned: "previousWindowShortcut"))
|
||||
|
||||
// alt + shift+tab / alt+shift + tab => pressing tab is ambiguous which one should trigger
|
||||
ControlsTab.shortcuts["previousWindowShortcut"] = ATShortcut(Shortcut(keyEquivalent: "p")!, "previousWindowShortcut", .local, .down)
|
||||
ControlsTab.shortcuts["nextWindowShortcut2"] = ATShortcut(Shortcut(keyEquivalent: "⇧⇥")!, "nextWindowShortcut2", .global, .down)
|
||||
@@ -60,4 +65,12 @@ final class CustomRecorderControlTests: XCTestCase {
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("nextWindowShortcut", Shortcut(keyEquivalent: "⇥")!), .accepted)
|
||||
ControlsTab.shortcuts = ControlsTab.defaultShortcuts
|
||||
}
|
||||
|
||||
func testIsShortcutAcceptable_usedByGameOverlay() {
|
||||
if #available(macOS 26.0, *) {
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("holdShortcut", Shortcut(keyEquivalent: "⌘")!), .usedByGameOverlay(shortcutUsingGameOverlay: "cancelShortcut"))
|
||||
} else {
|
||||
XCTAssertEqual(CustomRecorderControlTestable.isShortcutAcceptable("holdShortcut", Shortcut(keyEquivalent: "⌘")!), .accepted)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user