11import logging
22
33import win32con
4- from PyQt6 .QtCore import QEasingCurve , QEvent , QPropertyAnimation , QRect , Qt , pyqtSignal
4+ from PyQt6 .QtCore import QEasingCurve , QEvent , QPropertyAnimation , QRect , Qt , QTimer , pyqtSignal
55from PyQt6 .QtGui import QScreen
66from PyQt6 .QtWidgets import QFrame , QGridLayout , QHBoxLayout , QWidget
77
@@ -108,6 +108,11 @@ def __init__(
108108
109109 self .position_bar (init )
110110 self .monitor_hwnd = get_monitor_hwnd (int (self .winId ()))
111+
112+ if self ._is_auto_width :
113+ self ._sync_auto_width ()
114+ self ._bar_frame .installEventFilter (self )
115+
111116 self ._add_widgets (widgets )
112117
113118 if not self ._window_flags ["windows_app_bar" ]:
@@ -138,7 +143,7 @@ def __init__(
138143 self ._autohide_manager = AutoHideManager (self , self )
139144 self ._autohide_manager .setup_autohide ()
140145
141- self .show ( )
146+ QTimer . singleShot ( 0 , self .show )
142147
143148 @property
144149 def bar_id (self ) -> str :
@@ -151,6 +156,9 @@ def on_geometry_changed(self, geo: QRect) -> None:
151156 if self ._autohide_manager and self ._autohide_manager .is_enabled ():
152157 self ._autohide_manager .setup_detection_zone ()
153158
159+ if self ._is_auto_width :
160+ QTimer .singleShot (0 , self ._sync_auto_width )
161+
154162 def try_add_app_bar (self , scale_screen_height = False ) -> None :
155163 if self .app_bar_manager :
156164 self .app_bar_manager .create_appbar (
@@ -203,8 +211,8 @@ def position_bar(self, init=False) -> None:
203211
204212 scale_state = self .screen ().devicePixelRatio () > 1.0
205213
206- if str ( self ._dimensions [ "width" ]). lower () == "auto" :
207- bar_width = max ( self ._bar_frame . sizeHint (). width (), 0 )
214+ if self ._is_auto_width :
215+ bar_width = self ._update_auto_width ( )
208216
209217 elif is_valid_percentage_str (str (self ._dimensions ["width" ])):
210218 percent = percent_to_float (self ._dimensions ["width" ])
@@ -221,6 +229,46 @@ def position_bar(self, init=False) -> None:
221229 self ._bar_frame .setGeometry (0 , 0 , bar_width , bar_height )
222230 self .try_add_app_bar (scale_screen_height = scale_state )
223231
232+ def _update_auto_width (self ) -> int :
233+ """Calculate the current auto width based on the layout's size hint."""
234+ layout = self ._bar_frame .layout ()
235+ if layout :
236+ layout .activate ()
237+
238+ requested = max (self ._bar_frame .sizeHint ().width (), 0 )
239+ available = self .screen ().geometry ().width () - self ._padding ["left" ] - self ._padding ["right" ]
240+ new_width = min (requested , available )
241+ self ._current_auto_width = new_width
242+ return new_width
243+
244+ def _apply_auto_width (self , new_width : int ) -> None :
245+ """Resize and reposition the bar using the supplied auto width."""
246+ if new_width < 0 :
247+ return
248+
249+ bar_height = self ._dimensions ["height" ]
250+ screen_geometry = self .screen ().geometry ()
251+ bar_x , bar_y = self .bar_pos (
252+ new_width ,
253+ bar_height ,
254+ screen_geometry .width (),
255+ screen_geometry .height (),
256+ )
257+
258+ self .setGeometry (bar_x , bar_y , new_width , bar_height )
259+ self ._bar_frame .setGeometry (0 , 0 , new_width , bar_height )
260+
261+ def _sync_auto_width (self ) -> None :
262+ """Ensure auto width matches the layout after a DPI/geometry."""
263+ if not self ._is_auto_width :
264+ return
265+
266+ previous_width = self ._current_auto_width
267+ new_width = self ._update_auto_width ()
268+
269+ if new_width != previous_width or self .width () != new_width :
270+ self ._apply_auto_width (new_width )
271+
224272 def _add_widgets (self , widgets : dict [str , list ] = None ):
225273 bar_layout = QGridLayout ()
226274 bar_layout .setContentsMargins (0 , 0 , 0 , 0 )
@@ -257,9 +305,6 @@ def _add_widgets(self, widgets: dict[str, list] = None):
257305
258306 self ._bar_frame .setLayout (bar_layout )
259307
260- if self ._is_auto_width :
261- self ._bar_frame .installEventFilter (self )
262-
263308 def show_bar (self ):
264309 self .setWindowOpacity (0.0 )
265310 self .opacity_animation = QPropertyAnimation (self , b"windowOpacity" )
@@ -310,24 +355,10 @@ def changeEvent(self, event: QEvent) -> None:
310355
311356 def eventFilter (self , obj , event ):
312357 if self ._is_auto_width and obj == self ._bar_frame and event .type () == QEvent .Type .LayoutRequest :
313- requested = max (self ._bar_frame .sizeHint ().width (), 0 )
314- available = self .screen ().geometry ().width () - self ._padding ["left" ] - self ._padding ["right" ]
315- new_width = min (requested , available )
316- if new_width != self ._current_auto_width :
317- self ._current_auto_width = new_width
318- bar_height = self .height ()
319- self .resize (new_width , bar_height )
320- self ._bar_frame .resize (new_width , bar_height )
321-
322- screen_geometry = self .screen ().geometry ()
323- bar_x , bar_y = self .bar_pos (
324- new_width ,
325- bar_height ,
326- screen_geometry .width (),
327- screen_geometry .height (),
328- )
329- if self .x () != bar_x or self .y () != bar_y :
330- self .move (bar_x , bar_y )
358+ previous_width = self ._current_auto_width
359+ new_width = self ._update_auto_width ()
360+ if new_width != previous_width :
361+ self ._apply_auto_width (new_width )
331362
332363 return super ().eventFilter (obj , event )
333364
0 commit comments