diff options
author | suzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-24 07:58:08 +0000 |
---|---|---|
committer | suzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-24 07:58:08 +0000 |
commit | 51552aae65a96d19e1adcbf6fe760f102b53a8bf (patch) | |
tree | 13002d427575989063b09e190b39b8e0decd7485 | |
parent | dcd3de72cb870e3b70fdeadbb43acbbc35fc11ae (diff) | |
download | chromium_src-51552aae65a96d19e1adcbf6fe760f102b53a8bf.zip chromium_src-51552aae65a96d19e1adcbf6fe760f102b53a8bf.tar.gz chromium_src-51552aae65a96d19e1adcbf6fe760f102b53a8bf.tar.bz2 |
[Linux] Implement input methods context menu.
BUG=31008
TEST=Right click in the content area, there will be an "Input Method" submenu.
Review URL: http://codereview.chromium.org/549100
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36977 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/chrome_dll_resource.h | 3 | ||||
-rw-r--r-- | chrome/app/generated_resources.grd | 6 | ||||
-rw-r--r-- | chrome/browser/gtk/menu_gtk.cc | 65 | ||||
-rw-r--r-- | chrome/browser/renderer_host/gtk_im_context_wrapper.cc | 19 | ||||
-rw-r--r-- | chrome/browser/renderer_host/gtk_im_context_wrapper.h | 8 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_gtk.cc | 4 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_gtk.h | 7 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu.cc | 8 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu_gtk.cc | 9 |
9 files changed, 97 insertions, 32 deletions
diff --git a/chrome/app/chrome_dll_resource.h b/chrome/app/chrome_dll_resource.h index d0eb82f..b1351c5 100644 --- a/chrome/app/chrome_dll_resource.h +++ b/chrome/app/chrome_dll_resource.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 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. @@ -250,6 +250,7 @@ #define IDC_HISTORY_MENU 46000 // OSX only #define IDC_HISTORY_MENU_VISITED 46100 // OSX only #define IDC_HISTORY_MENU_CLOSED 46200 // OSX only +#define IDC_INPUT_METHODS_MENU 46300 // Linux only // Custom context menu entries #define IDC_CONTENT_CONTEXT_CUSTOM_FIRST 47000 diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 2670712..3ca3859 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -495,6 +495,9 @@ each locale. --> <message name="IDS_CONTENT_CONTEXT_ADDSEARCHENGINE" desc="The name of the Add as Search Engine command in the content area context menu"> Add as search en&gine... </message> + <message name="IDS_CONTENT_CONTEXT_INPUT_METHODS_MENU" desc="The name of the input method submenu in the content area context menu"> + Input &methods + </message> </if> <if expr="pp_ifdef('use_titlecase')"> <message name="IDS_CONTENT_CONTEXT_BACK" desc="In Title Case: The name of the Back command in the content area context menu"> @@ -671,6 +674,9 @@ each locale. --> <message name="IDS_CONTENT_CONTEXT_ADDSEARCHENGINE" desc="In Title Case: The name of the Add as Search Engine command in the content area context menu"> Add As Search En&gine... </message> + <message name="IDS_CONTENT_CONTEXT_INPUT_METHODS_MENU" desc="In Title Case: The name of the input method submenu in the content area context menu"> + Input &Methods + </message> </if> <!-- On quick look, I didn't find any uses of this, is it stale? --> diff --git a/chrome/browser/gtk/menu_gtk.cc b/chrome/browser/gtk/menu_gtk.cc index 75b96cb..b987a1e 100644 --- a/chrome/browser/gtk/menu_gtk.cc +++ b/chrome/browser/gtk/menu_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 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. @@ -20,6 +20,40 @@ using gtk_util::ConvertAcceleratorsFromWindowsStyle; bool MenuGtk::block_activation_ = false; +namespace { + +// Sets the ID of a menu item. +void SetMenuItemID(GtkWidget* menu_item, int menu_id) { + DCHECK(menu_id >= 0); + + // Add 1 to the menu_id to avoid setting zero (null) to "menu-id". + g_object_set_data(G_OBJECT(menu_item), "menu-id", + GINT_TO_POINTER(menu_id + 1)); +} + +// Gets the ID of a menu item. +// Returns true if the menu item has an ID. +bool GetMenuItemID(GtkWidget* menu_item, int* menu_id) { + const MenuCreateMaterial* data = + reinterpret_cast<const MenuCreateMaterial*>( + g_object_get_data(G_OBJECT(menu_item), "menu-data")); + + if (data) { + *menu_id = data->id; + return true; + } + + gpointer id_ptr = g_object_get_data(G_OBJECT(menu_item), "menu-id"); + if (id_ptr != NULL) { + *menu_id = GPOINTER_TO_INT(id_ptr) - 1; + return true; + } + + return false; +} + +} // namespace + MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, const MenuCreateMaterial* menu_data) : delegate_(delegate), @@ -109,9 +143,7 @@ void MenuGtk::AppendMenuItem(int command_id, GtkWidget* menu_item) { void MenuGtk::AppendMenuItemToMenu(int command_id, GtkWidget* menu_item, GtkWidget* menu) { - g_object_set_data(G_OBJECT(menu_item), "menu-id", - reinterpret_cast<void*>(command_id)); - + SetMenuItemID(menu_item, command_id); g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(OnMenuItemActivated), this); @@ -333,17 +365,9 @@ void MenuGtk::OnMenuItemActivated(GtkMenuItem* menuitem, MenuGtk* menu) { return; } - const MenuCreateMaterial* data = - reinterpret_cast<const MenuCreateMaterial*>( - g_object_get_data(G_OBJECT(menuitem), "menu-data")); - int id; - if (data) { - id = data->id; - } else { - id = reinterpret_cast<intptr_t>(g_object_get_data(G_OBJECT(menuitem), - "menu-id")); - } + if (!GetMenuItemID(GTK_WIDGET(menuitem), &id)) + return; menus::MenuModel* model = reinterpret_cast<menus::MenuModel*>( @@ -462,18 +486,11 @@ void MenuGtk::SetMenuItemInfo(GtkWidget* widget, gpointer userdata) { return; } - MenuGtk* menu = reinterpret_cast<MenuGtk*>(userdata); int id; - const MenuCreateMaterial* data = - reinterpret_cast<const MenuCreateMaterial*>( - g_object_get_data(G_OBJECT(widget), "menu-data")); - if (data) { - id = data->id; - } else { - id = reinterpret_cast<intptr_t>(g_object_get_data(G_OBJECT(widget), - "menu-id")); - } + if (!GetMenuItemID(widget, &id)) + return; + MenuGtk* menu = reinterpret_cast<MenuGtk*>(userdata); menus::MenuModel* model = reinterpret_cast<menus::MenuModel*>( g_object_get_data(G_OBJECT(widget), "model")); diff --git a/chrome/browser/renderer_host/gtk_im_context_wrapper.cc b/chrome/browser/renderer_host/gtk_im_context_wrapper.cc index 90cc00c..e2b2ded 100644 --- a/chrome/browser/renderer_host/gtk_im_context_wrapper.cc +++ b/chrome/browser/renderer_host/gtk_im_context_wrapper.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 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. @@ -8,13 +8,18 @@ #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> +#include "app/l10n_util.h" #include "base/gfx/rect.h" #include "base/logging.h" #include "base/string_util.h" +#include "chrome/app/chrome_dll_resource.h" +#include "chrome/common/gtk_util.h" #include "chrome/common/native_web_keyboard_event.h" #include "chrome/common/render_messages.h" +#include "chrome/browser/gtk/menu_gtk.h" #include "chrome/browser/renderer_host/render_widget_host.h" #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" +#include "grit/generated_resources.h" GtkIMContextWrapper::GtkIMContextWrapper(RenderWidgetHostViewGtk* host_view) : host_view_(host_view), @@ -247,6 +252,18 @@ void GtkIMContextWrapper::OnFocusOut() { host_view_->GetRenderWidgetHost()->ImeSetInputMode(false); } +void GtkIMContextWrapper::AppendInputMethodsContextMenu(MenuGtk* menu) { + std::string label = gtk_util::ConvertAcceleratorsFromWindowsStyle( + l10n_util::GetStringUTF8(IDS_CONTENT_CONTEXT_INPUT_METHODS_MENU)); + GtkWidget* menuitem = gtk_menu_item_new_with_mnemonic(label.c_str()); + GtkWidget* submenu = gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); + gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(context_), + GTK_MENU_SHELL(submenu)); + menu->AppendSeparator(); + menu->AppendMenuItem(IDC_INPUT_METHODS_MENU, menuitem); +} + bool GtkIMContextWrapper::NeedCommitByForwardingCharEvent() { // If there is no composition text and has only one character to be // committed, then the character will be send to webkit as a Char event diff --git a/chrome/browser/renderer_host/gtk_im_context_wrapper.h b/chrome/browser/renderer_host/gtk_im_context_wrapper.h index 86ff0f0..7c6094f 100644 --- a/chrome/browser/renderer_host/gtk_im_context_wrapper.h +++ b/chrome/browser/renderer_host/gtk_im_context_wrapper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 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. @@ -14,8 +14,9 @@ namespace gfx { class Rect; } -class RenderWidgetHostViewGtk; +class MenuGtk; class NativeWebKeyboardEvent; +class RenderWidgetHostViewGtk; typedef struct _GtkIMContext GtkIMContext; typedef struct _GtkWidget GtkWidget; @@ -43,6 +44,8 @@ class GtkIMContextWrapper { void OnFocusIn(); void OnFocusOut(); + void AppendInputMethodsContextMenu(MenuGtk* menu); + private: // Check if a text needs commit by forwarding a char event instead of // by confirming as a composition text. @@ -169,5 +172,4 @@ class GtkIMContextWrapper { DISALLOW_COPY_AND_ASSIGN(GtkIMContextWrapper); }; - #endif // CHROME_BROWSER_RENDERER_HOST_GTK_IM_CONTEXT_WRAPPER_H_ diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc index 3ada2eb..d7a7ff2 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc @@ -602,6 +602,10 @@ void RenderWidgetHostViewGtk::ShowingContextMenu(bool showing) { is_showing_context_menu_ = showing; } +void RenderWidgetHostViewGtk::AppendInputMethodsContextMenu(MenuGtk* menu) { + im_context_->AppendInputMethodsContextMenu(menu); +} + BackingStore* RenderWidgetHostViewGtk::AllocBackingStore( const gfx::Size& size) { if (gpu_view_host_.get()) diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.h b/chrome/browser/renderer_host/render_widget_host_view_gtk.h index f05f7fe..f44a92b 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.h +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 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. @@ -23,6 +23,7 @@ class RenderWidgetHost; class GpuViewHost; class GtkIMContextWrapper; class GtkKeyBindingsHandler; +class MenuGtk; class NativeWebKeyboardEvent; typedef struct _GtkClipboard GtkClipboard; @@ -82,6 +83,10 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView { // RenderWidgetHost::ForwardEditCommandsForNextKeyEvent(). void ForwardKeyboardEvent(const NativeWebKeyboardEvent& event); + // Appends the input methods context menu to the specified |menu| object as a + // submenu. + void AppendInputMethodsContextMenu(MenuGtk* menu); + private: friend class RenderWidgetHostViewGtkWidget; diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc index 4bb701f..4be28b5 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.cc +++ b/chrome/browser/tab_contents/render_view_context_menu.cc @@ -509,6 +509,14 @@ bool RenderViewContextMenu::IsItemCommandEnabled(int id) const { case IDC_CHECK_SPELLING_OF_THIS_FIELD: return profile_->GetPrefs()->GetBoolean(prefs::kEnableSpellCheck); +#if defined(OS_LINUX) + // Enable the input methods context menu if the content is editable. + // TODO(suzhe): It should not be enabled in password boxes. Anyway, + // it's not a big issue. + case IDC_INPUT_METHODS_MENU: + return params_.is_editable; +#endif + case IDS_CONTENT_CONTEXT_SAVEFRAMEAS: case IDS_CONTENT_CONTEXT_PRINTFRAME: case IDS_CONTENT_CONTEXT_ADDSEARCHENGINE: // Not implemented. diff --git a/chrome/browser/tab_contents/render_view_context_menu_gtk.cc b/chrome/browser/tab_contents/render_view_context_menu_gtk.cc index f8c4617..470173b 100644 --- a/chrome/browser/tab_contents/render_view_context_menu_gtk.cc +++ b/chrome/browser/tab_contents/render_view_context_menu_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 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. @@ -7,7 +7,7 @@ #include <gtk/gtk.h> #include "base/string_util.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" +#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "webkit/glue/context_menu.h" @@ -26,6 +26,11 @@ RenderViewContextMenuGtk::~RenderViewContextMenuGtk() { void RenderViewContextMenuGtk::DoInit() { DoneMakingMenu(&menu_); gtk_menu_.reset(new MenuGtk(this, menu_.data())); + + RenderWidgetHostViewGtk* rwhv = static_cast<RenderWidgetHostViewGtk*>( + source_tab_contents_->render_widget_host_view()); + if (rwhv) + rwhv->AppendInputMethodsContextMenu(gtk_menu_.get()); } void RenderViewContextMenuGtk::Popup(const gfx::Point& point) { |