Commit Graph

51 Commits

Author SHA1 Message Date
Ken Thomases 5ebb83ad4e winemac: Defer ordering a window out if it's in the process of entering or exiting Cocoa full-screen mode.
Cocoa doesn't handle the window being ordered out or closed during the
animation well and leaves a ghost window around.

Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
2017-04-24 20:32:11 +02:00
Ken Thomases c5eca7be91 winemac: Discard key repeat events after a modifier key has been pressed.
Sierra (macOS 10.12) changed the behavior of key repeat.  In previous versions
of macOS, key repeat stops when a modifier key is pressed or released.  In
Sierra, it does not; it just keeps repeating as newly-modified.

On Windows, key repeat stops when a modifier key is pressed, although not when
one is released.  Some programs depend on this behavior.  So, the Mac driver
emulates it.

Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
2017-03-10 10:03:56 +01:00
Ken Thomases fdd7db0593 winemac: Set windows to transparent until they have content to draw, to reduce flicker.
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>
2016-09-02 23:31:01 +09:00
Ken Thomases 1c94bf396f winemac: Add support for a high-resolution ("Retina") rendering mode.
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>
2016-05-06 11:45:24 +09:00
Ken Thomases b4fc81bdf2 winemac: Stop the CVDisplayLink when there are no more changes to flush.
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>
2015-11-10 11:58:42 +09:00
Ken Thomases bb44de787d winemac: Remove the live-resize display timer.
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>
2015-11-06 23:20:35 +09:00
Ken Thomases 3beec95a09 winemac: Use CVDisplayLink to limit window redrawing to the display refresh rate.
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>
2015-11-06 23:20:29 +09:00
Ken Thomases 496b001ae0 winemac: Use a snapshot of an owned window when a zero-sized owner window is minimized.
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>
2015-10-23 19:20:00 +09:00
Ken Thomases 792b47ad3b winemac: Restore a maximized window if a user tries to move it by dragging its title bar.
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.
2015-03-24 13:55:34 +09:00
Ken Thomases 31d7f61cc3 winemac: Properly ignore attempts to set a window's shape to its current shape.
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.
2014-10-03 08:39:49 +02:00
Ken Thomases ef4677106a winemac: Disable moving or resizing windows when cursor clipping is in effect.
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.
2014-04-29 11:22:58 +02:00
Ken Thomases d1f554711f winemac: Send WM_SIZING messages during resizing to let app alter the proposed size. 2014-04-24 11:37:34 +02:00
Ken Thomases ae47323604 winemac: Track whether our windows would be visible if the process 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.
2013-12-31 12:31:21 +01:00
Ken Thomases 66736b4ab3 winemac: Implement support for maximizing windows.
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.
2013-12-30 19:01:50 +01:00
Ken Thomases 3a03dcf097 winemac: Avoid moving owned windows when programmatically moving the owner.
Cocoa normally maintains the relative position of owned windows with respect
to the owner, which differs from Windows.
2013-11-15 12:00:12 +01:00
Ken Thomases f4f50c9e4a winemac: Implement support for Cocoa-style full-screen mode.
Based in large part on a patch submitted by Kevin Eaves.
2013-10-11 11:04:53 +02:00
Ken Thomases c043587d56 winemac: Tell Wine when Cocoa has brought a window to the front. 2013-10-08 15:39:01 +02:00
Ken Thomases 54291ad3d1 winemac: Let Wine always drive window minimization; Cocoa just requests it. 2013-09-30 20:36:34 +02:00
Ken Thomases d7f4d67514 winemac: Fix hiding windows that are minimized using -close instead of -orderOut:.
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.
2013-09-27 10:39:13 +02:00
Ken Thomases 4e0e9ca84a winemac: When programmatically focusing a window, don't generate WINDOW_LOST_FOCUS event for previously focused window.
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.)
2013-09-26 20:05:41 +02:00
Ken Thomases a3197b8ad0 winemac: At the start of a resize operation, get window min/max size info and pass it to Cocoa. 2013-09-18 22:23:09 +02:00
Ken Thomases 84903c5db3 winemac: Track latent child windows (the inverse of the latent parent window relationship).
This allows the relationship to be restored when the window becomes eligible
again.
2013-08-30 11:18:35 +02:00
Ken Thomases a39b02c3e7 winemac: Dispatch key-up events directly to window to be sure to get them.
For keys pressed in combination with Command, -[NSApplication sendEvent:]
simply doesn't pass the key-up event through to the window.  We have to
track which keys we've told Wine are pressed because Cocoa may consume
key-downs that trigger menus or system behaviors.
2013-07-09 10:30:45 +02:00
Ken Thomases a723af61ac Revert "winemac: Dispatch key events directly to window to be sure to get key-up events.".
This reverts commit 0d20ac02f7.
2013-07-09 10:30:43 +02:00
Ken Thomases 0d20ac02f7 winemac: Dispatch key events directly to window to be sure to get key-up events.
For keys pressed in combination with Command, -[NSApplication sendEvent:]
simply doesn't pass the key-up event through to the window.
2013-06-28 11:40:41 +02:00
Ken Thomases 3faf1a92b0 winemac: Don't bring disabled or no-activate windows forward when clicked. 2013-06-18 12:57:43 +02:00
Ken Thomases 220b8b7946 winemac: Add an option to capture the displays for full-screen windows in addition to display mode changes.
Under HKCU\Software\Wine\Mac Driver, set string value
CaptureDisplaysForFullscreen to "y" to enable the new behavior.
2013-06-07 11:57:06 +02:00
Ken Thomases b285c5706e winemac: Defer minimizing hidden windows until they are shown.
Minimizing invisible windows causes weird phantoms to appear in
Exposé, the Window menu, and the Dock.
2013-06-04 15:00:54 +02:00
Ken Thomases 27510fae8e winemac: Centralize adjusting of window levels using the window server's z-order. 2013-05-17 16:36:24 +02:00
Ken Thomases 1ac1cd69ad winemac: Fix disabling of resizable windows. 2013-05-14 17:28:30 +02:00
Ken Thomases 72e893237c winemac: Consolidate mouse move handling into -[WineApplicationController handleMouseMove:]. 2013-05-07 11:19:21 +02:00
Ken Thomases 192b8dbf9d winemac: Implement an IME that uses the OS X input methods.
Developed with Aric Stewart.
2013-04-22 12:37:50 +02:00
Ken Thomases 94dc91a45d winemac: During live resize, force occasional redisplay due to spontaneous redrawing. 2013-04-02 12:47:27 +02:00
Ken Thomases 0a56ef356a winemac: Handle mouse moves in -[WineApplication sendEvent:] instead of WineWindow. 2013-02-25 10:40:38 +01:00
Ken Thomases d26a6bf451 winemac: Implement ChangeDisplaySettingsEx(). 2013-02-18 10:35:46 +01:00
Ken Thomases be6af9a169 winemac: Implement support for full-screen windows. 2013-02-18 10:34:46 +01:00
Ken Thomases 572324bae3 winemac: Implement MOUSE_MOVED(_ABSOLUTE) events. 2013-02-07 12:04:49 +01:00
Ken Thomases 77de57683f winemac: Generate KEY_PRESS/RELEASE events from Cocoa key events. 2013-02-05 11:06:43 +01:00
Ken Thomases 8a0c8d9264 winemac: Implement support for minimizing windows. 2013-02-05 11:05:23 +01:00
Ken Thomases 7863a230ec winemac: Implement a WINDOW_GOT_FOCUS event for when Cocoa tries to focus a window. 2013-01-28 14:03:40 +01:00
Ken Thomases 6cde62ac18 winemac: Take control over when a window can become focused away from Cocoa. 2013-01-28 14:03:18 +01:00
Ken Thomases 177b67e6bd winemac: Make each Mac driver window track the HWND it's associated with. 2013-01-21 12:51:18 +01:00
Ken Thomases 207c4d193f winemac: Associate an event queue with each thread that creates windows and with each window. 2013-01-21 12:51:17 +01:00
Ken Thomases c0d43fb51f winemac: Implement layered windows: SetLayeredWindowAttributes() and UpdateLayeredWindow(). 2013-01-15 12:17:02 +01:00
Ken Thomases 2d4bcc47be winemac: Implement SetWindowRgn. 2013-01-15 12:16:52 +01:00
Ken Thomases 7d6ebfa742 winemac: Implement window surface rendering. 2013-01-15 12:16:44 +01:00
Ken Thomases b6544d19dd winemac: Implement support for owned windows. 2013-01-11 18:14:07 +01:00
Ken Thomases 429732ce1a winemac: Implement support for WS_EX_TOPMOST windows. 2013-01-11 18:14:07 +01:00
Ken Thomases 9d29ea42e1 winemac: Implement support for no-activate windows. 2013-01-11 18:14:07 +01:00
Ken Thomases 064186e739 winemac: Implement support for WS_DISABLED windows. 2013-01-11 18:14:07 +01:00