diff options
author | tapted <tapted@chromium.org> | 2016-02-03 15:45:34 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-03 23:46:49 +0000 |
commit | eb0962214e28fcbe6349bae6214d020cfe67f7cc (patch) | |
tree | 54a2e170df606c9e90f817ae3221b7a9d7b3ea31 | |
parent | 3c0ef4309a77bbf172f081c99bbb33e732ea07af (diff) | |
download | chromium_src-eb0962214e28fcbe6349bae6214d020cfe67f7cc.zip chromium_src-eb0962214e28fcbe6349bae6214d020cfe67f7cc.tar.gz chromium_src-eb0962214e28fcbe6349bae6214d020cfe67f7cc.tar.bz2 |
Enable showing the toolkit-views simplified fullscreen UI on Mac.
Puts the new simplified fullscreen UI behind
chrome://flags/#simplified-fullscreen-ui on Mac.
It uses the toolkit-views UI, since it's already written and works
pretty well. Only few things need to be farmed out to the delegate
since the bubble can't assume its parent is a views::Widget.
Fixes a quirk where opacity-animating bubbles would briefly change
their bounds to have zero-height and back during construction. (We
complain about visible but zero-sized Widgets on Mac).
If this all works we can delete some ~700 lines of Cocoa code when
this simplified fullscreen UI is default on Mac.
BUG=352425
Review URL: https://codereview.chromium.org/1654723002
Cr-Commit-Position: refs/heads/master@{#373386}
8 files changed, 153 insertions, 31 deletions
diff --git a/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.h b/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.h index 49a2e94..1cd03e3 100644 --- a/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.h +++ b/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.h @@ -12,18 +12,24 @@ #import "base/mac/scoped_nsobject.h" #include "base/macros.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h" +#include "chrome/browser/ui/views/exclusive_access_bubble_views_context.h" +#include "ui/base/accelerators/accelerator.h" class Browser; class BrowserWindow; @class BrowserWindowController; +class ExclusiveAccessBubbleViews; @class ExclusiveAccessBubbleWindowController; class GURL; // Component placed into a browser window controller to manage communication // with the exclusive access bubble, which appears for events such as entering // fullscreen. -class ExclusiveAccessController : public ExclusiveAccessContext { +class ExclusiveAccessController : public ExclusiveAccessContext, + public ui::AcceleratorProvider, + public ExclusiveAccessBubbleViewsContext { public: ExclusiveAccessController(BrowserWindowController* controller, Browser* browser); @@ -63,6 +69,20 @@ class ExclusiveAccessController : public ExclusiveAccessContext { void UnhideDownloadShelf() override; void HideDownloadShelf() override; + // ui::AcceleratorProvider: + bool GetAcceleratorForCommandId(int command_id, + ui::Accelerator* accelerator) override; + + // ExclusiveAccessBubbleViewsContext: + ExclusiveAccessManager* GetExclusiveAccessManager() override; + views::Widget* GetBubbleAssociatedWidget() override; + ui::AcceleratorProvider* GetAcceleratorProvider() override; + gfx::NativeView GetBubbleParentView() const override; + gfx::Point GetCursorPointInParent() const override; + gfx::Rect GetClientAreaBoundsInScreen() const override; + bool IsImmersiveModeEnabled() override; + gfx::Rect GetTopContainerBoundsInScreen() override; + private: BrowserWindow* GetBrowserWindow() const; @@ -75,6 +95,7 @@ class ExclusiveAccessController : public ExclusiveAccessContext { GURL url_; ExclusiveAccessBubbleType bubble_type_; + scoped_ptr<ExclusiveAccessBubbleViews> views_bubble_; base::scoped_nsobject<ExclusiveAccessBubbleWindowController> cocoa_bubble_; DISALLOW_COPY_AND_ASSIGN(ExclusiveAccessController); diff --git a/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.mm b/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.mm index 65b44a8..7026b32 100644 --- a/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.mm +++ b/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.mm @@ -7,9 +7,13 @@ #include "chrome/browser/download/download_shelf.h" #include "chrome/browser/fullscreen.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/cocoa/accelerators_cocoa.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/exclusive_access_bubble_window_controller.h" +#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" #include "chrome/browser/ui/status_bubble.h" +#include "chrome/browser/ui/views/exclusive_access_bubble_views.h" +#import "ui/gfx/mac/coordinate_conversion.h" ExclusiveAccessController::ExclusiveAccessController( BrowserWindowController* controller, @@ -21,6 +25,12 @@ ExclusiveAccessController::ExclusiveAccessController( ExclusiveAccessController::~ExclusiveAccessController() {} void ExclusiveAccessController::Show() { + if (ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled()) { + views_bubble_.reset( + new ExclusiveAccessBubbleViews(this, url_, bubble_type_)); + return; + } + [cocoa_bubble_ closeImmediately]; cocoa_bubble_.reset([[ExclusiveAccessBubbleWindowController alloc] initWithOwner:controller_ @@ -32,6 +42,7 @@ void ExclusiveAccessController::Show() { } void ExclusiveAccessController::Destroy() { + views_bubble_.reset(); [cocoa_bubble_ closeImmediately]; cocoa_bubble_.reset(); url_ = GURL(); @@ -39,6 +50,8 @@ void ExclusiveAccessController::Destroy() { } void ExclusiveAccessController::Layout(CGFloat max_y) { + if (views_bubble_) + views_bubble_->RepositionIfVisible(); [cocoa_bubble_ positionInWindowAtTop:max_y]; } @@ -98,7 +111,8 @@ void ExclusiveAccessController::UpdateExclusiveAccessExitBubbleContent( } void ExclusiveAccessController::OnExclusiveAccessUserInput() { - // TODO(mgiuca): Route this signal to the exclusive access bubble on Mac. + if (views_bubble_) + views_bubble_->OnUserInput(); } content::WebContents* ExclusiveAccessController::GetActiveWebContents() { @@ -116,6 +130,51 @@ void ExclusiveAccessController::HideDownloadShelf() { statusBubble->Hide(); } +bool ExclusiveAccessController::GetAcceleratorForCommandId( + int cmd_id, + ui::Accelerator* accelerator) { + *accelerator = + *AcceleratorsCocoa::GetInstance()->GetAcceleratorForCommand(cmd_id); + return true; +} + +ExclusiveAccessManager* ExclusiveAccessController::GetExclusiveAccessManager() { + return browser_->exclusive_access_manager(); +} + +views::Widget* ExclusiveAccessController::GetBubbleAssociatedWidget() { + NOTREACHED(); // Only used for non-simplified UI. + return nullptr; +} + +ui::AcceleratorProvider* ExclusiveAccessController::GetAcceleratorProvider() { + return this; +} + +gfx::NativeView ExclusiveAccessController::GetBubbleParentView() const { + return [[controller_ window] contentView]; +} + +gfx::Point ExclusiveAccessController::GetCursorPointInParent() const { + NSWindow* window = [controller_ window]; + NSPoint location = [window convertScreenToBase:[NSEvent mouseLocation]]; + return gfx::Point(location.x, + NSHeight([[window contentView] frame]) - location.y); +} + +gfx::Rect ExclusiveAccessController::GetClientAreaBoundsInScreen() const { + return gfx::ScreenRectFromNSRect([[controller_ window] frame]); +} + +bool ExclusiveAccessController::IsImmersiveModeEnabled() { + return false; +} + +gfx::Rect ExclusiveAccessController::GetTopContainerBoundsInScreen() { + NOTREACHED(); // Only used for ImmersiveMode. + return gfx::Rect(); +} + BrowserWindow* ExclusiveAccessController::GetBrowserWindow() const { return [controller_ browserWindow]; } diff --git a/chrome/browser/ui/views/exclusive_access_bubble_views.cc b/chrome/browser/ui/views/exclusive_access_bubble_views.cc index 7b34b1a..55e8107 100644 --- a/chrome/browser/ui/views/exclusive_access_bubble_views.cc +++ b/chrome/browser/ui/views/exclusive_access_bubble_views.cc @@ -389,7 +389,7 @@ ExclusiveAccessBubbleViews::ExclusiveAccessBubbleViews( bubble_view_context_(context), popup_(nullptr), animation_(new gfx::SlideAnimation(this)), - animated_attribute_(ANIMATED_ATTRIBUTE_BOUNDS) { + animated_attribute_(ExpectedAnimationAttribute()) { // With the simplified fullscreen UI flag, initially hide the bubble; // otherwise, initially show it. double initial_value = @@ -399,8 +399,8 @@ ExclusiveAccessBubbleViews::ExclusiveAccessBubbleViews( // Create the contents view. ui::Accelerator accelerator(ui::VKEY_UNKNOWN, ui::EF_NONE); bool got_accelerator = - bubble_view_context_->GetBubbleAssociatedWidget()->GetAccelerator( - IDC_FULLSCREEN, &accelerator); + bubble_view_context_->GetAcceleratorProvider() + ->GetAcceleratorForCommandId(IDC_FULLSCREEN, &accelerator); DCHECK(got_accelerator); view_ = new ExclusiveAccessView(this, accelerator.GetShortcutText(), url, bubble_type_); @@ -413,8 +413,7 @@ ExclusiveAccessBubbleViews::ExclusiveAccessBubbleViews( views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.parent = - bubble_view_context_->GetBubbleAssociatedWidget()->GetNativeView(); + params.parent = bubble_view_context_->GetBubbleParentView(); // The simplified UI just shows a notice; clicks should go through to the // underlying window. params.accept_events = @@ -440,7 +439,7 @@ ExclusiveAccessBubbleViews::ExclusiveAccessBubbleViews( bubble_view_context_->GetExclusiveAccessManager() ->fullscreen_controller())); - UpdateForImmersiveState(); + UpdateMouseWatcher(); } ExclusiveAccessBubbleViews::~ExclusiveAccessBubbleViews() { @@ -492,6 +491,14 @@ views::View* ExclusiveAccessBubbleViews::GetView() { return view_; } +ExclusiveAccessBubbleViews::AnimatedAttribute +ExclusiveAccessBubbleViews::ExpectedAnimationAttribute() { + return ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled() || + bubble_view_context_->IsImmersiveModeEnabled() + ? ANIMATED_ATTRIBUTE_OPACITY + : ANIMATED_ATTRIBUTE_BOUNDS; +} + void ExclusiveAccessBubbleViews::UpdateMouseWatcher() { bool should_watch_mouse = false; if (popup_->IsVisible()) @@ -510,11 +517,7 @@ void ExclusiveAccessBubbleViews::UpdateMouseWatcher() { } void ExclusiveAccessBubbleViews::UpdateForImmersiveState() { - AnimatedAttribute expected_animated_attribute = - ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled() || - bubble_view_context_->IsImmersiveModeEnabled() - ? ANIMATED_ATTRIBUTE_OPACITY - : ANIMATED_ATTRIBUTE_BOUNDS; + AnimatedAttribute expected_animated_attribute = ExpectedAnimationAttribute(); if (animated_attribute_ != expected_animated_attribute) { // If an animation is currently in progress, skip to the end because // switching the animated attribute midway through the animation looks @@ -575,8 +578,7 @@ void ExclusiveAccessBubbleViews::AnimationEnded( gfx::Rect ExclusiveAccessBubbleViews::GetPopupRect( bool ignore_animation_state) const { gfx::Size size(view_->GetPreferredSize()); - gfx::Rect widget_bounds = bubble_view_context_->GetBubbleAssociatedWidget() - ->GetClientAreaBoundsInScreen(); + gfx::Rect widget_bounds = bubble_view_context_->GetClientAreaBoundsInScreen(); int x = widget_bounds.x() + (widget_bounds.width() - size.width()) / 2; int top_container_bottom = widget_bounds.y(); @@ -612,9 +614,7 @@ gfx::Rect ExclusiveAccessBubbleViews::GetPopupRect( } gfx::Point ExclusiveAccessBubbleViews::GetCursorScreenPoint() { - gfx::Point cursor_pos = gfx::Screen::GetScreen()->GetCursorScreenPoint(); - views::View::ConvertPointFromScreen(GetBrowserRootView(), &cursor_pos); - return cursor_pos; + return bubble_view_context_->GetCursorPointInParent(); } bool ExclusiveAccessBubbleViews::WindowContainsPoint(gfx::Point pos) { diff --git a/chrome/browser/ui/views/exclusive_access_bubble_views.h b/chrome/browser/ui/views/exclusive_access_bubble_views.h index ce614a8..3268cb9 100644 --- a/chrome/browser/ui/views/exclusive_access_bubble_views.h +++ b/chrome/browser/ui/views/exclusive_access_bubble_views.h @@ -51,6 +51,9 @@ class ExclusiveAccessBubbleViews : public ExclusiveAccessBubble, ANIMATED_ATTRIBUTE_OPACITY }; + // Returns the expected animated attribute based on flags and bubble type. + AnimatedAttribute ExpectedAnimationAttribute(); + // Starts or stops polling the mouse location based on |popup_| and // |bubble_type_|. void UpdateMouseWatcher(); diff --git a/chrome/browser/ui/views/exclusive_access_bubble_views_context.h b/chrome/browser/ui/views/exclusive_access_bubble_views_context.h index 5d0f3d4..d2300ea 100644 --- a/chrome/browser/ui/views/exclusive_access_bubble_views_context.h +++ b/chrome/browser/ui/views/exclusive_access_bubble_views_context.h @@ -5,9 +5,14 @@ #define CHROME_BROWSER_UI_VIEWS_EXCLUSIVE_ACCESS_BUBBLE_VIEWS_CONTEXT_H_ #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/native_widget_types.h" class ExclusiveAccessManager; +namespace ui { +class AcceleratorProvider; +} + namespace views { class Widget; } @@ -15,16 +20,28 @@ class Widget; // Context in which the exclusive access bubble view is initiated. class ExclusiveAccessBubbleViewsContext { public: - virtual ~ExclusiveAccessBubbleViewsContext() {} - // Returns ExclusiveAccessManager controlling exclusive access for the given // webview. virtual ExclusiveAccessManager* GetExclusiveAccessManager() = 0; // Returns the Widget that hosts the view containing the exclusive access - // bubble. + // bubble. Not used for the simplified fullscreen UI. virtual views::Widget* GetBubbleAssociatedWidget() = 0; + // Returns the AcceleratorProvider, providing the shortcut key to exit the + // exclusive access. + virtual ui::AcceleratorProvider* GetAcceleratorProvider() = 0; + + // Returns the view used to parent the bubble Widget. + virtual gfx::NativeView GetBubbleParentView() const = 0; + + // Return the current mouse cursor location, offset from the top-left of the + // parent window. + virtual gfx::Point GetCursorPointInParent() const = 0; + + // Return the current bounds (not restored bounds) of the parent window. + virtual gfx::Rect GetClientAreaBoundsInScreen() const = 0; + // Returns true if immersive mode is enabled. virtual bool IsImmersiveModeEnabled() = 0; diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 3575a25..2b316d6 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -2688,7 +2688,7 @@ int BrowserView::GetMaxTopInfoBarArrowHeight() { } /////////////////////////////////////////////////////////////////////////////// -// BrowserView, ExclusiveAccessContext overrides +// BrowserView, ExclusiveAccessContext implementation: Profile* BrowserView::GetProfile() { return browser_->profile(); } @@ -2712,19 +2712,37 @@ void BrowserView::HideDownloadShelf() { } /////////////////////////////////////////////////////////////////////////////// -// BrowserView, ExclusiveAccessBubbleViewsContext overrides +// BrowserView, ExclusiveAccessBubbleViewsContext implementation: ExclusiveAccessManager* BrowserView::GetExclusiveAccessManager() { return browser_->exclusive_access_manager(); } -bool BrowserView::IsImmersiveModeEnabled() { - return immersive_mode_controller()->IsEnabled(); -} - views::Widget* BrowserView::GetBubbleAssociatedWidget() { return GetWidget(); } +ui::AcceleratorProvider* BrowserView::GetAcceleratorProvider() { + return this; +} + +gfx::NativeView BrowserView::GetBubbleParentView() const { + return GetWidget()->GetNativeView(); +} + +gfx::Point BrowserView::GetCursorPointInParent() const { + gfx::Point cursor_pos = gfx::Screen::GetScreen()->GetCursorScreenPoint(); + views::View::ConvertPointFromScreen(GetWidget()->GetRootView(), &cursor_pos); + return cursor_pos; +} + +gfx::Rect BrowserView::GetClientAreaBoundsInScreen() const { + return GetWidget()->GetClientAreaBoundsInScreen(); +} + +bool BrowserView::IsImmersiveModeEnabled() { + return immersive_mode_controller()->IsEnabled(); +} + gfx::Rect BrowserView::GetTopContainerBoundsInScreen() { return top_container_->GetBoundsInScreen(); } diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 885b712..d2fce2f 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -464,8 +464,12 @@ class BrowserView : public BrowserWindow, // ExclusiveAccessBubbleViewsContext overrides ExclusiveAccessManager* GetExclusiveAccessManager() override; - bool IsImmersiveModeEnabled() override; views::Widget* GetBubbleAssociatedWidget() override; + ui::AcceleratorProvider* GetAcceleratorProvider() override; + gfx::NativeView GetBubbleParentView() const override; + gfx::Point GetCursorPointInParent() const override; + gfx::Rect GetClientAreaBoundsInScreen() const override; + bool IsImmersiveModeEnabled() override; gfx::Rect GetTopContainerBoundsInScreen() override; // extension::ExtensionKeybindingRegistry::Delegate overrides diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 4e1b1e9..4b0df69 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -2091,6 +2091,9 @@ 'browser/ui/views/content_setting_bubble_contents.h', 'browser/ui/views/cookie_info_view.cc', 'browser/ui/views/cookie_info_view.h', + 'browser/ui/views/exclusive_access_bubble_views.cc', + 'browser/ui/views/exclusive_access_bubble_views.h', + 'browser/ui/views/exclusive_access_bubble_views_context.h', 'browser/ui/views/extensions/extension_keybinding_registry_views.cc', 'browser/ui/views/extensions/extension_keybinding_registry_views.h', 'browser/ui/views/frame/native_widget_mac_frameless_nswindow.h', @@ -2233,9 +2236,6 @@ 'browser/ui/views/edit_search_engine_dialog.h', 'browser/ui/views/elevation_icon_setter.cc', 'browser/ui/views/elevation_icon_setter.h', - 'browser/ui/views/exclusive_access_bubble_views.cc', - 'browser/ui/views/exclusive_access_bubble_views.h', - 'browser/ui/views/exclusive_access_bubble_views_context.h', 'browser/ui/views/find_bar_host.cc', 'browser/ui/views/find_bar_host.h', 'browser/ui/views/find_bar_view.cc', |