Chromium Code Reviews| 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 |