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 11drv
:X11DRV_ConfigureNotify win 0x10024 new X rect 0,25,640x512
> (event 0,0,640x512)
> trace:win:GetWindowRect hwnd 0x10024 (0,0)-(640,512)
> trace 11drv
: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 11drv
:X11DRV_SetWindowPos hwnd 0x10024, after (nil), swp 0,25
> 640x512 flags 00000015
> trace 11drv
:SWP_DoWinPosChanging hwnd 0x10024, after (nil), swp 0,25
> 640x512 flags 00001815
> trace 11drv
:SWP_DoWinPosChanging current (0,0)-(640,512) style 80000000
> new (0,25)-(640,537)
> trace 11drv
: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 11drv
:X11DRV_SetWindowPos status flags = 0805
> trace:event:process_events ConfigureNotify for
hwnd/window 0x10024/2000001
> trace 11drv
: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 11drv
: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 11drv
: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 11drv
: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 11drv
: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
_______________________________________________
metacity-devel-list mailing list
metacity-devel-list gnome.org
http://mail.gnome.org/mailman/listinfo/metacity-devel-
list
|