Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4064)

Unified Diff: chrome/browser/ui/fullscreen_controller.cc

Issue 10261011: Windowed mode mouse lock addded to fullscreen controller. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: indent Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/fullscreen_controller.h ('k') | chrome/browser/ui/gtk/browser_window_gtk.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/fullscreen_controller.cc
diff --git a/chrome/browser/ui/fullscreen_controller.cc b/chrome/browser/ui/fullscreen_controller.cc
index 8f50aff764afd76f8efd6731cc20320e0eec1fd7..088437af5c2b640cc7af585f6a10605b65b4889e 100644
--- a/chrome/browser/ui/fullscreen_controller.cc
+++ b/chrome/browser/ui/fullscreen_controller.cc
@@ -18,6 +18,7 @@
#include "chrome/common/extensions/extension.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
@@ -34,6 +35,8 @@ FullscreenController::FullscreenController(BrowserWindow* window,
fullscreened_tab_(NULL),
tab_caused_fullscreen_(false),
tab_fullscreen_accepted_(false),
+ toggled_into_fullscreen_(false),
+ mouse_lock_tab_(NULL),
mouse_lock_state_(MOUSELOCK_NOT_REQUESTED) {
}
@@ -64,29 +67,39 @@ 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());
+ NotifyMouseLockChange();
- // 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 we must not lock the mouse yet,
+ // or it would prevent pressing those buttons. Instead, merge the request.
+ if (fullscreen_bubble::ShowButtonsForType(bubble_type)) {
mouse_lock_state_ = MOUSELOCK_REQUESTED;
+ } else {
+ // Lock mouse.
+ if (tab->GotResponseToLockMouseRequest(true)) {
+ mouse_lock_state_ = MOUSELOCK_ACCEPTED;
+ } else {
+ mouse_lock_tab_ = NULL;
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+ }
}
break;
case CONTENT_SETTING_BLOCK:
tab->GotResponseToLockMouseRequest(false);
+ mouse_lock_tab_ = NULL;
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
break;
case CONTENT_SETTING_ASK:
mouse_lock_state_ = MOUSELOCK_REQUESTED;
@@ -142,7 +155,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,24 +182,26 @@ void FullscreenController::ToggleFullscreenModeWithExtension(
void FullscreenController::LostMouseLock() {
mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
+ mouse_lock_tab_ = NULL;
+ NotifyMouseLockChange();
UpdateFullscreenExitBubbleContent();
}
void FullscreenController::OnTabClosing(WebContents* web_contents) {
if (IsFullscreenForTabOrPending(web_contents)) {
- ExitTabbedFullscreenModeIfNecessary();
+ ExitTabFullscreenOrMouseLockIfNecessary();
// 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
- // |fullscreen_tab_| may not be valid. Instead, we call it here to clean up
- // tab fullscreen related state.
- NotifyTabOfFullscreenExitIfNecessary();
+ // to call NotifyTabOfExitIfNecessary(), because at that point
+ // |fullscreened_tab_| may not be valid. Instead, we call it here to clean
+ // up tab fullscreen related state.
+ NotifyTabOfExitIfNecessary();
}
}
void FullscreenController::OnTabDeactivated(TabContentsWrapper* contents) {
if (contents == fullscreened_tab_)
- ExitTabbedFullscreenModeIfNecessary();
+ ExitTabFullscreenOrMouseLockIfNecessary();
}
void FullscreenController::OnAcceptFullscreenPermission(
@@ -196,12 +211,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 +226,20 @@ 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;
+ }
+ NotifyMouseLockChange();
}
- if (!tab_fullscreen_accepted_) {
+
+ if (fullscreen && !tab_fullscreen_accepted_) {
+ DCHECK(fullscreened_tab_);
if (pattern.IsValid()) {
settings_map->SetContentSetting(
pattern, ContentSettingsPattern::Wildcard(),
@@ -232,19 +257,27 @@ 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 (mouse_lock_tab_ && mouse_lock_tab_->web_contents())
+ mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(false);
+ mouse_lock_tab_ = NULL;
+ NotifyMouseLockChange();
+
+ // UpdateFullscreenExitBubbleContent() must be called, but to avoid
+ // duplicate calls we do so only if not adjusting the fullscreen state
+ // below, which also calls UpdateFullscreenExitBubbleContent().
if (!fullscreen)
UpdateFullscreenExitBubbleContent();
}
if (fullscreen)
- ExitTabbedFullscreenModeIfNecessary();
+ ExitTabFullscreenOrMouseLockIfNecessary();
}
void FullscreenController::WindowFullscreenStateChanged() {
@@ -257,7 +290,7 @@ void FullscreenController::WindowFullscreenStateChanged() {
exiting_fullscreen = !window_->IsFullscreen();
#endif
if (exiting_fullscreen)
- NotifyTabOfFullscreenExitIfNecessary();
+ NotifyTabOfExitIfNecessary();
if (exiting_fullscreen)
window_->GetDownloadShelf()->Unhide();
else
@@ -265,47 +298,72 @@ void FullscreenController::WindowFullscreenStateChanged() {
}
bool FullscreenController::HandleUserPressedEscape() {
- if (!IsFullscreenForTabOrPending())
- return false;
- ExitTabbedFullscreenModeIfNecessary();
- return true;
+ if (IsFullscreenForTabOrPending() ||
+ IsMouseLocked() || IsMouseLockRequested()) {
+ ExitTabFullscreenOrMouseLockIfNecessary();
+ 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();
+ if (IsMouseLockRequested()) {
+ web_contents->GotResponseToLockMouseRequest(false);
+ } else if (web_contents->GetRenderViewHost() &&
+ web_contents->GetRenderViewHost()->GetView()) {
+ web_contents->GetRenderViewHost()->GetView()->UnlockMouse();
+ }
+ mouse_lock_tab_ = NULL;
+ mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
}
UpdateFullscreenExitBubbleContent();
}
-void FullscreenController::ExitTabbedFullscreenModeIfNecessary() {
+void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() {
if (tab_caused_fullscreen_)
ToggleFullscreenMode();
else
- NotifyTabOfFullscreenExitIfNecessary();
+ NotifyTabOfExitIfNecessary();
}
void FullscreenController::UpdateFullscreenExitBubbleContent() {
GURL url;
if (fullscreened_tab_)
url = fullscreened_tab_->web_contents()->GetURL();
+ else if (mouse_lock_tab_)
+ url = mouse_lock_tab_->web_contents()->GetURL();
else if (!extension_caused_fullscreen_.is_empty())
url = extension_caused_fullscreen_;
- window_->UpdateFullscreenExitBubbleContent(url,
- GetFullscreenExitBubbleType());
+ FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType();
+
+ // If bubble displays buttons, unlock mouse to allow pressing them.
+ if (fullscreen_bubble::ShowButtonsForType(bubble_type) &&
+ IsMouseLocked() &&
+ mouse_lock_tab_->web_contents()) {
+ WebContents* web_contents = mouse_lock_tab_->web_contents();
+ if (web_contents && web_contents->GetRenderViewHost() &&
+ web_contents->GetRenderViewHost()->GetView())
+ web_contents->GetRenderViewHost()->GetView()->UnlockMouse();
+ }
+
+ window_->UpdateFullscreenExitBubbleContent(url, bubble_type);
}
void FullscreenController::NotifyFullscreenChange() {
@@ -315,24 +373,55 @@ 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;
+ // In kiosk mode we always want to be fullscreen and do not want to show
+ // exit instructions for browser mode fullscreen.
+ bool kiosk = false;
+#if !defined(OS_MACOSX) // Kiosk mode not available on Mac.
+ kiosk = CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode);
+#endif
+
+ 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 { // Not tab full screen.
+ if (IsMouseLocked()) {
+ return FEB_TYPE_MOUSELOCK_EXIT_INSTRUCTION;
+ } else if (IsMouseLockRequested()) {
+ return FEB_TYPE_MOUSELOCK_BUTTONS;
+ } else {
+ if (!extension_caused_fullscreen_.is_empty()) {
+ return FEB_TYPE_BROWSER_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION;
+ } else if (toggled_into_fullscreen_ && !kiosk) {
+ 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
@@ -357,17 +446,18 @@ ContentSetting
#if defined(OS_MACOSX)
void FullscreenController::TogglePresentationModeInternal(bool for_tab) {
- bool entering_fullscreen = !window_->InPresentationMode();
+ toggled_into_fullscreen_ = !window_->InPresentationMode();
GURL url;
if (for_tab) {
url = browser_->GetSelectedWebContents()->GetURL();
- tab_fullscreen_accepted_ = entering_fullscreen &&
+ tab_fullscreen_accepted_ = toggled_into_fullscreen_ &&
GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW;
}
- if (entering_fullscreen)
+ if (toggled_into_fullscreen_)
window_->EnterPresentationMode(url, GetFullscreenExitBubbleType());
else
window_->ExitPresentationMode();
+ UpdateFullscreenExitBubbleContent();
// WindowFullscreenStateChanged will be called by BrowserWindowController
// when the transition completes.
@@ -376,11 +466,11 @@ 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();
+ toggled_into_fullscreen_ = !window_->IsFullscreen();
-#if !defined(OS_MACOSX)
- // In kiosk mode, we always want to be fullscreen. When the browser first
- // starts we're not yet fullscreen, so let the initial toggle go through.
+ // In kiosk mode, we always want to be fullscreen. When the browser first
+ // starts we're not yet fullscreen, so let the initial toggle go through.
+#if !defined(OS_MACOSX) // Kiosk mode not available on Mac.
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) &&
window_->IsFullscreen())
return;
@@ -389,19 +479,20 @@ void FullscreenController::ToggleFullscreenModeInternal(bool for_tab) {
GURL url;
if (for_tab) {
url = browser_->GetSelectedWebContents()->GetURL();
- tab_fullscreen_accepted_ = entering_fullscreen &&
+ tab_fullscreen_accepted_ = toggled_into_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 (toggled_into_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
« no previous file with comments | « chrome/browser/ui/fullscreen_controller.h ('k') | chrome/browser/ui/gtk/browser_window_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698