0

Let's say that I want to iconify a tkinter window. I would use something like this:

from time import perf_counter
import tkinter as tk

def time(function, *args, **kwargs):
    start = perf_counter()
    function(*args, **kwargs)
    return perf_counter() - start

root = tk.Tk()
root.update() # Make sure that the window appears on the screen
print(time(root.iconify)) # 2.0016179770000235

The problem is that it always takes a bit more than 2 seconds for the .iconify() to run. Why is that? I looked at tkinter's source code:

def wm_iconify(self):
    """Display widget as icon."""
    return self.tk.call('wm', 'iconify', self._w)

iconify = wm_iconify

and it directly calls _tkinter with the parameters. I tried reading _tkinter's source code (here) but I can't find a trace for where the 2 seconds are going. My guess is that the problem is somewhere bellow _tkinter.

Edit: This issue only effects Python 3.8.6 + Ubuntu 20.10 but doesn't appear on Python 3.7.9 + Window 10.

TheLizzard
  • 7,248
  • 2
  • 11
  • 31
  • somethings wrong with the way you are calculating the time. Check this code https://dpaste.com/9HK339MHD Also take a look at https://stackoverflow.com/questions/25785243/understanding-time-perf-counter-and-time-process-time – Nouman Apr 17 '21 at 00:08
  • @BlackThunder It was suggested to me when I has [this](https://stackoverflow.com/questions/66286367/why-is-my-function-faster-than-pythons-print-function-in-idle) question. `perf_counter` is supposed to be more accurate and it works. Also I forgot to mention that the issue doesn't appear on Windows 10 but it does on Ubuntu 20.10 – TheLizzard Apr 17 '21 at 08:44

1 Answers1

2

At the very bottom (there's other bits in between, many of them, but they're all really fast) of Tk's implementation on Unix X11 is this, reproduced here for your convenience:

if (XIconifyWindow(winPtr->display, wmPtr->wrapperPtr->window,
        winPtr->screenNum) == 0) {
    return 0;
}
WaitForMapNotify(winPtr, 0);

(The WaitForMapNotify is complex, but does what it says on the tin: waiting for a MapNotify event from X11.)

It sends a request to iconify and then waits for the Window manager to respond. For some reason, Ubuntu is taking a very long time (2 seconds!) to send that message. I'd describe that as a bug in Ubuntu… unless for some reason you've got some fancy animations enabled and the Window Manager is only finalizing the state change after performing them.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • Thanks. This is were the 2 seconds are going. Btw I have the default setting on my Ubuntu. – TheLizzard Apr 19 '21 at 08:42
  • What would happen is `WaitForMapNotify(winPtr, 0)` was removed? That call doesn't look important. – TheLizzard Apr 19 '21 at 08:55
  • @TheLizzard Without that, there'll be state inconsistencies. I truly don't know what the consequences of those inconsistencies will be. (The code in question dates from very early in Tk, before the start of our SCM records — things got lost somewhere around 1999.) – Donal Fellows Apr 20 '21 at 08:15
  • Wow the code is very old. Thanks for the help. – TheLizzard Apr 20 '21 at 08:31