Drop the tick from drop-lists; the row is already tinted

The selected row carries selection-background-color, so a checkmark repeats
what the colour says — and in a combo as wide as "VN" it repeated it on top of
the letters. A combo's default delegate paints menu-style, which is where the
glyph comes from; a plain QStyledItemDelegate paints item-view style, which has
none. widen_popup does both jobs now, so it is tidy_popup.

check_combo_popup additionally requires the delegate to be the plain one and the
stylesheet to still tint the current row — removing the delegate line fails it.

21/21 checkers pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nam Pham Dinh Thanh
2026-08-18 15:03:39 +09:00
co-authored by Claude Opus 5
parent 509ae96854
commit 416d88d72f
3 changed files with 35 additions and 12 deletions
+5 -5
View File
@@ -20,7 +20,7 @@ from . import APP_NAME, DISPLAY_NAME, __version__
from .config import PROVIDER_LABELS, AppConfig
from .i18n import LANGUAGE_SHORT, LANGUAGES, get_language, on_language_changed, set_language, tr
from .state import AppContext
from .ui.widgets import widen_popup
from .ui.widgets import tidy_popup
from .theme import current_palette, set_active_theme, stylesheet
from .core.task_scheduler import TaskScheduler
from .ui.cowork_tab import CoworkTab
@@ -261,7 +261,7 @@ class MainWindow(QMainWindow):
self.nav_project.setObjectName("navProjectPick")
self.nav_project.setToolTip(tr("app.nav.project_pick"))
self.nav_project.currentIndexChanged.connect(self._on_rail_project_pick)
widen_popup(self.nav_project)
tidy_popup(self.nav_project)
self.nav_new_chat = QPushButton(tr("cowork.new_chat"))
self.nav_new_chat.setObjectName("navNewChatBtn")
self.nav_new_chat.setIcon(_icon("plus"))
@@ -675,7 +675,7 @@ class MainWindow(QMainWindow):
if idx >= 0:
self.nav_project.setCurrentIndex(idx)
has = bool(choices)
widen_popup(self.nav_project)
tidy_popup(self.nav_project)
self.nav_project.setEnabled(has)
self.nav_project_btn.setEnabled(has)
self.nav_project_btn.setToolTip(
@@ -991,7 +991,7 @@ class MainWindow(QMainWindow):
idx = self.language_combo.findData(get_language())
if idx >= 0:
self.language_combo.setCurrentIndex(idx)
widen_popup(self.language_combo)
tidy_popup(self.language_combo)
self.language_combo.currentIndexChanged.connect(self._on_language_changed)
who.addWidget(self.language_combo)
self.theme_btn = self._build_theme_button()
@@ -1005,7 +1005,7 @@ class MainWindow(QMainWindow):
self.provider_combo.setToolTip(tr("app.provider"))
for key, label in PROVIDER_LABELS.items():
self.provider_combo.addItem(label, key)
widen_popup(self.provider_combo)
tidy_popup(self.provider_combo)
idx = self.provider_combo.findData(self.ctx.config.active_provider)
if idx >= 0:
self.provider_combo.setCurrentIndex(idx)
+15
View File
@@ -50,6 +50,7 @@ def main() -> int:
app.processEvents()
fails = []
from PySide6.QtWidgets import QStyledItemDelegate
for name in ("language_combo", "nav_project", "provider_combo"):
combo = getattr(win, name, None)
if combo is None or not combo.count():
@@ -66,6 +67,20 @@ def main() -> int:
if have < need:
fails.append(f"{name}: popup {have}px, khong du {need}px cho chu + dau tick")
# No tick: the row is already tinted, and the menu-style delegate that
# draws one on macOS covered the two letters it was marking.
deleg = combo.itemDelegate()
plain = type(deleg) is QStyledItemDelegate
print(f"{'':15} delegate={type(deleg).__name__} (khong ve dau tick={plain})")
if not plain:
fails.append(f"{name}: dung delegate kieu menu — macOS se ve dau tick")
# ...and the current row must still be obvious without one.
view = combo.view()
sheet = app.styleSheet()
if "selection-background-color" not in sheet:
fails.append("popup khong to mau muc dang chon")
print()
for f in fails:
print("FAIL " + f)
+15 -7
View File
@@ -162,17 +162,25 @@ def guard_wheel(root: QWidget) -> None:
w.installEventFilter(_wheel_guard)
def widen_popup(combo) -> None:
"""Give a drop-list room for its text AND the tick beside the current item.
def tidy_popup(combo) -> None:
"""Make a drop-list show its options and nothing else.
macOS draws a checkmark against the selected row; Windows does not. A combo
only as wide as "VN" therefore looked fine here and had its two letters
covered there. The popup inherits the combo's width unless told otherwise,
so measure what has to fit and say so.
Two platform habits to undo. macOS marks the current row with a checkmark,
drawn by the menu-style delegate a combo gets by default; the row is already
tinted by selection-background-color, so the tick says nothing twice and, in
a combo only as wide as "VN", covered the letters it was marking. Handing
the view a plain QStyledItemDelegate switches it to item-view painting,
where no such glyph exists.
And the popup inherits the combo's width unless told otherwise, which had
the project and provider names cut off here regardless of platform. So
measure the longest item — plus an indicator's worth of room, in case a
style still draws one — and set that as the view's minimum.
"""
from PySide6.QtWidgets import QStyle
from PySide6.QtWidgets import QStyle, QStyledItemDelegate
view = combo.view()
combo.setItemDelegate(QStyledItemDelegate(combo))
fm = view.fontMetrics()
longest = max((fm.horizontalAdvance(combo.itemText(i))
for i in range(combo.count())), default=0)