Commit 1d7114f8 authored by leng@chromium.org's avatar leng@chromium.org

Enables permission bubbles to remain visible during fullscreen on Mac.

Adds IsVisible() function to PermissionBubbleView so that the browser window
knows if it is currently being shown.  It's added to the base class, rather than
just the cocoa implementation, because similar functionality will likely be
used for views in the future.

Adds alwaysShowDropdown property to the PresentationModeController.
When set to YES, it disables hiding of the dropdown - toolbar and tab strip.

Also adds a hack to ensure the UI is drawn correctly when entering fullscreen
mode.  Specifically, for the duration of the animation, the top-level view for
the browser window has setWantsLayer set to YES.  Without this, tabStripView
is not rendered into the destination frame for the animation.  (It is a sibling of
the content view, not a subview, and I believe that the non-layer-based
render path bypasses it when the animation begins.)  I could not come up
with any other mechanism to fix this, and without it, fullscreen looks quite
bad - the toolbar displays properly, but the tab strip is missing.

BUG=384260

Review URL: https://codereview.chromium.org/390503003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284438 0039d316-1c4b-4281-b951-d872f2087c98
parent 2d5fe8ed
...@@ -48,6 +48,7 @@ class FakePermissionBubbleView : public PermissionBubbleView { ...@@ -48,6 +48,7 @@ class FakePermissionBubbleView : public PermissionBubbleView {
virtual bool CanAcceptRequestUpdate() OVERRIDE { return false; } virtual bool CanAcceptRequestUpdate() OVERRIDE { return false; }
virtual void Hide() OVERRIDE {} virtual void Hide() OVERRIDE {}
virtual bool IsVisible() OVERRIDE { return false; }
private: private:
DownloadRequestLimiterTest* test_; DownloadRequestLimiterTest* test_;
......
...@@ -104,6 +104,11 @@ ...@@ -104,6 +104,11 @@
regularWindow:(NSWindow*)regularWindow regularWindow:(NSWindow*)regularWindow
fullscreenWindow:(NSWindow*)fullscreenWindow; fullscreenWindow:(NSWindow*)fullscreenWindow;
// Called when a permission bubble closes, and informs the presentation
// controller that the dropdown can be hidden. (The dropdown should never be
// hidden while a permissions bubble is visible.)
- (void)permissionBubbleWindowWillClose:(NSNotification*)notification;
// Sets presentation mode, creating the PresentationModeController if needed and // Sets presentation mode, creating the PresentationModeController if needed and
// forcing a relayout. If |forceDropdown| is YES, this method will always // forcing a relayout. If |forceDropdown| is YES, this method will always
// initially show the floating bar when entering presentation mode, even if the // initially show the floating bar when entering presentation mode, even if the
...@@ -133,6 +138,10 @@ ...@@ -133,6 +138,10 @@
- (void)enableBarVisibilityUpdates; - (void)enableBarVisibilityUpdates;
- (void)disableBarVisibilityUpdates; - (void)disableBarVisibilityUpdates;
// If there are no visibility locks and bar visibity updates are enabled, hides
// the bar with |animation| and |delay|. Otherwise, does nothing.
- (void)hideOverlayIfPossibleWithAnimation:(BOOL)animation delay:(BOOL)delay;
// The opacity for the toolbar divider; 0 means that it shouldn't be shown. // The opacity for the toolbar divider; 0 means that it shouldn't be shown.
- (CGFloat)toolbarDividerOpacity; - (CGFloat)toolbarDividerOpacity;
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h"
#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
#import "chrome/browser/ui/cocoa/version_independent_window.h" #import "chrome/browser/ui/cocoa/version_independent_window.h"
#import "chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h"
#include "chrome/browser/ui/fullscreen/fullscreen_controller.h" #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
...@@ -635,6 +636,18 @@ willPositionSheet:(NSWindow*)sheet ...@@ -635,6 +636,18 @@ willPositionSheet:(NSWindow*)sheet
[self enableBarVisibilityUpdates]; [self enableBarVisibilityUpdates];
} }
- (void)permissionBubbleWindowWillClose:(NSNotification*)notification {
DCHECK(permissionBubbleCocoa_);
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
[center removeObserver:self
name:NSWindowWillCloseNotification
object:[notification object]];
[self releaseBarVisibilityForOwner:[notification object]
withAnimation:YES
delay:YES];
}
- (void)setPresentationModeInternal:(BOOL)presentationMode - (void)setPresentationModeInternal:(BOOL)presentationMode
forceDropdown:(BOOL)forceDropdown { forceDropdown:(BOOL)forceDropdown {
if (presentationMode == [self inPresentationMode]) if (presentationMode == [self inPresentationMode])
...@@ -648,9 +661,36 @@ willPositionSheet:(NSWindow*)sheet ...@@ -648,9 +661,36 @@ willPositionSheet:(NSWindow*)sheet
BOOL showDropdown = !fullscreen_for_tab && BOOL showDropdown = !fullscreen_for_tab &&
!kiosk_mode && !kiosk_mode &&
(forceDropdown || [self floatingBarHasFocus]); (forceDropdown || [self floatingBarHasFocus]);
NSView* contentView = [[self window] contentView];
presentationModeController_.reset( presentationModeController_.reset(
[[PresentationModeController alloc] initWithBrowserController:self]); [[PresentationModeController alloc] initWithBrowserController:self]);
if (permissionBubbleCocoa_ && permissionBubbleCocoa_->IsVisible()) {
DCHECK(permissionBubbleCocoa_->window());
// A visible permission bubble will force the dropdown to remain visible.
[self lockBarVisibilityForOwner:permissionBubbleCocoa_->window()
withAnimation:NO
delay:NO];
showDropdown = YES;
// Register to be notified when the permission bubble is closed, to
// allow fullscreen to hide the dropdown.
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
[center addObserver:self
selector:@selector(permissionBubbleWindowWillClose:)
name:NSWindowWillCloseNotification
object:permissionBubbleCocoa_->window()];
}
if (showDropdown) {
// Turn on layered mode for the window's root view for the entry
// animation. Without this, the OS fullscreen animation for entering
// fullscreen mode does not correctly draw the tab strip.
// It will be turned off (set back to NO) when the animation finishes,
// in -windowDidEnterFullScreen:.
// Leaving wantsLayer on for the duration of presentation mode causes
// performance issues when the dropdown is animated in/out. It also does
// not seem to be required for the exit animation.
[[[self window] cr_windowView] setWantsLayer:YES];
}
NSView* contentView = [[self window] contentView];
[presentationModeController_ enterPresentationModeForContentView:contentView [presentationModeController_ enterPresentationModeForContentView:contentView
showDropdown:showDropdown]; showDropdown:showDropdown];
} else { } else {
...@@ -777,7 +817,7 @@ willPositionSheet:(NSWindow*)sheet ...@@ -777,7 +817,7 @@ willPositionSheet:(NSWindow*)sheet
if (enteringFullscreen_) if (enteringFullscreen_)
return; return;
[presentationModeController_ ensureOverlayHiddenWithAnimation:NO delay:NO]; [self hideOverlayIfPossibleWithAnimation:NO delay:NO];
if (fullscreenBubbleType_ == FEB_TYPE_NONE || if (fullscreenBubbleType_ == FEB_TYPE_NONE ||
fullscreenBubbleType_ == FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION) { fullscreenBubbleType_ == FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION) {
...@@ -871,6 +911,7 @@ willPositionSheet:(NSWindow*)sheet ...@@ -871,6 +911,7 @@ willPositionSheet:(NSWindow*)sheet
[self showFullscreenExitBubbleIfNecessary]; [self showFullscreenExitBubbleIfNecessary];
browser_->WindowFullscreenStateChanged(); browser_->WindowFullscreenStateChanged();
[[[self window] cr_windowView] setWantsLayer:NO];
} }
- (void)windowWillExitFullScreen:(NSNotification*)notification { - (void)windowWillExitFullScreen:(NSNotification*)notification {
...@@ -925,6 +966,13 @@ willPositionSheet:(NSWindow*)sheet ...@@ -925,6 +966,13 @@ willPositionSheet:(NSWindow*)sheet
[presentationModeController_ cancelAnimationAndTimers]; [presentationModeController_ cancelAnimationAndTimers];
} }
- (void)hideOverlayIfPossibleWithAnimation:(BOOL)animation delay:(BOOL)delay {
if (!barVisibilityUpdatesEnabled_ || [barVisibilityLocks_ count])
return;
[presentationModeController_ ensureOverlayHiddenWithAnimation:animation
delay:delay];
}
- (CGFloat)toolbarDividerOpacity { - (CGFloat)toolbarDividerOpacity {
return [bookmarkBarController_ toolbarDividerOpacity]; return [bookmarkBarController_ toolbarDividerOpacity];
} }
......
...@@ -27,13 +27,21 @@ class PermissionBubbleCocoa : public PermissionBubbleView { ...@@ -27,13 +27,21 @@ class PermissionBubbleCocoa : public PermissionBubbleView {
const std::vector<bool>& accept_state, const std::vector<bool>& accept_state,
bool customization_mode) OVERRIDE; bool customization_mode) OVERRIDE;
virtual void Hide() OVERRIDE; virtual void Hide() OVERRIDE;
virtual bool IsVisible() OVERRIDE;
virtual void SetDelegate(Delegate* delegate) OVERRIDE; virtual void SetDelegate(Delegate* delegate) OVERRIDE;
virtual bool CanAcceptRequestUpdate() OVERRIDE; virtual bool CanAcceptRequestUpdate() OVERRIDE;
// Called when |bubbleController_| is closing. // Called when |bubbleController_| is closing.
void OnBubbleClosing(); void OnBubbleClosing();
private: // Returns the point, in screen coordinates, to which the bubble's arrow
// should point.
NSPoint GetAnchorPoint();
// Returns the NSWindow containing the bubble.
NSWindow* window();
private:
NSWindow* parent_window_; // Weak. NSWindow* parent_window_; // Weak.
Delegate* delegate_; // Weak. Delegate* delegate_; // Weak.
......
...@@ -31,10 +31,7 @@ void PermissionBubbleCocoa::Show( ...@@ -31,10 +31,7 @@ void PermissionBubbleCocoa::Show(
bridge:this]; bridge:this];
} }
LocationBarViewMac* location_bar = [bubbleController_ showAtAnchor:GetAnchorPoint()
[[parent_window_ windowController] locationBarBridge];
NSPoint anchor = location_bar->GetPageInfoBubblePoint();
[bubbleController_ showAtAnchor:[parent_window_ convertBaseToScreen:anchor]
withDelegate:delegate_ withDelegate:delegate_
forRequests:requests forRequests:requests
acceptStates:accept_state acceptStates:accept_state
...@@ -45,6 +42,10 @@ void PermissionBubbleCocoa::Hide() { ...@@ -45,6 +42,10 @@ void PermissionBubbleCocoa::Hide() {
[bubbleController_ close]; [bubbleController_ close];
} }
bool PermissionBubbleCocoa::IsVisible() {
return bubbleController_ != nil;
}
void PermissionBubbleCocoa::SetDelegate(Delegate* delegate) { void PermissionBubbleCocoa::SetDelegate(Delegate* delegate) {
if (delegate_ == delegate) if (delegate_ == delegate)
return; return;
...@@ -62,3 +63,14 @@ bool PermissionBubbleCocoa::CanAcceptRequestUpdate() { ...@@ -62,3 +63,14 @@ bool PermissionBubbleCocoa::CanAcceptRequestUpdate() {
void PermissionBubbleCocoa::OnBubbleClosing() { void PermissionBubbleCocoa::OnBubbleClosing() {
bubbleController_ = nil; bubbleController_ = nil;
} }
NSPoint PermissionBubbleCocoa::GetAnchorPoint() {
LocationBarViewMac* location_bar =
[[parent_window_ windowController] locationBarBridge];
NSPoint anchor = location_bar->GetPageInfoBubblePoint();
return [parent_window_ convertBaseToScreen:anchor];
}
NSWindow* PermissionBubbleCocoa::window() {
return [bubbleController_ window];
}
...@@ -236,6 +236,7 @@ class MenuDelegate : public ui::SimpleMenuModel::Delegate { ...@@ -236,6 +236,7 @@ class MenuDelegate : public ui::SimpleMenuModel::Delegate {
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:NO]); defer:NO]);
[window setAllowedAnimations:info_bubble::kAnimateNone]; [window setAllowedAnimations:info_bubble::kAnimateNone];
[window setReleasedWhenClosed:NO];
if ((self = [super initWithWindow:window if ((self = [super initWithWindow:window
parentWindow:parentWindow parentWindow:parentWindow
anchoredAt:NSZeroPoint])) { anchoredAt:NSZeroPoint])) {
...@@ -252,6 +253,15 @@ class MenuDelegate : public ui::SimpleMenuModel::Delegate { ...@@ -252,6 +253,15 @@ class MenuDelegate : public ui::SimpleMenuModel::Delegate {
[super windowWillClose:notification]; [super windowWillClose:notification];
} }
- (void)parentWindowWillBecomeFullScreen:(NSNotification*)notification {
// Override the base class implementation, which would have closed the bubble.
}
- (void)parentWindowDidResize:(NSNotification*)notification {
DCHECK(bridge_);
[self setAnchorPoint:bridge_->GetAnchorPoint()];
}
- (void)showAtAnchor:(NSPoint)anchorPoint - (void)showAtAnchor:(NSPoint)anchorPoint
withDelegate:(PermissionBubbleView::Delegate*)delegate withDelegate:(PermissionBubbleView::Delegate*)delegate
forRequests:(const std::vector<PermissionBubbleRequest*>&)requests forRequests:(const std::vector<PermissionBubbleRequest*>&)requests
......
...@@ -456,6 +456,10 @@ void PermissionBubbleViewViews::Hide() { ...@@ -456,6 +456,10 @@ void PermissionBubbleViewViews::Hide() {
} }
} }
bool PermissionBubbleViewViews::IsVisible() {
return bubble_delegate_ != NULL;
}
void PermissionBubbleViewViews::Closing() { void PermissionBubbleViewViews::Closing() {
if (bubble_delegate_) if (bubble_delegate_)
bubble_delegate_ = NULL; bubble_delegate_ = NULL;
......
...@@ -27,6 +27,7 @@ class PermissionBubbleViewViews : public PermissionBubbleView { ...@@ -27,6 +27,7 @@ class PermissionBubbleViewViews : public PermissionBubbleView {
bool customization_mode) OVERRIDE; bool customization_mode) OVERRIDE;
virtual bool CanAcceptRequestUpdate() OVERRIDE; virtual bool CanAcceptRequestUpdate() OVERRIDE;
virtual void Hide() OVERRIDE; virtual void Hide() OVERRIDE;
virtual bool IsVisible() OVERRIDE;
void Closing(); void Closing();
void Toggle(int index, bool value); void Toggle(int index, bool value);
......
...@@ -50,6 +50,10 @@ class MockView : public PermissionBubbleView { ...@@ -50,6 +50,10 @@ class MockView : public PermissionBubbleView {
return can_accept_updates_; return can_accept_updates_;
} }
virtual bool IsVisible() OVERRIDE {
return shown_;
}
bool shown_; bool shown_;
bool can_accept_updates_; bool can_accept_updates_;
Delegate* delegate_; Delegate* delegate_;
......
...@@ -53,6 +53,9 @@ class PermissionBubbleView { ...@@ -53,6 +53,9 @@ class PermissionBubbleView {
// Hides the permission bubble. // Hides the permission bubble.
virtual void Hide() = 0; virtual void Hide() = 0;
// Returns true if there is a bubble currently showing.
virtual bool IsVisible() = 0;
}; };
#endif // CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_VIEW_H_ #endif // CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_VIEW_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment