Binding callbacks to minimize and maximize events in Toplevel windows
<p>I've read through related answers and it seems that the accepted way to do this is by binding callbacks to <code>&lt;Map&gt;</code> and <code>&lt;Unmap&gt;</code> events in the Toplevel widget. I've tried the following but to no effect:</p>

<pre><code>from Tkinter import *

tk = Tk()

def visible(event):
    print 'visible'

def invisible(event):
    print 'invisible'

tk.bind('&lt;Map&gt;', visible)
tk.bind('&lt;Unmap&gt;', invisible)

tk.mainloop()
</code></pre>

<p>I'm running python 2.7 on Linux. Could this be related to window manager code in different operating systems?</p>

<p>Calling <code>tk.iconify()</code> before <code>tk.mainloop()</code> has no effect either. In fact, the only command that produces the correct behavior is <code>tk.withdraw()</code> which is certainly not the same thing as minimizing the window. Additionally, if <code>&lt;Map&gt;</code> and <code>&lt;Unmap&gt;</code> events are triggered by calling <code>pack()</code>, <code>grid()</code>, or <code>place()</code>, why is <code>&lt;Map&gt;</code> triggered when the application window is minimized on Windows and/or Mac, as <a href="http://stackoverflow.com/a/3840216/2592879">this</a> and <a href="http://stackoverflow.com/a/26160588/2592879">this</a> answer suggest. And why would they be triggered when calling <code>withdraw()</code> and <code>deiconify()</code> on Linux?</p>

<p>My own implementation of the <a href="http://stackoverflow.com/a/39586786/2592879">hack</a> suggested by Jacob.</p>

<pre><code>from Tkinter import Tk, Toplevel
import subprocess


class CustomWindow(Toplevel):

    class State(object):
        NORMAL = 'normal'
        MINIMIZED = 'minimized'

    def __init__(self, parent, **kwargs):
        Toplevel.__init__(self, parent, **kwargs)
        self._state = CustomWindow.State.NORMAL
        self.protocol('WM_DELETE_WINDOW', self.quit)
        self.after(50, self._poll_window_state)

    def _poll_window_state(self):
        id = self.winfo_id() + 1
        winfo = subprocess.check_output(
            ['xprop', '-id', str(id)]).decode('utf-8')

        if '_NET_WM_STATE_HIDDEN' in winfo:
            state = CustomWindow.State.MINIMIZED
        else:
            state = CustomWindow.State.NORMAL

        if state != self._state:
            sequence = {
                CustomWindow.State.NORMAL: '&lt;&lt;Restore&gt;&gt;',
                CustomWindow.State.MINIMIZED: '&lt;&lt;Minimize&gt;&gt;'
            }[state]
            self.event_generate(sequence)
            self._state = state

        self.after(50, self._poll_window_state)


if __name__ == '__main__':
    root = Tk()
    root.withdraw()
    window = CustomWindow(root)

    def on_restore(event):
        print 'restore'

    def on_minimize(event):
        print 'minimize'

    window.bind('&lt;&lt;Restore&gt;&gt;', on_restore)
    window.bind('&lt;&lt;Minimize&gt;&gt;', on_minimize)

    root.mainloop()
</code></pre>

python linux tkinter