开发者

NSOpenPanel above a fullscreen NSWindow?

开发者 https://www.devze.com 2022-12-14 09:21 出处:网络
I open a window with the following: NSRect screenRect = [[NSScreen mainScreen] frame]; [super initWithContentRect:screenRect

I open a window with the following:

NSRect screenRect = [[NSScreen mainScreen] frame];
[super initWithContentRect:screenRect 
               styleMask:NSBorderlessWindowMask 
                 backing:NSBackingStoreBuffered 
                   defer:NO]; 
int windowLevel = CGShieldingWindowLevel();
[self setLevel:windowLevel];

... so the window is fullscreen & above all other window levels (including modal windows). I later want to display an open panel, however the following opens the dialog below the window I created above (it seems that the runModal stuff overrides the requested window level I try to set):

  NSOpenPanel *OP = [NSOpenPanel openPanel];      
  int windowLevel = CGShieldingWindowLevel();
  [OP setLevel:windowLevel];
  int returnCode = [OP runModal];

... and the following opens a sheet on the window created above (good), however it also winds up showing the menu bar, which I had previously hidden (not what I want):

  NSOpenPanel *OP = [NSOpenPanel openPanel];      
  [OP beginSheetModalForWindow:[self window]
             completionHandler:^(NSInteger returnCode) {
               NSLog(@"开发者_开发问答completionHandler called with %d", returnCode);
             }];

... so my questions are:

  • Does anyone know how to open a modal window above the CGShieldingWindowLevel ?
  • Is there any way to get the menu bar to not show up on the sheet solution I'm trying above ?

Thanks all :-)


OK, here's an even better option - missed this one completely when I was reviewing the docs:

NSOpenPanel *OP = [NSOpenPanel openPanel];
[OP setLevel:CGShieldingWindowLevel()];
[OP beginWithCompletionHandler:^(NSInteger returnCode) {
  NSLog(@"completionHandler called with %d", returnCode);
}];

... ie: open the panel as it's own window, which was exactly what I wanted to do in the fist place (duh!)


You can create a category of NSSavePanel like this :

@implementation NSSavePanel (SavePanelSetLevel)

- (void)setLevel:(NSInteger)newLevel
{
    [super setLevel:CGShieldingWindowLevel()] ; // NSWindow implementation call
}

@end

because runModal reset the level previously set !


OK, 5 years later, I sorta can make this work - the trick is to open up a second window, promote it to the CGShieldingWindowLevel, make it key & order front, then attach the open sheet to it - the sheet magically appears from wherever the second window is, and although not perfect, it looks a lot better than the solution I came up with originally. Here's the change:

  NSOpenPanel *OP = [NSOpenPanel openPanel];

  // this is the new bit - make the window 1x1 @ the location of your liking
  NSRect windowRect = NSMakeRect(0, 1000, 1, 1);
  NSWindow *OPW = [[NSWindow alloc] initWithContentRect:windowRect 
                                              styleMask:NSBorderlessWindowMask 
                                                backing:NSBackingStoreBuffered 
                                                  defer:NO];  
  int windowLevel = CGShieldingWindowLevel();
  [OPW setLevel:windowLevel];
  [OPW makeKeyAndOrderFront:nil];
  // end of new bit, apart from passing OPW for beginSheetModalForWindow
  // instead of [self window]

  [OP beginSheetModalForWindow:OPW
             completionHandler:^(NSInteger returnCode) {
               NSLog(@"completionHandler called with %d", returnCode);
             }];

... the only think to watch out for is that with the below you can wind up opening up several open dialogs, since the sheet is modal for a window other than the main window - the main window can still accept mouse click events ...

0

精彩评论

暂无评论...
验证码 换一张
取 消