1+ /**
2+ * Known system hotkey conflicts for different platforms
3+ * These hotkeys are reserved by the OS and may not work reliably
4+ */
5+
6+ interface ConflictInfo {
7+ hotkey : string ;
8+ description : string ;
9+ severity : 'error' | 'warning' ;
10+ }
11+
12+ const WINDOWS_CONFLICTS : ConflictInfo [ ] = [
13+ // Windows system hotkeys
14+ { hotkey : 'Ctrl+Shift+Period' , description : 'May conflict with Windows IME or Office shortcuts' , severity : 'warning' } ,
15+ { hotkey : 'CommandOrControl+Shift+Period' , description : 'May conflict with Windows IME or Office shortcuts' , severity : 'warning' } ,
16+ { hotkey : 'Win+Period' , description : 'Windows Emoji Picker' , severity : 'error' } ,
17+ { hotkey : 'Win+Semicolon' , description : 'Windows Emoji Picker' , severity : 'error' } ,
18+ { hotkey : 'Win+Space' , description : 'Windows Language/Keyboard switcher' , severity : 'error' } ,
19+ { hotkey : 'Win+Tab' , description : 'Windows Task View' , severity : 'error' } ,
20+ { hotkey : 'Alt+Tab' , description : 'Windows App Switcher' , severity : 'error' } ,
21+ { hotkey : 'Ctrl+Alt+Delete' , description : 'Windows Security Options' , severity : 'error' } ,
22+ { hotkey : 'Win+L' , description : 'Windows Lock Screen' , severity : 'error' } ,
23+ { hotkey : 'Win+D' , description : 'Windows Show Desktop' , severity : 'error' } ,
24+ { hotkey : 'Alt+F4' , description : 'Windows Close Application' , severity : 'warning' } ,
25+ { hotkey : 'Ctrl+Shift+Escape' , description : 'Windows Task Manager' , severity : 'error' } ,
26+ ] ;
27+
28+ const MACOS_CONFLICTS : ConflictInfo [ ] = [
29+ // macOS system hotkeys
30+ { hotkey : 'CommandOrControl+Space' , description : 'macOS Spotlight Search' , severity : 'error' } ,
31+ { hotkey : 'CommandOrControl+Tab' , description : 'macOS App Switcher' , severity : 'error' } ,
32+ { hotkey : 'CommandOrControl+Shift+3' , description : 'macOS Screenshot' , severity : 'warning' } ,
33+ { hotkey : 'CommandOrControl+Shift+4' , description : 'macOS Screenshot Selection' , severity : 'warning' } ,
34+ { hotkey : 'CommandOrControl+Shift+5' , description : 'macOS Screenshot/Recording' , severity : 'warning' } ,
35+ { hotkey : 'CommandOrControl+Option+Escape' , description : 'macOS Force Quit' , severity : 'error' } ,
36+ { hotkey : 'CommandOrControl+Q' , description : 'macOS Quit Application' , severity : 'warning' } ,
37+ { hotkey : 'CommandOrControl+W' , description : 'macOS Close Window' , severity : 'warning' } ,
38+ { hotkey : 'CommandOrControl+M' , description : 'macOS Minimize Window' , severity : 'warning' } ,
39+ { hotkey : 'CommandOrControl+H' , description : 'macOS Hide Application' , severity : 'warning' } ,
40+ { hotkey : 'Control+CommandOrControl+Q' , description : 'macOS Lock Screen' , severity : 'error' } ,
41+ { hotkey : 'Control+CommandOrControl+Space' , description : 'macOS Emoji Picker' , severity : 'warning' } ,
42+ ] ;
43+
44+ const LINUX_CONFLICTS : ConflictInfo [ ] = [
45+ // Common Linux desktop environment hotkeys
46+ { hotkey : 'Alt+Tab' , description : 'Linux App Switcher' , severity : 'error' } ,
47+ { hotkey : 'Alt+F4' , description : 'Linux Close Window' , severity : 'warning' } ,
48+ { hotkey : 'Super+Space' , description : 'Linux Application Launcher (varies by DE)' , severity : 'warning' } ,
49+ { hotkey : 'Super+L' , description : 'Linux Lock Screen (varies by DE)' , severity : 'warning' } ,
50+ { hotkey : 'Ctrl+Alt+T' , description : 'Linux Terminal (varies by DE)' , severity : 'warning' } ,
51+ { hotkey : 'Ctrl+Alt+Delete' , description : 'Linux System Monitor/Logout' , severity : 'error' } ,
52+ { hotkey : 'Ctrl+Alt+F1' , description : 'Linux TTY1' , severity : 'error' } ,
53+ { hotkey : 'Ctrl+Alt+F2' , description : 'Linux TTY2' , severity : 'error' } ,
54+ ] ;
55+
56+ /**
57+ * Check if a hotkey conflicts with known system shortcuts
58+ * @param hotkey The normalized hotkey string to check
59+ * @param platform Optional platform override (defaults to current platform)
60+ * @returns Conflict information if found, null otherwise
61+ */
62+ export function checkForSystemConflict (
63+ hotkey : string ,
64+ platform ?: 'windows' | 'macos' | 'linux'
65+ ) : ConflictInfo | null {
66+ // Determine platform if not provided
67+ if ( ! platform ) {
68+ if ( typeof window !== 'undefined' && window . navigator ) {
69+ const userAgent = window . navigator . userAgent . toLowerCase ( ) ;
70+ if ( userAgent . includes ( 'win' ) ) {
71+ platform = 'windows' ;
72+ } else if ( userAgent . includes ( 'mac' ) ) {
73+ platform = 'macos' ;
74+ } else {
75+ platform = 'linux' ;
76+ }
77+ } else {
78+ // Default to windows if we can't detect
79+ platform = 'windows' ;
80+ }
81+ }
82+
83+ // Get the appropriate conflict list
84+ let conflicts : ConflictInfo [ ] ;
85+ switch ( platform ) {
86+ case 'macos' :
87+ conflicts = MACOS_CONFLICTS ;
88+ break ;
89+ case 'linux' :
90+ conflicts = LINUX_CONFLICTS ;
91+ break ;
92+ case 'windows' :
93+ default :
94+ conflicts = WINDOWS_CONFLICTS ;
95+ break ;
96+ }
97+
98+ // Check for exact match (case-insensitive)
99+ const normalizedHotkey = hotkey . toLowerCase ( ) ;
100+ const conflict = conflicts . find ( c =>
101+ c . hotkey . toLowerCase ( ) === normalizedHotkey
102+ ) ;
103+
104+ return conflict || null ;
105+ }
106+
107+ /**
108+ * Get all known conflicts for the current platform
109+ * @param platform Optional platform override
110+ * @returns Array of all known conflicts
111+ */
112+ export function getAllConflicts (
113+ platform ?: 'windows' | 'macos' | 'linux'
114+ ) : ConflictInfo [ ] {
115+ if ( ! platform ) {
116+ if ( typeof window !== 'undefined' && window . navigator ) {
117+ const userAgent = window . navigator . userAgent . toLowerCase ( ) ;
118+ if ( userAgent . includes ( 'win' ) ) {
119+ platform = 'windows' ;
120+ } else if ( userAgent . includes ( 'mac' ) ) {
121+ platform = 'macos' ;
122+ } else {
123+ platform = 'linux' ;
124+ }
125+ } else {
126+ platform = 'windows' ;
127+ }
128+ }
129+
130+ switch ( platform ) {
131+ case 'macos' :
132+ return MACOS_CONFLICTS ;
133+ case 'linux' :
134+ return LINUX_CONFLICTS ;
135+ case 'windows' :
136+ default :
137+ return WINDOWS_CONFLICTS ;
138+ }
139+ }
140+
141+ /**
142+ * Format a conflict warning message
143+ * @param conflict The conflict information
144+ * @returns Formatted warning message
145+ */
146+ export function formatConflictMessage ( conflict : ConflictInfo ) : string {
147+ if ( conflict . severity === 'error' ) {
148+ return `⚠️ This hotkey is reserved by the system: ${ conflict . description } ` ;
149+ } else {
150+ return `ℹ️ This hotkey may conflict: ${ conflict . description } ` ;
151+ }
152+ }
0 commit comments