1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/exclusive_access/exclusive_access_bubble.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
#include "chrome/grit/generated_resources.h"
#include "extensions/browser/extension_registry.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/strings/grit/ui_strings.h"
// NOTE(koz): Linux doesn't use the thick shadowed border, so we add padding
// here.
#if defined(OS_LINUX)
const int ExclusiveAccessBubble::kPaddingPx = 8;
#else
const int ExclusiveAccessBubble::kPaddingPx = 15;
#endif
const int ExclusiveAccessBubble::kInitialDelayMs = 3800;
const int ExclusiveAccessBubble::kIdleTimeMs = 2300;
const int ExclusiveAccessBubble::kPositionCheckHz = 10;
const int ExclusiveAccessBubble::kSlideInRegionHeightPx = 4;
const int ExclusiveAccessBubble::kSlideInDurationMs = 350;
const int ExclusiveAccessBubble::kSlideOutDurationMs = 700;
const int ExclusiveAccessBubble::kPopupTopPx = 15;
ExclusiveAccessBubble::ExclusiveAccessBubble(
Browser* browser,
const GURL& url,
ExclusiveAccessBubbleType bubble_type)
: browser_(browser), url_(url), bubble_type_(bubble_type) {
DCHECK_NE(EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE, bubble_type_);
}
ExclusiveAccessBubble::~ExclusiveAccessBubble() {
}
void ExclusiveAccessBubble::StartWatchingMouse() {
// Start the initial delay timer and begin watching the mouse.
initial_delay_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kInitialDelayMs), this,
&ExclusiveAccessBubble::CheckMousePosition);
gfx::Point cursor_pos = GetCursorScreenPoint();
last_mouse_pos_ = cursor_pos;
mouse_position_checker_.Start(
FROM_HERE, base::TimeDelta::FromMilliseconds(1000 / kPositionCheckHz),
this, &ExclusiveAccessBubble::CheckMousePosition);
}
void ExclusiveAccessBubble::StopWatchingMouse() {
initial_delay_.Stop();
idle_timeout_.Stop();
mouse_position_checker_.Stop();
}
bool ExclusiveAccessBubble::IsWatchingMouse() const {
return mouse_position_checker_.IsRunning();
}
void ExclusiveAccessBubble::CheckMousePosition() {
// Desired behavior:
//
// +------------+-----------------------------+------------+
// | _ _ _ _ | Exit full screen mode (F11) | _ _ _ _ | Slide-in region
// | _ _ _ _ \_____________________________/ _ _ _ _ | Neutral region
// | | Slide-out region
// : :
//
// * If app is not active, we hide the popup.
// * If the mouse is offscreen or in the slide-out region, we hide the popup.
// * If the mouse goes idle, we hide the popup.
// * If the mouse is in the slide-in-region and not idle, we show the popup.
// * If the mouse is in the neutral region and not idle, and the popup is
// currently sliding out, we show it again. This facilitates users
// correcting us if they try to mouse horizontally towards the popup and
// unintentionally drop too low.
// * Otherwise, we do nothing, because the mouse is in the neutral region and
// either the popup is hidden or the mouse is not idle, so we don't want to
// change anything's state.
gfx::Point cursor_pos = GetCursorScreenPoint();
// Check to see whether the mouse is idle.
if (cursor_pos != last_mouse_pos_) {
// The mouse moved; reset the idle timer.
idle_timeout_.Stop(); // If the timer isn't running, this is a no-op.
idle_timeout_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kIdleTimeMs), this,
&ExclusiveAccessBubble::CheckMousePosition);
}
last_mouse_pos_ = cursor_pos;
if (!IsWindowActive() || !WindowContainsPoint(cursor_pos) ||
(cursor_pos.y() >= GetPopupRect(true).bottom()) ||
!idle_timeout_.IsRunning()) {
// The cursor is offscreen, in the slide-out region, or idle.
if (!initial_delay_.IsRunning()) {
Hide();
}
} else if (cursor_pos.y() < kSlideInRegionHeightPx &&
CanMouseTriggerSlideIn()) {
Show();
} else if (IsAnimating()) {
// The cursor is not idle and either it's in the slide-in region or it's in
// the neutral region and we're sliding in or out.
Show();
}
}
void ExclusiveAccessBubble::ToggleFullscreen() {
browser_->fullscreen_controller()
->ExitTabOrBrowserFullscreenToPreviousState();
}
void ExclusiveAccessBubble::Accept() {
browser_->fullscreen_controller()->OnAcceptFullscreenPermission();
}
void ExclusiveAccessBubble::Cancel() {
browser_->fullscreen_controller()->OnDenyFullscreenPermission();
}
base::string16 ExclusiveAccessBubble::GetCurrentMessageText() const {
return exclusive_access_bubble::GetLabelTextForType(
bubble_type_, url_,
extensions::ExtensionRegistry::Get(browser_->profile()));
}
base::string16 ExclusiveAccessBubble::GetCurrentDenyButtonText() const {
return exclusive_access_bubble::GetDenyButtonTextForType(bubble_type_);
}
base::string16 ExclusiveAccessBubble::GetAllowButtonText() const {
return l10n_util::GetStringUTF16(IDS_FULLSCREEN_ALLOW);
}
base::string16 ExclusiveAccessBubble::GetInstructionText() const {
return l10n_util::GetStringFUTF16(IDS_FULLSCREEN_PRESS_ESC_TO_EXIT,
l10n_util::GetStringUTF16(IDS_APP_ESC_KEY));
}
|