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 {
virtual bool CanAcceptRequestUpdate() OVERRIDE { return false; }
virtual void Hide() OVERRIDE {}
virtual bool IsVisible() OVERRIDE { return false; }
private:
DownloadRequestLimiterTest* test_;
......
......@@ -104,6 +104,11 @@
regularWindow:(NSWindow*)regularWindow
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
// forcing a relayout. If |forceDropdown| is YES, this method will always
// initially show the floating bar when entering presentation mode, even if the
......@@ -133,6 +138,10 @@
- (void)enableBarVisibilityUpdates;
- (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.
- (CGFloat)toolbarDividerOpacity;
......
......@@ -37,6 +37,7 @@
#import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h"
#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.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/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
......@@ -635,6 +636,18 @@ willPositionSheet:(NSWindow*)sheet
[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
forceDropdown:(BOOL)forceDropdown {
if (presentationMode == [self inPresentationMode])
......@@ -648,9 +661,36 @@ willPositionSheet:(NSWindow*)sheet
BOOL showDropdown = !fullscreen_for_tab &&
!kiosk_mode &&
(forceDropdown || [self floatingBarHasFocus]);
NSView* contentView = [[self window] contentView];
presentationModeController_.reset(
[[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
showDropdown:showDropdown];
} else {
......@@ -777,7 +817,7 @@ willPositionSheet:(NSWindow*)sheet
if (enteringFullscreen_)
return;
[presentationModeController_ ensureOverlayHiddenWithAnimation:NO delay:NO];
[self hideOverlayIfPossibleWithAnimation:NO delay:NO];
if (fullscreenBubbleType_ == FEB_TYPE_NONE ||
fullscreenBubbleType_ == FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION) {
......@@ -871,6 +911,7 @@ willPositionSheet:(NSWindow*)sheet
[self showFullscreenExitBubbleIfNecessary];
browser_->WindowFullscreenStateChanged();
[[[self window] cr_windowView] setWantsLayer:NO];
}
- (void)windowWillExitFullScreen:(NSNotification*)notification {
......@@ -925,6 +966,13 @@ willPositionSheet:(NSWindow*)sheet
[presentationModeController_ cancelAnimationAndTimers];
}
- (void)hideOverlayIfPossibleWithAnimation:(BOOL)animation delay:(BOOL)delay {
if (!barVisibilityUpdatesEnabled_ || [barVisibilityLocks_ count])
return;
[presentationModeController_ ensureOverlayHiddenWithAnimation:animation
delay:delay];
}
- (CGFloat)toolbarDividerOpacity {
return [bookmarkBarController_ toolbarDividerOpacity];
}
......
......@@ -27,13 +27,21 @@ class PermissionBubbleCocoa : public PermissionBubbleView {
const std::vector<bool>& accept_state,
bool customization_mode) OVERRIDE;
virtual void Hide() OVERRIDE;
virtual bool IsVisible() OVERRIDE;
virtual void SetDelegate(Delegate* delegate) OVERRIDE;
virtual bool CanAcceptRequestUpdate() OVERRIDE;
// Called when |bubbleController_| is closing.
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.
Delegate* delegate_; // Weak.
......
......@@ -31,10 +31,7 @@ void PermissionBubbleCocoa::Show(
bridge:this];
}
LocationBarViewMac* location_bar =
[[parent_window_ windowController] locationBarBridge];
NSPoint anchor = location_bar->GetPageInfoBubblePoint();
[bubbleController_ showAtAnchor:[parent_window_ convertBaseToScreen:anchor]
[bubbleController_ showAtAnchor:GetAnchorPoint()
withDelegate:delegate_
forRequests:requests
acceptStates:accept_state
......@@ -45,6 +42,10 @@ void PermissionBubbleCocoa::Hide() {
[bubbleController_ close];
}
bool PermissionBubbleCocoa::IsVisible() {
return bubbleController_ != nil;
}
void PermissionBubbleCocoa::SetDelegate(Delegate* delegate) {
if (delegate_ == delegate)
return;
......@@ -62,3 +63,14 @@ bool PermissionBubbleCocoa::CanAcceptRequestUpdate() {
void PermissionBubbleCocoa::OnBubbleClosing() {
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 {
backing:NSBackingStoreBuffered
defer:NO]);
[window setAllowedAnimations:info_bubble::kAnimateNone];
[window setReleasedWhenClosed:NO];
if ((self = [super initWithWindow:window
parentWindow:parentWindow
anchoredAt:NSZeroPoint])) {
......@@ -252,6 +253,15 @@ class MenuDelegate : public ui::SimpleMenuModel::Delegate {
[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
withDelegate:(PermissionBubbleView::Delegate*)delegate
forRequests:(const std::vector<PermissionBubbleRequest*>&)requests
......
......@@ -456,6 +456,10 @@ void PermissionBubbleViewViews::Hide() {
}
}
bool PermissionBubbleViewViews::IsVisible() {
return bubble_delegate_ != NULL;
}
void PermissionBubbleViewViews::Closing() {
if (bubble_delegate_)
bubble_delegate_ = NULL;
......
......@@ -27,6 +27,7 @@ class PermissionBubbleViewViews : public PermissionBubbleView {
bool customization_mode) OVERRIDE;
virtual bool CanAcceptRequestUpdate() OVERRIDE;
virtual void Hide() OVERRIDE;
virtual bool IsVisible() OVERRIDE;
void Closing();
void Toggle(int index, bool value);
......
......@@ -50,6 +50,10 @@ class MockView : public PermissionBubbleView {
return can_accept_updates_;
}
virtual bool IsVisible() OVERRIDE {
return shown_;
}
bool shown_;
bool can_accept_updates_;
Delegate* delegate_;
......
......@@ -53,6 +53,9 @@ class PermissionBubbleView {
// Hides the permission bubble.
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_
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