Skip to content

fix: missing timeline toolbar on reopening a file - #599

Merged
FelipeDefensor merged 1 commit into
TimeLineAnnotator:0.6.5from
FelipeDefensor:fix/595-missing-timeline-toolbar
Sep 5, 2026
Merged

fix: missing timeline toolbar on reopening a file#599
FelipeDefensor merged 1 commit into
TimeLineAnnotator:0.6.5from
FelipeDefensor:fix/595-missing-timeline-toolbar

Conversation

@FelipeDefensor

Copy link
Copy Markdown
Collaborator

Fixes the recurring "timeline toolbar is missing" bug. Same root cause as #407; in #595 it is why the beat toolbar is absent and pressing B does nothing.

Root cause

Not a Qt or C++ level problem. Three things in our own code combine:

  1. QtUI.on_file_loaded calls QMainWindow.restoreState() with a window state stored per absolute file path in QSettings (private/recent_files/<path>/state). That is what makes the bug look machine- and path-dependent: the same file reproduces on one machine and not on another, and moving it to a different directory "fixes" it.
  2. Every timeline toolbar used the object name timeline_toolbar. restoreState() matches saved entries to live toolbars by object name, in child order, so it can apply one timeline kind's saved state to a toolbar of another kind. That is exactly the Timeline toolbar is not displayed if file is saved in a certain directory (???) #407 report: the harmony toolbar stayed visible while the hierarchy toolbar did not appear.
  3. QMainWindow.addToolBar() only shows a toolbar on the next event loop iteration (QLayout::addChildWidget queues _q_showIfNotHidden). App.on_open saves the window state synchronously right after loading, so a toolbar created during that load is still hidden at save time and gets recorded as hidden. Reopening the file then restores it as hidden.

Point 3 only bites when the toolbar is created while the main window is already visible, which is why opening a file from the command line looks fine and opening it from the running app does not. It also explains @m-k94's "somehow it loaded fine the first time opening it".

Changes

  • Each toolbar class now gets its own object name (self.__class__.__name__), so restoreState() can no longer cross-assign state between timeline kinds.
  • A newly added toolbar is shown immediately, so the window state saved right after a load does not record it as hidden.
  • After restoring the window state, toolbar visibility is re-derived from the loaded timelines. The timelines are the source of truth, and this also repairs the states already stored in users' settings, so nobody has to clear their recent-files entries.

Also drops two unused attributes (visible, _visible_timelines_count) from TimelineToolbar.

Two regression tests in tests/ui/test_qtui.py, both verified to fail on 0.6.5 without the change:

  • a stored window state that hides the toolbar must not survive reopening the file;
  • toolbar object names must be unique across toolbar classes.

Repro bundle

Important deviation from the usual bundle: passing the file on the command line does not reproduce. boot() calls app.on_open before ui.launch(), so the toolbar is parented to a still-hidden window, which Qt does not treat as hidden, and the saved state records it as shown. The file has to be opened from the running app.

Build the fixture, from this branch's checkout (PowerShell on Windows; $PWD in Git Bash is an MSYS path the interpreter cannot open):

mkdir -p .repro && printf '%s\n' \
  'metadata set-media-length 60' \
  'timelines add beat --name "Measures" --beat-pattern 4' \
  'components beat --tl-name "Measures" --time 5' \
  'components beat --tl-name "Measures" --time 10' \
  'components beat --tl-name "Measures" --time 15' \
  'components beat --tl-name "Measures" --time 20' \
  "save \"$PWD/.repro/issue-595.tla\" --overwrite" \
  | uv run --python 3.12 tilia --user-interface cli

See the bug, on the base ref:

git worktree add --detach ../tilia-base 23232ff6
cd ../tilia-base
uv run --python 3.12 tilia

See the fix, from this branch's checkout:

uv run --python 3.12 tilia

Close with git worktree remove ../tilia-base. In both cases open the fixture through File > Open, using its absolute path, and do it twice in a row.

Acceptance criteria

  1. Action: start with a blank project, open .repro/issue-595.tla via File > Open, open the same file a second time, then press B.
  2. Bug: after the second open the beat toolbar is gone and B adds no beat.
  3. Correct: the beat toolbar stays visible after every open and B adds a beat at the current position.

What this bundle does not verify

The scenario, the fix and the tests all come from one analysis, so the before/after pair shows that behaviour changed, not that this is the bug as reported. Not covered: the cross-kind swap from #407 (only the object-name unit test speaks to that), window states written by older TiLiA versions or on another machine, and the beat-timeline behaviour that #595 originally opened with, which is a separate matter.

Refs #595, #407.

Opening a file restores the window state saved under its path, and that
state includes toolbar visibility. Two things made the saved state wrong.

QMainWindow.addToolBar() only shows a toolbar on the next event loop
iteration. A toolbar created while a file was loading was therefore
still hidden when App.on_open() saved the window state right afterwards,
so reopening that file restored the toolbar as hidden.

All timeline toolbars also shared the object name "timeline_toolbar".
restoreState() matches saved entries to live toolbars by object name, so
it could apply one timeline kind's state to a toolbar of another kind,
which is why a stale toolbar could stay visible while the right one
disappeared.

Show a newly added toolbar immediately, give each toolbar class its own
object name, and re-derive toolbar visibility from the loaded timelines
after restoring the window state, so a stale state cannot outlive a load.

Refs TimeLineAnnotator#595, TimeLineAnnotator#407.
@FelipeDefensor
FelipeDefensor merged commit 7193c84 into TimeLineAnnotator:0.6.5 Sep 5, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant