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

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: feedback addressed. 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 SetMouseLockTab(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 SetMouseLockTab(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 SetMouseLockTab(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 }
(...skipping 13 matching lines...) Expand all
168 #endif 167 #endif
169 168
170 bool in_browser_or_tab_fullscreen_mode; 169 bool in_browser_or_tab_fullscreen_mode;
171 #if defined(OS_MACOSX) 170 #if defined(OS_MACOSX)
172 in_browser_or_tab_fullscreen_mode = window_->InPresentationMode(); 171 in_browser_or_tab_fullscreen_mode = window_->InPresentationMode();
173 #else 172 #else
174 in_browser_or_tab_fullscreen_mode = window_->IsFullscreen(); 173 in_browser_or_tab_fullscreen_mode = window_->IsFullscreen();
175 #endif 174 #endif
176 175
177 if (enter_fullscreen) { 176 if (enter_fullscreen) {
178 fullscreened_tab_ = TabContents::FromWebContents(web_contents); 177 SetFullscreenedTab(TabContents::FromWebContents(web_contents));
179 EnterCancelFullscreenOnNavigateMode();
180 if (!in_browser_or_tab_fullscreen_mode) { 178 if (!in_browser_or_tab_fullscreen_mode) {
181 tab_caused_fullscreen_ = true; 179 tab_caused_fullscreen_ = true;
182 #if defined(OS_MACOSX) 180 #if defined(OS_MACOSX)
183 TogglePresentationModeInternal(true); 181 TogglePresentationModeInternal(true);
184 #else 182 #else
185 ToggleFullscreenModeInternal(true); 183 ToggleFullscreenModeInternal(true);
186 #endif 184 #endif
187 } else { 185 } else {
188 // We need to update the fullscreen exit bubble, e.g., going from browser 186 // We need to update the fullscreen exit bubble, e.g., going from browser
189 // fullscreen to tab fullscreen will need to show different content. 187 // fullscreen to tab fullscreen will need to show different content.
190 const GURL& url = web_contents->GetURL(); 188 const GURL& url = web_contents->GetURL();
191 if (!tab_fullscreen_accepted_) { 189 if (!tab_fullscreen_accepted_) {
192 tab_fullscreen_accepted_ = 190 tab_fullscreen_accepted_ =
193 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW; 191 GetFullscreenSetting(url) == CONTENT_SETTING_ALLOW;
194 } 192 }
195 UpdateFullscreenExitBubbleContent(); 193 UpdateFullscreenExitBubbleContent();
196 } 194 }
197 } else { 195 } else {
198 ExitCancelFullscreenOnNavigateMode();
199 if (in_browser_or_tab_fullscreen_mode) { 196 if (in_browser_or_tab_fullscreen_mode) {
200 if (tab_caused_fullscreen_) { 197 if (tab_caused_fullscreen_) {
201 #if defined(OS_MACOSX) 198 #if defined(OS_MACOSX)
202 TogglePresentationModeInternal(true); 199 TogglePresentationModeInternal(true);
203 #else 200 #else
204 ToggleFullscreenModeInternal(true); 201 ToggleFullscreenModeInternal(true);
205 #endif 202 #endif
206 } else { 203 } else {
207 // If currently there is a tab in "tab fullscreen" mode and fullscreen 204 // If currently there is a tab in "tab fullscreen" mode and fullscreen
208 // was not caused by it (i.e., previously it was in "browser fullscreen" 205 // was not caused by it (i.e., previously it was in "browser fullscreen"
(...skipping 27 matching lines...) Expand all
236 void FullscreenController::ToggleFullscreenModeWithExtension( 233 void FullscreenController::ToggleFullscreenModeWithExtension(
237 const GURL& extension_url) { 234 const GURL& extension_url) {
238 // |extension_caused_fullscreen_| will be reset if this causes fullscreen to 235 // |extension_caused_fullscreen_| will be reset if this causes fullscreen to
239 // exit. 236 // exit.
240 extension_caused_fullscreen_ = extension_url; 237 extension_caused_fullscreen_ = extension_url;
241 ToggleFullscreenModeInternal(false); 238 ToggleFullscreenModeInternal(false);
242 } 239 }
243 240
244 void FullscreenController::LostMouseLock() { 241 void FullscreenController::LostMouseLock() {
245 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; 242 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
246 mouse_lock_tab_ = NULL; 243 SetMouseLockTab(NULL);
247 NotifyMouseLockChange(); 244 NotifyMouseLockChange();
248 UpdateFullscreenExitBubbleContent(); 245 UpdateFullscreenExitBubbleContent();
249 } 246 }
250 247
251 void FullscreenController::OnTabClosing(WebContents* web_contents) { 248 void FullscreenController::OnTabClosing(WebContents* web_contents) {
252 if (IsFullscreenForTabOrPending(web_contents)) { 249 if (IsFullscreenForTabOrPending(web_contents)) {
253 ExitTabFullscreenOrMouseLockIfNecessary(); 250 ExitTabFullscreenOrMouseLockIfNecessary();
254 // The call to exit fullscreen may result in asynchronous notification of 251 // The call to exit fullscreen may result in asynchronous notification of
255 // fullscreen state change (e.g., on Linux). We don't want to rely on it 252 // fullscreen state change (e.g., on Linux). We don't want to rely on it
256 // to call NotifyTabOfExitIfNecessary(), because at that point 253 // to call NotifyTabOfExitIfNecessary(), because at that point
(...skipping 30 matching lines...) Expand all
287 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string(), 284 CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string(),
288 CONTENT_SETTING_ALLOW); 285 CONTENT_SETTING_ALLOW);
289 } 286 }
290 287
291 if (mouse_lock_tab_ && 288 if (mouse_lock_tab_ &&
292 mouse_lock_tab_->web_contents() && 289 mouse_lock_tab_->web_contents() &&
293 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(true)) { 290 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(true)) {
294 mouse_lock_state_ = MOUSELOCK_ACCEPTED; 291 mouse_lock_state_ = MOUSELOCK_ACCEPTED;
295 } else { 292 } else {
296 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; 293 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
297 mouse_lock_tab_ = NULL; 294 SetMouseLockTab(NULL);
298 } 295 }
299 NotifyMouseLockChange(); 296 NotifyMouseLockChange();
300 } 297 }
301 298
302 if (fullscreen && !tab_fullscreen_accepted_) { 299 if (fullscreen && !tab_fullscreen_accepted_) {
303 DCHECK(fullscreened_tab_); 300 DCHECK(fullscreened_tab_);
304 if (pattern.IsValid()) { 301 if (pattern.IsValid()) {
305 settings_map->SetContentSetting( 302 settings_map->SetContentSetting(
306 pattern, ContentSettingsPattern::Wildcard(), 303 pattern, ContentSettingsPattern::Wildcard(),
307 CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string(), 304 CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string(),
(...skipping 12 matching lines...) Expand all
320 &mouse_lock); 317 &mouse_lock);
321 DCHECK(fullscreened_tab_ || mouse_lock_tab_); 318 DCHECK(fullscreened_tab_ || mouse_lock_tab_);
322 DCHECK(!(fullscreen && tab_fullscreen_accepted_)); 319 DCHECK(!(fullscreen && tab_fullscreen_accepted_));
323 DCHECK(!(mouse_lock && IsMouseLocked())); 320 DCHECK(!(mouse_lock && IsMouseLocked()));
324 321
325 if (mouse_lock) { 322 if (mouse_lock) {
326 DCHECK(IsMouseLockRequested()); 323 DCHECK(IsMouseLockRequested());
327 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; 324 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
328 if (mouse_lock_tab_ && mouse_lock_tab_->web_contents()) 325 if (mouse_lock_tab_ && mouse_lock_tab_->web_contents())
329 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(false); 326 mouse_lock_tab_->web_contents()->GotResponseToLockMouseRequest(false);
330 mouse_lock_tab_ = NULL; 327 SetMouseLockTab(NULL);
331 NotifyMouseLockChange(); 328 NotifyMouseLockChange();
332 329
333 // UpdateFullscreenExitBubbleContent() must be called, but to avoid 330 // UpdateFullscreenExitBubbleContent() must be called, but to avoid
334 // duplicate calls we do so only if not adjusting the fullscreen state 331 // duplicate calls we do so only if not adjusting the fullscreen state
335 // below, which also calls UpdateFullscreenExitBubbleContent(). 332 // below, which also calls UpdateFullscreenExitBubbleContent().
336 if (!fullscreen) 333 if (!fullscreen)
337 UpdateFullscreenExitBubbleContent(); 334 UpdateFullscreenExitBubbleContent();
338 } 335 }
339 336
340 if (fullscreen) 337 if (fullscreen)
(...skipping 25 matching lines...) Expand all
366 return true; 363 return true;
367 } 364 }
368 365
369 return false; 366 return false;
370 } 367 }
371 368
372 FullscreenController::~FullscreenController() {} 369 FullscreenController::~FullscreenController() {}
373 370
374 void FullscreenController::NotifyTabOfExitIfNecessary() { 371 void FullscreenController::NotifyTabOfExitIfNecessary() {
375 if (fullscreened_tab_) { 372 if (fullscreened_tab_) {
376 ExitCancelFullscreenOnNavigateMode();
377 RenderViewHost* rvh = 373 RenderViewHost* rvh =
378 fullscreened_tab_->web_contents()->GetRenderViewHost(); 374 fullscreened_tab_->web_contents()->GetRenderViewHost();
379 fullscreened_tab_ = NULL; 375 SetFullscreenedTab(NULL);
380 tab_caused_fullscreen_ = false; 376 tab_caused_fullscreen_ = false;
381 tab_fullscreen_accepted_ = false; 377 tab_fullscreen_accepted_ = false;
382 if (rvh) 378 if (rvh)
383 rvh->ExitFullscreen(); 379 rvh->ExitFullscreen();
384 } 380 }
385 381
386 if (mouse_lock_tab_) { 382 if (mouse_lock_tab_) {
387 WebContents* web_contents = mouse_lock_tab_->web_contents(); 383 WebContents* web_contents = mouse_lock_tab_->web_contents();
388 if (IsMouseLockRequested()) { 384 if (IsMouseLockRequested()) {
389 web_contents->GotResponseToLockMouseRequest(false); 385 web_contents->GotResponseToLockMouseRequest(false);
386 NotifyMouseLockChange();
390 } else if (web_contents->GetRenderViewHost() && 387 } else if (web_contents->GetRenderViewHost() &&
391 web_contents->GetRenderViewHost()->GetView()) { 388 web_contents->GetRenderViewHost()->GetView()) {
392 web_contents->GetRenderViewHost()->GetView()->UnlockMouse(); 389 web_contents->GetRenderViewHost()->GetView()->UnlockMouse();
393 } 390 }
394 mouse_lock_tab_ = NULL; 391 SetMouseLockTab(NULL);
395 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED; 392 mouse_lock_state_ = MOUSELOCK_NOT_REQUESTED;
396 } 393 }
397 394
398 UpdateFullscreenExitBubbleContent(); 395 UpdateFullscreenExitBubbleContent();
399 } 396 }
400 397
401 void FullscreenController::EnterCancelFullscreenOnNavigateMode() { 398 void FullscreenController::UpdateNotificationRegistrations() {
402 if (cancel_fullscreen_on_navigate_mode_) 399 if (fullscreened_tab_ && mouse_lock_tab_)
403 return; 400 DCHECK(fullscreened_tab_ == mouse_lock_tab_);
sky 2012/06/21 18:07:22 This makes me mildly nervous because its a single
404 cancel_fullscreen_on_navigate_mode_ = true; 401
405 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 402 TabContents* tab = fullscreened_tab_ ? fullscreened_tab_ : mouse_lock_tab_;
406 content::Source<content::NavigationController>( 403
407 &fullscreened_tab_->web_contents()->GetController())); 404 if (tab && registrar_.IsEmpty()) {
405 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
406 content::Source<content::NavigationController>(
407 &tab->web_contents()->GetController()));
408 } else if (!tab && !registrar_.IsEmpty()) {
409 registrar_.RemoveAll();
410 }
408 } 411 }
409 412
410 void FullscreenController::ExitCancelFullscreenOnNavigateMode() {
411 if (!cancel_fullscreen_on_navigate_mode_)
412 return;
413 cancel_fullscreen_on_navigate_mode_ = false;
414 registrar_.RemoveAll();
415 }
416
417
418 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() { 413 void FullscreenController::ExitTabFullscreenOrMouseLockIfNecessary() {
419 if (tab_caused_fullscreen_) 414 if (tab_caused_fullscreen_)
420 ToggleFullscreenMode(); 415 ToggleFullscreenMode();
421 else 416 else
422 NotifyTabOfExitIfNecessary(); 417 NotifyTabOfExitIfNecessary();
423 } 418 }
424 419
425 void FullscreenController::UpdateFullscreenExitBubbleContent() { 420 void FullscreenController::UpdateFullscreenExitBubbleContent() {
426 GURL url; 421 GURL url;
427 if (fullscreened_tab_) 422 if (fullscreened_tab_)
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 window_->ExitFullscreen(); 576 window_->ExitFullscreen();
582 extension_caused_fullscreen_ = GURL(); 577 extension_caused_fullscreen_ = GURL();
583 } 578 }
584 UpdateFullscreenExitBubbleContent(); 579 UpdateFullscreenExitBubbleContent();
585 580
586 // Once the window has become fullscreen it'll call back to 581 // Once the window has become fullscreen it'll call back to
587 // WindowFullscreenStateChanged(). We don't do this immediately as 582 // WindowFullscreenStateChanged(). We don't do this immediately as
588 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let 583 // BrowserWindow::EnterFullscreen() asks for bookmark_bar_state_, so we let
589 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate. 584 // the BrowserWindow invoke WindowFullscreenStateChanged when appropriate.
590 } 585 }
586
587 void FullscreenController::SetFullscreenedTab(TabContents* tab) {
588 fullscreened_tab_ = tab;
589 UpdateNotificationRegistrations();
590 }
591
592 void FullscreenController::SetMouseLockTab(TabContents* tab) {
593 mouse_lock_tab_ = tab;
594 UpdateNotificationRegistrations();
595 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698