Don't select <Input/> text when focus is due to window focus

Closes https://feedback.yaak.app/p/url-input-auto-selects-all-text-when-regaining-focus-after
This commit is contained in:
Gregory Schier
2025-05-12 22:19:16 -07:00
parent 81e78ef24c
commit 417a02744b
2 changed files with 28 additions and 14 deletions

View File

@@ -13,6 +13,7 @@ import {
} from 'react'; } from 'react';
import { useIsEncryptionEnabled } from '../../hooks/useIsEncryptionEnabled'; import { useIsEncryptionEnabled } from '../../hooks/useIsEncryptionEnabled';
import { useStateWithDeps } from '../../hooks/useStateWithDeps'; import { useStateWithDeps } from '../../hooks/useStateWithDeps';
import { copyToClipboard } from '../../lib/copy';
import { import {
analyzeTemplate, analyzeTemplate,
convertTemplateToInsecure, convertTemplateToInsecure,
@@ -30,7 +31,6 @@ import { Icon } from './Icon';
import { IconButton } from './IconButton'; import { IconButton } from './IconButton';
import { Label } from './Label'; import { Label } from './Label';
import { HStack } from './Stacks'; import { HStack } from './Stacks';
import { copyToClipboard } from '../../lib/copy';
export type InputProps = Pick< export type InputProps = Pick<
EditorProps, EditorProps,
@@ -127,13 +127,29 @@ const BaseInput = forwardRef<EditorView, InputProps>(function InputBase(
useImperativeHandle<EditorView | null, EditorView | null>(ref, () => editorRef.current); useImperativeHandle<EditorView | null, EditorView | null>(ref, () => editorRef.current);
const lastWindowFocus = useRef<number>(0);
useEffect(() => {
const fn = () => (lastWindowFocus.current = Date.now());
window.addEventListener('focus', fn);
return () => {
window.removeEventListener('focus', fn);
};
}, []);
const handleFocus = useCallback(() => { const handleFocus = useCallback(() => {
if (readOnly) return; if (readOnly) return;
// Select all text of input when it's focused to match standard browser behavior.
// This should not, however, select when the input is focused due to a window focus event, so
// we handle that case as well.
const windowJustFocused = Date.now() - lastWindowFocus.current < 200;
if (!windowJustFocused) {
editorRef.current?.dispatch({
selection: { anchor: 0, head: editorRef.current.state.doc.length },
});
}
setFocused(true); setFocused(true);
// Select all text on focus
editorRef.current?.dispatch({
selection: { anchor: 0, head: editorRef.current.state.doc.length },
});
onFocus?.(); onFocus?.();
}, [onFocus, readOnly]); }, [onFocus, readOnly]);

View File

@@ -5,15 +5,13 @@ export function useWindowFocus() {
const [visible, setVisible] = useState(true); const [visible, setVisible] = useState(true);
useEffect(() => { useEffect(() => {
let unsub: undefined | (() => void) = undefined; const unlisten = getCurrentWebviewWindow().onFocusChanged((e) => {
getCurrentWebviewWindow() setVisible(e.payload);
.onFocusChanged((e) => { });
setVisible(e.payload);
}) return () => {
.then((fn) => { unlisten.then((fn) => fn());
unsub = fn; };
});
return () => unsub?.();
}, []); }, []);
return visible; return visible;