Ticket UUID: | ee3361a3ad36260b4eedbbf3fa920bf38b570c1 | |||
Title: | Document platform dependent behavior of iconify, withdraw, deiconify, raise, etc. | |||
Type: | RFE | Version: | 8.7 | |
Submitter: | marc_culler | Created on: | 2017-11-22 03:52:11 | |
Subsystem: | 65. Generic Window Operations | Assigned To: | nobody | |
Priority: | 3 Low | Severity: | Important | |
Status: | Open | Last Modified: | 2019-11-14 21:17:37 | |
Resolution: | None | Closed By: | nobody | |
Closed on: | ||||
Description: |
This seems like a fairly basic bug. If I run this on Ubuntu 16.04, the window .t does not reappear on the screen: $ wish8.7 % toplevel .t .t % wm iconify .t % wm deiconify .t On the other hand, if I run this, the window does reappear: $ wish8.7 % toplevel .t .t % wm withdraw .t % wm deiconify .t I am using Tk 8.7 from check-in [dca999e4]. | |||
User Comments: |
tombert added on 2019-11-14 21:17:37:
Please also follow these reports here: https://core.tcl-lang.org/tk/tktview/3131699cb421ec1de2b6fa08ff0835dd34eff3cb https://gitlab.gnome.org/GNOME/mutter/issues/589 For me it more looks like a bug. The developer at "mutter" confirms that the behaviour changed but the documentation lacks behind. bll added on 2017-11-30 15:34:59: I actually hate that type of behaviour (Only in Windows, if I have an open window in active focus, and am actively using it, will the window manager _not_ raise a window over my active window and not steal the focus), so I am all for it not working. Nevertheless, the behaviour should be consistent if possible. On linux, the work-around is: wm attributes . -topmost 1 update ; # probably wm attributes . -topmost 0 I am usually set to focus-follows-mouse everywhere, so I can't test focus changes of wish vs. other programs very easily. marc_culler added on 2017-11-30 13:36:02: The problem with the KDE behavior is that it means there is no way for an application to raise one toplevel to the top of the stack by using the 'raise' command. As a guess, that one use case accounts for 90% of the situations where one would want to 'raise' a toplevel. So I would consider that to be incorrect behavior, regardless of what the fine print in the manual may say. A partial workaround on KDE is that 'focus .a' does raise the toplevel '.a' to the top of the stacking order. However, what it does not do, oddly enough, is to give '.a' the focus. On KDE the following commands: toplevel .a wm geometry .a +100+100 toplevel .b wm geometry .b +120+120 focus .a produce 3 windows, with '.a' above '.b' but the focus belongs to the root. The same thing happens on Ubuntu Unity. If the last line is changed to 'raise .a' then '.b' will remain in front of '.a'. The behavior of Ubuntu Unity is arguably worse, because it is inconsistent. Using 'focus .a' has the same effect on both systems, but using 'raise .a' has different behaviors in Unity depending on how the commands are run. If you type the commands above into the wish console using 'raise .a' as the last line, the toplevel '.a' goes to the top. But when the same commands are run as a tcl script '.a' does not go to the top. On Windows and macOS, 'raise .a' moves '.a' to the top of the stacking order. Period. bll added on 2017-11-30 11:17:37: > "If the aboveThis argument is omitted then the command raises window > so that it is above all of its siblings in the stacking order" I believe this refers to the case of: raise .toplevel.frame1.widget will raise widget above all of its other siblings. So it is not incorrect, just not applicable to top-level windows. marc_culler added on 2017-11-30 05:56:24: When I mentioned the ambguity of the manual page I was actually referring to the manual page on my Ubuntu 16.04 system. The manual page in the core-8-6-branch has addressed this issue, and says that a toplevel may be reordered with respect to all toplevels. It also says that window managers may not "strictly" honor requests to restack. So maybe that lets KDE off the hook. Nevertheless, the behavior does vary a lot from one window manager to the next. marc_culler added on 2017-11-30 05:46:43: Continuing the catalog of anomalies with the raise command, on KDE if you create two toplevels '.a' and '.b' with '.b' higher in the stacking order than '.a', the command %raise .a has no effect whatsoever. However, the command %raise .a .b will raise '.a' above '.b'. This does not conform with the manual page, which says: "If the aboveThis argument is omitted then the command raises window so that it is above all of its siblings in the stacking order" Note also that this quote from the manual page is ambiguous. It does not say whether window should be raised above windows that are not siblings. In the case above, should 'raise .a' raise '.a' above '.'? On Windows, macOS and Ubuntu Unity that command raises '.a' above all on-screen windows, regardless of whether they are siblings. bll added on 2017-11-28 21:27:59: Looks like XFCE is more like Windows. De-iconifying a window always puts it on top. This area seems to be highly wm dependent. marc_culler added on 2017-11-28 20:53:14: OK, I installed kubuntu17.10 on a VM. With KDE, the wm remembers the position of a window in the stacking order when it is iconified. The raise command works to change the position of an iconified window, and raising a window above an iconified window places it in the same position that it would have if the target had not been iconified. That is, the window manager maintains a stacking order for all normal or iconified windows as one group and raise has the expected effect on any window in the group. If a raise operation involves a withdrawn window it is ignored. Deiconifying a withdrawn window puts it on top. There is no special case for the root window. A window does not automatically get focus by being deiconified. marc_culler added on 2017-11-28 18:07:07: On Windows when a window is deiconified it goes to the top of the stacking order no matter what. Its position in the order when it was iconified does not affect this, and neither do any raise operations applied to the window while it was iconified. So effectively the raise command is completely ignored when applied to a window which is iconified. When a normal window is raised above an iconified window it goes to the *bottom* of the stacking order, as if all inconified windows are below all normal windows. Similarly, raising a normal toplevel above a withdrawn window moves it to the bottom of the stacking order. However, the root window behaves differently from other toplevels with respect to withdrawn windows. Raising the root window above an iconified window moves it to the bottom, but raising the root window above a withdrawn window has no effect. I think it would be a simple matter to implement the same behavior on the Macintosh. But the behavior seems a bit quirky, because it is exceptional for the root window. So this brings up the question of whether linux window managers also behave this way. (I can't easily test that at the moment because all my linux systems have the bug.) bll added on 2017-11-28 15:55:57: Just for comparison purposes, here is KDE: % wm iconify . % wm state . iconic % raise . % wm state . iconic % wm deiconify . % wm state . normal bll added on 2017-11-28 15:43:34: As cinnamon is based on gnome-shell and has the bug, I don't think what it does can be trusted. % wm iconify . % wm state . normal # wrong % raise . % wm state . normal % I would be inclined to think that Windows and Linux are processing the raise command correctly. 'raise' should not change the window state. marc_culler added on 2017-11-28 15:17:35: Apropos of the cinnamon behavior and the title of this ticket, the manual does not say what should happen when an iconified window is raised. Ticket [164c1b1091] points out that the Aqua port deiconifies the window, while Windows and some unspecified linux window managers do not deiconify it. I am curious what happens on cinnamon. Also, I think it would be nice if the manual were to specify a correct behavior in this case. bll added on 2017-11-28 13:42:44: Also: https://bugs.launchpad.net/unity/+bug/998073 bll added on 2017-11-28 13:16:35: Also tested with: 8.6.5 - fail - linux mint 18.2 - cinnamon Interesting that with cinnamon, you can do wm deiconify . raise . as a work-around (the iconify is still slow), but in Unity, the raise does not help. Should text be added to the release notes? Such as: Due to a bug in gnome-shell and its variants (cinnamon, unity, etc.), ( https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1502370 ) 'wm iconify/wm deiconify' will not work properly, and the state of the window is not properly updated when the window is minimized. The only work around that can be suggested at this time is to use any window manager that is not based on gnome-shell (e.g. kde, mate, fvwm, xfce, etc.). kevin_walzer added on 2017-11-25 18:56:15: Ah, so you mean add an entry to the Dock menu and the native Window menu (rather than its own icon per se). I can follow that line of thinking. Ensuring it does not appear in the Window menu just means some manual addition and deletion depending on the window state and that should not be too hard to implement. I am not certain how to access the Dock menu from Tk, but Cocoa does provide some hooks. At what point should we look at implementing this? marc_culler added on 2017-11-25 15:11:26: Incidentally, Tk for Windows behaves exactly as I was suggesting. Windows creates an icon in the task bar for each running application. When you hover the mouse over that icon a list of windows pops up. Clicking on an item in that list causes a normal window to be minimized or a minimized window to be displayed. With Windows Tk when you iconify a window it appears in the window list. When you withdraw a window it does not appear in the window list and there is no user action that will redisplay it on the screen. When you deiconify either an iconified window or a withdrawn window it reappears on the screen. marc_culler added on 2017-11-25 14:43:46: I should have added, that currently withdraw does not completely hide the window. It does not create an icon for the window in the dock but it does add the window to the Window menu. That tells the user that the window exists and allows the window to be mapped to the screen. The change in behavior that I am advocating is simply to NOT put withdrawn windows into the Window menu. marc_culler added on 2017-11-25 14:29:47: Kevin, I think you are misinterpreting what I said. I was not referring to the *application* icon. I was referring to an icon for a minimized *window*. Currently when you iconify a window in macOS a new icon is created in the dock in addition to the application icon. This is exactly the same thing that happens when a window is minimized by clicking the yellow button in the title bar. In fact what Tk does to iconify a window is to call [NSWindow miniaturize]. And I think this is the correct behavior for iconify. I think withdraw should be used for a different purpose. There are many cases where an application needs to be able to open many windows, say with each one presenting a "document" of some sort, but has no need for a special "root" window. On other platforms this leads to things like spash windows whose only purpose is to indicate that the application is active. This is unnecessary on the mac because the menu bar indicates that the application is active even when it has no windows on the screen. If you are writing such an app with Tk you want to hide the root window from the user completely. There is no point in allowing the user to open up a blank 200x200 window. You don't want the root window to be minimized. You want it to be invisible and inaccessible. This is what withdraw should do for you. kevin_walzer added on 2017-11-25 13:46:22: I don't agree that a macOS app with a withdrawn window should have its Dock icon disappear. It's standard macOS behavior for a running application to display a Dock icon, even if no windows are visible, unless it is specifically designated as a background/faceless app via a flag in its Info.plist file. In fact, I'd suggest that the macOS behavior of these commands is correct in the context of the platform. wm_iconify minimizes the window, and wm_withdraw hides it. That's how other Mac apps behave. That may result in some inconsistency with other platforms that Tk runs on, but that's OK. There are other contexts where a native implementation may differ subtly from documented functionality; these differences should be noted, but not removed. marc_culler added on 2017-11-25 13:00:21: Thanks for the extensive testing! If I ran the zoo, I think I would say that the correct behavior for withdraw would be to remove the window from the screen, show no indicators that the window exists and provide no means for the user to redisplay it with any input actions. Only calling deiconify should redisplay it. On the other hand, the correct behavior for iconify should be to remove it from the screen, provide visual indication that the window exists and provide some way for the user to redisplay it. It should also be redisplayable with iconify. The macOS behavior would be wrong, according to this. A withdrawn window should have no dock icon and should not be listed in the Apple Window menu. An iconified window should have both a dock icon and a listing in the Window menu, either of which can be used to redisplay it. The Unity and gnome-3 behavior would also be wrong, since iconify does not work to redisplay a window which has been iconified. bll added on 2017-11-25 00:55:22: This is relevant: https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1502370 If multiple people report on it, the bug may gain some traction. (and would someone fix the login problem with this *&#$& ticket system). bll added on 2017-11-25 00:14:16: This may be relevant: https://stackoverflow.com/questions/30192347/how-to-restore-a-window-with-xlib I wonder how to test to see if gnome-shell is active. This bug is going to be really annoying. And the long timeout to execute a 'wm iconify' will be a problem. bll added on 2017-11-24 23:53:40: My comment (a) is no good. 'wm iconify' on XFCE allows the icon/window to be displayed in the window list. 'wm withdraw' does not display the icon/window in the window list. There are probably a dozen different window list variants across the different window managers, but I assume that they will all more or less work the same way. So this is the same action as on Mac OS X. bll added on 2017-11-24 23:20:12: The gnome-3 based window managers have the bug. Work around: Use a window manager that is not based on gnome-3. a) Is there any particular reason to keep the old 'wm iconify' code for unix systems? The old style of putting icons on to the desktop is long gone. As Marc suggests, the unix systems can simply process the request in the same manner as 'wm withdraw'. As this bug is present in the default window manager for Ubuntu LTS systems and the default window manager in Red Hat based systems, it may be worthwhile getting this change into 8.6.8. b) In the time being, the documentation can be updated to reflect that 'wm withdraw' is the preferred method for unix systems, and note the differences between 'wm iconify' and 'wm withdraw' on Mac OS X. 8.6.7 - ok - MX 17.1 - xfce 8.6.1 - ok - Ubuntu 15.02 - mate 8.6.5 - fail - Ubuntu 16.04.2 - unity 8.6.5 - fail - Ubuntu 16.04.3 - unity 8.6.5 - ok - Ubuntu 16.04.3 - mate 8.6.5 - ok - Ubuntu 16.04.3 - xfce 8.6.6 - fail - Ubuntu 16.10 - unity 8.6.1 - ok - Linux Mint 17 - mate 8.6.5 - ok - Linux Mint 18.2 - kde 8.6.2 - ok - Debian 8.8 - mate 8.6.6 - ok - Ubuntu 17.04 - kde 8.6.6 - ok - Ubuntu 17.04 - mate 8.6.6 - fail - Ubuntu 17.04 - gnome 3 8.6.7 - ok - Manjaro 17 - xfce 8.5.13 - fail - CentOS 7 - gnome 3 8.6.6 - fail - Fedora 25 - gnome 3 bll added on 2017-11-24 20:36:54: Note that this is Linux version dependent and is very possibly a window manager bug. Unfortunately, Ubuntu 16.04 is a LTS version (now at 16.04.3). MX Linux (Debian Jessie) w/XFCE: no issues. I'll see if I can make a chart. marc_culler added on 2017-11-22 13:28:56: The man page is clear enough: "Arrange for window to be displayed in normal (non-iconified) form." But that is not what happens on Ubuntu. The claim in that thread is that this is an Ubuntu bug. But the fact that deiconify does work correctly for a withdrawn window means that it would be possible for Tk to create the correct behavior on Ubuntu. Evidently it doesn't create the correct behavior because the Tk code handles the process of deiconifying an iconified window differently from how it handles deiconifying a withdrawn window. Presumably this difference is based on some unspecified abstract model of how a window manager should behave. It is not so clear to me that Ubuntu's failure to adhere to that model represents a bug in Ubuntu's window manager. In fact, I suspect that the percentage of window managers which do fit that model is pretty small these days. For example, the manual says that withdraw makes the window "forgotten about by the window manager". But that is not what happens on the aqua platform. There the difference between iconify and withdraw is that iconify puts an icon on the dock while withdraw doesn't. But both of them leave the window in the Window menu, which can be used to redisplay the window on the screen. So the window is not "forgotten". A concrete suggestion would be for the manual to say that the behaviors of iconify, withdraw, deiconify, raise (see ticket 164c1b1091) and lower are heavily dependent on the window manager, and to provide or refer to a table showing what the behaviors are (or should be) for the most common window managers, e.g. gnome, kde, ubuntu, Windows, macOS. Currently the manual discusses separately what happens with Windows, suggesting that there are only two behaviors: Windows and everything else. This is misleading. The bottom line is that people who are maintaining applications that are intended to run on many platforms need to know what behavior to expect on each platform that they support. They shouldn't have to run experiments on each one. And when they find unexpected behaviors they should be able to determine whether they are seeing a bug. Of course one expects such an application to have some platform-dependent code that can compensate for different behaviors. This is problematic, though, when the code needs to know not only which platform it is running on but also which of many possible window managers it is using on that platform. In my case, where the application is written in Python and uses Tk via the tkinter module, I do not know how get that information. Perhaps it is possible though. fvogel added on 2017-11-22 04:56:21: Isn't this invalid? See this recent thread in comp.lang.tcl Perhaps the man page is not clear enough since this comes back from time to time. Suggestions welcome. |