Commit 9ae32df7 authored by mazda@chromium.org's avatar mazda@chromium.org

Make accelerators not to work when the keyboard overlay is shown.

- Refactor PartialScreenshotEventFiler so that it can be reused, and renamed it to OverlayEventFilter
- Use OverlayEventFilter for the keyboard overlay

BUG=129834
TEST=Manually check accelerators do not work when the keyboard overlay.


Review URL: https://chromiumcodereview.appspot.com/10825026

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148504 0039d316-1c4b-4281-b951-d872f2087c98
parent 177bcf2f
......@@ -248,14 +248,14 @@
'wm/frame_painter.h',
'wm/image_grid.cc',
'wm/image_grid.h',
'wm/overlay_event_filter.cc',
'wm/overlay_event_filter.h',
'wm/panel_frame_view.cc',
'wm/panel_frame_view.h',
'wm/panel_layout_manager.cc',
'wm/panel_layout_manager.h',
'wm/panel_window_event_filter.cc',
'wm/panel_window_event_filter.h',
'wm/partial_screenshot_event_filter.cc',
'wm/partial_screenshot_event_filter.h',
'wm/partial_screenshot_view.cc',
'wm/partial_screenshot_view.h',
'wm/power_button_controller.cc',
......
......@@ -5,6 +5,7 @@
#include "ash/keyboard_overlay/keyboard_overlay_view.h"
#include "ash/keyboard_overlay/keyboard_overlay_delegate.h"
#include "ash/shell.h"
#include "base/utf_string_conversions.h"
#include "content/public/browser/browser_context.h"
#include "grit/ash_strings.h"
......@@ -16,8 +17,17 @@
using ui::WebDialogDelegate;
namespace {
// Store the pointer to the view currently shown.
KeyboardOverlayView* g_instance = NULL;
// Keys to invoke Cancel (Escape, Ctrl+Alt+/, or Shift+Ctrl+Alt+/).
const struct KeyEventData {
ui::KeyboardCode key_code;
int flags;
} kCancelKeys[] = {
{ ui::VKEY_ESCAPE, 0},
{ ui::VKEY_OEM_2, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN },
{ ui::VKEY_OEM_2, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN },
};
}
KeyboardOverlayView::KeyboardOverlayView(
......@@ -30,23 +40,41 @@ KeyboardOverlayView::KeyboardOverlayView(
KeyboardOverlayView::~KeyboardOverlayView() {
}
void KeyboardOverlayView::Cancel() {
ash::Shell::GetInstance()->overlay_filter()->Deactivate();
views::Widget* widget = GetWidget();
if (widget)
widget->Close();
}
bool KeyboardOverlayView::IsCancelingKeyEvent(aura::KeyEvent* event) {
if (event->type() != ui::ET_KEY_PRESSED)
return false;
for (size_t i = 0; i < arraysize(kCancelKeys); ++i) {
if ((kCancelKeys[i].key_code == event->key_code()) &&
(kCancelKeys[i].flags == event->flags()))
return true;
}
return false;
}
aura::Window* KeyboardOverlayView::GetWindow() {
return GetWidget()->GetNativeWindow();
}
void KeyboardOverlayView::ShowDialog(
content::BrowserContext* context,
WebContentsHandler* handler,
const GURL& url) {
// Ignore the call if another view is already shown.
if (g_instance)
return;
KeyboardOverlayDelegate* delegate = new KeyboardOverlayDelegate(
l10n_util::GetStringUTF16(IDS_ASH_KEYBOARD_OVERLAY_TITLE), url);
KeyboardOverlayView* view =
new KeyboardOverlayView(context, delegate, handler);
delegate->Show(view);
g_instance = view;
ash::Shell::GetInstance()->overlay_filter()->Activate(view);
}
void KeyboardOverlayView::WindowClosing() {
g_instance = NULL;
Cancel();
}
......@@ -6,6 +6,7 @@
#define ASH_KEYBOARD_OVERLAY_KEYBOARD_OVERLAY_VIEW_H_
#include "ash/ash_export.h"
#include "ash/wm/overlay_event_filter.h"
#include "base/compiler_specific.h"
#include "ui/views/controls/webview/web_dialog_view.h"
......@@ -20,13 +21,20 @@ class WebDialogDelegate;
}
// A customized dialog view for the keyboard overlay.
class ASH_EXPORT KeyboardOverlayView : public views::WebDialogView {
class ASH_EXPORT KeyboardOverlayView
: public views::WebDialogView,
public ash::internal::OverlayEventFilter::Delegate {
public:
KeyboardOverlayView(content::BrowserContext* context,
ui::WebDialogDelegate* delegate,
WebContentsHandler* handler);
virtual ~KeyboardOverlayView();
// Overridden from ash::internal::OverlayEventFilter::Delegate:
virtual void Cancel() OVERRIDE;
virtual bool IsCancelingKeyEvent(aura::KeyEvent* event) OVERRIDE;
virtual aura::Window* GetWindow() OVERRIDE;
// Shows the keyboard overlay.
static void ShowDialog(content::BrowserContext* context,
WebContentsHandler* handler,
......
......@@ -41,9 +41,9 @@
#include "ash/wm/dialog_frame_view.h"
#include "ash/wm/event_client_impl.h"
#include "ash/wm/event_rewriter_event_filter.h"
#include "ash/wm/overlay_event_filter.h"
#include "ash/wm/panel_layout_manager.h"
#include "ash/wm/panel_window_event_filter.h"
#include "ash/wm/partial_screenshot_event_filter.h"
#include "ash/wm/power_button_controller.h"
#include "ash/wm/resize_shadow_controller.h"
#include "ash/wm/root_window_layout_manager.h"
......@@ -209,7 +209,7 @@ Shell::~Shell() {
// Please keep in same order as in Init() because it's easy to miss one.
RemoveEnvEventFilter(user_activity_detector_.get());
RemoveEnvEventFilter(event_rewriter_filter_.get());
RemoveEnvEventFilter(partial_screenshot_filter_.get());
RemoveEnvEventFilter(overlay_filter_.get());
RemoveEnvEventFilter(input_method_filter_.get());
RemoveEnvEventFilter(window_modality_controller_.get());
if (mouse_cursor_filter_.get())
......@@ -398,9 +398,9 @@ void Shell::Init() {
AddEnvEventFilter(event_rewriter_filter_.get());
DCHECK_EQ(2U, GetEnvEventFilterCount());
partial_screenshot_filter_.reset(new internal::PartialScreenshotEventFilter);
AddEnvEventFilter(partial_screenshot_filter_.get());
AddShellObserver(partial_screenshot_filter_.get());
overlay_filter_.reset(new internal::OverlayEventFilter);
AddEnvEventFilter(overlay_filter_.get());
AddShellObserver(overlay_filter_.get());
DCHECK_EQ(3U, GetEnvEventFilterCount());
input_method_filter_.reset(new aura::shared::InputMethodEventFilter());
......
......@@ -79,14 +79,14 @@ class AcceleratorFilter;
class ActivationController;
class AppListController;
class CaptureController;
class DisplayController;
class DragDropController;
class EventRewriterEventFilter;
class FocusCycler;
class MagnificationController;
class DisplayController;
class MouseCursorEventFilter;
class OverlayEventFilter;
class PanelLayoutManager;
class PartialScreenshotEventFilter;
class ResizeShadowController;
class RootWindowController;
class RootWindowLayoutManager;
......@@ -95,9 +95,9 @@ class ShadowController;
class ShelfLayoutManager;
class ShellContextMenu;
class SlowAnimationEventFilter;
class SystemGestureEventFilter;
class StackingController;
class StatusAreaWidget;
class SystemGestureEventFilter;
class TooltipController;
class TouchObserverHUD;
class VisibilityController;
......@@ -262,8 +262,8 @@ class ASH_EXPORT Shell : ash::CursorDelegate {
internal::EventRewriterEventFilter* event_rewriter_filter() {
return event_rewriter_filter_.get();
}
internal::PartialScreenshotEventFilter* partial_screenshot_filter() {
return partial_screenshot_filter_.get();
internal::OverlayEventFilter* overlay_filter() {
return overlay_filter_.get();
}
DesktopBackgroundController* desktop_background_controller() {
return desktop_background_controller_.get();
......@@ -447,7 +447,7 @@ class ASH_EXPORT Shell : ash::CursorDelegate {
// An event filter that pre-handles key events while the partial
// screenshot UI is active.
scoped_ptr<internal::PartialScreenshotEventFilter> partial_screenshot_filter_;
scoped_ptr<internal::OverlayEventFilter> overlay_filter_;
// An event filter which handles system level gestures
scoped_ptr<internal::SystemGestureEventFilter> system_gesture_filter_;
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/wm/partial_screenshot_event_filter.h"
#include "ash/wm/overlay_event_filter.h"
#include "ash/wm/partial_screenshot_view.h"
#include "ui/aura/window.h"
......@@ -12,80 +12,85 @@
namespace ash {
namespace internal {
PartialScreenshotEventFilter::PartialScreenshotEventFilter()
: view_(NULL) {
OverlayEventFilter::OverlayEventFilter()
: delegate_(NULL) {
}
PartialScreenshotEventFilter::~PartialScreenshotEventFilter() {
view_ = NULL;
OverlayEventFilter::~OverlayEventFilter() {
delegate_ = NULL;
}
bool PartialScreenshotEventFilter::PreHandleKeyEvent(
bool OverlayEventFilter::PreHandleKeyEvent(
aura::Window* target, aura::KeyEvent* event) {
if (!view_)
if (!delegate_)
return false;
// Do not consume a translated key event which is generated by an IME (e.g.,
// ui::VKEY_PROCESSKEY) since the key event is generated in response to a key
// press or release before showing the screenshot view. This is important not
// to confuse key event handling JavaScript code in a page.
// press or release before showing the ovelay. This is important not to
// confuse key event handling JavaScript code in a page.
if (event->type() == ui::ET_TRANSLATED_KEY_PRESS ||
event->type() == ui::ET_TRANSLATED_KEY_RELEASE) {
return false;
}
if (event->key_code() == ui::VKEY_ESCAPE)
if (delegate_ && delegate_->IsCancelingKeyEvent(event))
Cancel();
// Handle key events only when they are sent to a child of the delegate's
// window.
if (delegate_ && delegate_->GetWindow()->Contains(target))
target->delegate()->OnKeyEvent(event);
// Always handled: other windows shouldn't receive input while we're
// taking a screenshot.
// displaying an overlay.
return true;
}
bool PartialScreenshotEventFilter::PreHandleMouseEvent(
bool OverlayEventFilter::PreHandleMouseEvent(
aura::Window* target, aura::MouseEvent* event) {
if (view_) {
DCHECK_EQ(target, view_->GetWidget()->GetNativeWindow());
if (delegate_) {
DCHECK_EQ(target, delegate_->GetWindow());
target->delegate()->OnMouseEvent(event);
return true;
}
return false; // Not handled.
}
ui::TouchStatus PartialScreenshotEventFilter::PreHandleTouchEvent(
ui::TouchStatus OverlayEventFilter::PreHandleTouchEvent(
aura::Window* target, aura::TouchEvent* event) {
return ui::TOUCH_STATUS_UNKNOWN; // Not handled.
}
ui::GestureStatus PartialScreenshotEventFilter::PreHandleGestureEvent(
ui::GestureStatus OverlayEventFilter::PreHandleGestureEvent(
aura::Window* target, aura::GestureEvent* event) {
return ui::GESTURE_STATUS_UNKNOWN; // Not handled.
}
void PartialScreenshotEventFilter::OnLoginStateChanged(
void OverlayEventFilter::OnLoginStateChanged(
user::LoginStatus status) {
Cancel();
}
void PartialScreenshotEventFilter::OnAppTerminating() {
void OverlayEventFilter::OnAppTerminating() {
Cancel();
}
void PartialScreenshotEventFilter::OnLockStateChanged(bool locked) {
void OverlayEventFilter::OnLockStateChanged(bool locked) {
Cancel();
}
void PartialScreenshotEventFilter::Activate(PartialScreenshotView* view) {
view_ = view;
void OverlayEventFilter::Activate(Delegate* delegate) {
delegate_ = delegate;
}
void PartialScreenshotEventFilter::Deactivate() {
view_ = NULL;
void OverlayEventFilter::Deactivate() {
delegate_ = NULL;
}
void PartialScreenshotEventFilter::Cancel() {
if (view_)
view_->Cancel();
void OverlayEventFilter::Cancel() {
if (delegate_)
delegate_->Cancel();
}
} // namespace internal
} // namespace ash
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_PARTIAL_SCREENSHOT_EVENT_FILTER_H_
#define ASH_WM_PARTIAL_SCREENSHOT_EVENT_FILTER_H_
#ifndef ASH_WM_OVERLAY_EVENT_FILTER_H_
#define ASH_WM_OVERLAY_EVENT_FILTER_H_
#include "ash/shell_observer.h"
#include "base/compiler_specific.h"
......@@ -11,28 +11,40 @@
#include "ui/aura/event_filter.h"
namespace ash {
class PartialScreenshotView;
namespace internal {
// EventFilter for the partial screenshot UI. It does nothing
// for the first time, but works when |Activate()| is called. The
// main task of this event filter is just to stop propagation of any
// key events during activation, and also signal cancellation when Esc is
// pressed.
class PartialScreenshotEventFilter : public aura::EventFilter,
public ShellObserver {
// EventFilter for the "overlay window", which intercepts events before they are
// processed by the usual path (e.g. the partial screenshot UI, the keyboard
// overlay). It does nothing the first time, but works when |Activate()| is
// called. The main task of this event filter is just to stop propagation
// of any key events during activation, and also signal cancellation when keys
// for canceling are pressed.
class OverlayEventFilter : public aura::EventFilter,
public ShellObserver {
public:
PartialScreenshotEventFilter();
virtual ~PartialScreenshotEventFilter();
// Windows that need to receive events from OverlayEventFilter implement this.
class Delegate {
public:
// Invoked when OverlayEventFilter needs to stop handling events.
virtual void Cancel() = 0;
// Returns true if the overlay should be canceled in response to |event|.
virtual bool IsCancelingKeyEvent(aura::KeyEvent* event) = 0;
// Returns the window that needs to receive events.
virtual aura::Window* GetWindow() = 0;
};
OverlayEventFilter();
virtual ~OverlayEventFilter();
// Start the filtering of events. It also notifies the specified
// |view| when a key event means cancel (like Esc). It holds the
// pointer to the specified |view| until Deactivate() is called, but
// Starts the filtering of events. It also notifies the specified
// |delegate| when a key event means cancel (like Esc). It holds the
// pointer to the specified |delegate| until Deactivate() is called, but
// does not take ownership.
void Activate(PartialScreenshotView* view);
void Activate(Delegate* delegate);
// End the filtering of events.
// Ends the filtering of events.
void Deactivate();
// Cancels the partial screenshot UI. Do nothing if it's not activated.
......@@ -54,12 +66,12 @@ class PartialScreenshotEventFilter : public aura::EventFilter,
virtual void OnLockStateChanged(bool locked) OVERRIDE;
private:
PartialScreenshotView* view_;
Delegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(PartialScreenshotEventFilter);
DISALLOW_COPY_AND_ASSIGN(OverlayEventFilter);
};
} // namespace internal
} // namespace ash
#endif // ASH_WM_PARTIAL_SCREENSHOT_EVENT_FILTER_H_
#endif // ASH_WM_OVERLAY_EVENT_FILTER_H_
......@@ -7,7 +7,7 @@
#include "ash/screenshot_delegate.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/partial_screenshot_event_filter.h"
#include "ash/wm/overlay_event_filter.h"
#include "ui/aura/root_window.h"
#include "ui/base/cursor/cursor.h"
#include "ui/gfx/canvas.h"
......@@ -54,20 +54,28 @@ void PartialScreenshotView::StartPartialScreenshot(
// events. This will close the context menu.
widget->GetNativeView()->SetCapture();
Shell::GetInstance()->partial_screenshot_filter()->Activate(view);
Shell::GetInstance()->overlay_filter()->Activate(view);
}
gfx::NativeCursor PartialScreenshotView::GetCursor(
const views::MouseEvent& event) {
// Always use "crosshair" cursor.
return ui::kCursorCross;
}
void PartialScreenshotView::Cancel() {
Shell::GetInstance()->partial_screenshot_filter()->Deactivate();
Shell::GetInstance()->overlay_filter()->Deactivate();
views::Widget* widget = GetWidget();
if (widget)
widget->Close();
}
gfx::NativeCursor PartialScreenshotView::GetCursor(
const views::MouseEvent& event) {
// Always use "crosshair" cursor.
return ui::kCursorCross;
bool PartialScreenshotView::IsCancelingKeyEvent(aura::KeyEvent* event) {
return event->key_code() == ui::VKEY_ESCAPE;
}
aura::Window* PartialScreenshotView::GetWindow() {
return GetWidget()->GetNativeWindow();
}
void PartialScreenshotView::OnPaint(gfx::Canvas* canvas) {
......
......@@ -6,6 +6,7 @@
#define ASH_WM_PARTIAL_SCREENSHOT_VIEW_H_
#include "ash/ash_export.h"
#include "ash/wm/overlay_event_filter.h"
#include "base/compiler_specific.h"
#include "ui/gfx/point.h"
#include "ui/views/widget/widget_delegate.h"
......@@ -16,7 +17,9 @@ class ScreenshotDelegate;
// The view of taking partial screenshot, i.e.: drawing region
// rectangles during drag, and changing the mouse cursor to indicate
// the current mode.
class ASH_EXPORT PartialScreenshotView : public views::WidgetDelegateView {
class ASH_EXPORT PartialScreenshotView
: public views::WidgetDelegateView,
public internal::OverlayEventFilter::Delegate {
public:
PartialScreenshotView(ScreenshotDelegate* screenshot_delegate);
virtual ~PartialScreenshotView();
......@@ -24,12 +27,14 @@ class ASH_EXPORT PartialScreenshotView : public views::WidgetDelegateView {
// Starts the UI for taking partial screenshot; dragging to select a region.
static void StartPartialScreenshot(ScreenshotDelegate* screenshot_delegate);
// Cancels the current screenshot UI.
void Cancel();
// Overriddden from View:
virtual gfx::NativeCursor GetCursor(const views::MouseEvent& event) OVERRIDE;
// Overridden from internal::OverlayEventFilter::Delegate:
virtual void Cancel() OVERRIDE;
virtual bool IsCancelingKeyEvent(aura::KeyEvent* event) OVERRIDE;
virtual aura::Window* GetWindow() OVERRIDE;
private:
gfx::Rect GetScreenshotRect() const;
......
......@@ -307,20 +307,6 @@ function getKeyLabel(keyData, modifiers) {
return keyLabel;
}
/**
* Returns the label corresponding to the key code.
* @param {string} keyCode Key code
* @return {string} Label of the key code.
*/
function getKeyLabelFromKeyCode(keyCode) {
if ('0'.charCodeAt(0) <= keyCode && keyCode <= 'Z'.charCodeAt(0))
return String.fromCharCode(keyCode).toLowerCase();
var label = KEYCODE_TO_LABEL[keyCode];
if (label)
return label;
return '';
}
/**
* Returns a normalized string used for a key of shortcutData.
*
......@@ -448,15 +434,7 @@ function handleKeyEvent(e) {
if (!getKeyboardOverlayId()) {
return;
}
var label = getKeyLabelFromKeyCode(e.keyCode);
var modifiers = getModifiers(e);
var shortcutData = getShortcutData();
var action = getAction(label, modifiers);
if (e.type == 'keydown' &&
(contains(CLOSE_LABELS, label) || shortcutData[action])) {
chrome.send('DialogClose');
return;
}
update(modifiers);
KeyboardOverlayAccessibilityHelper.maybeSpeakAllShortcuts(modifiers);
e.preventDefault();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment