When the display mode changes such that the screen height changes, we'd like
our windows to keep their position relative to the top-left of the primary
screen. That's how WinAPI's coordinate system works and we want the WinAPI
position of the window to not change just because the display mode changed.
Unfortunately that's not achievable in Cocoa. Cocoa keeps the window
stationary relative to the screen it's on, not necessarily the primary screen,
and it's sometimes relative to the bottom-left and sometimes the top-left of
that screen.
So, what we do instead is queue an event to get the back end to reassert the
WinAPI position of the window. This is queued before Cocoa can adjust the
Cocoa position of the window which would queue a WINDOW_FRAME_CHANGED to the
back end and mess up the WinAPI position. The back end's reassertion of the
WinAPI position won't be processed by the Cocoa thread until after Cocoa has
adjusted the position and will thus override it. It will also discard any
wrong WINDOW_FRAME_CHANGED that may have been queued.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
OS X doesn't have the same concept of maximized windows as Windows does.
There's no mode that prevents a normally-resizable window from being resized.
If a window is "zoomed", it mostly fills the screen but the user can still
move or resize it, at which point it ceases to be in the zoomed state. So,
users are confused and frustrated when they can't resize a window that's
maximized.
To get similar behavior while still respecting Win32 semantics, we now let the
user try to resize maximized windows. (The resize cursors are shown at the
edges of the window frame.) When they start, a request is submitted to the app
to restore the window. Unless and until the window is restored, we don't
actually allow the window to change its size.
The user expects to resize the window from its current (maximized) position.
It should not jump to its normal position upon being restored. So, we set the
window's normal position to its current position before restoring it.
For some empty RECTs, such as { INT_MAX, INT_MAX, INT_MIN, INT_MIN }, right
minus left or bottom minus top underflow and wrap around to positive values.
The user is prevented from moving or resizing a maximized window. The zoom
button is still present and enabled for a maximized window but requests that
it be restored rather than simply resizing it, which is what it does for
normal windows.
If a window is not resizable (lacks WS_THICKFRAME) but has a maximize box
(WS_MAXIMIZEBOX), then the zoom button requests that it be maximized rather
than resizing it.
This simulates some of what would happen if user32 were managing the drag. The
click in the caption would cause WM_SYSCOMMAND/SC_MOVE. The processing of that
message is synchronous and doesn't return until the move is complete.
Some games require that "blocking" in the internal event loop to prevent them
from misbehaving during the drag.
Queries can be run out of order because the main thread is waiting on the
response. The main thread didn't really need a response from QUERY_RESIZE_END.
It was only a query for symmetry with QUERY_RESIZE_START.
This improves the animation of the window unminimizing from the Dock in some
cases. The window would often be blank or, for shaped windows, invisible
during that animation.