Index: ui/aura/desktop_host_linux.cc |
diff --git a/ui/aura/desktop_host_linux.cc b/ui/aura/desktop_host_linux.cc |
index 9934467fcbb2b8b49208f0a45a5fcdf60137d293..a6e8623a98f589cb141845268142834d9e8aadf3 100644 |
--- a/ui/aura/desktop_host_linux.cc |
+++ b/ui/aura/desktop_host_linux.cc |
@@ -12,6 +12,8 @@ |
#include <algorithm> |
+#include "base/event_types.h" |
+#include "base/memory/scoped_ptr.h" |
#include "base/message_loop.h" |
#include "base/message_pump_x.h" |
#include "ui/aura/cursor.h" |
@@ -26,6 +28,12 @@ |
#include <X11/extensions/XInput2.h> |
#include <X11/Xlib.h> |
+#if defined(HAVE_IBUS) |
+#include "ui/base/ime/input_method_ibus.h" |
+#else |
+#include "ui/base/ime/mock_input_method.h" |
+#endif |
+ |
using std::max; |
using std::min; |
@@ -181,47 +189,6 @@ int CoalescePendingXIMotionEvents(const XEvent* xev, XEvent* last_event) { |
return num_coalesed; |
} |
-// We emulate Windows' WM_KEYDOWN and WM_CHAR messages. WM_CHAR events are only |
-// generated for certain keys; see |
-// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268.aspx. |
-bool ShouldSendCharEventForKeyboardCode(ui::KeyboardCode keycode) { |
- if ((keycode >= ui::VKEY_0 && keycode <= ui::VKEY_9) || |
- (keycode >= ui::VKEY_A && keycode <= ui::VKEY_Z) || |
- (keycode >= ui::VKEY_NUMPAD0 && keycode <= ui::VKEY_NUMPAD9)) { |
- return true; |
- } |
- |
- switch (keycode) { |
- case ui::VKEY_BACK: |
- case ui::VKEY_RETURN: |
- case ui::VKEY_ESCAPE: |
- case ui::VKEY_SPACE: |
- case ui::VKEY_TAB: |
- // In addition to the keys listed at MSDN, we include other |
- // graphic-character and numpad keys. |
- case ui::VKEY_MULTIPLY: |
- case ui::VKEY_ADD: |
- case ui::VKEY_SUBTRACT: |
- case ui::VKEY_DECIMAL: |
- case ui::VKEY_DIVIDE: |
- case ui::VKEY_OEM_1: |
- case ui::VKEY_OEM_2: |
- case ui::VKEY_OEM_3: |
- case ui::VKEY_OEM_4: |
- case ui::VKEY_OEM_5: |
- case ui::VKEY_OEM_6: |
- case ui::VKEY_OEM_7: |
- case ui::VKEY_OEM_102: |
- case ui::VKEY_OEM_PLUS: |
- case ui::VKEY_OEM_COMMA: |
- case ui::VKEY_OEM_MINUS: |
- case ui::VKEY_OEM_PERIOD: |
- return true; |
- default: |
- return false; |
- } |
-} |
- |
class DesktopHostLinux : public DesktopHost { |
public: |
explicit DesktopHostLinux(const gfx::Rect& bounds); |
@@ -242,6 +209,13 @@ class DesktopHostLinux : public DesktopHost { |
virtual void SetCursor(gfx::NativeCursor cursor_type) OVERRIDE; |
virtual gfx::Point QueryMouseLocation() OVERRIDE; |
virtual void PostNativeEvent(const base::NativeEvent& event) OVERRIDE; |
+ virtual void SetInputMethod(ui::InputMethod*) OVERRIDE; |
+ virtual ui::InputMethod* GetInputMethod() const OVERRIDE; |
+ |
+ // ui::internal::InputMethodDelegate Override. |
+ virtual void DispatchKeyEventPostIME(const base::NativeEvent& event) OVERRIDE; |
+ virtual void DispatchFabricatedKeyEventPostIME( |
+ ui::EventType type, ui::KeyboardCode key_code, int flags) OVERRIDE; |
sky
2011/12/01 17:01:09
each param on its own line.
Yusuke Sato
2011/12/02 02:18:31
Done.
|
// Returns true if there's an X window manager present... in most cases. Some |
// window managers (notably, ion3) don't implement enough of ICCCM for us to |
@@ -257,6 +231,9 @@ class DesktopHostLinux : public DesktopHost { |
// The native root window. |
::Window root_window_; |
+ // The input method for the desktop. |
+ scoped_ptr<ui::InputMethod> input_method_; |
+ |
// Current Aura cursor. |
gfx::NativeCursor current_cursor_; |
@@ -271,6 +248,14 @@ DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds) |
xdisplay_(base::MessagePumpX::GetDefaultXDisplay()), |
xwindow_(0), |
root_window_(DefaultRootWindow(xdisplay_)), |
+#if defined(HAVE_IBUS) |
+ ALLOW_THIS_IN_INITIALIZER_LIST( |
+ input_method_(new ui::InputMethodIBus(this))), |
+#else |
+ ALLOW_THIS_IN_INITIALIZER_LIST( |
+ input_method_(new ui::MockInputMethod(this))), |
+#endif |
+ |
current_cursor_(aura::kCursorNull), |
bounds_(bounds) { |
xwindow_ = XCreateSimpleWindow(xdisplay_, root_window_, |
@@ -278,7 +263,7 @@ DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds) |
bounds.width(), bounds.height(), |
0, 0, 0); |
- long event_mask = ButtonPressMask | ButtonReleaseMask | |
+ long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | |
KeyPressMask | KeyReleaseMask | |
ExposureMask | VisibilityChangeMask | |
StructureNotifyMask | PropertyChangeMask | |
@@ -292,6 +277,8 @@ DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds) |
if (base::MessagePumpForUI::HasXInput2()) |
ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); |
#endif |
+ |
+ input_method_->Init(xwindow_); |
} |
DesktopHostLinux::~DesktopHostLinux() { |
@@ -311,19 +298,10 @@ base::MessagePumpDispatcher::DispatchStatus DesktopHostLinux::Dispatch( |
desktop_->Draw(); |
handled = true; |
break; |
- case KeyPress: { |
- KeyEvent keydown_event(xev, false); |
- handled = desktop_->DispatchKeyEvent(&keydown_event); |
- if (ShouldSendCharEventForKeyboardCode(keydown_event.key_code())) { |
- KeyEvent char_event(xev, true); |
- handled |= desktop_->DispatchKeyEvent(&char_event); |
- } |
- break; |
- } |
+ case KeyPress: |
case KeyRelease: { |
- KeyEvent keyup_event(xev, false); |
- handled = desktop_->DispatchKeyEvent(&keyup_event); |
- break; |
+ input_method_->DispatchKeyEvent(xev); |
+ handled = true; |
} |
case ButtonPress: |
case ButtonRelease: { |
@@ -401,6 +379,14 @@ base::MessagePumpDispatcher::DispatchStatus DesktopHostLinux::Dispatch( |
XFreeEventData(xev->xgeneric.display, &last_event.xcookie); |
break; |
} |
+ case FocusIn: { |
+ input_method_->OnFocus(); |
+ break; |
+ } |
+ case FocusOut: { |
+ input_method_->OnBlur(); |
+ break; |
+ } |
case MapNotify: { |
// If there's no window manager running, we need to assign the X input |
// focus to our host window. |
@@ -541,6 +527,27 @@ bool DesktopHostLinux::IsWindowManagerPresent() { |
return XGetSelectionOwner(xdisplay_, wm_s0_atom) != None; |
} |
+void DesktopHostLinux::SetInputMethod(ui::InputMethod* input_method) { |
+ input_method_.reset(input_method); |
+} |
+ |
+ui::InputMethod* DesktopHostLinux::GetInputMethod() const { |
+ return input_method_.get(); |
+} |
+ |
+void DesktopHostLinux::DispatchKeyEventPostIME(const base::NativeEvent& event) { |
+ KeyEvent aura_event(event, false /* is_char */); |
+ desktop_->DispatchKeyEvent(&aura_event); |
+ // We don't send a Char event here since the input method takes care of it. |
+} |
+ |
+void DesktopHostLinux::DispatchFabricatedKeyEventPostIME( |
+ ui::EventType type, ui::KeyboardCode key_code, int flags) { |
+ // Dispatch a ui::VKEY_PROCESSKEY event etc. generated by |input_method_|. |
+ KeyEvent aura_event(type, key_code, flags); |
+ desktop_->DispatchKeyEvent(&aura_event); |
+} |
+ |
} // namespace |
// static |