So, me and Mike have been discussing some ideas for window management in Wine. Currently it hasn't turned into code, but I thought I'd write up what our thoughts were so others could comment and maybe be inspired to write patches.
The problem:
Currently Wine decides whether to make a window managed or not based on a series of heuristics, in is_window_toplevel in dlls/x11drv/window.c
Unfortunately these heuristics are frequently wrong, as they have only limited information to work with (window styles, mostly). In CrossOver, is_window_toplevel is easily the most hacked function in the entire codebase. This manifests itself in a variety of ways:
* Windows are marked unmanaged when they shouldn't be. For instance, see WinAmp, Trillian, the Counter-Strike CD Key screen etc: there are tons of examples of this problem. This at best means the window is "nailed" to the screen, at worst it makes the program unusable.
* The classic "my game starts but I can't type" problem where keyboard input goes to the terminal instead of the window, due to the lack of focus management in unmanaged windows.
* Some programs display splash screens and then pop up errors or question dialogs underneath them. Unmanaged windows are always-on-top -> you cannot get to the underlying managed window and the app appears to hang.
* Fullscreen windows are really hard to do properly because they must be managed to work correctly in KDE/GNOME.
We currently make certain windows unmanaged typically because we need to control their position or rendering with a high degree of accuracy. Unfortunately some X window managers ignore positioning hints, even when we ask them not to. There is no way to make things like menus and tooltips work correctly with these WMs, so we take the window out of the usual window management mechanism entirely.
Unfortunately due to the design of the win32 API there is no simple way to tell the difference between a large menu and the Trillian main window. We could mark our own menus specially to make them unmanaged and have everything else be managed, but we then run into problems with programs that draw their own menus and tooltips, of which there are a truly shocking number.
So what is a possible solution?
Well, one way forward is to implement another mode, in which Wine makes all windows managed and uses a variety of WM hints to get the desired behaviour. For instance, the PPosition flag asks the WM to place the window where the application requests it to. Some WMs respect this, others do not, in yet others it's a toggleable option. For people with WMs that meet the requirements of Wine all windows could be made managed, and for people that don't use such WMs the old way can still be used.
IIRC it's possible to ask the WM for identification which means this setting could be largely autodetected by having blacklists of WMs to use the old mode for (or vice-versa).
Unfortunately there's no way to know how well this approach would work, or even if it would work at all, short of trying it.
thanks -mike
On Tue, 6 Apr 2004, Mike Hearn wrote:
Well, one way forward is to implement another mode, in which Wine makes all windows managed and uses a variety of WM hints to get the desired behaviour. For instance, the PPosition flag asks the WM to place the window where the application requests it to. Some WMs respect this, others do not, in yet others it's a toggleable option. For people with WMs that meet the requirements of Wine all windows could be made managed, and for people that don't use such WMs the old way can still be used.
I personally think we should not care about non-compliant WMs. You use one of those, you suffer the consequences. We can't operate in a vacuum, there are standards, and we must be able to rely on something.
But this, I'm afraid, besides the point. This entire discussion assumes that the Win32 windows are mapped to X windows. If IIRC, Alexandre was saying that we need to switch back to the old ways, where we handle most of the windowing code. In which case I guess a lot of this will go away.
On Tue, 06 Apr 2004 11:25:13 -0400, Dimitrie O. Paun wrote:
But this, I'm afraid, besides the point. This entire discussion assumes that the Win32 windows are mapped to X windows. If IIRC, Alexandre was saying that we need to switch back to the old ways, where we handle most of the windowing code. In which case I guess a lot of this will go away.
I should have clarified things a bit: as far as I know the WM rewrite is about using X windows only for toplevel win32 windows, and not using X child windows for win32 child windows. The managed/unmanaged thing is only relevant to toplevel windows. So I think they are separate though it'd be nice for Alexandre to clarify exactly what the WM rewrite will affect and entail.
thanks -mike
Mike Hearn mh@codeweavers.com writes:
I should have clarified things a bit: as far as I know the WM rewrite is about using X windows only for toplevel win32 windows, and not using X child windows for win32 child windows. The managed/unmanaged thing is only relevant to toplevel windows. So I think they are separate though it'd be nice for Alexandre to clarify exactly what the WM rewrite will affect and entail.
Well, it's not really a rewrite, more the continuation of the address space separation work, to make all of the window management instead of just half of it behave properly across processes.
The managed/unmanaged thing is really a different issue, but the inter-process stuff will change a lot of things in x11drv, that hopefully will then make it easier to deal with the managed stuff (for instance by making it easier to recreate a window on the fly to switch to managed mode); so that's why I think the inter-process support should be finished before we start making big changes in the X11 WM support.
On Tue, 06 Apr 2004 11:25:13 -0400, Dimitrie O. Paun wrote:
But this, I'm afraid, besides the point. This entire discussion assumes that the Win32 windows are mapped to X windows. If IIRC, Alexandre was saying that we need to switch back to the old ways, where we handle most of the windowing code. In which case I guess a lot of this will go away.
I should have clarified things a bit: as far as I know the WM rewrite is about using X windows only for toplevel win32 windows, and not using X child windows for win32 child windows. The managed/unmanaged thing is only relevant to toplevel windows. So I think they are separate though it'd be nice for Alexandre to clarify exactly what the WM rewrite will affect and entail.
please keep in mind that for win32 plugin support (VST, DX etc), we need to be able to reparent the HWND provided to the plugin for its "editor". don't know if this has any relevance to this discussion. right now, we fetch the __wine_x11_whole_window atom using GetProp, and then use that in a call to XReparentWindow.
--p
Mike Hearn wrote:
So, me and Mike have been discussing some ideas for window management in Wine. Currently it hasn't turned into code, but I thought I'd write up what our thoughts were so others could comment and maybe be inspired to write patches.
<snip>
IIRC it's possible to ask the WM for identification which means this setting could be largely autodetected by having blacklists of WMs to use the old mode for (or vice-versa).
Do you have any list of WM that would likely be put on such a "WM blacklist"? Maybe that makes it easier to decide what to do. For example if either Gnome, KDE, XFCE or blackbox would be on that list it might be better to ask the WM projects first to fix it before going this route?
On the other hand, if you are sure it would work better on WMs that support it, then why not?
Henk Poley <><
On Tue, 06 Apr 2004 18:47:07 +0200, Henk Poley wrote:
Do you have any list of WM that would likely be put on such a "WM blacklist"? Maybe that makes it easier to decide what to do. For example if either Gnome, KDE, XFCE or blackbox would be on that list it might be better to ask the WM projects first to fix it before going this route?
No, we would have to figure this out by trial and error. It's made harder by the fact that in some WMs it's configurable!
Possibly a startup check might work better but our startup time is already bad enough....