Some programs minimize windows which are outside of the desktop. The Mac
driver had been leaving such windows ordered out, which prevented them from
minimizing and appearing on the Dock. That, in turn, made it difficult for
the user to restore them.
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.
The Mac driver was already sending these events when the user resizes the
window by dragging its corner/edges, but there are other occasions when the
window frame changes. For example, when the user zooms the window.
The tracking of whether it is over a window or not is only updated when the
mouse moves. If a window was created or moved under it, then the state can be
stale. That caused us to defer hiding the cursor until the mouse was moved.
This happens at the start of games pretty often.
The main dispatch queue is a serial queue and is a shared resource. If we
submit a long-running task to it, then no other tasks, including those submitted
by the system frameworks, can run until it completes.
The standard keyboard shortcut for switching the keyboard layout is Command-
Space, but the Mac driver never sees the Space key press. So, Wine only sees
a press and release of Alt, which puts focus on the menu bar. This prevents
that focus change.
The code had previously set the cursor back to the standard arrow and unhid
it when it left all app windows. Now it restores the cursor image that the
app set and re-hides it if necessary when it moves back over any app window.
Some events get queued for all GUI-connected threads but are only processed
by the first to dequeue them. Other threads which tend their event queue
discard such already-processed events. However, some threads may be
connected to the GUI but never tend their event queue. To prevent such
threads from accumulating zombie events, the zombies are cleared each time a
new event is queued.
This fixes a problem where windows could spontaneously re-minimize after
being unminimized. Cocoa would see the window unminimize. It would queue
a WINDOW_DID_UNMINIMIZE event. While that event was pending, Wine might do
something which caused set_cocoa_window_properties() to be called and tell
Cocoa to conform itself to the current Win32 state. The current Win32 state
still had the window minimized, so Cocoa would re-minimize the window. It
would even discard the WINDOW_DID_UNMINIMIZE event.
Cocoa would automatically do this for a normal app. However, the Mac driver
makes all of its windows inherit from NSPanel and Cocoa ignores panels for
this feature.
They show up in the taskbar on Windows 7. Selecting them from there is
meaningful and useful, as is selecting them from the Window menu.
In addition to just switching among windows from that menu, this is also
important to recovering a minimized window if the user has configured their
system preferences to minimize windows into the process's dock icon (rather
than as separate dock icons).
The Mac driver captures the displays when the program changes the display
mode. If the user types Command-Tab to switch away, it resets the displays
to their original modes and releases them. However, if they switched back,
it didn't restore the mode to what the program had set, so the program often
showed the game window in a corner of the screen with the top behind the Mac
menu bar.
Cocoa won't order a minimized window out of the screen list using -orderOut:.
This leaves a window that should be hidden still visible in the Dock, where
it can be unminimized.
That event can confuse things if the program switches focus from A to B and
then back to A and then processes events. It will get an event saying that
A lost focus in Cocoa, check that A does indeed have current focus in Wine,
and so switch focus away from it (to the desktop window). (It then gets an
event that B lost focus, but that does nothing at that point.)
This matches what Cocoa does when determining how to handle an event so that,
for example, our test if a click is in the window grow box corresponds to
whether Cocoa will run an internal mouse-tracking loop to resize the window
when we pass it the event. This fixes a problem where both Cocoa and user32
would try to run a resize loop and the cursor would get "stuck" resizing the
window after the button was released.