Re: wine's fullscreen code has no effect on metacity
- From: Havoc Pennington <hp redhat com>
- To: Dmitry Timoshkov <dmitry codeweavers com>
- Cc: Vincent Povirk <madewokherd+d41d gmail com>, wine-devel winehq org, metacity-devel-list gnome org
- Subject: Re: wine's fullscreen code has no effect on metacity
- Date: Thu, 13 Jul 2006 10:28:13 -0400
Dmitry Timoshkov wrote:
At this point WM decides to correct position of an invisible application's
window (why?)
In the metacity log, this is in the proper order (the window is mapped,
metacity sets its position, and the window is withdrawn). I would
conclude that this is a race; remember that if the app calls map, unmap
then some events that occurred prior to the unmap request can still
arrive after the unmap request. This is the asynchronicity I was talking
about.
to shift it below the top GNOME top panel by 25 pixels (btw,
that's why I wrongly thought that the top GNOME top panel remained above
in Z order of the main game's window, actually they do not overlap each
other).
Metacity does this with all windows (keeps them below the panel) unless
there's some reason not to (such as fullscreen); it's a longstanding UI
decision.
For some reason WM does this in a very inefficient way in multiple steps:
trace:event:process_events ConfigureNotify for hwnd/window 0x10024/2000001
trace:x11drv:X11DRV_ConfigureNotify win 0x10024 new X rect 0,25,640x512
(event 0,0,640x512)
trace:win:GetWindowRect hwnd 0x10024 (0,0)-(640,512)
trace:x11drv:X11DRV_ConfigureNotify 0x10024 moving from (0,0) to (0,25)
trace:win:SetWindowPos hwnd 0x10024, after (nil), 0,25 (640x512), flags
00000015
trace:win:dump_winpos_flags flags: SWP_NOSIZE SWP_NOZORDER SWP_NOACTIVATE
trace:x11drv:X11DRV_SetWindowPos hwnd 0x10024, after (nil), swp 0,25
640x512 flags 00000015
trace:x11drv:SWP_DoWinPosChanging hwnd 0x10024, after (nil), swp 0,25
640x512 flags 00001815
trace:x11drv:SWP_DoWinPosChanging current (0,0)-(640,512) style 80000000
new (0,25)-(640,537)
trace:x11drv:X11DRV_set_window_pos win 0x10024 window (0,25)-(640,537)
client (0,25)-(640,537) style 80000000
trace:win:RedrawWindow 0x10024 whole window flags: RDW_ERASE
RDW_ERASENOW RDW_FRAME
trace:x11drv:X11DRV_SetWindowPos status flags = 0805
trace:event:process_events ConfigureNotify for hwnd/window 0x10024/2000001
trace:x11drv:X11DRV_ConfigureNotify win 0x10024 new X rect 0,25,640x512
(event 0,25,640x512)
trace:win:GetWindowRect hwnd 0x10024 (0,25)-(640,537)
trace:event:process_events ConfigureNotify for hwnd/window 0x10024/2000001
trace:x11drv:X11DRV_ConfigureNotify win 0x10024 new X rect 0,25,640x512
(event 0,25,640x512)
trace:win:GetWindowRect hwnd 0x10024 (0,25)-(640,537)
trace:event:process_events ConfigureNotify for hwnd/window 0x10024/2000001
trace:x11drv:X11DRV_ConfigureNotify win 0x10024 new X rect 0,25,640x512
(event 0,25,640x512)
trace:win:GetWindowRect hwnd 0x10024 (0,25)-(640,537)
trace:event:process_events ConfigureNotify for hwnd/window 0x10024/2000001
trace:x11drv:X11DRV_ConfigureNotify win 0x10024 new X rect 0,25,640x512
(event 0,25,640x512)
trace:win:GetWindowRect hwnd 0x10024 (0,25)-(640,537)
trace:event:process_events MapNotify for hwnd/window 0x10024/2000001
Last line above confuses a lot: why WM behind our back maps a window?
What may
be a reason behind that?
From the metacity log, it looks to me like WINE here withdraws the
window, turns on window decorations, then remaps the window.
Metacity then has to unmap/map one more time in order to place the
window inside its window frame. Undecorated windows don't have a frame
so don't have the extra unmap/map caused by reparenting, but normal
windows do.
Clients and WMs both have to distinguish between maps that are
incidental to implementation details and maps that have a meaning in the
ICCCM. Essentially you need a "withdrawn" flag on windows indicating
whether you have yourself mapped or unmapped the window. The WM may also
map/unmap in order to reparent, manage workspaces, etc. and you should
just ignore those map events most of the time.
If you need a "steady state" mapped status that matches the Windows API,
then you would need to "simulate" it on the client side, by e.g. using
the client-side withdrawn flag instead of the mapped state.
That leads to a lot of confusion later: Wine
thinks
that a window is not visible and ignores take focus client message below,
while WM starts to send focus messages to the window:
trace:event:process_events Expose for hwnd/window 0x10024/2000001
trace:x11drv:X11DRV_Expose win 0x10024 (2000001) 0,0 640x512
trace:win:RedrawWindow 0x10024 rect (0,0)-(640,512) flags:
RDW_INVALIDATE RDW_ERASE RDW_ALLCHILDREN
trace:event:process_events FocusIn for hwnd/window 0x10024/2000001
trace:event:EVENT_FocusIn win 0x10024 xwin 2000001 detail=NotifyNonlinear
X will not send focus events to unmapped windows btw, if it's useful to
rely on that behavior.
The log above makes me ask several questions:
1. Why the WM thinks that it knows better than the app where to place
its window
and insists on moving it to another position? That's not a user related
interaction
related to moving a window using mouse or a keyboard, IMO the WM should
not do
this kind of things behind applications back.
As I mentioned before, there is no way to tell in the WM what is
user-initiated and what isn't, so any policies on window positioning
have to be for all configure requests (though the WM can and does adjust
the policy for window type, etc.).
metacity keeps windows from overlapping the panel because most of the
time that results in a better UI; this isn't anything new, it's been in
GNOME for years.
Plenty of just normal document editor or dialog type windows try to open
at 0,0 (which in GNOME would cover up the applications launcher menu) so
metacity keeps them underneath that. It'd be pretty annoying to use
GNOME otherwise.
A philosophical problem here is that you're trying to be a managed
window and trying to do everything yourself at the same time. This can
be done, but tends to be the hard path; the easy paths are to just be
override redirect (though I consider that broken, it may be required to
make wine work) or to just let the WM do everything (e.g. set the
fullscreen state and don't do your own resizing, undecorating, and so
forth that might confuse matters).
Some ideas:
- if setting the vid mode viewport presumably you will also end
up needing to grab the pointer... in this case there's
little downside to using override redirect since no "window
management" is possible anyhow
- figure out how to get the fullscreen state set... unfortunately
metacity doesn't understand vid modes, which will make this
not really work right
- patch metacity to understand vid modes (are there "vid mode events"?)
- could you put the vid mode viewport in a different place, e.g.
in the middle of the screen, then offset all Windows positions
requests to the viewport? (too much of a hack? would it work?)
2. How that could happen that the WM maps a window to the screen
although it
clearly was not asked to?
If your window is withdrawn, it would be a bad bug for the WM to map it;
but in the metacity log I see no evidence of this happening. However, if
your window is currently in the normal/managed state, the WM _must_
unmap/map from time to time in order to work; WMs work in different ways
but e.g. creating the frame by ReparentWindow to the frame window is
pretty standard and causes unmap/map events. Metacity also implements
multiple workspaces and minimization by unmapping, it's a bit unusual to
do workspaces this way, but many or even most WMs do minimization this way.
Havoc
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]