At least one Mac app, TextWrangler, puts UTF-16 data on the pasteboard with
lines separated by CR (although it uses LF for the UTF-8 form of the same text).
Other Mac apps handle it properly; we should, too.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
We had been posting it when exiting fullscreen mode ended. However, certain
events during exiting could provoke the back-end to assert the window frame as
it knows it, which would be the one from full-screen mode. This would be
handled by the Cocoa thread after exiting full-screen mode. So, the window
would animate to its pre-fullscreen frame and then spontaneously go back to
covering the screen. This would be Windows-style fullscreen rather than
Cocoa-style and there'd be no obvious way to get out.
The problem occurs on macOS 10.12 (Sierra) due to a change in what methods it
calls on the window while exiting fullscreen.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
When a window is shown, it may not have drawn its content into the backing
surface, yet. Cocoa will draw the window, starting with its standard light
gray background and then the content view. However, the content view won't
have anything to draw, yet, though, so the window background is not drawn over.
A short while later, usually, the app will paint its content into the window
backing surface and Cocoa will be told to redraw the window. This works, but
the user can often see the flash of the window background color first. This
is especially visible for windows with dark content.
Part of the fix is to set the window background to transparent until the
content view has actually drawn once since the window was shown.
That's not sufficient on its own, though. We had disabled Cocoa's automatic
display mechanism for windows and put display on a display-link timer. This
meant that the window was not actually cleared to its transparent color. When
the window was shown, the Window Server displayed a white backing buffer. It
is the app process which should fill that backing buffer with clear color but,
because we had disabled auto-display, that wasn't getting done at the same
time the window was displayed. It was happening some time after. Again, the
result was a visible flicker of white.
So, we now temporarily re-enable auto-display just before showing a window.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This works around a Cocoa bug that causes an exception and hang if the view is
being re-ordered within its current superview (as opposed to being moved to a
new superview).
This reverts commit 9fbc364ea1 but adds some
conditions around the call to avoid the flicker on platforms where it's
unnecessary.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This avoids a Cocoa bug where, if an app in the background which is not
hidden calls -unhide:, its main menu bar window is brought forward. The
active app hasn't actually been changed. Key events continue to go to
the app in the foreground. But it's confusing to the user when they
look at the menu bar and, if they click in the menu bar, the background
app really will be activated.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Apple added the same enum declaration to their headers, causing a build failure.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
It's only obliquely documented, but -[NSView addSubview:positioned:relativeTo:]
will remove the view from its old superview if it's changing superviews. If
it's just changing z-order within its current superview, it won't.
This avoids some flicker of OpenGL surfaces being removed and re-added.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
-[NSView subviews] returns the views in back-to-front order, not front-to-back
as I had thought.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
As opposed to just the immediate subviews of the window contentView.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This should be a common case and will reduce the number of Cocoa views.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This only really affects OpenGL child windows. GDI rendering to the window
surface is still only blitted to the window's content view. The descendant
views don't draw and so are transparent, letting the content view show through.
Using Cocoa views for child windows fixes a problem where changes to the
position and visibility of child GL windows didn't properly affect the Cocoa GL
view. Hiding, showing, and moving the top-level window affected the Cocoa
window and thus, indirectly, the GL view. Moving the child GL window itself
was propagated to the GL view, so that worked. But hiding, showing, or moving
any of the intervening ancestors of the child GL window didn't properly affect
the GL view. Neither did hiding or showing the child GL window itself.
This also slightly improves the clipping of the GL view by its ancestors,
although it still doesn't work quite right due to Cocoa bugs. There are also
remaining bugs with z-order among multiple GL views and clipping by overlapping
siblings. I hope to eventually fix those using Core Animation layers, for
which this is a prerequisite.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Minor no-op refactoring that makes subsequent commits cleaner.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Callers can use macdrv_set_view_superview() to do that separately.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Remove the no-longer-used functionality of potentially moving the view from one
window to another. That has been taken over by macdrv_set_view_superview().
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This allows for nesting views in a hierarchy rather than only ever adding them
as direct subviews of the window content view. This functionality will be used
in subsequent commits.
This takes over some of the functionality of macdrv_set_view_window_and_frame(),
which will be removed in a subsequent commit.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
When this Retina mode is enabled and the primary display is in the user's
default configuration, Wine gets told that screen and window sizes and mouse
coordinates are twice what Cocoa reports them as in its virtual coordinate
system ("points"). The Windows apps then renders at that high resolution and
the Mac driver blits it to screen. If the screen is actually a Retina display
in a high-DPI mode, then this extra detail will be preserved. Otherwise, the
rendering will be downsampled and blurry.
This is intended to be combined with increasing the Windows DPI, as via winecfg.
If that is doubled to 192, then, in theory, graphical elements will remain the
same visual size on screen but be rendered with finer detail. Unfortunately,
many Windows programs don't correctly handle non-standard DPI so the results
are not always perfect.
The registry setting to enable Retina mode is:
[HKEY_CURRENT_USER\Software\Wine\Mac Driver]
"RetinaMode"="y"
Note that this setting is not looked for in the AppDefaults\<exe name> key
because it doesn't make sense for only some processes in a Wine session to see
the high-resolution sizes and coordinates.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This is so negative coordinates are adjusted in the same direction as
positive ones (left and up).
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Signed-off-by: Charles Davis <cdavis5x@gmail.com>
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Signed-off-by: Charles Davis <cdavis5x@gmail.com>
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This reverts commits 38f579f9ba and
02416314ab.
No extant application uses this, nor are the wined3d maintainers
interested in using it.
Signed-off-by: Charles Davis <cdavis5x@gmail.com>
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
If the context is already current, don't do +clearCurrentContext followed by
-makeCurrentContext.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
The spec for GL_ARB_framebuffer_object (and thus, OpenGL 3.x and up) is
quite clear on what happens when a context is made current with no
drawable(s). In fact, the WGL_ARB_create_context extension amends
WGL_ARB_make_current_read (as well as the base spec for wglMakeCurrent)
specifically to allow this.
Signed-off-by: Charles Davis <cdavis5x@gmail.com>
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Signed-off-by: Charles Davis <cdavis5x@gmail.com>
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Cocoa manages an autorelease pool on the main thread, but it only drains it
when it processes an event. Our requests come through a run loop source, which
doesn't count as an event. So, autoreleased objects can accumulate when the
app is not being interacted with.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Signed-off-by: Charles Davis <cdavis5x@gmail.com>
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Most queries are handled even by threads which are otherwise blocked in
OnMainThread(). There's a problem with QUERY_IME_CHAR_RECT, though, in that it
can be handled before a previously-queued IM_SET_TEXT event, in which case its
character range may be out of bounds. Some apps (e.g. Excel 2007) hang due to
the bad range.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
It had been using the synchronous OnMainThread() to submit its work to the
Cocoa thread, but only queries are processed while OnMainThread() waits for the
work to complete. This led to QUERY_IME_CHAR_RECT queries being processed out
of order relative to IM_SET_TEXT events, making the character range out of
bounds with respect to the composition string.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Commit 793ab7d45 fixed a bug where WINDOW_BROUGHT_FORWARD events weren't being
posted when they should, but it caused a regression in Scribblenauts Unlimited.
Every click caused a window ordering operation that generated messages and
Scribblenauts would move the mouse cursor to the upper-left corner of the
window in response.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
It was added as an observer in commit 3beec95a0. Failing to remove it caused
the notification center to have a dangling pointer and caused crashes and hangs.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
On Macs with dual GPUs that automatically switch, the display ID is not stable.
It changes when the active GPU changes. The resulted in the lookup of the
initial display mode failing and games not being able to restore it properly.
The display unit number should be more reliable, although still not perfect.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
[image drawInRect:rect] is documented as being "exactly equivalent to calling
[image drawInRect:rect fromRect:NSZeroRect operation:NSCompositeSourceOver
fraction:1 respectFlipped:YES hints:nil]". So, that's what I replace it with.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
The change to a CVDisplayLink-driven display mechanism introduced a problem: a
Wine process never went completely idle for long periods. The display link
would fire for every refresh cycle of the display, waking a CPU from idle and
wasting energy.
To fix that, I have the display link stop itself when it determines that none
of its windows need to be displayed. When a window is subsequently marked as
needing display, it either temporarily re-enables Cocoa's normal autodisplay
mechanism so that it displays at the end of the current turn of the run loop,
or it restarts the display link. It chooses the former if it's been a long
time since the window was last displayed so that the display is done more
immediately.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This fixes a problem where child windows ("owned" windows in Windows
parlance) would never display their contents on OS X 10.8 or earlier.
Beginning with 10.9, Cocoa calls -windowDidChangeOcclusionState: when
the window becomes visible, which is why they display on that version
and later.
Reported by Huw Davies.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
It's redundant with the new CVDisplayLink-driven display mechanism.
This reverts commits d55d2ec85 and 94dc91a45.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Some Windows apps cause user32 to flush the window surface much faster than the
display refresh rate. The Mac driver only marks its window as needing to be
redrawn and lets Cocoa decide how often to actually redraw. Unfortunately,
Cocoa redraws each time through the run loop and, since the Mac driver uses a
run loop source to convey messages from background threads to the main thread,
it redraws after every batch of messages.
On some versions of OS X, this excessive drawing provokes synchronization with
the window server's buffer swaps, preventing the main thread from being
responsive. Even when that doesn't happen, it's wasteful.
So, we set our windows' autodisplay property to false so that Cocoa never
displays windows itself. Then, we arrange to call -displayIfNeeded once per
display refresh cycle using a CVDisplayLink. We maintain one CVDisplayLink per
display (on demand), move windows among them as the windows change screens,
start them when they acquire their first window, and stop them when they have
none left.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
The code had been checking the kDisplayModeDefaultFlag in the mode's IOFlags,
but that doesn't do what I thought. That indicates which mode the driver
considers to be the default for the hardware. It turns out there's no way to
query the user's default mode.
So, at the first opportunity during a given Wine session, the Mac driver
queries the current display mode and assumes that's the user's default mode.
It records that in a volatile registry key for use by subsequent processes
during that same session.
This doesn't use the existing registry key under
HKEY_CURRENT_CONFIG\System\CurrentControlSet\Control\Video that records the
mode when CDS_UPDATEREGISTRY is used with ChangeDisplaySettingsEx() -- which
explorer.exe does during start-up -- because a) that doesn't support the
distinction between pixel size and point size for Retina modes, and b) in
theory, apps could overwrite that.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Some apps create a zero-sized window as their "main" window and then create
all of the other top-level windows as owned windows with that main window as
the owner. The user interacts with these owned windows. When the user
attempts to minimize one of these owned windows, the app instead minimizes the
zero-sized owner window. When an owner window is minimized, all of its owned
windows are hidden.
The Mac driver faithfully carries out these window operations. The only
visible windows are hidden and the zero-sized window is minimized. This
results in an invisible animation of the window down to a slot in the Dock -
a slot which appears mostly empty. The invisible window thumbnail is badged
with the app icon, but it still looks strange.
On Windows, the Alt-Tab switcher uses the image of the owned window to
represent the zero-sized owner.
This commit attempts to do something similar. It takes over drawing of the
Dock icon for minimized, zero-sized window. It grabs a snapshot of one of the
owned windows and draws the app badge onto it. Since the owned windows are
hidden before the zero-sized owner is minimized and we can't take snapshots of
hidden windows, we use heuristics to guess when it may be useful to grab the
snapshot. If the user minimizes an owned window from the Cocoa side, we grab
that window's snapshot. If an owned window is being hidden and no snapshot has
been taken recently, we grab its snapshot on the theory that this may be the
beginning of hiding all of the owned windows before minimizing the owner.
Unfortunately, this doesn't address the invisible animations when minimizing
and unminimizing the zero-sized owner window.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Since a983cfb01, the Mac driver won't even present formats, like this one,
which don't correspond to a known Windows format through the clipboard APIs, so
it's pointless.
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
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>
The default behavior is that GL surfaces are on top of all non-GL content in
the window. This maximizes the performance for the common case of games, but
clipping by parents, siblings, and child windows isn't respected.
Setting OpenGLSurfaceMode to "behind" pushes the GL surface to be behind the
Mac window. The window has transparent holes punched through it so that the GL
surface shows through. USER32 and the wineserver take care of making sure the
holes are only where the GL windows would be unclipped and unoccluded. Because
the OS X window server has to composite the GL surface with the window, this
limits the framerate.
Since the Mac driver has no server-side rendering path, GDI rendering to a
window which has a GL surface doesn't work. As a partial workaround, mostly
for cases where a GL surface is created but never used, setting
OpenGLSurfaceMode to "transparent" allows the GDI rendering to show through the
transparent parts of the GL surface. The GDI rendering is drawn to the
top-level window's surface as normal. (The behavior of user32 to exclude the
portion covered by a GL window from GDI rendering is disabled.) The GL surface
is in front of the window but potentially wholly or partially transparent. It
is composited with the window behind it.
The GL surface is initially cleared to be completely transparent. So, if
no GL rendering is done, the window will appear as though the GL surface didn't
exist.
Not sending the brought-forward event for a click that was sent was an artifact
of a time when that branch was only used for posting a request for focus. When
I added the brought-forward event, I didn't reconsider that logic.
OS X doesn't have the same concept of maximized windows as Windows does.
There's no mode that prevents a normally-movable window from being moved. 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 move a window that's maximized.
To get similar behavior while still respecting Win32 semantics, we detect when
the user tries to move a maximized window. 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 move.
The user expects to move 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.
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.
OS X doesn't really have the concept of windows being maximized; that is, being
in a mode where they can't be moved or resized. As a consequence, it doesn't
have a button in the window title bar to restore a maximized window to normal.
So, when a Wine window is maximized, the Mac driver hijacks the green zoom
button to act as a restore button. (When a window is zoomed, the green button
"unzooms" back to its last user size and position, so it's analogous.)
However, with OS X 10.10 (Yosemite), the green button prefers to act as a
toggle for the Cocoa full-screen mode rather than zooming and unzooming. This
made it difficult for users to restore a maximized window. They would have to
Option-click the green button, double-click the title bar, or choose Zoom
from the Window menu, none of which is obvious.
The fix is to disable Cocoa full-screen mode for maximized windows. Then, the
green button reverts to unzoom and restoring the window.
Status items are the things on the right end of the Mac menu bar, like the
clock and volume widget. It turns out that they are displayed at a higher
window level than everything else in the menu bar. For the case where the
displays are not captured for a full-screen window, the window ends up at the
same window level as the status items, and they would sometimes end up on top.
They would draw over the full-screen window and could be clicked.
On high-resolution Retina displays, the OS X window backing store has twice the
pixels as Wine's window backing store. So, our images get scaled up. Core
Graphics had been interpolating/smoothing the image, which resulted in
fuzziness. This tells it not to do that.
I had assumed this wouldn't be necessary since we pass FALSE for the
shouldInterpolate parameter of CGImageCreate() when we create the images.
Apparently, that's not sufficient.
When a window is being dragged, we prevent delivery of clicks to Wine. We were
also preventing telling Wine that a window had been brought forward, but this
was incorrect. It prevented clicks in the title bar from activating the window.
If the mouse is captured, we change which window receives the click event, but
that shouldn't change which window we tell Wine was brought forward by Cocoa.
We can't prevent Cocoa from bringing disabled/no-activate windows forward. So,
we need to tell Wine about the z-order change.
We still do avoid telling Wine to activate disabled/no-activate windows, though.
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.
On Yosemite, in full-screen mode, Cocoa adds child windows of its own to our
windows. These windows are, of course, not instances of WineWindow. So, when
we call WineWindow-specific methods on them, it throws exceptions.
On Yosemite, double-clicking a window's title bar zooms it. (This is to
compensate for the fact that the zoom button has been replaced by a full-screen
button.) Sometimes, double-clicking in the content area would count as double-
clicking in the title bar.
This is controlled, in part, by the -mouseDownCanMoveWindow method of the view
that was hit in the window. The default implementation of that returns YES
for non-opaque views, as the views are in the Mac driver. Overriding it to
return NO prevents the problem.
NSBezierPath doesn't override the -isEqual: method to actually compare paths,
so it just falls back to object identity which, in our case, makes paths seem
like they're never equal.
Also, memcmp()-ing the rectangle array is almost certainly faster than any
general test for equality between two paths.
This avoids flickering and tearing on some versions of OS X during frequent
redrawing in a shaped window, such as when scrolling a document in Word 2007.
Since we aren't guaranteed that the window surface has updated bits for us to
draw, we mark the whole content view as needing redisplay and draw the window's
shape in the background color on the first -drawRect: after the shape change.
This means the resulting rectangle will be short, but we don't have much
choice. Some apps don't cope properly with the one-past-the-end character.
For example, Excel 2007 gets stuck in an infinite loop.
The Mac driver can generate scroll wheel events with values which are not integral
multiples of WHEEL_DELTA. Apps should handle that by scrolling a corresponding
non-integral multiple of what they'd do for a WHEEL_DELTA-valued scroll or, if
they can't, then at least accumulate scroll distance until its magnitude exceeds
WHEEL_DELTA and do a "chunky" scroll. However, many apps don't do that properly.
They may scroll way too far/fast or even in the opposite direction.
If the registry setting UsePreciseScrolling is set to "n", the Mac driver will do
that accumulation and chunking itself to work around such broken app behavior.
Cocoa will bring an unowned window to the front of its level when it's clicked,
but it doesn't do that for owned windows. The old code went out of its way to
make owned windows behave like unowned windows in this respect. That was
exactly backward. We wish we could control whether windows are raised on a
click. We don't have that opportunity for unowned windows, but, by ripping
out a bunch of code, we do for owned windows.
Many games clip the cursor to the client area of the window. However, on OS X,
the resizing controls extend into that client area. So, it's possible that
while playing, the user might unintentionally click in the resizing area and
drag, resizing the window.
It's not necessary. Unlike with X11, on Mac OS X the pixel format doesn't affect
the properties of windows and views. The pixel format is a property of the GL
context, which can attach to any view.
Its superclass, NSOpenGLContext, only holds a weak reference. The view was
sometimes being deallocated before the context was disposed of, resulting in
crashes.
We clear it if the context or the view is NULL. If the context is non-NULL,
we want to disassociate the views of both the current and passed-in contexts,
if they differ.
We only care if we have changed the mode and we're changing it back to its
original. Even if the current mode matches the target mode, we may still
need to release the displays and clear the entry from originalDisplayModes.
originalDisplayModes should be used when active, empty when inactive.
latentDisplayModes is used when inactive, empty when active.
The count of entries in originalDisplayModes is used to test whether the
process has the displays captured so adding entries when inactive would give
incorrect results. This could have led us to mistakenly change the display
mode when we don't have the displays captured.
Among other things, this fixes Syberia 2. That game shows, hides, and then
shows its window. Hiding it caused a WINDOW_LOST_FOCUS event to be queued.
By the time it was processed, the window was the foreground window again.
In response to being told it had lost focus, the game minimized its window.
Hiding the window should have prevented or discarded the WINDOW_LOST_FOCUS
event since the change was driven from Wine and the Win32 foreground/active
window state would already be correct. In addition, when the program
re-showed its window and made it foreground, that should have discarded the
event as being out of date. Now they do.
The Win32 window state might have changed while the event was in the queue,
making it obsolete. Sending WM_SYSCOMMAND/SC_RESTORE might re-show a hidden
window, for example.
Cocoa would implictly unhide it when we order a window, anyway. Doing it
early avoids problems from querying -[NSWindow isVisible] while the app is
hidden. That method returns FALSE even for windows which would be visible
if the app weren't hidden.
The -[NSWindow isVisible] method returns FALSE when the process is hidden,
but that's not what we need to know in some cases.
This fixes full-screen games which minimize their window when they lose
focus. Command-Tabbing away hides the process. Because the window was not
visible, the code didn't actually minimize it. When switching back to the
process, no event was sent to the Wine back-end telling it the window had
been restored, so it never resumed drawing to it.
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.
The window menu items are not updated as the window state changes; they only
update when the menu is shown. So the item state is not a reliable indicator
of whether minimization is allowed.
Fixes a problem in some games which repeatedly (re)establish the same cursor
clipping rect, making it exceedingly difficult to move the camera with the
mouse.
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.
This fixes a problem where some apps move their window to the front after
the user switches away to another app. OS X prevents the background app
from actually coming in front of the active app's front window, but the
window gets ordered in second place, possibly obscuring other windows of the
active app.
New clipboard formats had been registered for them, but that was pointless.
No Windows app would ever expect or make use of such clipboard formats or the
associated pasteboard data.
It has a non-object pointer from the caller, so it can't allow the caller
to continue until it's finished with it. Also, it discards events from the
event queue and we don't want the caller to process them first.
Fixes brokenness introduced by 784a9139.
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.