mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-11 23:04:40 +02:00
fix: strip playback accelerators whenever any text input is focused (#2059)
The command-palette-specific IPC approach didn't cover other modals with inputs (settings search, playlist creation, etc.). Replace it with document-level focusin/focusout listeners that signal the main process whenever any input/textarea/contenteditable gains or loses focus, so the menu rebuild is triggered automatically for all current and future input surfaces. Co-authored-by: muckymucky <muckymucky@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+6
-6
@@ -280,12 +280,12 @@ let currentRepeatMode: PlayerRepeat = PlayerRepeat.NONE;
|
|||||||
let currentSidebarCollapsed = false;
|
let currentSidebarCollapsed = false;
|
||||||
let currentShuffleEnabled = false;
|
let currentShuffleEnabled = false;
|
||||||
let playbackMenuAccelerators: MenuPlaybackState['accelerators'] = {};
|
let playbackMenuAccelerators: MenuPlaybackState['accelerators'] = {};
|
||||||
let commandPaletteOpen = false;
|
let inputFocused = false;
|
||||||
|
|
||||||
ipcMain.on('command-palette-state', (_event, opened: boolean) => {
|
ipcMain.on('input-focus-state', (_event, focused: boolean) => {
|
||||||
const next = !!opened;
|
const next = !!focused;
|
||||||
if (commandPaletteOpen === next) return;
|
if (inputFocused === next) return;
|
||||||
commandPaletteOpen = next;
|
inputFocused = next;
|
||||||
if (isMacOS()) {
|
if (isMacOS()) {
|
||||||
rebuildMainMenu();
|
rebuildMainMenu();
|
||||||
}
|
}
|
||||||
@@ -350,7 +350,7 @@ const rebuildMainMenu = () => {
|
|||||||
if (!menuBuilder || !mainWindow) return;
|
if (!menuBuilder || !mainWindow) return;
|
||||||
|
|
||||||
menuBuilder.buildMenu({
|
menuBuilder.buildMenu({
|
||||||
accelerators: commandPaletteOpen ? {} : playbackMenuAccelerators,
|
accelerators: inputFocused ? {} : playbackMenuAccelerators,
|
||||||
playbackStatus: currentPlaybackStatus,
|
playbackStatus: currentPlaybackStatus,
|
||||||
privateMode: currentPrivateMode,
|
privateMode: currentPrivateMode,
|
||||||
repeatMode: currentRepeatMode,
|
repeatMode: currentRepeatMode,
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ const forceGarbageCollection = (): boolean => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const setCommandPaletteOpen = (opened: boolean) => {
|
const setInputFocused = (focused: boolean) => {
|
||||||
ipcRenderer.send('command-palette-state', opened);
|
ipcRenderer.send('input-focus-state', focused);
|
||||||
};
|
};
|
||||||
|
|
||||||
const rendererOpenSettings = (cb: () => void) => {
|
const rendererOpenSettings = (cb: () => void) => {
|
||||||
@@ -105,7 +105,7 @@ export const utils = {
|
|||||||
rendererTogglePrivateMode,
|
rendererTogglePrivateMode,
|
||||||
rendererToggleSidebar,
|
rendererToggleSidebar,
|
||||||
rendererUpdateAvailable,
|
rendererUpdateAvailable,
|
||||||
setCommandPaletteOpen,
|
setInputFocused,
|
||||||
startPowerSaveBlocker,
|
startPowerSaveBlocker,
|
||||||
stopPowerSaveBlocker,
|
stopPowerSaveBlocker,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ const AppEffects = () => (
|
|||||||
<GlobalShortcutsEffect />
|
<GlobalShortcutsEffect />
|
||||||
<LanguageEffect />
|
<LanguageEffect />
|
||||||
<NativeMenuSyncEffect />
|
<NativeMenuSyncEffect />
|
||||||
|
<InputFocusEffect />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -170,3 +171,42 @@ const NativeMenuSyncEffect = () => {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const InputFocusEffect = () => {
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isElectron()) return;
|
||||||
|
|
||||||
|
const handleFocusIn = (e: FocusEvent) => {
|
||||||
|
const target = e.target as Element | null;
|
||||||
|
if (
|
||||||
|
target instanceof HTMLInputElement ||
|
||||||
|
target instanceof HTMLTextAreaElement ||
|
||||||
|
(target instanceof HTMLElement && target.isContentEditable)
|
||||||
|
) {
|
||||||
|
window.api?.utils?.setInputFocused?.(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFocusOut = (e: FocusEvent) => {
|
||||||
|
const related = e.relatedTarget as Element | null;
|
||||||
|
if (
|
||||||
|
related instanceof HTMLInputElement ||
|
||||||
|
related instanceof HTMLTextAreaElement ||
|
||||||
|
(related instanceof HTMLElement && related.isContentEditable)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.api?.utils?.setInputFocused?.(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('focusin', handleFocusIn);
|
||||||
|
document.addEventListener('focusout', handleFocusOut);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('focusin', handleFocusIn);
|
||||||
|
document.removeEventListener('focusout', handleFocusOut);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|||||||
@@ -201,22 +201,17 @@ export const useAppStore = createWithEqualityFn<AppSlice>()(
|
|||||||
set((state) => {
|
set((state) => {
|
||||||
state.commandPalette.opened = false;
|
state.commandPalette.opened = false;
|
||||||
});
|
});
|
||||||
window.api?.utils?.setCommandPaletteOpen?.(false);
|
|
||||||
},
|
},
|
||||||
open: () => {
|
open: () => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.commandPalette.opened = true;
|
state.commandPalette.opened = true;
|
||||||
});
|
});
|
||||||
window.api?.utils?.setCommandPaletteOpen?.(true);
|
|
||||||
},
|
},
|
||||||
opened: false,
|
opened: false,
|
||||||
toggle: () => {
|
toggle: () => {
|
||||||
let nextOpened = false;
|
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.commandPalette.opened = !state.commandPalette.opened;
|
state.commandPalette.opened = !state.commandPalette.opened;
|
||||||
nextOpened = state.commandPalette.opened;
|
|
||||||
});
|
});
|
||||||
window.api?.utils?.setCommandPaletteOpen?.(nextOpened);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
commandPaletteSearchSectionsExpanded: {},
|
commandPaletteSearchSectionsExpanded: {},
|
||||||
|
|||||||
Reference in New Issue
Block a user