Hi,

On May 9, 2013, at 5:48 PM, Kevin Eaves wrote:

> Attached patch is a proof-of-concept for the fullscreen APIs provided in OS X 
> 10.7+, which allows applications to enter fullscreen in a separate desktop 
> space.

Thanks for this.  It's quite interesting.

> The fullscreen button appears if a main window is resizable.

We may want to narrow this down a bit.  For example, the common file dialogs 
are resizable, but probably shouldn't be full-screen-enabled.  Perhaps no owned 
window should be.

> Basically this feature is the zoom button on crack.  It doesn't actually go 
> fullscreen 'natively' but simply resizes the window fullscreen, and 
> automatically moves it to its own space.  As far as Wine is concerned the 
> window resized — just like clicking the zoom button and manually assigning 
> the window to its own space.

Understood.

> I doubled the MaxTrackSize in user32/winpos.c, but it only  needs +15 for the 
> height.

This is a gross hack that's going to have to be reworked if this is ever going 
to get accepted. :)

If I'm understanding correctly, user32 is restricting the window to a size that 
keeps its caption (title bar) within the desktop.  Without this hack, the 
window resizes to be slightly smaller than would actually fill the screen.  Is 
that right?

Maybe we could add a new driver entry point to have user32 offer the driver the 
opportunity to override the default MINMAXINFO values.


>From cocoa_window.m.diff:

> +#import <Cocoa/Cocoa.h>


Was that actually needed?  cocoa_window.h already imports <AppKit/AppKit.h>.

On a related note, to enable this to compile against the 10.6 SDK, we should 
have something like:

#if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < 
MAC_OS_X_VERSION_10_7
enum {
    NSFullScreenWindowMask = 0,
    NSWindowCollectionBehaviorFullScreenPrimary = 0,
    NSWindowFullScreenButton = 7,
};
#endif

>          if (self.disabled)
>              style &= ~NSResizableWindowMask;
> -        if (style != [self styleMask])
> +        if (style != [self styleMask] && !([self styleMask] & 
> NSFullScreenWindowMask))
>              [self setStyleMask:style];

This is to avoid accidentally removing NSFullScreenWindowMask just because it's 
never in normalStyleMask, right?  I think a simpler solution is to just do:

        style |= [self styleMask] & NSFullScreenWindowMask;

In fact, we should probably make a mask of the style mask bits that are ever 
valid in normalStyleMask and only tweak those.  That would be more future 
proof.  So, something like:

enum {
    MACDRV_KNOWN_STYLES = NSTitledWindowMask | NSClosableWindowMask | 
NSMiniaturizableWindowMask | NSResizableWindowMask | NSUtilityWindowMask | 
NSBorderlessWindowMask
};
…
        NSUInteger style = normalStyleMask | ([self styleMask] & 
~MACDRV_KNOWN_STYLES);


This:

> +        if (style & NSResizableWindowMask)
> +            [[self standardWindowButton:NSWindowZoomButton] 
> setEnabled:!self.disabled];


is to compensate for the fact that you might not call -setStyleMask:, above, 
right?  So it wouldn't be necessary after the change I suggested.  Furthermore, 
it isn't adequate.  You've disabled the zoom button but not the resize cursors 
all around the window border.

However, it does make me realize that we need to disable 
NSWindowFullScreenButton if the window is disabled.  Or is that what you meant 
to do here?  (We'd need to a protect against calling -standardWindowButton: 
with NSWindowFullScreenButton on OSes that don't support it.  It should suffice 
to test if [self respondsToSelector:@selector(toggleFullScreen:)].)


> -        if (captured || fullscreen)
> +        if (captured || (fullscreen && !(normalStyleMask & 
> NSResizableWindowMask)))

You're trying to distinguish between a window that was full-screened at the 
instigation of the Windows program versus one which has been full-screened by 
Cocoa, right?  Hmm.  I think we need a better technique to determine that.  I 
agree that it's not likely the Windows program would make its window 
full-screen while still allowing it to be resized but it feels wrong to assume 
that.

Also, I think we can entirely avoid setting the window level for windows that 
have been Cocoa full-screened.  Setting the window level is mostly about 
relationship to other windows, but a Cocoa full-screen window should be on a 
space by itself, shouldn't it?

> +            else if ([self styleMask] & NSFullScreenWindowMask)
> +                level = NSMainMenuWindowLevel + 2;

I'm not following why Cocoa full-screened windows should be at +2 vs. +1.

Also, fair warning: I've got some in-progress changes that will overhaul the 
management of window levels.  I don't think it will be too hard to adapt your 
patch, but methods will be moving or going away.


> +            if (normalStyleMask & NSResizableWindowMask)
> +                behavior |= NSWindowCollectionBehaviorFullScreenPrimary;

This is in -setMacDrvState: but, since normalStyleMask is changed in 
-setWindowFeatures:, the collection behavior has to be updated there, too.


> +    - (NSSize)window:(NSWindow *)window 
> willUseFullScreenContentSize:(NSSize)proposedSize
> +    {
> +        return NSMakeSize(proposedSize.width, proposedSize.height);
> +    }

Is this actually needed?  I assume that's the default behavior when the 
delegate method is absent.  (Also, if it is necessary, it can just return 
proposedSize without making a new size struct.)

In addition to this work, it would probably good to add an "Enter Full Screen" 
item in the Window menu.  We'd do so only if [NSWindow 
instancesRespondToSelector:@(toggleFullScreen:)] and the item would use that 
action and a target of nil (first responder).

Sorry to have nitpicked just about every hunk of the patch.  I realize you were 
just hacking and I appreciate your sharing this with us.

Thanks again,
Ken



Reply via email to