v0.20.2: the cancel button stops flying around

The status bar's transfer widgets are permanent widgets: Qt lays them out
left to right but justifies the group right, so whichever is added last
owns the corner and never moves, and everything before it slides whenever
the group's total width changes. The label carries the song title of the
moment, so it changed width on nearly every track — dragging the ✕ across
the bar, which is the one widget you're aiming at.

So the ✕ is added last instead of first. It sits in the corner, the label
absorbs the movement, and the progress bar stops jittering too. Hovering
still expands it to "cancel transfer" and pushes the row left, which is
the one shift trav asked to keep.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SKXUgsBBwe3qaHEjeV8ubP
This commit is contained in:
2026-09-11 21:08:32 -05:00
co-authored by Claude Opus 5
parent c797cf570c
commit 370ea498cc
3 changed files with 102 additions and 7 deletions
+90
View File
@@ -0,0 +1,90 @@
"""Round 53 — the cancel button stops flying around.
The status bar's transfer widgets are permanent widgets, so Qt lays them out
left to right but justifies the group right: whichever one is added *last*
owns the corner and never moves, and everything before it slides whenever the
group's total width changes. The label carries the song title of the moment,
so it changes width on nearly every track — which used to drag the ✕ across
the bar, since it was added first.
So the ✕ is added last. It sits in the corner; the label absorbs the movement.
Hovering it is the one thing that may still shift the row, because the button
expands to say "cancel transfer" — trav asked for that to stay.
"""
import pytest
from PyQt6.QtCore import QEvent, QPointF
from PyQt6.QtGui import QEnterEvent
from lintunes.library_manager import LibraryManager
from lintunes.models import Library, Track
from lintunes.preferences import Preferences
def _library(tmp_path):
media = tmp_path / "media"
library = Library(music_folder=str(media))
path = media / "Music" / "Artist" / "Album" / "T1.mp3"
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(b"audio")
library.tracks[1] = Track(track_id=1, name="T1", artist="Artist",
location=str(path))
return library
@pytest.fixture
def window(qapp, tmp_path, monkeypatch):
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path / "config"))
from lintunes.gui.main_window import MainWindow
manager = LibraryManager(_library(tmp_path), tmp_path / "data")
win = MainWindow(manager, Preferences(tmp_path / "data"))
win.resize(1280, 800)
win.show()
for widget in (win._sync_label, win._sync_progress, win._sync_cancel):
widget.show()
qapp.processEvents()
yield win
win.close()
def _right_edge(widget):
return widget.x() + widget.width()
class TestCancelButtonStaysInTheCorner:
def test_a_longer_song_title_does_not_move_the_button(self, window, qapp):
window._sync_label.setText("Rabbit R1 · 3/40 04 Song")
qapp.processEvents()
before = window._sync_cancel.x()
window._sync_label.setText(
"Rabbit R1 · 12/40 07 A Considerably Longer Song Title Indeed")
qapp.processEvents()
assert window._sync_label.width() > 0
assert window._sync_cancel.x() == before
def test_the_button_is_the_rightmost_of_the_three(self, window, qapp):
window._sync_label.setText("Rabbit R1 · 3/40 04 Song")
qapp.processEvents()
assert (_right_edge(window._sync_label)
<= window._sync_progress.x())
assert (_right_edge(window._sync_progress)
<= window._sync_cancel.x())
def test_hovering_expands_leftwards(self, window, qapp):
window._sync_label.setText("Rabbit R1 · 3/40 04 Song")
qapp.processEvents()
edge = _right_edge(window._sync_cancel)
progress_x = window._sync_progress.x()
narrow = window._sync_cancel.width()
here = QPointF(1, 1)
window._sync_cancel.enterEvent(QEnterEvent(here, here, here))
qapp.processEvents()
assert window._sync_cancel.width() > narrow
assert _right_edge(window._sync_cancel) == edge
assert window._sync_progress.x() < progress_x
window._sync_cancel.leaveEvent(QEvent(QEvent.Type.Leave))
qapp.processEvents()
assert _right_edge(window._sync_cancel) == edge
assert window._sync_progress.x() == progress_x