Search code examples
cocoafullscreennswindow

How can I display a modal sheet in NSWindow fullscreen mode without visually shifting the host window?


Objective-C desktop Cocoa ap. The application is a highly specific edge case (a standalone kiosk with a one-button interface). I mention this first in hopes of avoiding the HIG lecture. ;)

I am using a modal sheet view to display a PDF document over top of my usual content. The code is very simple:

[docViewerHostWindow beginSheet:docViewer completionHandler:nil];

DocViewerHostWindow is an NSWindow accessed as the parent of the NSView that calls the sheet. If it matters, "docViewer" is a subclass of NSWindow containing a PDFView.

When the application is running in a window, everything functions as it should. When the application is running fullscreen things work as advertised but there is a visual glitch: the entire content behind the model shifts to the right until the sheet is dismissed. It appears this is deliberate (and animated) but I can't figure out where it is coming from or how to disable it.

I enter fullscreen this way:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],NSFullScreenModeAllScreens,nil];

[self enterFullScreenMode:[NSScreen mainScreen] withOptions:options];

This basic NSLog illustrates the problem:

NSLog(@"Before: %f,%f",docViewerHostWindow.frame.origin.x,docViewerHostWindow.frame.origin.y);

[docViewerHostWindow beginSheet:docViewer completionHandler:nil];

NSLog(@"After: %f,%f",docViewerHostWindow.frame.origin.x,docViewerHostWindow.frame.origin.y);

**Log when running windowed (same origin before and after) **
2015-08-09 22:52:46.641 Before: 311.000000,491.000000
2015-08-09 22:52:47.050 After: 311.000000,491.000000

**Log when running fullscreen (origin shifts in fullscreen) **
2015-08-09 22:52:46.641 Before: 0.000000,0.000000
2015-08-09 22:52:47.050 After: 80.000000,-23.000000

I have tried to force the origin of the window both before and after opening the sheet, but this didn't help. I'm not even sure where to look - any clues on what is causing this and why?


Update: To be clear I am NOT talking about the default animation on the sheet itself (as described in this question) rather this is something that happens to the host window, but only in fullscreen.


Solution

  • The issue is apparently related to the window avoiding the Dock.

    I think it's also related to the fact that you're putting a view, not a window, in full-screen mode. When you do that, the view is sort of moved out of its normal window. But then, when you begin a sheet on the view's window, you're bringing that back into the picture, so to speak. (You might check if the view's window property is actually the same window it was before it entered full-screen mode. If it's not, you really have no business attaching a sheet to it.)

    I would recommend that you use a borderless window, positioned to cover the screen, at a window level of NSStatusWindowLevel + 1. That's the technique recommended in Apple's OpenGL Programming Guide for Mac: Drawing to the Full Screen (which is, admittedly, a somewhat different context that you're working in). So, you would not use -[NSView enterFullScreenMode:withOptions:]. If you want to set the application's presentationOptions for kiosk-mode-type behavior, you can do that, too.