freeforall tousez
freeforall tousez

Reputation: 845

minimize to tray, stuck in loop, python gtk

python: 2.7.5

os: linux, fedora 19

this is a minimum example code to show the problem that i am having, the tray part of the code is excluded cause it is working fine.

run it in a terminal, when the minimize button is press, it enter a show() and hide() loop

i think the easiest way to show it is to make it print a number every it show or hide itself.

the question is: how do i get it to work correctly without it getting stuck in a loop?

from gi.repository import Gtk, Gdk

class Win(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.connect("delete-event", self.delete_event)
        #something to make it easier to see the loop
        self.num = 0
        self.connect('window-state-event', self.window_state_event_cb)

    def window_state_event_cb(self, widget, event):
       if event.changed_mask & Gdk.WindowState.ICONIFIED:
          if event.new_window_state & Gdk.WindowState.ICONIFIED:
             self.hide()
             print 'Window was minimized!'
          else:
             self.show()
             print 'Window was unminimized!'
          self.num += 1
          print(self.num)

    def delete_event(self,window,event):
        Gtk.main_quit()

if __name__=="__main__":
    win = Win()
    win.show_all()
    Gtk.main()

code pieced together from http://faq.pygtk.org/index.py?req=edit&file=faq10.022.htp

Upvotes: 2

Views: 1467

Answers (1)

Axel Heider
Axel Heider

Reputation: 626

I had the same issue and this works for me.

def on_windowStateEvent(self, widget, event):
  if (event.changed_mask & Gdk.WindowState.ICONIFIED):
    if (event.new_window_state & Gdk.WindowState.ICONIFIED):
      # minimize visible widow. We hide the window to remove it
      # from the active tasks windows, a click the tray icon will
      # bring it back
      self.window.hide()
    else:
      # don't do anything here. The call from hide() above causes a 
      # new event that ends here. And calling show() now will result
      # in a loop
      pass

def statusIcon_activate(self, statusIcon):
  # restore the hidden window on a click on the tray icon
  self.window.deiconify()
  self.window.present() # present the window on the active desktop

...
self.window = Gtk.Window()
self.window.connect("window-state-event", self.on_windowStateEvent)
....
self.statusIcon = Gtk.StatusIcon()
self.statusIcon.connect("activate", self.statusIcon_activate)
...

And there is the short form:

def isEventIconify(event):
  return (event.changed_mask
          & event.new_window_state
          & Gdk.WindowState.ICONIFIED)

def on_windowStateEvent(self, widget, event):
  if isEventIconify(event):
    self.window.hide()

Upvotes: 3

Related Questions