diff options
author | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-22 23:42:31 +0000 |
---|---|---|
committer | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-22 23:42:31 +0000 |
commit | 6b98e52b28fa37b71d4dd80556e936277a85dbc6 (patch) | |
tree | 51ba108da81657563670b942dee4c5de315ffd5e | |
parent | 988ace29e4f1990cf22f7d9781049e0b14d3d5cd (diff) | |
download | chromium_src-6b98e52b28fa37b71d4dd80556e936277a85dbc6.zip chromium_src-6b98e52b28fa37b71d4dd80556e936277a85dbc6.tar.gz chromium_src-6b98e52b28fa37b71d4dd80556e936277a85dbc6.tar.bz2 |
Revert 82751 - Add NativeWidgetDelegate/Widget::OnKeyEvent post-IME handling.Refactor XEvent code and InputMethodGtk::DispatchKeyEvent.Nix WidgetWin::GetFocusedViewRootView, rename RootView::OnKeyEvent.Cleanup headers and refactor code in extension_input_api.cc.BUG=72040TEST=Key event handling in win/linux_views/touch; extension input API SendKeyboardEventInputFunction use.Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=82713Review URL: http://codereview.chromium.org/6823055
TBR=msw@chromium.org
Review URL: http://codereview.chromium.org/6897033
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@82752 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/extensions/extension_input_api.cc | 42 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_input_api.h | 6 | ||||
-rw-r--r-- | views/focus/accelerator_handler_touch.cc | 9 | ||||
-rw-r--r-- | views/ime/input_method_gtk.cc | 72 | ||||
-rw-r--r-- | views/widget/native_widget_delegate.h | 3 | ||||
-rw-r--r-- | views/widget/root_view.cc | 2 | ||||
-rw-r--r-- | views/widget/root_view.h | 4 | ||||
-rw-r--r-- | views/widget/widget.cc | 4 | ||||
-rw-r--r-- | views/widget/widget.h | 1 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 12 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 2 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 19 | ||||
-rw-r--r-- | views/widget/widget_win.h | 4 |
13 files changed, 119 insertions, 61 deletions
diff --git a/chrome/browser/extensions/extension_input_api.cc b/chrome/browser/extensions/extension_input_api.cc index ffcd659..b3b8473 100644 --- a/chrome/browser/extensions/extension_input_api.cc +++ b/chrome/browser/extensions/extension_input_api.cc @@ -8,12 +8,17 @@ #include "base/string_util.h" #include "base/values.h" +#include "chrome/browser/extensions/extension_tabs_module.h" #include "chrome/browser/extensions/key_identifier_conversion_views.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "content/browser/renderer_host/render_view_host.h" +#include "content/common/native_web_keyboard_event.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" #include "views/events/event.h" #include "views/ime/input_method.h" +#include "views/widget/root_view.h" #include "views/widget/widget.h" namespace { @@ -51,7 +56,7 @@ void InputFunction::Run() { SendResponse(RunImpl()); } -views::Widget* SendKeyboardEventInputFunction::GetTopLevelWidget() { +views::RootView* SendKeyboardEventInputFunction::GetRootView() { Browser* browser = GetCurrentBrowser(); if (!browser) return NULL; @@ -62,7 +67,10 @@ views::Widget* SendKeyboardEventInputFunction::GetTopLevelWidget() { BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow( window->GetNativeHandle()); - return browser_view ? browser_view->GetWidget() : NULL; + if (!browser_view) + return NULL; + + return browser_view->GetRootView(); } bool SendKeyboardEventInputFunction::RunImpl() { @@ -88,28 +96,36 @@ bool SendKeyboardEventInputFunction::RunImpl() { return false; } - bool flag = false; int flags = prototype_event.flags(); - flags |= (args->GetBoolean(kAlt, &flag) && flag) ? ui::EF_ALT_DOWN : 0; - flags |= (args->GetBoolean(kCtrl, &flag) && flag) ? ui::EF_CONTROL_DOWN : 0; - flags |= (args->GetBoolean(kShift, &flag) && flag) ? ui::EF_SHIFT_DOWN : 0; - if (args->GetBoolean(kMeta, &flag) && flag) { + bool alt = false; + if (args->GetBoolean(kAlt, &alt)) + flags |= alt ? ui::EF_ALT_DOWN : 0; + bool ctrl = false; + if (args->GetBoolean(kCtrl, &ctrl)) + flags |= ctrl ? ui::EF_CONTROL_DOWN : 0; + bool shift = false; + if (args->GetBoolean(kShift, &shift)) + flags |= shift ? ui::EF_SHIFT_DOWN : 0; + bool meta = false; + if (args->GetBoolean(kMeta, &meta)) { // Views does not have a Meta event flag, so return an error for now. - error_ = kUnsupportedModifier; - return false; + if (meta) { + error_ = kUnsupportedModifier; + return false; + } } - views::Widget* widget = GetTopLevelWidget(); - if (!widget) { + views::RootView* root_view = GetRootView(); + if (!root_view) { error_ = kNoValidRecipientError; return false; } views::KeyEvent event(type, prototype_event.key_code(), flags); - views::InputMethod* ime = widget->GetInputMethod(); + views::InputMethod* ime = root_view->GetWidget()->GetInputMethod(); if (ime) { ime->DispatchKeyEvent(event); - } else if (!widget->OnKeyEvent(event)) { + } else if (!root_view->ProcessKeyEvent(event)) { error_ = kKeyEventUnprocessedError; return false; } diff --git a/chrome/browser/extensions/extension_input_api.h b/chrome/browser/extensions/extension_input_api.h index 39a8161..3000211 100644 --- a/chrome/browser/extensions/extension_input_api.h +++ b/chrome/browser/extensions/extension_input_api.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -9,7 +9,7 @@ #include "chrome/browser/extensions/extension_function.h" namespace views { -class Widget; + class RootView; } // namespace views // Base class for input APIs. @@ -30,7 +30,7 @@ class SendKeyboardEventInputFunction : public InputFunction { DECLARE_EXTENSION_FUNCTION_NAME("experimental.input.sendKeyboardEvent"); private: - views::Widget* GetTopLevelWidget(); + views::RootView* GetRootView(); }; #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_INPUT_API_H_ diff --git a/views/focus/accelerator_handler_touch.cc b/views/focus/accelerator_handler_touch.cc index a18bbe1..716cb29 100644 --- a/views/focus/accelerator_handler_touch.cc +++ b/views/focus/accelerator_handler_touch.cc @@ -179,7 +179,14 @@ bool DispatchXEvent(XEvent* xev) { case KeyRelease: { Event::FromNativeEvent2 from_native; KeyEvent keyev(xev, from_native); - return widget->OnKeyEvent(keyev); + InputMethod* ime = widget->GetInputMethod(); + // Always dispatch key events to the input method first, to make sure + // that the input method's hotkeys work all time. + if (ime) { + ime->DispatchKeyEvent(keyev); + return true; + } + return root->ProcessKeyEvent(keyev); } case ButtonPress: diff --git a/views/ime/input_method_gtk.cc b/views/ime/input_method_gtk.cc index 07da18f..023bcc6 100644 --- a/views/ime/input_method_gtk.cc +++ b/views/ime/input_method_gtk.cc @@ -110,13 +110,13 @@ void InputMethodGtk::OnBlur() { } void InputMethodGtk::DispatchKeyEvent(const KeyEvent& key) { - DCHECK(key.type() == ui::ET_KEY_PRESSED || key.type() == ui::ET_KEY_RELEASED); suppress_next_result_ = false; // We should bypass |context_| and |context_simple_| only if there is no - // text input client focused. Otherwise, always send the key event to either - // |context_| or |context_simple_| even if the text input type is - // ui::TEXT_INPUT_TYPE_NONE, to make sure we can get correct character result. + // text input client is focused at all. Otherwise, we should always send the + // key event to either |context_| or |context_simple_| even if the text input + // type is ui::TEXT_INPUT_TYPE_NONE, to make sure we can get correct character + // result. if (!GetTextInputClient()) { DispatchKeyEventPostIME(key); return; @@ -126,11 +126,22 @@ void InputMethodGtk::DispatchKeyEvent(const KeyEvent& key) { composition_changed_ = false; result_text_.clear(); - // If it's a fake key event, then we need to synthesize a GdkEventKey. - GdkEvent* event = key.native_event() ? key.native_event() : - SynthesizeGdkEventKey(key); - gboolean filtered = gtk_im_context_filter_keypress( - context_focused_ ? context_ : context_simple_, &event->key); + GdkEvent* event = key.native_event(); + DCHECK(!event || event->type == GDK_KEY_PRESS || + event->type == GDK_KEY_RELEASE); + + // If it's a fake key event, then we need to synthesis a GdkEventKey. + bool need_free_event = false; + if (!event) { + event = SynthesizeGdkEventKey(key); + need_free_event = true; + } + + gboolean filtered = false; + if (context_focused_) + filtered = gtk_im_context_filter_keypress(context_, &event->key); + else + filtered = gtk_im_context_filter_keypress(context_simple_, &event->key); handling_key_event_ = false; @@ -138,21 +149,24 @@ void InputMethodGtk::DispatchKeyEvent(const KeyEvent& key) { if (key.type() == ui::ET_KEY_PRESSED && filtered) ProcessFilteredKeyPressEvent(key); - // Ensure no focus change from processing the key event. - if (old_focused_view == focused_view()) { - if (HasInputMethodResult()) - ProcessInputMethodResult(key, filtered); - // Ensure no focus change sending input method results to the focused View. - if (old_focused_view == focused_view()) { - if (key.type() == ui::ET_KEY_PRESSED && !filtered) - ProcessUnfilteredKeyPressEvent(key); - else if (key.type() == ui::ET_KEY_RELEASED) - DispatchKeyEventPostIME(key); - } - } + // In case the focus was changed by the key event. + if (old_focused_view != focused_view()) + return; + + if (HasInputMethodResult()) + ProcessInputMethodResult(key, filtered); + + // In case the focus was changed when sending input method results to the + // focused View. + if (old_focused_view != focused_view()) + return; + + if (key.type() == ui::ET_KEY_PRESSED && !filtered) + ProcessUnfilteredKeyPressEvent(key); + else if (key.type() == ui::ET_KEY_RELEASED) + DispatchKeyEventPostIME(key); - // Free the synthesized event if there was no underlying native event. - if (event != key.native_event()) + if (need_free_event) gdk_event_free(event); } @@ -346,10 +360,14 @@ GdkEvent* InputMethodGtk::SynthesizeGdkEventKey(const KeyEvent& key) const { guint keyval = ui::GdkKeyCodeForWindowsKeyCode(key.key_code(), key.IsShiftDown()); guint state = 0; - state |= key.IsShiftDown() ? GDK_SHIFT_MASK : 0; - state |= key.IsControlDown() ? GDK_CONTROL_MASK : 0; - state |= key.IsAltDown() ? GDK_MOD1_MASK : 0; - state |= key.IsCapsLockDown() ? GDK_LOCK_MASK : 0; + if (key.IsShiftDown()) + state |= GDK_SHIFT_MASK; + if (key.IsControlDown()) + state |= GDK_CONTROL_MASK; + if (key.IsAltDown()) + state |= GDK_MOD1_MASK; + if (key.IsCapsLockDown()) + state |= GDK_LOCK_MASK; DCHECK(widget()->GetNativeView()->window); return ui::SynthesizeKeyEvent(widget()->GetNativeView()->window, diff --git a/views/widget/native_widget_delegate.h b/views/widget/native_widget_delegate.h index 0ac5e09..e5e3752 100644 --- a/views/widget/native_widget_delegate.h +++ b/views/widget/native_widget_delegate.h @@ -41,8 +41,7 @@ class NativeWidgetDelegate { // tree if necessary when accelerated painting is enabled. virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) = 0; - // Mouse and key event handlers. - virtual bool OnKeyEvent(const KeyEvent& event) = 0; + // MouseEvent handlers. virtual bool OnMouseEvent(const MouseEvent& event) = 0; virtual void OnMouseCaptureLost() = 0; }; diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc index f69c6a4..323612e 100644 --- a/views/widget/root_view.cc +++ b/views/widget/root_view.cc @@ -82,7 +82,7 @@ void RootView::NotifyNativeViewHierarchyChanged(bool attached, // Input ----------------------------------------------------------------------- -bool RootView::OnKeyEvent(const KeyEvent& event) { +bool RootView::ProcessKeyEvent(const KeyEvent& event) { bool consumed = false; View* v = GetFocusManager()->GetFocusedView(); diff --git a/views/widget/root_view.h b/views/widget/root_view.h index 11541d2..3465312 100644 --- a/views/widget/root_view.h +++ b/views/widget/root_view.h @@ -61,8 +61,8 @@ class RootView : public View, // Process a key event. Send the event to the focused view and up the focus // path, and finally to the default keyboard handler, until someone consumes - // it. Returns whether anyone consumed the event. - bool OnKeyEvent(const KeyEvent& event); + // it. Returns whether anyone consumed the event. + bool ProcessKeyEvent(const KeyEvent& event); #if defined(TOUCH_UI) && defined(UNIT_TEST) // For unit testing purposes, we use this method to set a mock diff --git a/views/widget/widget.cc b/views/widget/widget.cc index aeaebad8..924c448 100644 --- a/views/widget/widget.cc +++ b/views/widget/widget.cc @@ -320,10 +320,6 @@ void Widget::OnNativeWidgetPaint(gfx::Canvas* canvas) { RefreshCompositeTree(); } -bool Widget::OnKeyEvent(const KeyEvent& event) { - return GetRootView()->OnKeyEvent(event); -} - bool Widget::OnMouseEvent(const MouseEvent& event) { switch (event.type()) { case ui::ET_MOUSE_PRESSED: diff --git a/views/widget/widget.h b/views/widget/widget.h index d2c17a7..ec126a0 100644 --- a/views/widget/widget.h +++ b/views/widget/widget.h @@ -291,7 +291,6 @@ class Widget : public internal::NativeWidgetDelegate, virtual void OnSizeChanged(const gfx::Size& new_size) OVERRIDE; virtual bool HasFocusManager() const OVERRIDE; virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) OVERRIDE; - virtual bool OnKeyEvent(const KeyEvent& event) OVERRIDE; virtual bool OnMouseEvent(const MouseEvent& event) OVERRIDE; virtual void OnMouseCaptureLost() OVERRIDE; diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 85b361c..00c9610 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -615,9 +615,9 @@ void WidgetGtk::Init(GtkWidget* parent, // See views::Views::Focus and views::FocusManager::ClearNativeFocus // for more details. g_signal_connect(widget_, "key_press_event", - G_CALLBACK(&OnEventKeyThunk), this); + G_CALLBACK(&OnKeyEventThunk), this); g_signal_connect(widget_, "key_release_event", - G_CALLBACK(&OnEventKeyThunk), this); + G_CALLBACK(&OnKeyEventThunk), this); // Drag and drop. gtk_drag_dest_set(window_contents_, static_cast<GtkDestDefaults>(0), @@ -1291,7 +1291,7 @@ gboolean WidgetGtk::OnFocusOut(GtkWidget* widget, GdkEventFocus* event) { return false; } -gboolean WidgetGtk::OnEventKey(GtkWidget* widget, GdkEventKey* event) { +gboolean WidgetGtk::OnKeyEvent(GtkWidget* widget, GdkEventKey* event) { KeyEvent key(reinterpret_cast<NativeEvent>(event)); if (input_method_.get()) input_method_->DispatchKeyEvent(key); @@ -1385,8 +1385,10 @@ void WidgetGtk::DispatchKeyEventPostIME(const KeyEvent& key) { if (key.key_code() != ui::VKEY_MENU || key.type() != ui::ET_KEY_RELEASED) should_handle_menu_key_release_ = false; - // Send the key event to View hierarchy first. - bool handled = delegate_->OnKeyEvent(key); + bool handled = false; + + // Dispatch the key event to View hierarchy first. + handled = GetRootView()->ProcessKeyEvent(key); if (key.key_code() == ui::VKEY_PROCESSKEY || handled) return; diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index a7ede90..e931f59 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -272,7 +272,7 @@ class WidgetGtk : public Widget, CHROMEGTK_CALLBACK_1(WidgetGtk, gboolean, OnButtonRelease, GdkEventButton*); CHROMEGTK_CALLBACK_1(WidgetGtk, gboolean, OnFocusIn, GdkEventFocus*); CHROMEGTK_CALLBACK_1(WidgetGtk, gboolean, OnFocusOut, GdkEventFocus*); - CHROMEGTK_CALLBACK_1(WidgetGtk, gboolean, OnEventKey, GdkEventKey*); + CHROMEGTK_CALLBACK_1(WidgetGtk, gboolean, OnKeyEvent, GdkEventKey*); CHROMEGTK_CALLBACK_4(WidgetGtk, gboolean, OnQueryTooltip, gint, gint, gboolean, GtkTooltip*); CHROMEGTK_CALLBACK_1(WidgetGtk, gboolean, OnScroll, GdkEventScroll*); diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index 16332b5..bc6cf23c 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -1028,6 +1028,19 @@ Window* WidgetWin::GetWindowImpl(HWND hwnd) { return NULL; } +RootView* WidgetWin::GetFocusedViewRootView() { + // TODO(beng): get rid of this + FocusManager* focus_manager = GetFocusManager(); + if (!focus_manager) { + NOTREACHED(); + return NULL; + } + View* focused_view = focus_manager->GetFocusedView(); + if (!focused_view) + return NULL; + return focused_view->GetRootView(); +} + // static void WidgetWin::PostProcessActivateMessage(WidgetWin* widget, int activation_state) { @@ -1113,7 +1126,11 @@ gfx::AcceleratedWidget WidgetWin::GetAcceleratedWidget() { } void WidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) { - SetMsgHandled(delegate_->OnKeyEvent(key)); + RootView* root_view = GetFocusedViewRootView(); + if (!root_view) + root_view = GetRootView(); + + SetMsgHandled(root_view->ProcessKeyEvent(key)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h index 5f92a1f..6e795de 100644 --- a/views/widget/widget_win.h +++ b/views/widget/widget_win.h @@ -419,6 +419,10 @@ class WidgetWin : public ui::WindowImpl, // first ancestor that is a Window. static Window* GetWindowImpl(HWND hwnd); + // Returns the RootView that contains the focused view, or NULL if there is no + // focused view. + RootView* GetFocusedViewRootView(); + // Called after the WM_ACTIVATE message has been processed by the default // windows procedure. static void PostProcessActivateMessage(WidgetWin* widget, |