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.
This commit is contained in:
parent
ba40509f90
commit
220b8b7946
|
@ -66,6 +66,7 @@ @interface WineApplicationController : NSObject <NSApplicationDelegate>
|
|||
NSUInteger unmatchedMouseDowns;
|
||||
|
||||
NSMutableDictionary* originalDisplayModes;
|
||||
BOOL displaysCapturedForFullscreen;
|
||||
|
||||
NSArray* cursorFrames;
|
||||
int cursorFrame;
|
||||
|
@ -109,6 +110,7 @@ - (void) flipRect:(NSRect*)rect;
|
|||
|
||||
- (WineWindow*) frontWineWindow;
|
||||
- (void) adjustWindowLevels;
|
||||
- (void) updateFullscreenWindows;
|
||||
|
||||
- (BOOL) handleEvent:(NSEvent*)anEvent;
|
||||
- (void) didSendEvent:(NSEvent*)anEvent;
|
||||
|
|
|
@ -575,6 +575,41 @@ - (void) adjustWindowLevels
|
|||
[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,6 +715,7 @@ - (BOOL) setMode:(CGDisplayModeRef)mode forDisplay:(CGDirectDisplayID)displayID
|
|||
if ([originalDisplayModes count] == 1) // If this is the last changed display, do a blanket reset
|
||||
{
|
||||
CGRestorePermanentDisplayConfiguration();
|
||||
if (!displaysCapturedForFullscreen)
|
||||
CGReleaseAllDisplays();
|
||||
[originalDisplayModes removeAllObjects];
|
||||
ret = TRUE;
|
||||
|
@ -695,7 +731,8 @@ - (BOOL) setMode:(CGDisplayModeRef)mode forDisplay:(CGDirectDisplayID)displayID
|
|||
}
|
||||
else
|
||||
{
|
||||
if ([originalDisplayModes count] || CGCaptureAllDisplays() == CGDisplayNoErr)
|
||||
if ([originalDisplayModes count] || displaysCapturedForFullscreen ||
|
||||
CGCaptureAllDisplays() == CGDisplayNoErr)
|
||||
{
|
||||
if (CGDisplaySetDisplayMode(displayID, mode, NULL) == CGDisplayNoErr)
|
||||
{
|
||||
|
@ -705,6 +742,7 @@ - (BOOL) setMode:(CGDisplayModeRef)mode forDisplay:(CGDirectDisplayID)displayID
|
|||
else if (![originalDisplayModes count])
|
||||
{
|
||||
CGRestorePermanentDisplayConfiguration();
|
||||
if (!displaysCapturedForFullscreen)
|
||||
CGReleaseAllDisplays();
|
||||
}
|
||||
}
|
||||
|
@ -720,7 +758,7 @@ - (BOOL) setMode:(CGDisplayModeRef)mode forDisplay:(CGDirectDisplayID)displayID
|
|||
|
||||
- (BOOL) areDisplaysCaptured
|
||||
{
|
||||
return ([originalDisplayModes count] > 0);
|
||||
return ([originalDisplayModes count] > 0 || displaysCapturedForFullscreen);
|
||||
}
|
||||
|
||||
- (void) hideCursor
|
||||
|
@ -851,11 +889,12 @@ - (void) handleCommandTab
|
|||
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 @@ - (void) setupObservations
|
|||
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 @@ - (void) setupObservations
|
|||
[NSTextInputContext self];
|
||||
|
||||
[wsnc addObserver:self
|
||||
selector:@selector(adjustWindowLevels)
|
||||
selector:@selector(activeSpaceDidChange)
|
||||
name:NSWorkspaceActiveSpaceDidChangeNotification
|
||||
object:nil];
|
||||
}
|
||||
|
@ -1705,6 +1750,7 @@ - (void)applicationDidBecomeActive:(NSNotification *)notification
|
|||
{
|
||||
[self activateCursorClipping];
|
||||
|
||||
[self updateFullscreenWindows];
|
||||
[self adjustWindowLevels:YES];
|
||||
|
||||
if (beenActive && ![self frontWineWindow])
|
||||
|
|
|
@ -29,6 +29,7 @@ @interface WineWindow : NSPanel <NSWindowDelegate>
|
|||
BOOL disabled;
|
||||
BOOL noActivate;
|
||||
BOOL floating;
|
||||
BOOL fullscreen;
|
||||
BOOL pendingMinimize;
|
||||
WineWindow* latentParentWindow;
|
||||
|
||||
|
@ -60,7 +61,9 @@ @interface WineWindow : NSPanel <NSWindowDelegate>
|
|||
|
||||
@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 @@ - (NSInteger) windowLevel
|
|||
|
||||
@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 @@ + (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)w
|
|||
[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 @@ - (BOOL) isOrderedIn
|
|||
|
||||
- (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 @@ - (NSInteger) minimumLevelForActive:(BOOL)active
|
|||
{
|
||||
BOOL captured;
|
||||
|
||||
captured = (screen || [self screen]) && [[WineApplicationController sharedController] areDisplaysCaptured];
|
||||
captured = (fullscreen || [self screen]) && [[WineApplicationController sharedController] areDisplaysCaptured];
|
||||
|
||||
if (captured || fullscreen)
|
||||
{
|
||||
|
@ -717,6 +719,7 @@ - (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next
|
|||
if (on_screen && ![self isMiniaturized])
|
||||
{
|
||||
BOOL needAdjustWindowLevels = FALSE;
|
||||
BOOL wasVisible = [self isVisible];
|
||||
|
||||
[controller transformProcessToForeground];
|
||||
|
||||
|
@ -758,7 +761,11 @@ - (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next
|
|||
needAdjustWindowLevels = TRUE;
|
||||
}
|
||||
if (needAdjustWindowLevels)
|
||||
{
|
||||
if (!wasVisible && fullscreen && [self isOnActiveSpace])
|
||||
[controller updateFullscreenWindows];
|
||||
[controller adjustWindowLevels];
|
||||
}
|
||||
|
||||
if (pendingMinimize)
|
||||
{
|
||||
|
@ -783,15 +790,38 @@ - (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next
|
|||
|
||||
- (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 @@ - (BOOL) setFrameIfOnScreen:(NSRect)contentRect
|
|||
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 @@ - (void) makeFocused:(BOOL)activate
|
|||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
NSArray* screens;
|
||||
WineWindow* front;
|
||||
BOOL wasVisible = [self isVisible];
|
||||
|
||||
[controller transformProcessToForeground];
|
||||
|
||||
|
@ -961,6 +988,8 @@ - (void) makeFocused:(BOOL)activate
|
|||
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 @@ - (void) makeKeyAndOrderFront:(id)sender
|
|||
{
|
||||
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 @@ - (void) makeKeyAndOrderFront:(id)sender
|
|||
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 @@ - (void)windowDidDeminiaturize:(NSNotification *)notification
|
|||
|
||||
ignore_windowDeminiaturize = FALSE;
|
||||
|
||||
if (fullscreen && [self isOnActiveSpace])
|
||||
[controller updateFullscreenWindows];
|
||||
[controller adjustWindowLevels];
|
||||
|
||||
if (!self.disabled && !self.noActivate)
|
||||
|
@ -1240,6 +1274,12 @@ - (void) windowDidEndLiveResize:(NSNotification *)notification
|
|||
liveResizeDisplayTimer = nil;
|
||||
}
|
||||
|
||||
- (void)windowDidMiniaturize:(NSNotification *)notification
|
||||
{
|
||||
if (fullscreen && [self isOnActiveSpace])
|
||||
[[WineApplicationController sharedController] updateFullscreenWindows];
|
||||
}
|
||||
|
||||
- (void)windowDidMove:(NSNotification *)notification
|
||||
{
|
||||
[self windowDidResize:notification];
|
||||
|
@ -1281,6 +1321,7 @@ - (void)windowDidResize:(NSNotification *)notification
|
|||
macdrv_release_event(event);
|
||||
|
||||
[[[self contentView] inputContext] invalidateCharacterCoordinates];
|
||||
[self updateFullscreen];
|
||||
}
|
||||
|
||||
- (BOOL)windowShouldClose:(id)sender
|
||||
|
|
|
@ -136,6 +136,7 @@
|
|||
/* 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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue