Repository navigation
fix(export): stop the filename field from stealing the cursor while typing - #1075
Conversation
…yping ExportSettingsForm.load() runs on every debounced AppState resync (config_updated -> 150ms timer), and its setText() calls on the destination text fields unconditionally move the caret to the end. Typing in the Filename field pauses long enough between keystrokes to trigger the export sidebar's own 500ms persist debounce, which round-trips through AppState and calls load() again, yanking the cursor to the end roughly once a second and making the field unusable. Skip the refresh for a focused field: its own textChanged handler already keeps AppState in sync with what's on screen, so there's nothing to restore. Fixes marcinz606#1071 Claude-Session: https://claude.ai/code/session_01BsXPYFcGbAo4hxTTXzxRay
…eet path field Code review on marcinz606#1075 caught that the Contact Sheet "Output path" field (cs_output_path_edit) goes through the identical debounce round-trip as the Filename field but was left calling setText() unconditionally in sync_ui(), reproducing the same marcinz606#1071 caret-jump bug the PR was meant to fix. Claude-Session: https://claude.ai/code/session_01BsXPYFcGbAo4hxTTXzxRay
|
Code review caught that `cs_output_path_edit` (Contact Sheet → Output path) goes through the identical `config_updated` → 150ms `_sync_debounce` → `sync_ui()` round-trip as the Filename field, and was still calling `setText()` unconditionally — same bug, same field class. Pushed a follow-up commit applying the same focus guard there, plus a regression test (`test_sync_ui_does_not_reset_cursor_in_focused_contact_sheet_path`) that fails without the fix and passes with it. I checked the rest of `export.py`/`export_settings_form.py` for other unconditional `setText()` calls on user-typed fields — the remaining ones (`cs_output_path_edit` from the folder-picker, `abspath_edit` from the folder-picker, and various label/button text) are all direct responses to a user action, not periodic resyncs, so they're fine as-is. |
Summary
ExportSettingsForm.load()runs on every debounced AppState resync (config_updated-> 150ms timer inright_panel.py). Typing in the Filename field routes through the export sidebar's own 500ms persist debounce (update_timerinexport.py), which writes the value back to AppState and firesconfig_updated, which callsload()again.QLineEdit.setText()unconditionally moves the caret to the end, even when the text is unchanged, so any pause of ~650ms between keystrokes yanks the cursor to the end.setText()on the destination text fields (filename_edit,subfolder_edit,abspath_edit) while they have focus — the field's owntextChangedhandler already keeps AppState current, so there's nothing to restore.Test plan
test_load_does_not_reset_cursor_in_focused_filename_field, which reproduces the bug by focusing the field, positioning the caret mid-string, then callingload()again as the debounced resync would — fails before the fix (caret jumps to the end), passes after.uv run pytest tests/test_export_settings_form.py -v— 27 passeduv run pytest tests/ -q— full suite passes (5437 passed, 26 skipped, 14 deselected)make format/ruff check— cleanty checkon the changed file — no new diagnostics (one pre-existing unrelated warning at line 536)