2727
2828import gobject , gtk , pango
2929
30- # Prevent deprecation warning for egg:
31- warnings .simplefilter ('ignore' , DeprecationWarning )
32- try :
33- import egg .trayicon
34- HAVE_EGG = True
35- HAVE_STATUS_ICON = False
36- except ImportError :
37- HAVE_EGG = False
38- HAVE_STATUS_ICON = True
39- # Reset so that we can see any other deprecation warnings
40- warnings .simplefilter ('default' , DeprecationWarning )
4130
4231# Default to no sugar, then test...
4332HAVE_SUGAR = False
@@ -90,10 +79,6 @@ def __init__(self, args, window=None, _sugar=False):
9079 self .remote_dest_filename = None
9180 self .remotefilelist = None
9281 self .seekidle = None
93- self .statusicon = None
94- self .trayeventbox = None
95- self .trayicon = None
96- self .trayimage = None
9782 self .artwork = None
9883
9984 self .client = mpd .MPDClient ()
@@ -161,9 +146,6 @@ def __init__(self, args, window=None, _sugar=False):
161146
162147 self .last_status_text = ""
163148
164- self .eggtrayfile = None
165- self .eggtrayheight = None
166-
167149 self .img_clicked = False
168150
169151 self .mpd_update_queued = False
@@ -494,6 +476,9 @@ def __init__(self, args, window=None, _sugar=False):
494476 mainvbox = gtk .VBox ()
495477 tophbox = gtk .HBox ()
496478
479+ TrayFactory = tray .get_tray_icon_factory ()
480+ self .tray_icon = TrayFactory (self .window , self .traymenu , self .traytips )
481+
497482 self .albumimage = self .artwork .get_albumimage ()
498483
499484 self .imageeventbox = ui .eventbox (add = self .albumimage )
@@ -725,7 +710,7 @@ def __init__(self, args, window=None, _sugar=False):
725710 self .iterate_now ()
726711 if self .window_owner :
727712 if self .config .withdrawn :
728- if ( HAVE_EGG and self .trayicon . get_property ( 'visible' )) or ( HAVE_STATUS_ICON and self . statusicon . is_embedded () and self . statusicon . get_visible () ):
713+ if self .tray_icon . is_visible ( ):
729714 ui .hide (self .window )
730715 self .window .show_all ()
731716
@@ -748,9 +733,6 @@ def __init__(self, args, window=None, _sugar=False):
748733 self .on_currsong_notify ()
749734 self .current .center_song_in_list ()
750735
751- if HAVE_STATUS_ICON :
752- gobject .timeout_add (250 , self .iterate_status_icon )
753-
754736 gc .disable ()
755737
756738 gobject .idle_add (self .header_save_column_widths )
@@ -1032,17 +1014,12 @@ def iterate(self):
10321014 self .iterate_handler = gobject .timeout_add (self .iterate_time , self .iterate ) # Repeat ad infitum..
10331015
10341016 if self .config .show_trayicon :
1035- if HAVE_STATUS_ICON :
1036- if self .statusicon .is_embedded () and not self .statusicon .get_visible ():
1037- # Systemtray appears, add icon:
1038- self .systemtray_initialize ()
1039- elif not self .statusicon .is_embedded () and self .config .withdrawn :
1040- # Systemtray gone, unwithdraw app:
1041- self .withdraw_app_undo ()
1042- elif HAVE_EGG :
1043- if not self .trayicon .get_property ('visible' ):
1044- # Systemtray appears, add icon:
1045- self .systemtray_initialize ()
1017+ if self .tray_icon .is_available () and not self .tray_icon .is_visible ():
1018+ # Systemtray appears, add icon
1019+ self .systemtray_initialize ()
1020+ elif not self .tray_icon .is_available () and self .config .withdrawn :
1021+ # Systemtray gone, unwithdraw app
1022+ self .withdraw_app_undo ()
10461023
10471024 if self .call_gc_collect :
10481025 gc .collect ()
@@ -1065,15 +1042,6 @@ def iterate_now(self):
10651042 self .iterate_stop ()
10661043 self .iterate ()
10671044
1068- def iterate_status_icon (self ):
1069- # Polls for the users' cursor position to display the custom tooltip window when over the
1070- # gtk.StatusIcon. We use this instead of self.iterate() in order to poll more often and
1071- # increase responsiveness.
1072- if self .config .show_trayicon :
1073- if self .statusicon .is_embedded () and self .statusicon .get_visible ():
1074- self .tooltip_show_manually ()
1075- gobject .timeout_add (250 , self .iterate_status_icon )
1076-
10771045 def on_topwindow_keypress (self , _widget , event ):
10781046 shortcut = gtk .accelerator_name (event .keyval , event .state )
10791047 shortcut = shortcut .replace ("<Mod2>" , "" )
@@ -1085,11 +1053,9 @@ def on_topwindow_keypress(self, _widget, event):
10851053 self .library .on_search_end (None )
10861054 elif self .current_tab == self .TAB_CURRENT and self .current .filterbox_visible :
10871055 self .current .searchfilter_toggle (None )
1088- elif self .config .minimize_to_systray :
1089- if HAVE_STATUS_ICON and self .statusicon .is_embedded () and self .statusicon .get_visible ():
1090- self .withdraw_app ()
1091- elif HAVE_EGG and self .trayicon .get_property ('visible' ):
1092- self .withdraw_app ()
1056+ elif self .config .minimize_to_systray and \
1057+ self .tray_icon .is_visible ():
1058+ self .withdraw_app ()
10931059 return
10941060 elif shortcut == 'Delete' :
10951061 self .on_remove (None )
@@ -1136,11 +1102,7 @@ def handle_change_conn(self):
11361102 self .currentdata .clear ()
11371103 if self .current_treeview .get_model ():
11381104 self .current_treeview .get_model ().clear ()
1139- if HAVE_STATUS_ICON :
1140- self .statusicon .set_from_file (self .find_path ('sonata_disconnect.png' ))
1141- elif HAVE_EGG and self .eggtrayheight :
1142- self .eggtrayfile = self .find_path ('sonata_disconnect.png' )
1143- self .trayimage .set_from_pixbuf (img .get_pixbuf_of_size (gtk .gdk .pixbuf_new_from_file (self .eggtrayfile ), self .eggtrayheight )[0 ])
1105+ self .tray_icon .update_icon (self .find_path ('sonata_disconnect.png' ))
11441106 self .info_update (True )
11451107 if self .current .filterbox_visible :
11461108 gobject .idle_add (self .current .searchfilter_toggle , None )
@@ -1428,21 +1390,13 @@ def handle_change_status(self):
14281390 self .ppbutton .get_child ().get_child ().get_children ()[1 ].set_text ('' )
14291391 self .UIManager .get_widget ('/traymenu/playmenu' ).show ()
14301392 self .UIManager .get_widget ('/traymenu/pausemenu' ).hide ()
1431- if HAVE_STATUS_ICON :
1432- self .statusicon .set_from_file (self .find_path ('sonata.png' ))
1433- elif HAVE_EGG and self .eggtrayheight :
1434- self .eggtrayfile = self .find_path ('sonata.png' )
1435- self .trayimage .set_from_pixbuf (img .get_pixbuf_of_size (gtk .gdk .pixbuf_new_from_file (self .eggtrayfile ), self .eggtrayheight )[0 ])
1393+ self .tray_icon .update_icon (self .find_path ('sonata.png' ))
14361394 elif self .status ['state' ] == 'pause' :
14371395 self .ppbutton .set_image (ui .image (stock = gtk .STOCK_MEDIA_PLAY , stocksize = gtk .ICON_SIZE_BUTTON ))
14381396 self .ppbutton .get_child ().get_child ().get_children ()[1 ].set_text ('' )
14391397 self .UIManager .get_widget ('/traymenu/playmenu' ).show ()
14401398 self .UIManager .get_widget ('/traymenu/pausemenu' ).hide ()
1441- if HAVE_STATUS_ICON :
1442- self .statusicon .set_from_file (self .find_path ('sonata_pause.png' ))
1443- elif HAVE_EGG and self .eggtrayheight :
1444- self .eggtrayfile = self .find_path ('sonata_pause.png' )
1445- self .trayimage .set_from_pixbuf (img .get_pixbuf_of_size (gtk .gdk .pixbuf_new_from_file (self .eggtrayfile ), self .eggtrayheight )[0 ])
1399+ self .tray_icon .update_icon (self .find_path ('sonata_pause.png' ))
14461400 elif self .status ['state' ] == 'play' :
14471401 self .ppbutton .set_image (ui .image (stock = gtk .STOCK_MEDIA_PAUSE , stocksize = gtk .ICON_SIZE_BUTTON ))
14481402 self .ppbutton .get_child ().get_child ().get_children ()[1 ].set_text ('' )
@@ -1452,11 +1406,7 @@ def handle_change_status(self):
14521406 if self .prevstatus ['state' ] == 'pause' :
14531407 # Forces the notification to popup if specified
14541408 self .on_currsong_notify ()
1455- if HAVE_STATUS_ICON :
1456- self .statusicon .set_from_file (self .find_path ('sonata_play.png' ))
1457- elif HAVE_EGG and self .eggtrayheight :
1458- self .eggtrayfile = self .find_path ('sonata_play.png' )
1459- self .trayimage .set_from_pixbuf (img .get_pixbuf_of_size (gtk .gdk .pixbuf_new_from_file (self .eggtrayfile ), self .eggtrayheight )[0 ])
1409+ self .tray_icon .update_icon (self .find_path ('sonata_play.png' ))
14601410
14611411 self .playing_song_change ()
14621412 if self .status_is_play_or_pause ():
@@ -1737,10 +1687,8 @@ def on_currsong_notify(self, _foo=None, _bar=None, force_popup=False):
17371687 try :
17381688 self .traytips .notifications_location = self .config .traytips_notifications_location
17391689 self .traytips .use_notifications_location = True
1740- if HAVE_STATUS_ICON and self .statusicon .is_embedded () and self .statusicon .get_visible ():
1741- self .traytips ._real_display (self .statusicon )
1742- elif HAVE_EGG and self .trayicon .get_property ('visible' ):
1743- self .traytips ._real_display (self .trayeventbox )
1690+ if self .tray_icon .is_visible ():
1691+ self .traytips ._real_display (self .tray_icon )
17441692 else :
17451693 self .traytips ._real_display (None )
17461694 if self .config .popup_option != len (self .popuptimes )- 1 :
@@ -1761,10 +1709,7 @@ def on_currsong_notify(self, _foo=None, _bar=None, force_popup=False):
17611709 else :
17621710 self .traytips .hide ()
17631711 elif self .traytips .get_property ('visible' ):
1764- try :
1765- self .traytips ._real_display (self .trayeventbox )
1766- except :
1767- pass
1712+ self .traytips ._real_display (self .tray_icon )
17681713
17691714 def on_progressbar_notify_fraction (self , * _args ):
17701715 self .trayprogressbar .set_fraction (self .progressbar .get_fraction ())
@@ -1812,11 +1757,7 @@ def on_delete_event_yes(self, _widget):
18121757 # This one makes sure the program exits when the window is closed
18131758 def on_delete_event (self , _widget , _data = None ):
18141759 if not self .exit_now and self .config .minimize_to_systray :
1815- if HAVE_STATUS_ICON and self .statusicon .is_embedded () and self .statusicon .get_visible ():
1816- self .withdraw_app ()
1817- return True
1818- elif HAVE_EGG and self .trayicon .get_property ('visible' ):
1819- self .withdraw_app ()
1760+ if self .tray_icon .is_visible ():
18201761 return True
18211762 self .settings_save ()
18221763 self .artwork .artwork_save_cache ()
@@ -2469,35 +2410,13 @@ def systemtray_activate(self, _status_icon):
24692410 #self.traytips._remove_timer()
24702411 gobject .timeout_add (100 , self .tooltip_set_ignore_toggle_signal_false )
24712412
2472- def tooltip_show_manually (self ):
2473- # Since there is no signal to connect to when the user puts their
2474- # mouse over the trayicon, we will check the mouse position
2475- # manually and show/hide the window as appropriate. This is called
2476- # every iteration. Note: This should not occur if self.traytips.notif_
2477- # handler has a value, because that means that the tooltip is already
2478- # visible, and we don't want to override that setting simply because
2479- # the user's cursor is not over the tooltip.
2480- if self .traymenu .get_property ('visible' ) and self .traytips .notif_handler != - 1 :
2481- self .traytips ._remove_timer ()
2482- elif not self .traytips .notif_handler :
2483- _pscreen , px , py , _mods = self .window .get_screen ().get_display ().get_pointer ()
2484- _icon_screen , icon_rect , _icon_orient = self .statusicon .get_geometry ()
2485- x = icon_rect [0 ]
2486- y = icon_rect [1 ]
2487- width = icon_rect [2 ]
2488- height = icon_rect [3 ]
2489- if px >= x and px <= x + width and py >= y and py <= y + height :
2490- self .traytips ._start_delay (self .statusicon )
2491- else :
2492- self .traytips ._remove_timer ()
2493-
24942413 def systemtray_click (self , _widget , event ):
24952414 # Clicking on an egg system tray icon:
24962415 if event .button == 1 and not self .ignore_toggle_signal : # Left button shows/hides window(s)
24972416 self .systemtray_activate (None )
24982417 elif event .button == 2 : # Middle button will play/pause
24992418 if self .conn :
2500- self .mpd_pp (self . trayeventbox )
2419+ self .mpd_pp (None )
25012420 elif event .button == 3 : # Right button pops up menu
25022421 self .traymenu .popup (None , None , None , event .button , event .time )
25032422 return False
@@ -2531,7 +2450,7 @@ def withdraw_app_undo_present_and_focus(self):
25312450 self .window .set_keep_above (True )
25322451
25332452 def withdraw_app (self ):
2534- if HAVE_EGG or HAVE_STATUS_ICON :
2453+ if self . tray_icon . is_available () :
25352454 # Save the playlist column widths before withdrawing the app.
25362455 # Otherwise we will not be able to correctly save the column
25372456 # widths if the user quits sonata while it is withdrawn.
@@ -2558,17 +2477,6 @@ def systemtray_scroll(self, widget, event):
25582477 if self .conn :
25592478 self .volumebutton .emit ("scroll-event" , event )
25602479
2561- def systemtray_size (self , widget , _allocation ):
2562- if widget .allocation .height <= 5 :
2563- # For vertical panels, height can be 1px, so use width
2564- size = widget .allocation .width
2565- else :
2566- size = widget .allocation .height
2567- if not self .eggtrayheight or self .eggtrayheight != size :
2568- self .eggtrayheight = size
2569- if size > 5 and self .eggtrayfile :
2570- self .trayimage .set_from_pixbuf (img .get_pixbuf_of_size (gtk .gdk .pixbuf_new_from_file (self .eggtrayfile ), self .eggtrayheight )[0 ])
2571-
25722480 def switch_to_tab_name (self , tab_name ):
25732481 self .notebook .set_current_page (self .notebook_get_tab_num (self .notebook , tab_name ))
25742482
@@ -2679,7 +2587,6 @@ def on_random_clicked(self, widget):
26792587 self ._toggle_clicked ('random' , widget )
26802588
26812589 def setup_prefs_callbacks (self ):
2682- trayicon_available = HAVE_EGG or HAVE_STATUS_ICON
26832590 extras = preferences .Extras_cbs
26842591 extras .popuptimes = self .popuptimes
26852592 extras .notif_toggled = self .prefs_notif_toggled
@@ -2693,7 +2600,11 @@ def setup_prefs_callbacks(self):
26932600 display .progress_toggled = self .prefs_progress_toggled
26942601 display .statusbar_toggled = self .prefs_statusbar_toggled
26952602 display .lyrics_toggled = self .prefs_lyrics_toggled
2696- display .trayicon_available = trayicon_available
2603+ # TODO: the tray icon object has not been build yet, so we don't know if
2604+ # the tray icon will be available at this time.
2605+ # We should find a way to update this when the tray icon will be
2606+ # initialized.
2607+ display .trayicon_available = True
26972608
26982609 behavior = preferences .Behavior_cbs
26992610 behavior .trayicon_toggled = self .prefs_trayicon_toggled
@@ -2710,14 +2621,7 @@ def setup_prefs_callbacks(self):
27102621 format .currsongoptions2_changed = self .prefs_currsongoptions2_changed
27112622
27122623 def on_prefs (self , _widget ):
2713- trayicon_in_use = ((HAVE_STATUS_ICON and
2714- self .statusicon .is_embedded () and
2715- self .statusicon .get_visible ())
2716- or
2717- (HAVE_EGG and
2718- self .trayicon .get_property ('visible' )))
2719-
2720- preferences .Behavior_cbs .trayicon_in_use = trayicon_in_use
2624+ preferences .Behavior_cbs .trayicon_in_use = self .tray_icon .is_visible ()
27212625 self .preferences .on_prefs_real ()
27222626
27232627 def prefs_currentoptions_changed (self , entry , _event ):
@@ -2866,21 +2770,12 @@ def prefs_trayicon_toggled(self, button, minimize):
28662770 # CheckButton to reflect if the trayicon is visible.
28672771 if button .get_active ():
28682772 self .config .show_trayicon = True
2869- if HAVE_STATUS_ICON :
2870- self .statusicon .set_visible (True )
2871- if self .statusicon .is_embedded () or self .statusicon .get_visible ():
2872- minimize .set_sensitive (True )
2873- elif HAVE_EGG :
2874- self .trayicon .show_all ()
2875- if self .trayicon .get_property ('visible' ):
2876- minimize .set_sensitive (True )
2773+ self .tray_icon .show ()
2774+ minimize .set_sensitive (True )
28772775 else :
28782776 self .config .show_trayicon = False
28792777 minimize .set_sensitive (False )
2880- if HAVE_STATUS_ICON :
2881- self .statusicon .set_visible (False )
2882- elif HAVE_EGG :
2883- self .trayicon .hide_all ()
2778+ self .tray_icon .hide ()
28842779
28852780 def seek (self , song , seektime ):
28862781 mpdh .call (self .client , 'seek' , song , seektime )
@@ -3140,30 +3035,18 @@ def on_about(self, _action):
31403035
31413036 def systemtray_initialize (self ):
31423037 # Make system tray 'icon' to sit in the system tray
3143- if HAVE_STATUS_ICON :
3144- self .statusicon = gtk .StatusIcon ()
3145- self .statusicon .set_from_file (self .find_path ('sonata.png' ))
3146- self .statusicon .set_visible (self .config .show_trayicon )
3147- self .statusicon .connect ('popup_menu' , self .systemtray_menu )
3148- self .statusicon .connect ('activate' , self .systemtray_activate )
3149- elif HAVE_EGG :
3150- self .trayimage = ui .image ()
3151- self .trayeventbox = ui .eventbox (add = self .trayimage )
3152- self .trayeventbox .connect ('button_press_event' , self .systemtray_click )
3153- self .trayeventbox .connect ('scroll-event' , self .systemtray_scroll )
3154- self .trayeventbox .connect ('size-allocate' , self .systemtray_size )
3155- self .traytips .set_tip (self .trayeventbox )
3156- try :
3157- self .trayicon = egg .trayicon .TrayIcon ("TrayIcon" )
3158- self .trayicon .add (self .trayeventbox )
3159- if self .config .show_trayicon :
3160- self .trayicon .show_all ()
3161- self .eggtrayfile = self .find_path ('sonata.png' )
3162- self .trayimage .set_from_pixbuf (img .get_pixbuf_of_size (gtk .gdk .pixbuf_new_from_file (self .eggtrayfile ), self .eggtrayheight )[0 ])
3163- else :
3164- self .trayicon .hide_all ()
3165- except :
3166- pass
3038+ self .tray_icon .initialize (
3039+ self .systemtray_menu ,
3040+ self .systemtray_click ,
3041+ self .systemtray_scroll ,
3042+ self .systemtray_activate ,
3043+ )
3044+
3045+ if self .config .show_trayicon :
3046+ self .tray_icon .show ()
3047+ else :
3048+ self .tray_icon .hide ()
3049+ self .tray_icon .update_icon (self .find_path ('sonata.png' ))
31673050
31683051 def dbus_show (self ):
31693052 self .window .hide ()
0 commit comments