Skip to content

Commit 16900e2

Browse files
committed
refactor(taskbar): optimize layout handling and improve widget structure
- Added support for Recycle Bin in the taskbar context menu. - Simplified layout count retrieval by storing it in a variable. - Refactored insertion logic for pinned apps to enhance readability. - Improved widget container structure by adding a content wrapper for better shadow effects.
1 parent c0e6772 commit 16900e2

File tree

18 files changed

+1337
-573
lines changed

18 files changed

+1337
-573
lines changed

docs/widgets/(Widget)-Taskbar.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ taskbar:
102102
.taskbar-widget .app-container.flashing {
103103
background-color: rgba(255, 106, 106, 0.63);
104104
}
105+
.taskbar-widget .app-container.running {
106+
background-color: rgba(255, 255, 255, 0.25);
107+
}
108+
.taskbar-widget .app-container:hover {
109+
background-color: rgba(255, 255, 255, 0.15);
110+
}
105111
.taskbar-widget .app-container .app-title {
106112
padding-left: 4px;
107113
}

src/core/bar.py

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ def __init__(
6666
self._os_theme_manager = None
6767
self._fullscreen_manager = None
6868
self._autohide_manager = None
69+
self._target_screen = bar_screen
6970

70-
self.screen_name = self.screen().name()
71+
self.screen_name = self._target_screen.name()
7172
self.app_bar_edge = (
7273
app_bar.AppBarEdge.Top if self._alignment["position"] == "top" else app_bar.AppBarEdge.Bottom
7374
)
@@ -109,11 +110,11 @@ def __init__(
109110
self.position_bar(init)
110111
self.monitor_hwnd = get_monitor_hwnd(int(self.winId()))
111112

113+
self._add_widgets(widgets)
114+
112115
if self._is_auto_width:
113-
self._sync_auto_width()
114116
self._bar_frame.installEventFilter(self)
115-
116-
self._add_widgets(widgets)
117+
QTimer.singleShot(0, self._sync_auto_width)
117118

118119
if not self._window_flags["windows_app_bar"]:
119120
try:
@@ -133,7 +134,7 @@ def __init__(
133134
BorderColor=blur_effect["border_color"],
134135
)
135136

136-
self.screen().geometryChanged.connect(self.on_geometry_changed, Qt.ConnectionType.QueuedConnection)
137+
self._target_screen.geometryChanged.connect(self.on_geometry_changed, Qt.ConnectionType.QueuedConnection)
137138

138139
self.handle_bar_management.connect(self._handle_bar_management)
139140
self._event_service.register_event("handle_bar_cli", self.handle_bar_management)
@@ -143,7 +144,7 @@ def __init__(
143144
self._autohide_manager = AutoHideManager(self, self)
144145
self._autohide_manager.setup_autohide()
145146

146-
QTimer.singleShot(0, self.show)
147+
self.show()
147148

148149
@property
149150
def bar_id(self) -> str:
@@ -165,7 +166,7 @@ def try_add_app_bar(self, scale_screen_height=False) -> None:
165166
self.winId().__int__(),
166167
self.app_bar_edge,
167168
self._dimensions["height"] + self._padding["top"] + self._padding["bottom"],
168-
self.screen(),
169+
self._target_screen,
169170
scale_screen_height,
170171
)
171172

@@ -174,8 +175,8 @@ def try_remove_app_bar(self) -> None:
174175
self.app_bar_manager.remove_appbar()
175176

176177
def bar_pos(self, bar_w: int, bar_h: int, screen_w: int, screen_h: int) -> tuple[int, int]:
177-
screen_x = self.screen().geometry().x()
178-
screen_y = self.screen().geometry().y()
178+
screen_x = self._target_screen.geometry().x()
179+
screen_y = self._target_screen.geometry().y()
179180

180181
if self._align == "center" or self._alignment.get("center", False):
181182
available_x = screen_x + self._padding["left"]
@@ -206,13 +207,16 @@ def position_bar(self, init=False) -> None:
206207
bar_width = self._dimensions["width"]
207208
bar_height = self._dimensions["height"]
208209

209-
screen_width = self.screen().geometry().width()
210-
screen_height = self.screen().geometry().height()
210+
screen_width = self._target_screen.geometry().width()
211+
screen_height = self._target_screen.geometry().height()
211212

212-
scale_state = self.screen().devicePixelRatio() > 1.0
213+
scale_state = self._target_screen.devicePixelRatio() > 1.0
213214

214215
if self._is_auto_width:
215-
bar_width = self._update_auto_width()
216+
if self._bar_frame.layout() is not None:
217+
bar_width = self._update_auto_width()
218+
else:
219+
bar_width = 0
216220

217221
elif is_valid_percentage_str(str(self._dimensions["width"])):
218222
percent = percent_to_float(self._dimensions["width"])
@@ -236,7 +240,7 @@ def _update_auto_width(self) -> int:
236240
layout.activate()
237241

238242
requested = max(self._bar_frame.sizeHint().width(), 0)
239-
available = self.screen().geometry().width() - self._padding["left"] - self._padding["right"]
243+
available = self._target_screen.geometry().width() - self._padding["left"] - self._padding["right"]
240244
new_width = min(requested, available)
241245
self._current_auto_width = new_width
242246
return new_width
@@ -247,7 +251,7 @@ def _apply_auto_width(self, new_width: int) -> None:
247251
return
248252

249253
bar_height = self._dimensions["height"]
250-
screen_geometry = self.screen().geometry()
254+
screen_geometry = self._target_screen.geometry()
251255
bar_x, bar_y = self.bar_pos(
252256
new_width,
253257
bar_height,
@@ -260,9 +264,6 @@ def _apply_auto_width(self, new_width: int) -> None:
260264

261265
def _sync_auto_width(self) -> None:
262266
"""Ensure auto width matches the layout after a DPI/geometry."""
263-
if not self._is_auto_width:
264-
return
265-
266267
previous_width = self._current_auto_width
267268
new_width = self._update_auto_width()
268269

@@ -369,7 +370,7 @@ def hide(self):
369370
super().hide()
370371

371372
def _handle_bar_management(self, action, screen_name):
372-
current_screen_matches = not screen_name or self.screen().name() == screen_name
373+
current_screen_matches = not screen_name or self._target_screen.name() == screen_name
373374
if current_screen_matches:
374375
if action == "show":
375376
self.show()

src/core/utils/widgets/animation_manager.py

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
class AnimationManager:
88
_instances = {}
99
_repeating_animations = {} # Track widgets with repeating animations
10-
ALLOWED_ANIMATIONS = ["fadeInOut", "blink"]
10+
ALLOWED_ANIMATIONS = ["fadeInOut"]
1111

1212
@classmethod
1313
def animate(cls, widget, animation_type: str, duration: int = 200):
1414
"""Execute a single animation on a widget.
1515
1616
Args:
1717
widget: The widget to animate
18-
animation_type: Type of animation ('fadeInOut', 'flash', etc.)
18+
animation_type: Type of animation ('fadeInOut', etc.)
1919
duration: Duration of the animation in milliseconds
2020
"""
2121
if animation_type not in cls.ALLOWED_ANIMATIONS:
@@ -39,7 +39,7 @@ def start_animation(
3939
4040
Args:
4141
widget: The widget to animate
42-
animation_type: Type of animation ('blink', 'fadeInOut', etc.)
42+
animation_type: Type of animation ('fadeInOut', etc.)
4343
animation_duration: Duration of each animation cycle in ms (default 800ms)
4444
repeat_interval: Time between animation cycles in ms (default 2000ms = 2s)
4545
timeout: Auto-stop after this many ms (default 5000ms = 5s), 0 = no timeout
@@ -128,44 +128,13 @@ def on_finished():
128128
widget.setGraphicsEffect(None)
129129
except Exception:
130130
pass
131-
132-
anim.finished.connect(on_finished)
133-
134-
# Keep reference to prevent garbage collection
135-
widget._yasb_animation = anim
136-
anim.start()
137-
138-
def blink(self, widget):
139-
"""Blink animation - dim and brighten like Windows taskbar notification blinking."""
140-
effect = QGraphicsOpacityEffect(widget)
141-
effect.setEnabled(True)
142-
effect.setOpacity(1.0)
143-
widget.setGraphicsEffect(effect)
144-
145-
anim = QPropertyAnimation(effect, b"opacity", widget)
146-
anim.setDuration(self.duration)
147-
anim.setStartValue(1.0)
148-
anim.setEndValue(0.7)
149-
anim.setEasingCurve(QEasingCurve.Type.InOutQuad)
150-
151-
# Reverse the animation to go back to full opacity
152-
anim.setDirection(QPropertyAnimation.Direction.Forward)
153-
154-
def on_finished():
155131
try:
156-
# Fade back to full opacity
157-
if anim.direction() == QPropertyAnimation.Direction.Forward:
158-
anim.setDirection(QPropertyAnimation.Direction.Backward)
159-
anim.start()
160-
else:
161-
# Animation complete, clean up
162-
effect.setEnabled(False)
163-
widget.setGraphicsEffect(None)
132+
widget._yasb_animation = None
164133
except Exception:
165134
pass
166135

167136
anim.finished.connect(on_finished)
168137

169-
# Keep reference to prevent garbage collection
138+
# Keep reference to prevent garbage collection if not cleared
170139
widget._yasb_animation = anim
171140
anim.start()

0 commit comments

Comments
 (0)