Commit 220b8b79 authored by Ken Thomases's avatar Ken Thomases Committed by Alexandre Julliard

winemac: Add an option to capture the displays for full-screen windows in…

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.
parent ba40509f
......@@ -66,6 +66,7 @@ enum {
NSUInteger unmatchedMouseDowns;
NSMutableDictionary* originalDisplayModes;
BOOL displaysCapturedForFullscreen;
NSArray* cursorFrames;
int cursorFrame;
......@@ -109,6 +110,7 @@ enum {
- (WineWindow*) frontWineWindow;
- (void) adjustWindowLevels;
- (void) updateFullscreenWindows;
- (BOOL) handleEvent:(NSEvent*)anEvent;
- (void) didSendEvent:(NSEvent*)anEvent;
......
......@@ -575,6 +575,41 @@ int macdrv_err_on;
[self adjustWindowLevels:[NSApp isActive]];
}
- (void) updateFullscreenWindows
{
if (capture_displays_for_fullscreen && [NSApp isActive])
{
BOOL anyFullscreen = FALSE;
NSNumber* windowNumber;
for (windowNumber in [NSWindow windowNumbersWithOptions:0])
{
WineWindow* window = (WineWindow*)[NSApp windowWithWindowNumber:[windowNumber integerValue]];
if ([window isKindOfClass:[WineWindow class]] && window.fullscreen)
{
anyFullscreen = TRUE;
break;
}
}
if (anyFullscreen)
{
if ([self areDisplaysCaptured] || CGCaptureAllDisplays() == CGDisplayNoErr)
displaysCapturedForFullscreen = TRUE;
}
else if (displaysCapturedForFullscreen)
{
if ([originalDisplayModes count] || CGReleaseAllDisplays() == CGDisplayNoErr)
displaysCapturedForFullscreen = FALSE;
}
}
}
- (void) activeSpaceDidChange
{
[self updateFullscreenWindows];
[self adjustWindowLevels];
}
- (void) sendDisplaysChanged:(BOOL)activating
{
macdrv_event* event;
......@@ -680,7 +715,8 @@ int macdrv_err_on;
if ([originalDisplayModes count] == 1) // If this is the last changed display, do a blanket reset
{
CGRestorePermanentDisplayConfiguration();
CGReleaseAllDisplays();
if (!displaysCapturedForFullscreen)
CGReleaseAllDisplays();
[originalDisplayModes removeAllObjects];
ret = TRUE;
}
......@@ -695,7 +731,8 @@ int macdrv_err_on;
}
else
{
if ([originalDisplayModes count] || CGCaptureAllDisplays() == CGDisplayNoErr)
if ([originalDisplayModes count] || displaysCapturedForFullscreen ||
CGCaptureAllDisplays() == CGDisplayNoErr)
{
if (CGDisplaySetDisplayMode(displayID, mode, NULL) == CGDisplayNoErr)
{
......@@ -705,7 +742,8 @@ int macdrv_err_on;
else if (![originalDisplayModes count])
{
CGRestorePermanentDisplayConfiguration();
CGReleaseAllDisplays();
if (!displaysCapturedForFullscreen)
CGReleaseAllDisplays();
}
}
}
......@@ -720,7 +758,7 @@ int macdrv_err_on;
- (BOOL) areDisplaysCaptured
{
return ([originalDisplayModes count] > 0);
return ([originalDisplayModes count] > 0 || displaysCapturedForFullscreen);
}
- (void) hideCursor
......@@ -851,11 +889,12 @@ int macdrv_err_on;
NSRunningApplication* app;
NSRunningApplication* otherValidApp = nil;
if ([originalDisplayModes count])
if ([originalDisplayModes count] || displaysCapturedForFullscreen)
{
CGRestorePermanentDisplayConfiguration();
CGReleaseAllDisplays();
[originalDisplayModes removeAllObjects];
displaysCapturedForFullscreen = FALSE;
}
for (app in [[NSWorkspace sharedWorkspace] runningApplications])
......@@ -1661,6 +1700,12 @@ int macdrv_err_on;
lastTargetWindow = nil;
if (window == self.mouseCaptureWindow)
self.mouseCaptureWindow = nil;
if ([window isKindOfClass:[WineWindow class]] && [(WineWindow*)window isFullscreen])
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{
[self updateFullscreenWindows];
});
}
}];
[nc addObserver:self
......@@ -1673,7 +1718,7 @@ int macdrv_err_on;
[NSTextInputContext self];
[wsnc addObserver:self
selector:@selector(adjustWindowLevels)
selector:@selector(activeSpaceDidChange)
name:NSWorkspaceActiveSpaceDidChangeNotification
object:nil];
}
......@@ -1705,6 +1750,7 @@ int macdrv_err_on;
{
[self activateCursorClipping];
[self updateFullscreenWindows];
[self adjustWindowLevels:YES];
if (beenActive && ![self frontWineWindow])
......
......@@ -29,6 +29,7 @@
BOOL disabled;
BOOL noActivate;
BOOL floating;
BOOL fullscreen;
BOOL pendingMinimize;
WineWindow* latentParentWindow;
......@@ -60,7 +61,9 @@
@property (retain, readonly, nonatomic) WineEventQueue* queue;
@property (readonly, nonatomic) BOOL floating;
@property (readonly, getter=isFullscreen, nonatomic) BOOL fullscreen;
- (NSInteger) minimumLevelForActive:(BOOL)active;
- (void) updateFullscreen;
@end
......@@ -450,7 +450,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
@implementation WineWindow
@synthesize disabled, noActivate, floating, latentParentWindow, hwnd, queue;
@synthesize disabled, noActivate, floating, fullscreen, latentParentWindow, hwnd, queue;
@synthesize surface, surface_mutex;
@synthesize shape, shapeChangedSinceLastDraw;
@synthesize colorKeyed, colorKeyRed, colorKeyGreen, colorKeyBlue;
......@@ -513,11 +513,18 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
[window setContentView:contentView];
[window setInitialFirstResponder:contentView];
[[NSNotificationCenter defaultCenter] addObserver:window
selector:@selector(updateFullscreen)
name:NSApplicationDidChangeScreenParametersNotification
object:NSApp];
[window updateFullscreen];
return window;
}
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[liveResizeDisplayTimer invalidate];
[liveResizeDisplayTimer release];
[queue release];
......@@ -570,13 +577,8 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
- (NSInteger) minimumLevelForActive:(BOOL)active
{
NSScreen* screen;
BOOL fullscreen;
NSInteger level;
screen = screen_covered_by_rect([self frame], [NSScreen screens]);
fullscreen = (screen != nil);
if (self.floating && (active || topmost_float_inactive == TOPMOST_FLOAT_INACTIVE_ALL ||
(topmost_float_inactive == TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN && !fullscreen)))
level = NSFloatingWindowLevel;
......@@ -587,7 +589,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
{
BOOL captured;
captured = (screen || [self screen]) && [[WineApplicationController sharedController] areDisplaysCaptured];
captured = (fullscreen || [self screen]) && [[WineApplicationController sharedController] areDisplaysCaptured];
if (captured || fullscreen)
{
......@@ -717,6 +719,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
if (on_screen && ![self isMiniaturized])
{
BOOL needAdjustWindowLevels = FALSE;
BOOL wasVisible = [self isVisible];
[controller transformProcessToForeground];
......@@ -758,7 +761,11 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
needAdjustWindowLevels = TRUE;
}
if (needAdjustWindowLevels)
{
if (!wasVisible && fullscreen && [self isOnActiveSpace])
[controller updateFullscreenWindows];
[controller adjustWindowLevels];
}
if (pendingMinimize)
{
......@@ -783,15 +790,38 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
- (void) doOrderOut
{
WineApplicationController* controller = [WineApplicationController sharedController];
BOOL wasVisible = [self isVisible];
BOOL wasOnActiveSpace = [self isOnActiveSpace];
if ([self isMiniaturized])
pendingMinimize = TRUE;
self.latentParentWindow = [self parentWindow];
[latentParentWindow removeChildWindow:self];
[self orderOut:nil];
[[WineApplicationController sharedController] adjustWindowLevels];
if (wasVisible && wasOnActiveSpace && fullscreen)
[controller updateFullscreenWindows];
[controller adjustWindowLevels];
[NSApp removeWindowsItem:self];
}
- (void) updateFullscreen
{
NSRect contentRect = [self contentRectForFrameRect:[self frame]];
BOOL nowFullscreen = (screen_covered_by_rect(contentRect, [NSScreen screens]) != nil);
if (nowFullscreen != fullscreen)
{
WineApplicationController* controller = [WineApplicationController sharedController];
fullscreen = nowFullscreen;
if ([self isVisible] && [self isOnActiveSpace])
[controller updateFullscreenWindows];
[controller adjustWindowLevels];
}
}
- (BOOL) setFrameIfOnScreen:(NSRect)contentRect
{
NSArray* screens = [NSScreen screens];
......@@ -829,14 +859,10 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
else
[self setFrame:frame display:YES];
[self updateFullscreen];
if (on_screen)
{
BOOL fullscreen = (screen_covered_by_rect(frame, screens) != nil);
BOOL oldFullscreen = (screen_covered_by_rect(oldFrame, screens) != nil);
if (fullscreen != oldFullscreen)
[[WineApplicationController sharedController] adjustWindowLevels];
/* In case Cocoa adjusted the frame we tried to set, generate a frame-changed
event. The back end will ignore it if nothing actually changed. */
[self windowDidResize:nil];
......@@ -929,6 +955,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
WineApplicationController* controller = [WineApplicationController sharedController];
NSArray* screens;
WineWindow* front;
BOOL wasVisible = [self isVisible];
[controller transformProcessToForeground];
......@@ -961,6 +988,8 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
if (front && [self level] < [front level])
[self setLevel:[front level]];
[self orderFront:nil];
if (!wasVisible && fullscreen && [self isOnActiveSpace])
[controller updateFullscreenWindows];
[controller adjustWindowLevels];
if (pendingMinimize)
......@@ -1071,6 +1100,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
{
WineApplicationController* controller = [WineApplicationController sharedController];
WineWindow* front = [controller frontWineWindow];
BOOL wasVisible = [self isVisible];
if (![self isKeyWindow] && !self.disabled && !self.noActivate)
[controller windowGotFocus:self];
......@@ -1078,6 +1108,8 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
if (front && [self level] < [front level])
[self setLevel:[front level]];
[self orderFront:nil];
if (!wasVisible && fullscreen && [self isOnActiveSpace])
[controller updateFullscreenWindows];
[controller adjustWindowLevels];
if (pendingMinimize)
......@@ -1220,6 +1252,8 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
ignore_windowDeminiaturize = FALSE;
if (fullscreen && [self isOnActiveSpace])
[controller updateFullscreenWindows];
[controller adjustWindowLevels];
if (!self.disabled && !self.noActivate)
......@@ -1240,6 +1274,12 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
liveResizeDisplayTimer = nil;
}
- (void)windowDidMiniaturize:(NSNotification *)notification
{
if (fullscreen && [self isOnActiveSpace])
[[WineApplicationController sharedController] updateFullscreenWindows];
}
- (void)windowDidMove:(NSNotification *)notification
{
[self windowDidResize:notification];
......@@ -1281,6 +1321,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
macdrv_release_event(event);
[[[self contentView] inputContext] invalidateCharacterCoordinates];
[self updateFullscreen];
}
- (BOOL)windowShouldClose:(id)sender
......
......@@ -136,6 +136,7 @@ struct macdrv_display {
/* main */
extern int macdrv_err_on;
extern int topmost_float_inactive DECLSPEC_HIDDEN;
extern int capture_displays_for_fullscreen DECLSPEC_HIDDEN;
extern int macdrv_start_cocoa_app(unsigned long long tickcount) DECLSPEC_HIDDEN;
extern void macdrv_window_rejected_focus(const struct macdrv_event *event) DECLSPEC_HIDDEN;
......
......@@ -38,11 +38,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(macdrv);
#define kCFCoreFoundationVersionNumber10_7 635.00
#endif
#define IS_OPTION_TRUE(ch) \
((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
C_ASSERT(NUM_EVENT_TYPES <= sizeof(macdrv_event_mask) * 8);
DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
int topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN;
int capture_displays_for_fullscreen = 0;
/**************************************************************************
......@@ -149,6 +153,9 @@ static void setup_options(void)
topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN;
}
if (!get_config_key(hkey, appkey, "CaptureDisplaysForFullscreen", buffer, sizeof(buffer)))
capture_displays_for_fullscreen = IS_OPTION_TRUE(buffer[0]);
if (appkey) RegCloseKey(appkey);
if (hkey) RegCloseKey(hkey);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment