summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorsail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-03 04:38:57 +0000
committersail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-03 04:38:57 +0000
commit6e8c06595173e67890421b44c2440ca2c772553b (patch)
tree2c706e26782727df67bbc87d0591244126772ea3 /ui
parente18217a971a5edade02107717872891adbe4e941 (diff)
downloadchromium_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
Diffstat (limited to 'ui')
-rw-r--r--ui/base/cocoa/fullscreen_window_manager.h39
-rw-r--r--ui/base/cocoa/fullscreen_window_manager.mm113
-rw-r--r--ui/base/cocoa/fullscreen_window_manager_unittest.mm31
-rw-r--r--ui/base/cocoa/underlay_opengl_hosting_window.h33
-rw-r--r--ui/base/cocoa/underlay_opengl_hosting_window.mm29
-rw-r--r--ui/ui.gyp8
-rw-r--r--ui/ui_unittests.gypi1
7 files changed, 252 insertions, 2 deletions
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
diff --git a/ui/ui.gyp b/ui/ui.gyp
index 22adc59..e8abe9ec 100644
--- a/ui/ui.gyp
+++ b/ui/ui.gyp
@@ -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',