NSWindow autosave - 位置未保存在第二台显示器上

时间:2015-05-11 06:28:21

标签: objective-c nswindow nswindowcontroller autosave

在Yosemite(可能更早)中,窗框自动保存机制不能自动定位已从主显示屏移动到第二个显示器的窗口,或任何与第二个显示器重叠的位置。

相反,当下次实例化时,窗口会自动定位在前一个位置(如果有默认值记录的有效位置)或窗口的默认位置,或者在窗口重叠的情况下,放置一个位置窗口完全在主屏幕上。

无论是在Interface Builder中的窗口上还是通过NSWindowController设置了自动保存名称属性,都会发生这种情况。 e.g。

-(void)windowDidLoad
{
    [super windowDidLoad];
    [self setShouldCascadeWindows:NO];
    [self setWindowFrameAutosaveName:@"MyWindowAutoSaveName"];
}

有没有人知道解决方法?

1 个答案:

答案 0 :(得分:3)

我永远无法将自动保存恢复到第二台显示器。没有任何鞭打会使它起作用。它将恢复到与第二个监视器上的窗口相同的xy位置的第一个监视器。为了解决这个问题,我放弃了使用自动保存API并制作了自己的API。

当窗口的windowWillClose:方法被调用时,首先存储一个BOOL,指示窗口是否全屏缩放。接下来如果窗口没有缩放(在一秒钟内更多),请使用NSStringFromRect并保存窗口的框架矩形。

-(void)windowWillClose:(NSNotification *)notification
{
  NSString  *mainWindowFrameString;

  [_defaults setObject:[NSNumber numberWithBool:[_flimFlamViewController windowIsFullScreen]] forKey:QUITTING_ZOOM_STATE];

  if ([_flimFlamViewController windowIsFullScreen] == NO) {
    mainWindowFrameString = NSStringFromRect([_ourWindow frame]);
    [_defaults setObject:mainWindowFrameString forKey:MAIN_WINDOW_FRAME];
    }

  [_defaults synchronize];

}

相反,当创建窗口时(可能在awakeFromNib中)从NSUserDefaults加载字符串并使用NSRectFromString来获取边界。检查框架尺寸是否为零,以查看这是否是第一次启动应用程序。如果帧不是全零,则将窗口的帧设置为该CGRect。

  mainWindowFrameString = [_defaults objectForKey:MAIN_WINDOW_FRAME];       // get the last saved window frame values
  mainWindowFrame = NSRectFromString(mainWindowFrameString);                // convert it to a CGRect

  if ((mainWindowFrame.size.width != 0) && (mainWindowFrame.size.height != 0)) {
    [_ourWindow setFrame:mainWindowFrame display:YES];
    }
  else {
    [_ourWindow center];
    }

要处理窗口关闭时窗口全屏缩放的情况,首先要保存帧在全屏显示之前的位置 - 稍后当窗口打开以将窗口放在适当的显示器上时,您将使用它。 / p>

-(void)windowWillEnterFullScreen:(NSNotification *)notification
{
  NSString  *mainWindowFrameString;

  // save the frame's coordinates before going full screen

  mainWindowFrameString = NSStringFromRect([_ourWindow frame]);
  [_defaults setObject:mainWindowFrameString forKey:MAIN_WINDOW_FRAME];
}

然后在viewWillAppear中:确定是否需要缩放窗口(此时窗口已经放在适当的监视器上)。 toggleFullScreen:将使窗口全屏显示。

  lastZoomStateDefault = [_defaults objectForKey:QUITTING_ZOOM_STATE];
  _windowIsFullScreen = [lastZoomStateDefault boolValue];

  if (_windowIsFullScreen == YES) {
    [_window toggleFullScreen:nil];
    }