diff options
author | sail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-03 04:38:57 +0000 |
---|---|---|
committer | sail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-03 04:38:57 +0000 |
commit | 6e8c06595173e67890421b44c2440ca2c772553b (patch) | |
tree | 2c706e26782727df67bbc87d0591244126772ea3 | |
parent | e18217a971a5edade02107717872891adbe4e941 (diff) | |
download | chromium_src-6e8c06595173e67890421b44c2440ca2c772553b.zip chromium_src-6e8c06595173e67890421b44c2440ca2c772553b.tar.gz chromium_src-6e8c06595173e67890421b44c2440ca2c772553b.tar.bz2 |
This CL adds pepper flash fullscreen support on Mac.
Pepper has two fullscreen APIs:
src/ppapi/cpp/fullscreen.h pp::FullScreen::SetFullscreen()
src/ppapi/cpp/private/flash_fullscreen.h pp::FlashFullScreen::SetFullscreen()
The first fullscreen API simply causes the browser window to enter fullscreen as normal. This means that the menu bar and tab strip is auto-shown when the mouse is moved to the top of the screen. This feature is already working on the Mac and this CL doesn't change anything with respect to that API.
The second fullscreen API creates a new web content that is hosted in its own window. To keep the architecture similar to the Windows and Linux implementation I decided not to host the web content inside a browser window. Instead I'm using a custom borderless window that's similar to windows that NPAPI plugins use today.
The chrome browser fullscreen window has three interesting functionality:
1. allow OpenGL surface under the window to be visible to the user
2. Setup the background color for the tab strip / toolbar drawing
3. Auto-show the menu bar / tab strip when the mouse is at the top of the screen
Of these the flash fullscreen window only needs the first. For this reason I factored out that functionality into a new common base class, UnderlayOpenGLHostingWindow.
BUG=
TEST=call pp::FlashFullscreen::SetFullscreen(true). Verify that the plugin goes fullscreen.
Review URL: http://codereview.chromium.org/9838071
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@130311 0039d316-1c4b-4281-b951-d872f2087c98
18 files changed, 347 insertions, 102 deletions
diff --git a/chrome/browser/ui/cocoa/chrome_browser_window.h b/chrome/browser/ui/cocoa/chrome_browser_window.h index 59114a2..396c6f5 100644 --- a/chrome/browser/ui/cocoa/chrome_browser_window.h +++ b/chrome/browser/ui/cocoa/chrome_browser_window.h @@ -6,24 +6,10 @@ #define CHROME_BROWSER_UI_COCOA_CHROME_BROWSER_WINDOW_H_ #pragma once -#import <Cocoa/Cocoa.h> - -#import "content/public/browser/accelerated_window_interface.h" #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h" -// Common base class for chrome browser windows. Contains methods relating to -// hole punching that are shared between framed and fullscreen windows. -@interface ChromeBrowserWindow - : ChromeEventProcessingWindow<UnderlayableSurface> { - @private - int underlaySurfaceCount_; -} - -// Informs the window that an underlay surface has been added/removed. The -// window is non-opaque while underlay surfaces are present. -- (void)underlaySurfaceAdded; -- (void)underlaySurfaceRemoved; - +// Common base class for chrome browser windows. +@interface ChromeBrowserWindow : ChromeEventProcessingWindow @end #endif // CHROME_BROWSER_UI_COCOA_CHROME_BROWSER_WINDOW_H_ diff --git a/chrome/browser/ui/cocoa/chrome_browser_window.mm b/chrome/browser/ui/cocoa/chrome_browser_window.mm index c5f1fab..b0f03d6 100644 --- a/chrome/browser/ui/cocoa/chrome_browser_window.mm +++ b/chrome/browser/ui/cocoa/chrome_browser_window.mm @@ -10,24 +10,6 @@ @implementation ChromeBrowserWindow -- (void)underlaySurfaceAdded { - DCHECK_GE(underlaySurfaceCount_, 0); - ++underlaySurfaceCount_; - - // We're having the OpenGL surface render under the window, so the window - // needs to be not opaque. - if (underlaySurfaceCount_ == 1) - [self setOpaque:NO]; -} - -- (void)underlaySurfaceRemoved { - --underlaySurfaceCount_; - DCHECK_GE(underlaySurfaceCount_, 0); - - if (underlaySurfaceCount_ == 0) - [self setOpaque:YES]; -} - - (ui::ThemeProvider*)themeProvider { id delegate = [self delegate]; if (![delegate respondsToSelector:@selector(themeProvider)]) diff --git a/chrome/browser/ui/cocoa/chrome_event_processing_window.h b/chrome/browser/ui/cocoa/chrome_event_processing_window.h index be60afd..142008d 100644 --- a/chrome/browser/ui/cocoa/chrome_event_processing_window.h +++ b/chrome/browser/ui/cocoa/chrome_event_processing_window.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,11 +9,12 @@ #import <Cocoa/Cocoa.h> #include "base/memory/scoped_nsobject.h" +#import "ui/base/cocoa/underlay_opengl_hosting_window.h" // Override NSWindow to access unhandled keyboard events (for command // processing); subclassing NSWindow is the only method to do // this. -@interface ChromeEventProcessingWindow : NSWindow { +@interface ChromeEventProcessingWindow : UnderlayOpenGLHostingWindow { @private BOOL redispatchingEvent_; BOOL eventHandled_; diff --git a/content/browser/renderer_host/accelerated_plugin_view_mac.mm b/content/browser/renderer_host/accelerated_plugin_view_mac.mm index 3571ae0..aeb86c9 100644 --- a/content/browser/renderer_host/accelerated_plugin_view_mac.mm +++ b/content/browser/renderer_host/accelerated_plugin_view_mac.mm @@ -9,8 +9,8 @@ #include "base/command_line.h" #include "base/debug/trace_event.h" #include "content/browser/renderer_host/render_widget_host_view_mac.h" -#import "content/public/browser/accelerated_window_interface.h" #include "content/public/browser/browser_thread.h" +#import "ui/base/cocoa/underlay_opengl_hosting_window.h" #include "ui/gfx/gl/gl_context.h" #include "ui/gfx/gl/gl_switches.h" #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" diff --git a/content/browser/renderer_host/accelerated_plugin_view_mac_unittest.mm b/content/browser/renderer_host/accelerated_plugin_view_mac_unittest.mm index 8ad3334..3a4464a 100644 --- a/content/browser/renderer_host/accelerated_plugin_view_mac_unittest.mm +++ b/content/browser/renderer_host/accelerated_plugin_view_mac_unittest.mm @@ -5,9 +5,9 @@ #include "content/browser/renderer_host/accelerated_plugin_view_mac.h" #include "base/logging.h" -#import "content/public/browser/accelerated_window_interface.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" +#import "ui/base/cocoa/underlay_opengl_hosting_window.h" @interface UnderlayCountingWindow : NSWindow<UnderlayableSurface> { @private diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index f676635..6530195 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h @@ -22,6 +22,7 @@ #include "webkit/glue/webcursor.h" @class AcceleratedPluginView; +@class FullscreenWindowManager; class RenderWidgetHostViewMac; @protocol RenderWidgetHostViewMacDelegate; class RenderWidgetHostViewMacEditCommandHelper; @@ -358,6 +359,10 @@ class RenderWidgetHostViewMac : public content::RenderWidgetHostViewBase { // Helper class for managing instances of accelerated plug-ins. AcceleratedSurfaceContainerManagerMac plugin_container_manager_; + NSWindow* pepper_fullscreen_window() const { + return pepper_fullscreen_window_; + } + private: friend class content::RenderWidgetHostView; @@ -413,6 +418,10 @@ class RenderWidgetHostViewMac : public content::RenderWidgetHostViewBase { gfx::PluginWindowHandle compositing_surface_; + // The fullscreen window used for pepper flash. + scoped_nsobject<NSWindow> pepper_fullscreen_window_; + scoped_nsobject<FullscreenWindowManager> fullscreen_window_manager_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMac); }; diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index c1434b3..0947af9 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -43,6 +43,8 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebScreenInfoFactory.h" #import "third_party/mozilla/ComplexTextInputPanel.h" #include "third_party/skia/include/core/SkColor.h" +#import "ui/base/cocoa/fullscreen_window_manager.h" +#import "ui/base/cocoa/underlay_opengl_hosting_window.h" #include "ui/gfx/point.h" #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" #include "ui/gfx/surface/io_surface_support_mac.h" @@ -119,6 +121,25 @@ static inline int ToWebKitModifiers(NSUInteger flags) { // NSEvent subtype for scroll gestures events. static const short kIOHIDEventTypeScroll = 6; +// A window subclass that allows the fullscreen window to become main and gain +// keyboard focus. This is only used for pepper flash. Normal fullscreen is +// handled by the browser. +@interface PepperFlashFullscreenWindow : UnderlayOpenGLHostingWindow +@end + +@implementation PepperFlashFullscreenWindow + +- (BOOL)canBecomeKeyWindow { + return YES; +} + +- (BOOL)canBecomeMainWindow { + return YES; +} + +@end + + namespace { // Maximum number of characters we allow in a tooltip. @@ -293,9 +314,37 @@ void RenderWidgetHostViewMac::InitAsPopup( [cocoa_view_ setFrame:initial_frame]; } +// This function creates the fullscreen window and hides the dock and menubar if +// necessary. Note, this codepath is only used for pepper flash when +// pp::FlashFullScreen::SetFullscreen() is called. If +// pp::FullScreen::SetFullscreen() is called then the entire browser window +// will enter fullscreen instead. void RenderWidgetHostViewMac::InitAsFullscreen( - RenderWidgetHostView* /*reference_host_view*/) { - NOTIMPLEMENTED() << "Full screen not implemented on Mac"; + RenderWidgetHostView* reference_host_view) { + NSWindow* parent_window = nil; + if (reference_host_view) + parent_window = [reference_host_view->GetNativeView() window]; + NSScreen* screen = [parent_window screen]; + if (!screen) + screen = [NSScreen mainScreen]; + + pepper_fullscreen_window_.reset([[PepperFlashFullscreenWindow alloc] + initWithContentRect:[screen frame] + styleMask:NSBorderlessWindowMask + backing:NSBackingStoreBuffered + defer:NO]); + [pepper_fullscreen_window_ setLevel:NSFloatingWindowLevel]; + [pepper_fullscreen_window_ setReleasedWhenClosed:NO]; + [cocoa_view_ setCanBeKeyView:YES]; + [cocoa_view_ setFrame:[[pepper_fullscreen_window_ contentView] bounds]]; + [cocoa_view_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [[pepper_fullscreen_window_ contentView] addSubview:cocoa_view_]; + + fullscreen_window_manager_.reset([[FullscreenWindowManager alloc] + initWithWindow:pepper_fullscreen_window_.get() + desiredScreen:screen]); + [fullscreen_window_manager_ enterFullscreenMode]; + [pepper_fullscreen_window_ makeKeyAndOrderFront:nil]; } RenderWidgetHost* RenderWidgetHostViewMac::GetRenderWidgetHost() const { @@ -633,6 +682,11 @@ void RenderWidgetHostViewMac::Destroy() { [cocoa_view_ removeFromSuperview]; [cocoa_view_ autorelease]; + [fullscreen_window_manager_ exitFullscreenMode]; + fullscreen_window_manager_.reset(); + [pepper_fullscreen_window_ close]; + pepper_fullscreen_window_.reset(); + // We get this call just before |render_widget_host_| deletes // itself. But we are owned by |cocoa_view_|, which may be retained // by some other code. Examples are WebContentsViewMac's @@ -1487,6 +1541,15 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) { NativeWebKeyboardEvent event(theEvent); + // Force fullscreen windows to close on Escape so they won't keep the keyboard + // grabbed or be stuck onscreen if the renderer is hanging. + if (event.type == NativeWebKeyboardEvent::RawKeyDown && + event.windowsKeyCode == ui::VKEY_ESCAPE && + renderWidgetHostView_->pepper_fullscreen_window()) { + widgetHost->Shutdown(); + return; + } + // We only handle key down events and just simply forward other events. if ([theEvent type] != NSKeyDown) { widgetHost->ForwardKeyboardEvent(event); diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm index 78491a3..17be33c 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm @@ -201,3 +201,8 @@ TEST_F(RenderWidgetHostViewMacTest, TakesFocusOnMouseDownWithAcceleratedView) { // Clean up. rwhv_mac_->DestroyFakePluginWindowHandle(accelerated_handle); } + +TEST_F(RenderWidgetHostViewMacTest, Fullscreen) { + rwhv_mac_->InitAsFullscreen(NULL); + EXPECT_TRUE(rwhv_mac_->pepper_fullscreen_window()); +} diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 4425a07..32bdc65 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -28,7 +28,6 @@ ], 'sources': [ 'port/browser/render_widget_host_view_port.h', - 'public/browser/accelerated_window_interface.h', 'public/browser/access_token_store.h', 'public/browser/browser_accessibility_state.h', 'public/browser/browser_child_process_host.h', diff --git a/content/public/browser/accelerated_window_interface.h b/content/public/browser/accelerated_window_interface.h deleted file mode 100644 index 7a6a2bc..0000000 --- a/content/public/browser/accelerated_window_interface.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_PUBLIC_BROWSER_ACCELERATED_WINDOW_INTERFACE_H_ -#define CONTENT_PUBLIC_BROWSER_ACCELERATED_WINDOW_INTERFACE_H_ -#pragma once - -// Protocol implemented by windows that need to be informed explicitly about -// underlay surfaces. -@protocol UnderlayableSurface -- (void)underlaySurfaceAdded; -- (void)underlaySurfaceRemoved; -@end - -#endif // CONTENT_PUBLIC_BROWSER_ACCELERATED_WINDOW_INTERFACE_H_ diff --git a/content/shell/shell_mac.mm b/content/shell/shell_mac.mm index 6e55a9e..b01bd4d0 100644 --- a/content/shell/shell_mac.mm +++ b/content/shell/shell_mac.mm @@ -11,46 +11,12 @@ #import "base/memory/scoped_nsobject.h" #include "base/string_piece.h" #include "base/sys_string_conversions.h" -#import "content/public/browser/accelerated_window_interface.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_view.h" #include "content/shell/resource.h" #include "googleurl/src/gurl.h" - -@interface ShellWindow : NSWindow<UnderlayableSurface> { - @private - int underlaySurfaceCount_; -} - -// Informs the window that an underlay surface has been added/removed. The -// window is non-opaque while underlay surfaces are present. -- (void)underlaySurfaceAdded; -- (void)underlaySurfaceRemoved; - -@end - -@implementation ShellWindow - -- (void)underlaySurfaceAdded { - DCHECK_GE(underlaySurfaceCount_, 0); - ++underlaySurfaceCount_; - - // We're having the OpenGL surface render under the window, so the window - // needs to be not opaque. - if (underlaySurfaceCount_ == 1) - [self setOpaque:NO]; -} - -- (void)underlaySurfaceRemoved { - --underlaySurfaceCount_; - DCHECK_GE(underlaySurfaceCount_, 0); - - if (underlaySurfaceCount_ == 0) - [self setOpaque:YES]; -} - -@end +#import "ui/base/cocoa/underlay_opengl_hosting_window.h" // Receives notification that the window is closing so that it can start the // tear-down process. Is responsible for deleting itself when done. @@ -177,14 +143,14 @@ void Shell::PlatformSetIsLoading(bool loading) { void Shell::PlatformCreateWindow(int width, int height) { NSRect initial_window_bounds = NSMakeRect(0, 0, width, height); - window_ = - [[ShellWindow alloc] initWithContentRect:initial_window_bounds - styleMask:(NSTitledWindowMask | - NSClosableWindowMask | - NSMiniaturizableWindowMask | - NSResizableWindowMask ) - backing:NSBackingStoreBuffered - defer:NO]; + window_ = [[UnderlayOpenGLHostingWindow alloc] + initWithContentRect:initial_window_bounds + styleMask:(NSTitledWindowMask | + NSClosableWindowMask | + NSMiniaturizableWindowMask | + NSResizableWindowMask ) + backing:NSBackingStoreBuffered + defer:NO]; [window_ setTitle:kWindowTitle]; NSView* content = [window_ contentView]; diff --git a/ui/base/cocoa/fullscreen_window_manager.h b/ui/base/cocoa/fullscreen_window_manager.h new file mode 100644 index 0000000..6564ce9 --- /dev/null +++ b/ui/base/cocoa/fullscreen_window_manager.h @@ -0,0 +1,39 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_BASE_COCOA_FULLSCREEN_WINDOW_MANAGER_H_ +#define UI_BASE_COCOA_FULLSCREEN_WINDOW_MANAGER_H_ +#pragma once + +#import <Cocoa/Cocoa.h> + +#include "base/mac/mac_util.h" +#include "base/memory/scoped_nsobject.h" + +// A utility class to manage the fullscreen mode for a given window. This class +// also updates the window frame if the screen changes. +@interface FullscreenWindowManager : NSObject { + @private + scoped_nsobject<NSWindow> window_; + // Explicitly keep track of the screen we want to position the window in. + // This is better than using -[NSWindow screen] because that might change if + // the screen changes to a low resolution. + scoped_nsobject<NSScreen> desiredScreen_; + base::mac::FullScreenMode fullscreenMode_; + BOOL fullscreenActive_; +} + +- (id)initWithWindow:(NSWindow*)window + desiredScreen:(NSScreen*)desiredScreen; + +// Enables fullscreen mode which causes the menubar and dock to be hidden as +// needed. +- (void)enterFullscreenMode; + +// Exists fullscreen mode which stops hiding the menubar and dock. +- (void)exitFullscreenMode; + +@end + +#endif // UI_BASE_COCOA_FULLSCREEN_WINDOW_MANAGER_H_ diff --git a/ui/base/cocoa/fullscreen_window_manager.mm b/ui/base/cocoa/fullscreen_window_manager.mm new file mode 100644 index 0000000..8482168 --- /dev/null +++ b/ui/base/cocoa/fullscreen_window_manager.mm @@ -0,0 +1,113 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ui/base/cocoa/fullscreen_window_manager.h" + +namespace { + +// Get the screen with the menu bar. +NSScreen* GetMenuBarScreen() { + // Documentation in NSScreen says that the first object in + // +[NSScreen screens] is the menu bar screen. + NSArray *screens = [NSScreen screens]; + if ([screens count]) + return [screens objectAtIndex:0]; + return nil; +} + +// Get the screen with the dock. +NSScreen* GetDockScreen() { + NSArray *screens = [NSScreen screens]; + NSUInteger count = [screens count]; + if (count == 0) + return NULL; + if (count == 1) + return [screens objectAtIndex:0]; + + for (NSUInteger i = 1; i < count; ++i) { + NSScreen* screen = [screens objectAtIndex:i]; + // This screen is not the menu bar screen since it's not index 0. Therefore, + // the only reason that the frame would not match the visible frame is if + // the dock is on the screen. + if (!NSEqualRects([screen frame], [screen visibleFrame])) + return screen; + } + return [screens objectAtIndex:0]; +} + +} // namespace + +@interface FullscreenWindowManager() +- (void)onScreenChanged:(NSNotification*)note; +- (void)update; +@end + +@implementation FullscreenWindowManager + +- (id)initWithWindow:(NSWindow*)window + desiredScreen:(NSScreen*)desiredScreen { + if ((self = [super init])) { + window_.reset([window retain]); + desiredScreen_.reset([desiredScreen retain]); + fullscreenMode_ = base::mac::kFullScreenModeNormal; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(onScreenChanged:) + name:NSApplicationDidChangeScreenParametersNotification + object:NSApp]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self exitFullscreenMode]; + [super dealloc]; +} + +- (void)enterFullscreenMode { + if (fullscreenActive_) + return; + fullscreenActive_ = true; + [self update]; +} + +- (void)exitFullscreenMode { + if (!fullscreenActive_) + return; + fullscreenActive_ = false; + [self update]; +} + +- (void)onScreenChanged:(NSNotification*)note { + [self update]; +} + +- (void)update { + if (![[NSScreen screens] containsObject:desiredScreen_]) + desiredScreen_.reset([[window_ screen] retain]); + + base::mac::FullScreenMode newMode; + if (!fullscreenActive_) + newMode = base::mac::kFullScreenModeNormal; + else if (desiredScreen_ == GetMenuBarScreen()) + newMode = base::mac::kFullScreenModeHideAll; + else if (desiredScreen_ == GetDockScreen()) + newMode = base::mac::kFullScreenModeHideDock; + else + newMode = base::mac::kFullScreenModeNormal; + + if (fullscreenMode_ != newMode) { + if (fullscreenMode_ != base::mac::kFullScreenModeNormal) + base::mac::ReleaseFullScreen(fullscreenMode_); + if (newMode != base::mac::kFullScreenModeNormal) + base::mac::RequestFullScreen(newMode); + fullscreenMode_ = newMode; + } + + if (fullscreenActive_) + [window_ setFrame:[desiredScreen_ frame] display:YES]; +} + +@end diff --git a/ui/base/cocoa/fullscreen_window_manager_unittest.mm b/ui/base/cocoa/fullscreen_window_manager_unittest.mm new file mode 100644 index 0000000..eee5097 --- /dev/null +++ b/ui/base/cocoa/fullscreen_window_manager_unittest.mm @@ -0,0 +1,31 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ui/base/cocoa/fullscreen_window_manager.h" + + +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" +#import "ui/base/test/ui_cocoa_test_helper.h" + +typedef ui::CocoaTest FullscreenWindowManagerTest; + +TEST_F(FullscreenWindowManagerTest, EnterExit) { + scoped_nsobject<FullscreenWindowManager> manager( + [[FullscreenWindowManager alloc] + initWithWindow:test_window() + desiredScreen:[NSScreen mainScreen]]); + + SystemUIMode mode = kUIModeNormal; + GetSystemUIMode(&mode, NULL); + EXPECT_EQ(kUIModeNormal, mode); + + [manager enterFullscreenMode]; + GetSystemUIMode(&mode, NULL); + EXPECT_EQ(kUIModeAllHidden, mode); + + [manager exitFullscreenMode]; + GetSystemUIMode(&mode, NULL); + EXPECT_EQ(kUIModeNormal, mode); +} diff --git a/ui/base/cocoa/underlay_opengl_hosting_window.h b/ui/base/cocoa/underlay_opengl_hosting_window.h new file mode 100644 index 0000000..caa3cf0 --- /dev/null +++ b/ui/base/cocoa/underlay_opengl_hosting_window.h @@ -0,0 +1,33 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_BASE_COCOA_UNDERLAY_OPENGL_HOSTING_WINDOW_H_ +#define UI_BASE_COCOA_UNDERLAY_OPENGL_HOSTING_WINDOW_H_ +#pragma once + +#import <Cocoa/Cocoa.h> + +// Protocol implemented by windows that need to be informed explicitly about +// underlay surfaces. +@protocol UnderlayableSurface +- (void)underlaySurfaceAdded; +- (void)underlaySurfaceRemoved; +@end + +// Common base class for windows that host a OpenGL surface that renders under +// the window. Contains methods relating to hole punching so that the OpenGL +// surface is visible through the window. +@interface UnderlayOpenGLHostingWindow : NSWindow<UnderlayableSurface> { + @private + int underlaySurfaceCount_; +} + +// Informs the window that an underlay surface has been added/removed. The +// window is non-opaque while underlay surfaces are present. +- (void)underlaySurfaceAdded; +- (void)underlaySurfaceRemoved; + +@end + +#endif // UI_BASE_COCOA_UNDERLAY_OPENGL_HOSTING_WINDOW_H_ diff --git a/ui/base/cocoa/underlay_opengl_hosting_window.mm b/ui/base/cocoa/underlay_opengl_hosting_window.mm new file mode 100644 index 0000000..95f36af --- /dev/null +++ b/ui/base/cocoa/underlay_opengl_hosting_window.mm @@ -0,0 +1,29 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ui/base/cocoa/underlay_opengl_hosting_window.h" + +#include "base/logging.h" + +@implementation UnderlayOpenGLHostingWindow + +- (void)underlaySurfaceAdded { + DCHECK_GE(underlaySurfaceCount_, 0); + ++underlaySurfaceCount_; + + // We're having the OpenGL surface render under the window, so the window + // needs to be not opaque. + if (underlaySurfaceCount_ == 1) + [self setOpaque:NO]; +} + +- (void)underlaySurfaceRemoved { + --underlaySurfaceCount_; + DCHECK_GE(underlaySurfaceCount_, 0); + + if (underlaySurfaceCount_ == 0) + [self setOpaque:YES]; +} + +@end @@ -91,10 +91,14 @@ 'base/cocoa/base_view.h', 'base/cocoa/base_view.mm', 'base/cocoa/events_mac.mm', - 'base/cocoa/focus_tracker.h', - 'base/cocoa/focus_tracker.mm', 'base/cocoa/find_pasteboard.h', 'base/cocoa/find_pasteboard.mm', + 'base/cocoa/focus_tracker.h', + 'base/cocoa/focus_tracker.mm', + 'base/cocoa/fullscreen_window_manager.h', + 'base/cocoa/fullscreen_window_manager.mm', + 'base/cocoa/underlay_opengl_hosting_window.h', + 'base/cocoa/underlay_opengl_hosting_window.mm', 'base/dragdrop/cocoa_dnd_util.h', 'base/dragdrop/cocoa_dnd_util.mm', 'base/dragdrop/drag_drop_types_gtk.cc', diff --git a/ui/ui_unittests.gypi b/ui/ui_unittests.gypi index 6a998db..2feb4b0 100644 --- a/ui/ui_unittests.gypi +++ b/ui/ui_unittests.gypi @@ -56,6 +56,7 @@ 'base/clipboard/clipboard_unittest.cc', 'base/clipboard/custom_data_helper_unittest.cc', 'base/cocoa/base_view_unittest.mm', + 'base/cocoa/fullscreen_window_manager_unittest.mm', 'base/cocoa/events_mac_unittest.mm', 'base/cocoa/focus_tracker_unittest.mm', 'base/gtk/gtk_expanded_container_unittest.cc', |