From fef4312996c02f0060ae667e0f05d34ebaac6c0e Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Mon, 21 Jul 2025 10:30:38 +0545 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(dock):=20improve?= =?UTF-8?q?=20music=20player=20popup=20handling=20and=20remove=20hover=20e?= =?UTF-8?q?vents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/dock/components/music_player.py | 100 +++++++++--------------- 1 file changed, 37 insertions(+), 63 deletions(-) diff --git a/modules/dock/components/music_player.py b/modules/dock/components/music_player.py index f3a5d6c..cf186ae 100644 --- a/modules/dock/components/music_player.py +++ b/modules/dock/components/music_player.py @@ -3,7 +3,7 @@ import time from fabric.widgets.box import Box from fabric.widgets.button import Button from fabric.widgets.circularprogressbar import CircularProgressBar -from fabric.widgets.eventbox import EventBox + from fabric.widgets.label import Label from fabric.widgets.overlay import Overlay from fabric.widgets.revealer import Revealer @@ -64,8 +64,6 @@ class MusicPlayerPopup(Window): # Connect to escape key to close self.connect("key-press-event", self.on_key_press) self.connect("button-press-event", self.on_button_press) - self.connect("enter-notify-event", self.on_enter_notify) - self.connect("leave-notify-event", self.on_leave_notify) self.set_can_focus(True) def on_active_player_changed(self, container, player): @@ -76,6 +74,8 @@ class MusicPlayerPopup(Window): def on_key_press(self, widget, event): """Handle key press events""" if event.keyval == Gdk.KEY_Escape: + if self.dock_component: + self.dock_component._popup_visible = False self.hide_popup() return True return False @@ -124,29 +124,24 @@ class MusicPlayerPopup(Window): return transition_map.get(dock_position, "slide-up") def on_button_press(self, widget, event): - """Handle button press events""" - return False - - def on_enter_notify(self, widget, event): - """Handle mouse entering popup""" - # Cancel any pending hide from dock component - if self.dock_component and hasattr(self.dock_component, '_hover_timeout'): - if self.dock_component._hover_timeout: - GLib.source_remove(self.dock_component._hover_timeout) - self.dock_component._hover_timeout = None - return False - - def on_leave_notify(self, widget, event): - """Handle mouse leaving popup""" - # Hide popup when mouse leaves + """Handle button press events - close popup when clicking outside""" + if self.dock_component: + self.dock_component._popup_visible = False self.hide_popup() return False def hide_popup(self): """Hide the music player popup""" self.revealer.set_reveal_child(False) - # Hide window after transition completes - GLib.timeout_add(350, lambda: self.set_visible(False)) + # Hide window after transition completes and notify dock component + GLib.timeout_add(350, self._complete_hide) + + def _complete_hide(self): + """Complete the hide process""" + self.set_visible(False) + if self.dock_component: + self.dock_component._popup_visible = False + return False class MusicPlayer(Box): @@ -188,29 +183,24 @@ class MusicPlayer(Box): # Create music icon label - always use generic music icon self.music_label = Label(name="music-label", markup=icons.music) - # Create button for the music icon + # Create button for the music icon with click handler self.music_button = Button(child=self.music_label) + self.music_button.connect("clicked", self.on_music_button_clicked) - # Create event box for scroll events and hover detection - self.event_box = EventBox( - events=["scroll", "smooth-scroll", "enter-notify", "leave-notify"], - child=Overlay(child=self.progress_bar, overlays=self.music_button), - ) + # Create overlay without EventBox to fix click issues + self.overlay = Overlay(child=self.progress_bar, overlays=self.music_button) - # Connect scroll events for seeking - self.event_box.connect("scroll-event", self.on_scroll) - # Connect hover events - self.event_box.connect("enter-notify-event", self.on_enter_notify) - self.event_box.connect("leave-notify-event", self.on_leave_notify) - self.add_events(Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.SMOOTH_SCROLL_MASK | Gdk.EventMask.ENTER_NOTIFY_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK) + # Add scroll events directly to the overlay for seeking + self.overlay.add_events(Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.SMOOTH_SCROLL_MASK) + self.overlay.connect("scroll-event", self.on_scroll) - self.add(self.event_box) + self.add(self.overlay) - # Pre-create popup for immediate display on hover + # Pre-create popup for immediate display on click self.popup = MusicPlayerPopup(dock_component=self) - # Hover timeout for debouncing - self._hover_timeout = None + # Track popup visibility state + self._popup_visible = False # Initialize players with delayed visibility check GLib.timeout_add(500, self._delayed_init) @@ -238,10 +228,7 @@ class MusicPlayer(Box): if hasattr(self, "active_player_check_timeout"): GLib.source_remove(self.active_player_check_timeout) - # Remove hover timeout - if hasattr(self, "_hover_timeout") and self._hover_timeout: - GLib.source_remove(self._hover_timeout) - self._hover_timeout = None + # No hover timeout to clean up anymore # Remove visibility timeout if hasattr(self, "_visibility_timeout") and self._visibility_timeout: @@ -690,30 +677,17 @@ class MusicPlayer(Box): else: self.on_pause(None) - def on_enter_notify(self, widget, event): - """Handle mouse entering the music player component""" - # Cancel any pending hover timeout - if self._hover_timeout: - GLib.source_remove(self._hover_timeout) - self._hover_timeout = None - - # Show popup immediately on hover (popup is pre-created) - if not self.popup.get_visible(): - self.popup.show_popup() - return False - - def on_leave_notify(self, widget, event): - """Handle mouse leaving the music player component""" - # Hide popup with a small delay to prevent flickering - self._hover_timeout = GLib.timeout_add(100, self._hide_popup_delayed) - return False - - def _hide_popup_delayed(self): - """Hide popup after delay""" - if self.popup and self.popup.get_visible(): + def on_music_button_clicked(self, button): + """Handle music button click to toggle popup""" + if self._popup_visible: + # Hide popup if currently visible self.popup.hide_popup() - self._hover_timeout = None - return False # Don't repeat timeout + self._popup_visible = False + else: + # Show popup if currently hidden + self.popup.show_popup() + self._popup_visible = True + return True def on_scroll(self, widget, event): """Handle scroll events for seeking"""