Index: chrome/browser/ui/fullscreen_controller.cc |
diff --git a/chrome/browser/ui/fullscreen_controller.cc b/chrome/browser/ui/fullscreen_controller.cc |
index ee112589f05a2e2fd6a8f9176712207f5783aa8c..ba5e94a917182703edd216a810660fe0b081f0e8 100644 |
--- a/chrome/browser/ui/fullscreen_controller.cc |
+++ b/chrome/browser/ui/fullscreen_controller.cc |
@@ -34,6 +34,8 @@ FullscreenController::FullscreenController(BrowserWindow* window, |
fullscreened_tab_(NULL), |
tab_caused_fullscreen_(false), |
tab_fullscreen_accepted_(false), |
+ in_or_entering_fullscreen_(false), |
+ mouse_lock_tab_(NULL), |
mouse_lock_state_(MOUSELOCK_NOT_REQUESTED) { |
} |
@@ -64,29 +66,37 @@ bool FullscreenController::IsMouseLocked() const { |
} |
void FullscreenController::RequestToLockMouse(WebContents* tab, |
- bool /* user_gesture */) { |
- // TODO(scheib) user_gesture required for Mouse Lock in Windowed Mode. |
- // See http://crbug.com/107013, which will land in multiple patches. |
- |
+ bool user_gesture) { |
DCHECK(!IsMouseLocked()); |
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(&FullscreenController::NotifyMouseLockChange, this)); |
yzshen1
2012/04/30 19:32:40
Is it sufficient to send chrome::NOTIFICATION_MOUS
scheib
2012/05/01 03:27:07
Tests are the reason this notification exists. A t
|
- // Mouse Lock is only permitted when browser is in tab fullscreen. |
- if (!IsFullscreenForTabOrPending(tab)) { |
+ // Must have a user gesture, or we must already be in tab fullscreen. |
+ if (!user_gesture && !IsFullscreenForTabOrPending(tab)) { |
tab->GotResponseToLockMouseRequest(false); |
return; |
} |
+ mouse_lock_tab_ = TabContentsWrapper::GetCurrentWrapperForContents(tab); |
+ FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); |
+ |
switch (GetMouseLockSetting(tab->GetURL())) { |
case CONTENT_SETTING_ALLOW: |
- if (tab_fullscreen_accepted_) { |
- if (tab->GotResponseToLockMouseRequest(true)) |
- mouse_lock_state_ = MOUSELOCK_ACCEPTED; |
- } else { |
+ // If bubble already displaying buttons, merge mouse lock request. |
+ if (fullscreen_bubble::ShowButtonsForType(bubble_type)) { |
mouse_lock_state_ = MOUSELOCK_REQUESTED; |
yzshen1
2012/04/30 19:32:40
Please add more comment about why we need to merge
scheib
2012/05/01 03:27:07
Done.
|
+ break; |
yzshen1
2012/04/30 19:32:40
You could use an "else" on line 89 instead of two
scheib
2012/05/01 03:27:07
Done.
|
} |
+ |
+ // Lock mouse. |
+ if (tab->GotResponseToLockMouseRequest(true)) |
+ mouse_lock_state_ = MOUSELOCK_ACCEPTED; |
+ else |
+ mouse_lock_tab_ = NULL; |
yzshen1
2012/04/30 19:32:40
Shall we explicitly set mouse_lock_state_ to not r
scheib
2012/05/01 03:27:07
Done.
|
break; |
case CONTENT_SETTING_BLOCK: |
tab->GotResponseToLockMouseRequest(false); |
+ mouse_lock_tab_ = NULL; |
yzshen1
2012/04/30 19:32:40
Shall we set mouse_lock_state_ to not requested in
scheib
2012/05/01 03:27:07
Done.
|
break; |
case CONTENT_SETTING_ASK: |
mouse_lock_state_ = MOUSELOCK_REQUESTED; |
@@ -142,7 +152,7 @@ void FullscreenController::ToggleFullscreenModeForTab(WebContents* tab, |
// mode), we need to switch back to "browser fullscreen" mode. In this |
// case, all we have to do is notifying the tab that it has exited "tab |
// fullscreen" mode. |
- NotifyTabOfFullscreenExitIfNecessary(); |
+ NotifyTabOfExitIfNecessary(); |
} |
} |
} |
@@ -169,6 +179,8 @@ void FullscreenController::ToggleFullscreenModeWithExtension( |
void FullscreenController::LostMouseLock() { |
mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(&FullscreenController::NotifyMouseLockChange, this)); |
UpdateFullscreenExitBubbleContent(); |
} |
@@ -177,10 +189,10 @@ void FullscreenController::OnTabClosing(WebContents* web_contents) { |
ExitTabbedFullscreenModeIfNecessary(); |
// The call to exit fullscreen may result in asynchronous notification of |
// fullscreen state change (e.g., on Linux). We don't want to rely on it |
- // to call NotifyTabOfFullscreenExitIfNecessary(), because at that point |
+ // to call NotifyTabOfExitIfNecessary(), because at that point |
// |fullscreen_tab_| may not be valid. Instead, we call it here to clean up |
// tab fullscreen related state. |
- NotifyTabOfFullscreenExitIfNecessary(); |
+ NotifyTabOfExitIfNecessary(); |
} |
} |
@@ -196,12 +208,13 @@ void FullscreenController::OnAcceptFullscreenPermission( |
bool fullscreen = false; |
fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen, |
&mouse_lock); |
- DCHECK(fullscreened_tab_); |
- DCHECK_NE(tab_fullscreen_accepted_, fullscreen); |
+ DCHECK(!(fullscreen && tab_fullscreen_accepted_)); |
+ DCHECK(!(mouse_lock && IsMouseLocked())); |
HostContentSettingsMap* settings_map = profile_->GetHostContentSettingsMap(); |
ContentSettingsPattern pattern = ContentSettingsPattern::FromURL(url); |
- if (mouse_lock) { |
+ |
+ if (mouse_lock && !IsMouseLocked()) { |
DCHECK(IsMouseLockRequested()); |
// TODO(markusheintz): We should allow patterns for all possible URLs here. |
if (pattern.IsValid()) { |
@@ -210,11 +223,22 @@ void FullscreenController::OnAcceptFullscreenPermission( |
CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string(), |
CONTENT_SETTING_ALLOW); |
} |
- mouse_lock_state_ = |
- fullscreened_tab_->web_contents()->GotResponseToLockMouseRequest(true) ? |
- MOUSELOCK_ACCEPTED : MOUSELOCK_NOT_REQUESTED; |
+ |
+ if (mouse_lock_tab_ && |
+ mouse_lock_tab_->web_contents() && |
+ mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(true)) { |
+ mouse_lock_state_ = MOUSELOCK_ACCEPTED; |
+ } else { |
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
+ mouse_lock_tab_ = NULL; |
+ } |
+ |
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(&FullscreenController::NotifyMouseLockChange, this)); |
} |
- if (!tab_fullscreen_accepted_) { |
+ |
+ if (fullscreen && !tab_fullscreen_accepted_) { |
+ DCHECK(fullscreened_tab_); |
if (pattern.IsValid()) { |
settings_map->SetContentSetting( |
pattern, ContentSettingsPattern::Wildcard(), |
@@ -232,19 +256,24 @@ void FullscreenController::OnDenyFullscreenPermission( |
bool fullscreen = false; |
fullscreen_bubble::PermissionRequestedByType(bubble_type, &fullscreen, |
&mouse_lock); |
- DCHECK(fullscreened_tab_); |
- DCHECK_NE(tab_fullscreen_accepted_, fullscreen); |
+ DCHECK(fullscreened_tab_ || mouse_lock_tab_); |
+ DCHECK(!(fullscreen && tab_fullscreen_accepted_)); |
+ DCHECK(!(mouse_lock && IsMouseLocked())); |
if (mouse_lock) { |
DCHECK(IsMouseLockRequested()); |
mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
- fullscreened_tab_->web_contents()->GotResponseToLockMouseRequest(false); |
- if (!fullscreen) |
- UpdateFullscreenExitBubbleContent(); |
+ if (mouse_lock_tab_ && mouse_lock_tab_->web_contents()) |
+ mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(false); |
+ mouse_lock_tab_ = NULL; |
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(&FullscreenController::NotifyMouseLockChange, this)); |
} |
if (fullscreen) |
ExitTabbedFullscreenModeIfNecessary(); |
+ |
+ UpdateFullscreenExitBubbleContent(); |
yzshen1
2012/04/30 19:32:40
nit: It is previously in the "if (mouse_lock)" blo
scheib
2012/05/01 03:27:07
Done. -- Reverted to previous code; added comment
|
} |
void FullscreenController::WindowFullscreenStateChanged() { |
@@ -257,7 +286,7 @@ void FullscreenController::WindowFullscreenStateChanged() { |
exiting_fullscreen = !window_->IsFullscreen(); |
#endif |
if (exiting_fullscreen) |
- NotifyTabOfFullscreenExitIfNecessary(); |
+ NotifyTabOfExitIfNecessary(); |
#if !defined(OS_CHROMEOS) |
if (exiting_fullscreen) |
window_->GetDownloadShelf()->Unhide(); |
@@ -267,26 +296,36 @@ void FullscreenController::WindowFullscreenStateChanged() { |
} |
bool FullscreenController::HandleUserPressedEscape() { |
- if (!IsFullscreenForTabOrPending()) |
- return false; |
- ExitTabbedFullscreenModeIfNecessary(); |
- return true; |
+ if (IsFullscreenForTabOrPending() || |
+ IsMouseLocked() || IsMouseLockRequested()) { |
+ ExitTabbedFullscreenModeIfNecessary(); |
yzshen1
2012/04/30 19:32:40
I don't get it: in windowed mouse lock mode, why d
scheib
2012/05/01 03:27:07
Done: Renamed to ExitTabFullscreenOrMouseLockIfNec
|
+ return true; |
+ } |
+ |
+ return false; |
} |
FullscreenController::~FullscreenController() {} |
-void FullscreenController::NotifyTabOfFullscreenExitIfNecessary() { |
+void FullscreenController::NotifyTabOfExitIfNecessary() { |
if (fullscreened_tab_) { |
RenderViewHost* rvh = |
fullscreened_tab_->web_contents()->GetRenderViewHost(); |
fullscreened_tab_ = NULL; |
tab_caused_fullscreen_ = false; |
tab_fullscreen_accepted_ = false; |
- mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
if (rvh) |
rvh->ExitFullscreen(); |
- } else { |
- DCHECK_EQ(mouse_lock_state_, MOUSELOCK_NOT_REQUESTED); |
+ } |
+ |
+ if (mouse_lock_tab_) { |
+ WebContents* web_contents = mouse_lock_tab_->web_contents(); |
+ mouse_lock_tab_ = NULL; |
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; |
+ if (web_contents) |
+ web_contents->GotResponseToLockMouseRequest(false); |
yzshen1
2012/04/30 19:32:40
If in ACCEPTED mode, we shouldn't call GotResponse
scheib
2012/05/01 03:27:07
Done. Changed to calling RVHV::UnlockMouse() when
|
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(&FullscreenController::NotifyMouseLockChange, this)); |
} |
UpdateFullscreenExitBubbleContent(); |
@@ -296,7 +335,7 @@ void FullscreenController::ExitTabbedFullscreenModeIfNecessary() { |
if (tab_caused_fullscreen_) |
ToggleFullscreenMode(); |
else |
- NotifyTabOfFullscreenExitIfNecessary(); |
+ NotifyTabOfExitIfNecessary(); |
} |
void FullscreenController::UpdateFullscreenExitBubbleContent() { |
@@ -305,9 +344,21 @@ void FullscreenController::UpdateFullscreenExitBubbleContent() { |
url = fullscreened_tab_->web_contents()->GetURL(); |
else if (!extension_caused_fullscreen_.is_empty()) |
url = extension_caused_fullscreen_; |
+ else if (mouse_lock_tab_) |
yzshen1
2012/04/30 19:32:40
Is this order right?
Consider the following two se
scheib
2012/05/01 03:27:07
I've moved the logic for using the extension url l
|
+ url = mouse_lock_tab_->web_contents()->GetURL(); |
+ |
+ FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); |
+ |
+ // If bubble displays buttons, unlock mouse to allow pressing them. |
+ if (fullscreen_bubble::ShowButtonsForType(bubble_type) |
+ && IsMouseLocked() |
yzshen1
2012/04/30 19:32:40
&& at the end of the previous line, please.
scheib
2012/05/01 03:27:07
Done.
|
+ && mouse_lock_tab_->web_contents()) { |
+ mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(false); |
yzshen1
2012/04/30 19:32:40
GotResponseToLockMouseRequest() should only be cal
scheib
2012/05/01 03:27:07
Done. Changed to calling RVHV::UnlockMouse().
|
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(&FullscreenController::NotifyMouseLockChange, this)); |
+ } |
- window_->UpdateFullscreenExitBubbleContent(url, |
- GetFullscreenExitBubbleType()); |
+ window_->UpdateFullscreenExitBubbleContent(url, bubble_type); |
} |
void FullscreenController::NotifyFullscreenChange() { |
@@ -317,24 +368,47 @@ void FullscreenController::NotifyFullscreenChange() { |
content::NotificationService::NoDetails()); |
} |
+void FullscreenController::NotifyMouseLockChange() { |
+ content::NotificationService::current()->Notify( |
+ chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, |
+ content::Source<FullscreenController>(this), |
+ content::NotificationService::NoDetails()); |
+} |
+ |
FullscreenExitBubbleType FullscreenController::GetFullscreenExitBubbleType() |
const { |
- if (!fullscreened_tab_) { |
- DCHECK_EQ(MOUSELOCK_NOT_REQUESTED, mouse_lock_state_); |
- return !extension_caused_fullscreen_.is_empty() ? |
- FEB_TYPE_BROWSER_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION : |
- FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION; |
- } |
- if (fullscreened_tab_ && !tab_fullscreen_accepted_) { |
- DCHECK_NE(MOUSELOCK_ACCEPTED, mouse_lock_state_); |
- return mouse_lock_state_ == MOUSELOCK_REQUESTED ? |
- FEB_TYPE_FULLSCREEN_MOUSELOCK_BUTTONS : FEB_TYPE_FULLSCREEN_BUTTONS; |
+ if (fullscreened_tab_) { |
+ if (tab_fullscreen_accepted_) { |
+ if (IsMouseLocked()) { |
+ return FEB_TYPE_FULLSCREEN_MOUSELOCK_EXIT_INSTRUCTION; |
+ } else if (IsMouseLockRequested()) { |
+ return FEB_TYPE_MOUSELOCK_BUTTONS; |
+ } else { |
+ return FEB_TYPE_FULLSCREEN_EXIT_INSTRUCTION; |
+ } |
+ } else { // Full screen not yet accepted. |
+ if (IsMouseLockRequested()) |
+ return FEB_TYPE_FULLSCREEN_MOUSELOCK_BUTTONS; |
+ else |
+ return FEB_TYPE_FULLSCREEN_BUTTONS; |
+ } |
+ } else if (!extension_caused_fullscreen_.is_empty()) { |
+ return FEB_TYPE_BROWSER_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION; |
yzshen1
2012/04/30 19:32:40
Here: what if the mouse lock is requested, etc.?
scheib
2012/05/01 03:27:07
Done. This should be used similar to Browser mode
|
+ } else { // Not a full screen tab. |
+ if (IsMouseLocked()) { |
+ return FEB_TYPE_MOUSELOCK_EXIT_INSTRUCTION; |
+ } else if (IsMouseLockRequested()) { |
+ return FEB_TYPE_MOUSELOCK_BUTTONS; |
+ } else { |
+ if (in_or_entering_fullscreen_) { |
+ return FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION; |
+ } else { |
+ return FEB_TYPE_NONE; |
+ } |
+ } |
} |
- if (mouse_lock_state_ == MOUSELOCK_REQUESTED) |
- return FEB_TYPE_MOUSELOCK_BUTTONS; |
- return mouse_lock_state_ == MOUSELOCK_ACCEPTED ? |
- FEB_TYPE_FULLSCREEN_MOUSELOCK_EXIT_INSTRUCTION : |
- FEB_TYPE_FULLSCREEN_EXIT_INSTRUCTION; |
+ NOTREACHED(); |
+ return FEB_TYPE_NONE; |
} |
ContentSetting |
@@ -359,14 +433,14 @@ ContentSetting |
#if defined(OS_MACOSX) |
void FullscreenController::TogglePresentationModeInternal(bool for_tab) { |
- bool entering_fullscreen = !window_->InPresentationMode(); |
+ in_or_entering_fullscreen_ = !window_->InPresentationMode(); |
GURL url; |
if (for_tab) { |
url = browser_->GetSelectedWebContents()->GetURL(); |
- tab_fullscreen_accepted_ = entering_fullscreen && |
+ tab_fullscreen_accepted_ = in_or_entering_fullscreen_ && |
GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; |
} |
- if (entering_fullscreen) |
+ if (in_or_entering_fullscreen_) |
window_->EnterPresentationMode(url, GetFullscreenExitBubbleType()); |
else |
window_->ExitPresentationMode(); |
@@ -376,7 +450,7 @@ void FullscreenController::TogglePresentationModeInternal(bool for_tab) { |
// TODO(koz): Change |for_tab| to an enum. |
void FullscreenController::ToggleFullscreenModeInternal(bool for_tab) { |
- bool entering_fullscreen = !window_->IsFullscreen(); |
+ in_or_entering_fullscreen_ = !window_->IsFullscreen(); |
yzshen1
2012/04/30 19:32:40
Is it possible that there are paths to change full
scheib
2012/05/01 03:27:07
Closing a tab does call Toggle, and this state is
|
#if !defined(OS_MACOSX) |
// In kiosk mode, we always want to be fullscreen. When the browser first |
@@ -389,19 +463,20 @@ void FullscreenController::ToggleFullscreenModeInternal(bool for_tab) { |
GURL url; |
if (for_tab) { |
url = browser_->GetSelectedWebContents()->GetURL(); |
- tab_fullscreen_accepted_ = entering_fullscreen && |
+ tab_fullscreen_accepted_ = in_or_entering_fullscreen_ && |
GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; |
} else { |
if (!extension_caused_fullscreen_.is_empty()) |
url = extension_caused_fullscreen_; |
content::RecordAction(UserMetricsAction("ToggleFullscreen")); |
} |
- if (entering_fullscreen) { |
+ if (in_or_entering_fullscreen_) { |
window_->EnterFullscreen(url, GetFullscreenExitBubbleType()); |
} else { |
window_->ExitFullscreen(); |
extension_caused_fullscreen_ = GURL(); |
} |
+ UpdateFullscreenExitBubbleContent(); |
// Once the window has become fullscreen it'll call back to |
// WindowFullscreenStateChanged(). We don't do this immediately as |