2013-05-13 79 views
0

我想創建一個方法,將在全屏和窗口之間切換。我試圖從一個繼承自NSOpenGLView的類中執行此操作, 基本上跟在 this blogpost 之後。從窗口到全屏從一次工作一次;試圖以各種方式返回失敗:窗口屏幕沒有得到更新,或者我甚至不管理切換到窗口,但全屏幕只是空白。無論如何都試着來回反覆(映射到'f'鍵),程序經常會鎖定,在最壞的情況下,我必須重新啓動計算機。 我已經附上了以下方法的代碼;出於調試目的,我已經將整個框架矩形設置的更小,所以如果事情凍結,應用程序永遠不會處於全屏狀態。NSOpenGLView切換到全屏從視圖

Apple開發人員示例中的fullscreen example建議使用控制器,並且不會從繼承的NSOpenGLView中全屏顯示。

我的問題:

  • 我應該使用的控制器代替,並從那裏窗口和全屏之間切換(每次都創建一個單獨的全屏視圖)?還是應該兩種方法都有效?
  • 如果兩種方法都應該起作用,哪一種更好?
  • 如果兩種方法都可以工作,那麼我目前在執行這個方法時做錯了什麼?
  • 或者,還有第三種更好的方法嗎?

請注意,對於這兩個引用,我將不得不假設事情沒有改變爲10.8(兩個引用似乎適用於10.6)。

代碼如下:

@implementation MyOpenGLView 

[...] 

- (void)toggleFullscreen 
{ 
    mainWindow = [self window]; 

    if (isFullscreen) { 
     [fullscreenWindow close]; 
     [mainWindow setAcceptsMouseMovedEvents:YES]; 
     [mainWindow setContentView: self]; 
     [mainWindow makeKeyAndOrderFront: self]; 
     [mainWindow makeFirstResponder: self]; 
     isFullscreen = false; 
    } else { 
     [mainWindow setAcceptsMouseMovedEvents:NO]; 
     //NSRect fullscreenFrame = [[NSScreen mainScreen] frame]; 
     NSRect fullscreenFrame = { {300, 300}, {300, 300} }; 
     fullscreenWindow = [[NSWindow alloc] initWithContentRect:fullscreenFrame 
                 styleMask:NSBorderlessWindowMask 
                 backing:NSBackingStoreBuffered 
                  defer:NO]; 
     if (fullscreenWindow) { 
      [fullscreenWindow setAcceptsMouseMovedEvents:YES]; 
      [fullscreenWindow setTitle:@"Full screen"]; 
      [fullscreenWindow setReleasedWhenClosed: YES]; 
      [fullscreenWindow setContentView: self]; 
      [fullscreenWindow makeKeyAndOrderFront: self]; 
      //[fullscreenWindow setOpaque:YES]; 
      //[fullscreenWindow setHidesOnDeactivate:YES]; 
      // Set the window level to be just above the menu bar 
      //[fullScreenWindow setLevel:NSMainMenuWindowLevel+1]; 
      // Set the window level to be just below the screen saver 
      [fullscreenWindow setLevel:NSScreenSaverWindowLevel-1]; 
      [fullscreenWindow makeFirstResponder:self]; 

      isFullscreen = true; 
     } else { 
      NSLog(@"Error: could not switch to full screen."); 
     } 
    } 
} 

[...] 

@end 

回答

0

我很好奇這個too-專門您的前兩個項目符號的問題。

這不解決這些問題,但你對這個bug第三個,我認爲你可以只是改變同一窗口的屬性閃避(爲我的作品):

- (void)toggleFullscreen 
{ 
    if (isFullscreen) { 
     NSRect windowFrame = [[NSScreen mainScreen] visibleFrame]; 
     [mainWindow setStyleMask:NSTitledWindowMask | NSClosableWindowMask | 
          NSMiniaturizableWindowMask | NSResizableWindowMask ]; 
     [mainWindow setFrame:windowFrame display:true]; 
     [mainWindow setAcceptsMouseMovedEvents:YES]; 
     [mainWindow setLevel:NSNormalWindowLevel]; 
     [mainWindow setTitle:@"SimpleOculus"]; 
     [mainWindow makeKeyAndOrderFront:self]; 
     [mainWindow makeFirstResponder:self]; 
     isFullscreen = false; 
    } 
    else { 
     NSRect fullscreenFrame = [[NSScreen mainScreen] frame]; 
     [mainWindow setStyleMask:NSBorderlessWindowMask]; 
     [mainWindow setFrame:fullscreenFrame display:true]; 
     [mainWindow setAcceptsMouseMovedEvents:YES]; 
     [mainWindow setLevel:NSScreenSaverWindowLevel-1]; 
     [mainWindow makeKeyAndOrderFront:self]; 
     [mainWindow makeFirstResponder:self]; 
     isFullscreen = true; 
    } 
} 
1

我現在認爲這是無法完成的,不應該這樣做。當窗口化時,渲染上下文是一個窗口,當渲染全屏時,這是一個與屏幕不同的野獸。 因此,切換時,每次切換時必須重新設置。

可以簡單地使用最新OS X變體中的原生全屏選項。這將(大概)將接觸窗口放大到全屏尺寸,同時移除框架,邊框和按鈕。因此,你仍然在渲染到一個窗口,儘管它看起來是全屏的。

我不確定這個選項是否會讓事情變得更慢:它們之間有一個窗口層,這可能使它比直接渲染到屏幕慢。爲了好奇,實現原生全屏幕很容易(至少在10.8和10.9中):在XCode中,選擇.xib文件,在編輯器側邊欄中選擇(主)窗口,然後選擇屬性選擇器對。您可以在「不支持」,「主窗口」或「輔助窗口」之間選擇「全屏」選項。這會自動將全屏切換添加到窗口。 即使是整潔的,現在選擇側邊欄中的主菜單 - >視圖菜單,在底部的檢查器中找到「全屏菜單項」(有一個搜索欄),將它拖到編輯器的視圖菜單中,和voilà,它將有一個快捷方式並自動連接到窗口的全屏選項(選擇新的視圖菜單項並查看連接檢查器,它已經連接到您)。

一個很好的方法來測試所有這些是抓住我的問題鏈接的full screen example,並按照上面的建議進行編輯。使用默認的控制命令F快捷鍵在全屏幕之間來回切換將在全屏幕中顯示其下方有文本的框架的opengl視圖。使用示例中編碼的全屏選項將切換openglview以使用全屏,而不需要額外的(Cocoa)框架,按鈕或文本。

+0

我想你的第一個例子,它只是一個CGL全屏幕表面。有關更多詳細信息,請參閱Robert P. Kuehne的書。 – 2016-02-18 22:31:37