feat: rest-to-reveal hint for dock separators
Separators stay invisible until the mouse rests on one for ~1s (or a drag starts); the QSS ::separator:hover rule does the hit-testing and a dynamic separatorHint property gates it, so event() never needs to know where separators are. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d5c9ed7467
commit
90ba13ad23
2 files changed
+44
No files matched your search
@@ -87,6 +87,7 @@ from aare.gui.styles import (
|
||||
APP_BACKGROUND,
|
||||
DARK_TEXT,
|
||||
DOCK_CONTENT_LEFT_PAD,
|
||||
SEPARATOR_HINT_DELAY_MS,
|
||||
THEME_FADE_MS,
|
||||
THEME_ORIGINAL,
|
||||
THEME_PORTRAIT,
|
||||
@@ -251,6 +252,16 @@ class MainWindow(QMainWindow):
|
||||
|
||||
self.setStyleSheet(f"background-color: {APP_BACKGROUND};")
|
||||
|
||||
# Resize-line hint (see SEPARATOR_HINT in styles.py): WA_Hover gives
|
||||
# us HoverMove without a button held; the single-shot timer implements
|
||||
# the "rested for 1s" gate. The QSS ::separator:hover rule does the
|
||||
# hit-testing, so event() never needs to know where separators are.
|
||||
self.setAttribute(Qt.WidgetAttribute.WA_Hover, True)
|
||||
self._separator_hint_timer = QTimer(self)
|
||||
self._separator_hint_timer.setSingleShot(True)
|
||||
self._separator_hint_timer.setInterval(SEPARATOR_HINT_DELAY_MS)
|
||||
self._separator_hint_timer.timeout.connect(lambda: self._set_separator_hint(True))
|
||||
|
||||
root_widget = QWidget(parent=self)
|
||||
root_widget.setObjectName("mainContentRoot")
|
||||
root_layout = QVBoxLayout(root_widget)
|
||||
@@ -2871,6 +2882,38 @@ class MainWindow(QMainWindow):
|
||||
if dx or dy:
|
||||
dock.move(geo.x() + dx, geo.y() + dy)
|
||||
|
||||
def _set_separator_hint(self, on: bool) -> None:
|
||||
if self.property("separatorHint") == on:
|
||||
return
|
||||
self.setProperty("separatorHint", on)
|
||||
# Property selectors are only re-evaluated on repolish.
|
||||
self.style().unpolish(self)
|
||||
self.style().polish(self)
|
||||
self.update()
|
||||
|
||||
def event(self, event):
|
||||
# Separator press/drag never reaches mousePressEvent — QMainWindow
|
||||
# eats it inside event() to start the separator move — so the hint
|
||||
# gate must sit here, before super() dispatches.
|
||||
t = event.type()
|
||||
if t in (QEvent.Type.HoverEnter, QEvent.Type.HoverMove):
|
||||
# Any move restarts the 1s countdown ("hover and rest"); during a
|
||||
# drag (button held) the hint stays on instead.
|
||||
if QApplication.mouseButtons() == Qt.MouseButton.NoButton:
|
||||
self._set_separator_hint(False)
|
||||
self._separator_hint_timer.start()
|
||||
elif t == QEvent.Type.HoverLeave:
|
||||
self._separator_hint_timer.stop()
|
||||
self._set_separator_hint(False)
|
||||
elif t == QEvent.Type.MouseButtonPress:
|
||||
# Press shows the line immediately, no 1s wait.
|
||||
self._separator_hint_timer.stop()
|
||||
self._set_separator_hint(True)
|
||||
elif t == QEvent.Type.MouseButtonRelease:
|
||||
self._set_separator_hint(False)
|
||||
self._separator_hint_timer.start()
|
||||
return super().event(event)
|
||||
|
||||
def eventFilter(self, obj, event):
|
||||
# Closing a floated (popped-out) dock re-docks it instead of hiding —
|
||||
# otherwise the panel silently disappears and has to be restored via
|
||||
|
||||
@@ -98,6 +98,7 @@ DOCK_CONTENT_LEFT_PAD = 10
|
||||
# separator under the cursor fills with SEPARATOR_HINT. The rest/drag gate
|
||||
# lives in MainWindow.event(); the QSS :hover part picks the one separator.
|
||||
SEPARATOR_HINT = "rgba(168, 178, 192, 50%)" # scrollbar-track grey @50%
|
||||
SEPARATOR_HINT_DELAY_MS = 888 # int, used in code, not QSS
|
||||
|
||||
# Theme-switch screenshot cross-fade duration (int ms, used in code).
|
||||
THEME_FADE_MS = 250
|
||||
|
||||
Reference in new issue
Block a user