diff options
author | suzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-10 07:22:48 +0000 |
---|---|---|
committer | suzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-10 07:22:48 +0000 |
commit | 4467058769b543946faf628c3b20a0803ca3f061 (patch) | |
tree | f4011c5e25465f291de65e72f688a46ad2b6677d /chrome/renderer | |
parent | 85f07ece0d4e006389f238c804e77b0496c02c30 (diff) | |
download | chromium_src-4467058769b543946faf628c3b20a0803ca3f061.zip chromium_src-4467058769b543946faf628c3b20a0803ca3f061.tar.gz chromium_src-4467058769b543946faf628c3b20a0803ca3f061.tar.bz2 |
Supports Gtk keyboard themes.
This CL fixes issue 11480: Support GTK keyboard themes (emacs keybindings).
A new class GtkKeyBindingsHandler has been added, which matches a key event against key bindings defined in current Gtk keyboard theme.
A new render message ViewMsg_SetEditCommandsForNextKeyEvent has been added for sending edit commands associated to a key event to renderer. This message shall be sent just before sending the key event. RenderView will handle this event and cache the edit commands until the key event is processed.
When processing the key event, EditClientImpl::handleKeyboardEvent() will eventually be called to handle the key event, if it's not handled by DOM and the focus is inside an input box. Then a newly added method WebViewDelegate::ExecuteEditCommandsForCurrentKeyEvent(), which is implemented in RenderView, will be called by EditClientImpl::handleKeyboardEvent() to execute edit commands previously sent from browser by ViewMsg_SetEditCommandsForNextKeyEvent message. If WebViewDelegate::ExecuteEditCommandsForCurrentKeyEvent() returns false, which means the key event doesn't have edit command associated, EditClientImpl will handle the key event with built-in logic, which may trigger a built-in key binding.
With this approach, system defined key bindings always have higher priority than built-in key bindings defined in editor_client_impl.cc.
Known issue:
If a key event matches not only a system defined key binding but also an accesskey of a DOM element, then both corresponding edit commands and accesskey action will be executed. Because accesskey is handled in WebViewImpl::CharEvent(), while edit commands are bound to RawKeyDown or KeyUp events.
BUG=11480 "Support GTK keyboard themes (emacs keybindings)"
TEST=Switch to Emacs keyboard theme by changing the value of gconf key
"/desktop/gnome/interface/gtk_key_theme" to "Emacs", then starts chrome and
opens a webpage with a text input box. Input something into the text box, then
press any of the Emacs key bindings defined in
/usr/share/themes/Emacs/gtk-2.0-key/gtkrc, to see if it works as expected. For
example, ctrl-p should move the cursor up one line, and ctrl-k should delete to
the end of paragraph.
Review URL: http://codereview.chromium.org/165293
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25852 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/render_view.cc | 31 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 9 | ||||
-rw-r--r-- | chrome/renderer/render_widget.cc | 5 | ||||
-rw-r--r-- | chrome/renderer/render_widget.h | 4 |
4 files changed, 49 insertions, 0 deletions
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index d19dcd0..f4204aa 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -427,6 +427,8 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { OnNotifyRendererViewType) IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt) IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive) + IPC_MESSAGE_HANDLER(ViewMsg_SetEditCommandsForNextKeyEvent, + OnSetEditCommandsForNextKeyEvent); // Have the super handle all other messages. IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message)) @@ -3439,3 +3441,32 @@ void RenderView::Print(WebFrame* frame, bool script_initiated) { } print_helper_->Print(frame, script_initiated); } + +void RenderView::OnSetEditCommandsForNextKeyEvent( + const EditCommands& edit_commands) { + edit_commands_ = edit_commands; +} + +void RenderView::DidHandleKeyEvent() { + edit_commands_.clear(); +} + +bool RenderView::HandleCurrentKeyboardEvent() { + if (edit_commands_.empty()) + return false; + + WebFrame* frame = webview()->GetFocusedFrame(); + if (!frame) + return false; + + EditCommands::iterator it = edit_commands_.begin(); + EditCommands::iterator end = edit_commands_.end(); + + for (; it != end; ++it) { + if (!frame->executeCommand(WebString::fromUTF8(it->name), + WebString::fromUTF8(it->value))) + break; + } + + return true; +} diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index d580f49..3c99ec3 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -20,6 +20,7 @@ #include "base/values.h" #include "base/weak_ptr.h" #include "build/build_config.h" +#include "chrome/common/edit_command.h" #include "chrome/common/navigation_gesture.h" #include "chrome/common/renderer_preferences.h" #include "chrome/common/view_types.h" @@ -262,6 +263,7 @@ class RenderView : public RenderWidget, virtual void ScriptedPrint(WebKit::WebFrame* frame); virtual void UserMetricsRecordAction(const std::wstring& action); virtual void DnsPrefetch(const std::vector<std::string>& host_names); + virtual bool HandleCurrentKeyboardEvent(); // WebKit::WebWidgetClient // Most methods are handled by RenderWidget. @@ -433,6 +435,8 @@ class RenderView : public RenderWidget, const gfx::Rect& resizer_rect); // RenderWidget override virtual void DidPaint(); + // RenderWidget override. + virtual void DidHandleKeyEvent(); private: // For unit tests. @@ -542,6 +546,7 @@ class RenderView : public RenderWidget, void OnSelectAll(); void OnCopyImageAt(int x, int y); void OnExecuteEditCommand(const std::string& name, const std::string& value); + void OnSetEditCommandsForNextKeyEvent(const EditCommands& edit_commands); void OnSetupDevToolsClient(); void OnCancelDownload(int32 download_id); void OnFind(int request_id, const string16&, const WebKit::WebFindOptions&); @@ -911,6 +916,10 @@ class RenderView : public RenderWidget, // The settings this render view initialized WebKit with. WebPreferences webkit_preferences_; + // Stores edit commands associated to the next key event. + // Shall be cleared as soon as the next key event is processed. + EditCommands edit_commands_; + DISALLOW_COPY_AND_ASSIGN(RenderView); }; diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc index f668896..3aa58e3 100644 --- a/chrome/renderer/render_widget.cc +++ b/chrome/renderer/render_widget.cc @@ -331,6 +331,11 @@ void RenderWidget::OnHandleInputEvent(const IPC::Message& message) { } handling_input_event_ = false; + + WebInputEvent::Type type = input_event->type; + if (type == WebInputEvent::RawKeyDown || type == WebInputEvent::KeyDown || + type == WebInputEvent::KeyUp || type == WebInputEvent::Char) + DidHandleKeyEvent(); } void RenderWidget::OnMouseCaptureLost() { diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h index 38dfad8..100aee0 100644 --- a/chrome/renderer/render_widget.h +++ b/chrome/renderer/render_widget.h @@ -196,6 +196,10 @@ class RenderWidget : public IPC::Channel::Listener, // GetWindowRect() we'll use this pending window rect as the size. void SetPendingWindowRect(const WebKit::WebRect& r); + // Called by OnHandleInputEvent() to notify subclasses that a key event was + // just handled. + virtual void DidHandleKeyEvent() {} + // Routing ID that allows us to communicate to the parent browser process // RenderWidgetHost. When MSG_ROUTING_NONE, no messages may be sent. int32 routing_id_; |