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

Side by Side Diff: chrome/browser/ui/fullscreen_controller.cc

Issue 10559071: Exit mouse lock or fullscreen on navigation and reload. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/fullscreen_controller.h" 5 #include "chrome/browser/ui/fullscreen_controller.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "chrome/browser/content_settings/host_content_settings_map.h" 10 #include "chrome/browser/content_settings/host_content_settings_map.h"
(...skipping 21 matching lines...) Expand all
32 Profile* profile, 32 Profile* profile,
33 Browser* browser) 33 Browser* browser)
34 : window_(window), 34 : window_(window),
35 profile_(profile), 35 profile_(profile),
36 browser_(browser), 36 browser_(browser),
37 fullscreened_tab_(NULL), 37 fullscreened_tab_(NULL),
38 tab_caused_fullscreen_(false), 38 tab_caused_fullscreen_(false),
39 tab_fullscreen_accepted_(false), 39 tab_fullscreen_accepted_(false),
40 toggled_into_fullscreen_(false), 40 toggled_into_fullscreen_(false),
41 mouse_lock_tab_(NULL), 41 mouse_lock_tab_(NULL),
42 mouse_lock_state_(MOUSELOCK_NOT_REQUESTED), 42 mouse_lock_state_(MOUSELOCK_NOT_REQUESTED) {
43 cancel_fullscreen_on_navigate_mode_(false) {
44 } 43 }
45 44
46 void FullscreenController::Observe(int type, 45 void FullscreenController::Observe(int type,
47 const content::NotificationSource& source, 46 const content::NotificationSource& source,
48 const content::NotificationDetails& details) { 47 const content::NotificationDetails& details) {
49 switch (type) { 48 switch (type) {
50 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: 49 case content::NOTIFICATION_NAV_ENTRY_COMMITTED:
51 if (content::Details<content::LoadCommittedDetails>(details)-> 50 if (content::Details<content::LoadCommittedDetails>(details)->
52 is_navigation_to_different_page()) { 51 is_navigation_to_different_page()) {
53 ExitTabFullscreenOrMouseLockIfNecessary(); 52 ExitTabFullscreenOrMouseLockIfNecessary();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 108
110 // Must have a user gesture to prevent misbehaving sites from constantly 109 // Must have a user gesture to prevent misbehaving sites from constantly
111 // re-locking the mouse. Exceptions are when the page has unlocked 110 // re-locking the mouse. Exceptions are when the page has unlocked
112 // (i.e. not the user), or if we're in tab fullscreen (user gesture required 111 // (i.e. not the user), or if we're in tab fullscreen (user gesture required
113 // for that) 112 // for that)
114 if (!last_unlocked_by_target && !user_gesture && 113 if (!last_unlocked_by_target && !user_gesture &&
115 !IsFullscreenForTabOrPending(web_contents)) { 114 !IsFullscreenForTabOrPending(web_contents)) {
116 web_contents->GotResponseToLockMouseRequest(false); 115 web_contents->GotResponseToLockMouseRequest(false);
117 return; 116 return;
118 } 117 }
119 mouse_lock_tab_ = TabContents::FromWebContents(web_contents); 118 set_mouse_lock_tab(TabContents::FromWebContents(web_contents));
120 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType(); 119 FullscreenExitBubbleType bubble_type = GetFullscreenExitBubbleType();
121 120
122 switch (GetMouseLockSetting(web_contents->GetURL())) { 121 switch (GetMouseLockSetting(web_contents->GetURL())) {
123 case CONTENT_SETTING_ALLOW: 122 case CONTENT_SETTING_ALLOW:
124 // If bubble already displaying buttons we must not lock the mouse yet, 123 // If bubble already displaying buttons we must not lock the mouse yet,
125 // or it would prevent pressing those buttons. Instead, merge the request. 124 // or it would prevent pressing those buttons. Instead, merge the request.
126 if (fullscreen_bubble::ShowButtonsForType(bubble_type)) { 125 if (fullscreen_bubble::ShowButtonsForType(bubble_type)) {
127 mouse_lock_state_ = MOUSELOCK_REQUESTED; 126 mouse_lock_state_ = MOUSELOCK_REQUESTED;
128 } else { 127 } else {
129 // Lock mouse. 128 // Lock mouse.
130 if (web_contents->GotResponseToLockMouseRequest(true)) { 129 if (web_contents->GotResponseToLockMouseRequest(true)) {
131 if (last_unlocked_by_target) { 130 if (last_unlocked_by_target) {
132 mouse_lock_state_ = MOUSELOCK_ACCEPTED_SILENTLY; 131 mouse_lock_state_ = MOUSELOCK_ACCEPTED_SILENTLY;
133 } else { 132 } else {
134 mouse_lock_state_ = MOUSELOCK_ACCEPTED; 133 mouse_lock_state_ = MOUSELOCK_ACCEPTED;
135 } 134 }
136 } else { 135 } else {
137 mouse_lock_tab_ = NULL; 136 set_mouse_lock_tab(NULL);
138 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; 137 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
139 } 138 }
140 } 139 }
141 break; 140 break;
142 case CONTENT_SETTING_BLOCK: 141 case CONTENT_SETTING_BLOCK:
143 web_contents->GotResponseToLockMouseRequest(false); 142 web_contents->GotResponseToLockMouseRequest(false);
144 mouse_lock_tab_ = NULL; 143 set_mouse_lock_tab(NULL);
145 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; 144 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
146 break; 145 break;
147 case CONTENT_SETTING_ASK: 146 case CONTENT_SETTING_ASK:
148 mouse_lock_state_ = MOUSELOCK_REQUESTED; 147 mouse_lock_state_ = MOUSELOCK_REQUESTED;
149 break; 148 break;
150 default: 149 default:
151 NOTREACHED(); 150 NOTREACHED();
152 } 151 }
153 UpdateFullscreenExitBubbleContent(); 152 UpdateFullscreenExitBubbleContent();
154 } 153 }
155 154
156 void FullscreenController::ToggleFullscreenModeForTab(WebContents* web_contents, 155 void FullscreenController::ToggleFullscreenModeForTab(WebContents* web_contents,
157 bool enter_fullscreen) { 156 bool enter_fullscreen) {
158 if (web_contents != browser_->GetActiveWebContents()) 157 if (web_contents != browser_->GetActiveWebContents())
159 return; 158 return;
160 159
161 bool in_browser_or_tab_fullscreen_mode; 160 bool in_browser_or_tab_fullscreen_mode;
162 #if defined(OS_MACOSX) 161 #if defined(OS_MACOSX)
163 in_browser_or_tab_fullscreen_mode = window_->InPresentationMode(); 162 in_browser_or_tab_fullscreen_mode = window_->InPresentationMode();
164 #else 163 #else
165 in_browser_or_tab_fullscreen_mode = window_->IsFullscreen(); 164 in_browser_or_tab_fullscreen_mode = window_->IsFullscreen();
166 #endif 165 #endif
167 166
168 if (enter_fullscreen) { 167 if (enter_fullscreen) {
169 fullscreened_tab_ = TabContents::FromWebContents(web_contents); 168 set_fullscreened_tab(TabContents::FromWebContents(web_contents));
170 EnterCancelFullscreenOnNavigateMode();
171 if (!in_browser_or_tab_fullscreen_mode) { 169 if (!in_browser_or_tab_fullscreen_mode) {
172 tab_caused_fullscreen_ = true; 170 tab_caused_fullscreen_ = true;
173 #if defined(OS_MACOSX) 171 #if defined(OS_MACOSX)
174 TogglePresentationModeInternal(true); 172 TogglePresentationModeInternal(true);
175 #else 173 #else
176 ToggleFullscreenModeInternal(true); 174 ToggleFullscreenModeInternal(true);
177 #endif 175 #endif
178 } else { 176 } else {
179 // We need to update the fullscreen exit bubble, e.g., going from browser 177 // We need to update the fullscreen exit bubble, e.g., going from browser
180 // fullscreen to tab fullscreen will need to show different content. 178 // fullscreen to tab fullscreen will need to show different content.
181 const GURL& url = web_contents->GetURL(); 179 const GURL& url = web_contents->GetURL();
182 if (!tab_fullscreen_accepted_) { 180 if (!tab_fullscreen_accepted_) {
183 tab_fullscreen_accepted_ = 181 tab_fullscreen_accepted_ =
184 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; 182 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW;
185 } 183 }
186 UpdateFullscreenExitBubbleContent(); 184 UpdateFullscreenExitBubbleContent();
187 } 185 }
188 } else { 186 } else {
189 ExitCancelFullscreenOnNavigateMode();
190 if (in_browser_or_tab_fullscreen_mode) { 187 if (in_browser_or_tab_fullscreen_mode) {
191 if (tab_caused_fullscreen_) { 188 if (tab_caused_fullscreen_) {
192 #if defined(OS_MACOSX) 189 #if defined(OS_MACOSX)
193 TogglePresentationModeInternal(true); 190 TogglePresentationModeInternal(true);
194 #else 191 #else
195 ToggleFullscreenModeInternal(true); 192 ToggleFullscreenModeInternal(true);
196 #endif 193 #endif
197 } else { 194 } else {
198 // If currently there is a tab in "tab fullscreen" mode and fullscreen 195 // If currently there is a tab in "tab fullscreen" mode and fullscreen
199 // was not caused by it (i.e., previously it was in "browser fullscreen" 196 // was not caused by it (i.e., previously it was in "browser fullscreen"
(...skipping 26 matching lines...) Expand all
226 void FullscreenController::ToggleFullscreenModeWithExtension( 223 void FullscreenController::ToggleFullscreenModeWithExtension(
227 const GURL& extension_url) { 224 const GURL& extension_url) {
228 // |extension_caused_fullscreen_| will be reset if this causes fullscreen to 225 // |extension_caused_fullscreen_| will be reset if this causes fullscreen to
229 // exit. 226 // exit.
230 extension_caused_fullscreen_ = extension_url; 227 extension_caused_fullscreen_ = extension_url;
231 ToggleFullscreenModeInternal(false); 228 ToggleFullscreenModeInternal(false);
232 } 229 }
233 230
234 void FullscreenController::LostMouseLock() { 231 void FullscreenController::LostMouseLock() {
235 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; 232 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
236 mouse_lock_tab_ = NULL; 233 set_mouse_lock_tab(NULL);
237 NotifyMouseLockChange(); 234 NotifyMouseLockChange();
238 UpdateFullscreenExitBubbleContent(); 235 UpdateFullscreenExitBubbleContent();
239 } 236 }
240 237
241 void FullscreenController::OnTabClosing(WebContents* web_contents) { 238 void FullscreenController::OnTabClosing(WebContents* web_contents) {
242 if (IsFullscreenForTabOrPending(web_contents)) { 239 if (IsFullscreenForTabOrPending(web_contents)) {
243 ExitTabFullscreenOrMouseLockIfNecessary(); 240 ExitTabFullscreenOrMouseLockIfNecessary();
244 // The call to exit fullscreen may result in asynchronous notification of 241 // The call to exit fullscreen may result in asynchronous notification of
245 // fullscreen state change (e.g., on Linux). We don't want to rely on it 242 // fullscreen state change (e.g., on Linux). We don't want to rely on it
246 // to call NotifyTabOfExitIfNecessary(), because at that point 243 // to call NotifyTabOfExitIfNecessary(), because at that point
(...skipping 30 matching lines...) Expand all
277 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string(), 274 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string(),
278 CONTENT_SETTING_ALLOW); 275 CONTENT_SETTING_ALLOW);
279 } 276 }
280 277
281 if (mouse_lock_tab_ && 278 if (mouse_lock_tab_ &&
282 mouse_lock_tab_->web_contents() && 279 mouse_lock_tab_->web_contents() &&
283 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(true)) { 280 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(true)) {
284 mouse_lock_state_ = MOUSELOCK_ACCEPTED; 281 mouse_lock_state_ = MOUSELOCK_ACCEPTED;
285 } else { 282 } else {
286 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; 283 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
287 mouse_lock_tab_ = NULL; 284 set_mouse_lock_tab(NULL);
288 } 285 }
289 NotifyMouseLockChange(); 286 NotifyMouseLockChange();
290 } 287 }
291 288
292 if (fullscreen && !tab_fullscreen_accepted_) { 289 if (fullscreen && !tab_fullscreen_accepted_) {
293 DCHECK(fullscreened_tab_); 290 DCHECK(fullscreened_tab_);
294 if (pattern.IsValid()) { 291 if (pattern.IsValid()) {
295 settings_map->SetContentSetting( 292 settings_map->SetContentSetting(
296 pattern, ContentSettingsPattern::Wildcard(), 293 pattern, ContentSettingsPattern::Wildcard(),
297 CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string(), 294 CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string(),
(...skipping 12 matching lines...) Expand all
310 &mouse_lock); 307 &mouse_lock);
311 DCHECK(fullscreened_tab_ || mouse_lock_tab_); 308 DCHECK(fullscreened_tab_ || mouse_lock_tab_);
312 DCHECK(!(fullscreen && tab_fullscreen_accepted_)); 309 DCHECK(!(fullscreen && tab_fullscreen_accepted_));
313 DCHECK(!(mouse_lock && IsMouseLocked())); 310 DCHECK(!(mouse_lock && IsMouseLocked()));
314 311
315 if (mouse_lock) { 312 if (mouse_lock) {
316 DCHECK(IsMouseLockRequested()); 313 DCHECK(IsMouseLockRequested());
317 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; 314 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
318 if (mouse_lock_tab_ && mouse_lock_tab_->web_contents()) 315 if (mouse_lock_tab_ && mouse_lock_tab_->web_contents())
319 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(false); 316 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(false);
320 mouse_lock_tab_ = NULL; 317 set_mouse_lock_tab(NULL);
321 NotifyMouseLockChange(); 318 NotifyMouseLockChange();
322 319
323 // UpdateFullscreenExitBubbleContent() must be called, but to avoid 320 // UpdateFullscreenExitBubbleContent() must be called, but to avoid
324 // duplicate calls we do so only if not adjusting the fullscreen state 321 // duplicate calls we do so only if not adjusting the fullscreen state
325 // below, which also calls UpdateFullscreenExitBubbleContent(). 322 // below, which also calls UpdateFullscreenExitBubbleContent().
326 if (!fullscreen) 323 if (!fullscreen)
327 UpdateFullscreenExitBubbleContent(); 324 UpdateFullscreenExitBubbleContent();
328 } 325 }
329 326
330 if (fullscreen) 327 if (fullscreen)
(...skipping 25 matching lines...) Expand all
356 return true; 353 return true;
357 } 354 }
358 355
359 return false; 356 return false;
360 } 357 }
361 358
362 FullscreenController::~FullscreenController() {} 359 FullscreenController::~FullscreenController() {}
363 360
364 void FullscreenController::NotifyTabOfExitIfNecessary() { 361 void FullscreenController::NotifyTabOfExitIfNecessary() {
365 if (fullscreened_tab_) { 362 if (fullscreened_tab_) {
366 ExitCancelFullscreenOnNavigateMode();
367 RenderViewHost* rvh = 363 RenderViewHost* rvh =
368 fullscreened_tab_->web_contents()->GetRenderViewHost(); 364 fullscreened_tab_->web_contents()->GetRenderViewHost();
369 fullscreened_tab_ = NULL; 365 set_fullscreened_tab(NULL);
370 tab_caused_fullscreen_ = false; 366 tab_caused_fullscreen_ = false;
371 tab_fullscreen_accepted_ = false; 367 tab_fullscreen_accepted_ = false;
372 if (rvh) 368 if (rvh)
373 rvh->ExitFullscreen(); 369 rvh->ExitFullscreen();
374 } 370 }
375 371
376 if (mouse_lock_tab_) { 372 if (mouse_lock_tab_) {
377 WebContents* web_contents = mouse_lock_tab_->web_contents(); 373 WebContents* web_contents = mouse_lock_tab_->web_contents();
378 if (IsMouseLockRequested()) { 374 if (IsMouseLockRequested()) {
379 web_contents->GotResponseToLockMouseRequest(false); 375 web_contents->GotResponseToLockMouseRequest(false);
376 NotifyMouseLockChange();
380 } else if (web_contents->GetRenderViewHost() && 377 } else if (web_contents->GetRenderViewHost() &&
381 web_contents->GetRenderViewHost()->GetView()) { 378 web_contents->GetRenderViewHost()->GetView()) {
382 web_contents->GetRenderViewHost()->GetView()->UnlockMouse(); 379 web_contents->GetRenderViewHost()->GetView()->UnlockMouse();
383 } 380 }
384 mouse_lock_tab_ = NULL; 381 set_mouse_lock_tab(NULL);
385 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; 382 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
386 } 383 }
387 384
388 UpdateFullscreenExitBubbleContent(); 385 UpdateFullscreenExitBubbleContent();
389 } 386 }
390 387
391 void FullscreenController::EnterCancelFullscreenOnNavigateMode() { 388 void FullscreenController::UpdateNotificationRegistrations() {
392 if (cancel_fullscreen_on_navigate_mode_) 389 if (fullscreened_tab_ && mouse_lock_tab_)
393 return; 390 DCHECK(fullscreened_tab_ == mouse_lock_tab_);
yzshen1 2012/06/20 18:07:54 nit: you could DCHECK(!(fullscreened_tab_ && mouse
scheib 2012/06/20 20:38:24 I considered, but felt this was easier to read.
yzshen1 2012/06/20 20:56:46 A if-block containing only a DCHECK is a little bi
394 cancel_fullscreen_on_navigate_mode_ = true; 391
395 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 392 TabContents* tab = fullscreened_tab_ ? fullscreened_tab_ : mouse_lock_tab_;
396 content::Source<content::NavigationController>( 393
397 &fullscreened_tab_->web_contents()->GetController())); 394 if (tab && registrar_.IsEmpty()) {
395 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
396 content::Source<content::NavigationController>(
397 &tab->web_contents()->GetController()));
398 } else if (!tab && !registrar_.IsEmpty()) {
399 registrar_.RemoveAll();
400 }
398 } 401 }
399 402
400 void FullscreenController::ExitCancelFullscreenOnNavigateMode() {
401 if (!cancel_fullscreen_on_navigate_mode_)
402 return;
403 cancel_fullscreen_on_navigate_mode_ = false;
404 registrar_.RemoveAll();
405 }
406
407
408 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() { 403 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() {
409 if (tab_caused_fullscreen_) 404 if (tab_caused_fullscreen_)
410 ToggleFullscreenMode(); 405 ToggleFullscreenMode();
411 else 406 else
412 NotifyTabOfExitIfNecessary(); 407 NotifyTabOfExitIfNecessary();
413 } 408 }
414 409
415 void FullscreenController::UpdateFullscreenExitBubbleContent() { 410 void FullscreenController::UpdateFullscreenExitBubbleContent() {
416 GURL url; 411 GURL url;
417 if (fullscreened_tab_) 412 if (fullscreened_tab_)
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 window_->ExitFullscreen(); 560 window_->ExitFullscreen();
566 extension_caused_fullscreen_ = GURL(); 561 extension_caused_fullscreen_ = GURL();
567 } 562 }
568 UpdateFullscreenExitBubbleContent(); 563 UpdateFullscreenExitBubbleContent();
569 564
570 // Once the window has become fullscreen it'll call back to 565 // Once the window has become fullscreen it'll call back to
571 // WindowFullscreenStateChanged(). We don't do this immediately as 566 // WindowFullscreenStateChanged(). We don't do this immediately as
572 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let 567 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let
573 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate. 568 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate.
574 } 569 }
570
571 void FullscreenController::set_fullscreened_tab(TabContents* tab) {
koz (OOO until 15th September) 2012/06/19 23:57:17 nit: I think it's more in line with C++ style to h
scheib 2012/06/20 20:38:24 Done.
572 fullscreened_tab_ = tab;
573 UpdateNotificationRegistrations();
574 }
575
576 void FullscreenController::set_mouse_lock_tab(TabContents* tab) {
577 mouse_lock_tab_ = tab;
578 UpdateNotificationRegistrations();
579 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698