Index: ui/aura/desktop_host_linux.cc |
diff --git a/ui/aura/desktop_host_linux.cc b/ui/aura/desktop_host_linux.cc |
index e20b1c57403bbeba3bf1b7d9e8b18aaec46642fc..3cf3a13b48a8e9ce060852af44f723a76bbcac2b 100644 |
--- a/ui/aura/desktop_host_linux.cc |
+++ b/ui/aura/desktop_host_linux.cc |
@@ -17,6 +17,7 @@ |
#include "ui/aura/cursor.h" |
#include "ui/aura/desktop.h" |
#include "ui/aura/event.h" |
+#include "ui/base/ime/input_method_delegate.h" |
#include "ui/base/keycodes/keyboard_codes.h" |
#include "ui/base/touch/touch_factory.h" |
#include "ui/base/x/x11_util.h" |
@@ -26,6 +27,12 @@ |
#include <X11/extensions/XInput2.h> |
#include <X11/Xlib.h> |
+#if defined(HAVE_IBUS) |
+#include "ui/base/ime/input_method_ibus_aura.h" |
+#else |
+#include "ui/base/ime/mock_input_method.h" |
+#endif |
+ |
using std::max; |
using std::min; |
@@ -181,48 +188,8 @@ 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 { |
+class DesktopHostLinux : public DesktopHost, |
+ public ui::internal::InputMethodDelegate { |
public: |
explicit DesktopHostLinux(const gfx::Rect& bounds); |
virtual ~DesktopHostLinux(); |
@@ -240,6 +207,10 @@ class DesktopHostLinux : public DesktopHost { |
virtual void SetSize(const gfx::Size& size) OVERRIDE; |
virtual void SetCursor(gfx::NativeCursor cursor_type) OVERRIDE; |
virtual gfx::Point QueryMouseLocation() OVERRIDE; |
+ virtual ui::InputMethod* GetInputMethod() OVERRIDE; |
+ |
+ // ui::internal::InputMethodDelegate Override. |
+ virtual void DispatchKeyEventPostIME(Event* event) OVERRIDE; |
// 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 |
@@ -252,6 +223,13 @@ class DesktopHostLinux : public DesktopHost { |
Display* xdisplay_; |
::Window xwindow_; |
+ // The input method for the desktop. |
+#if defined(HAVE_IBUS) |
+ ui::InputMethodIBusAura input_method_; |
+#else |
+ ui::MockInputMethod input_method_; |
+#endif |
+ |
// Current Aura cursor. |
gfx::NativeCursor current_cursor_; |
@@ -265,6 +243,7 @@ DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds) |
: desktop_(NULL), |
xdisplay_(base::MessagePumpX::GetDefaultXDisplay()), |
xwindow_(0), |
+ ALLOW_THIS_IN_INITIALIZER_LIST(input_method_(this)), |
current_cursor_(aura::kCursorNull), |
size_(bounds.size()) { |
xwindow_ = XCreateSimpleWindow(xdisplay_, DefaultRootWindow(xdisplay_), |
@@ -285,6 +264,10 @@ DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds) |
if (base::MessagePumpForUI::HasXInput2()) |
ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); |
#endif |
+ |
+ // You can't call input_method_.Init() here since ui::InputMethod might depend |
+ // on aura::Desktop, and this constructor might be called during the |
+ // construction of the desktop singleton instance. |
} |
DesktopHostLinux::~DesktopHostLinux() { |
@@ -302,19 +285,11 @@ 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; |
+ KeyEvent key_event(xev, false); |
+ input_method_.DispatchKeyEvent(&key_event); |
+ handled = true; |
} |
case ButtonPress: |
case ButtonRelease: { |
@@ -488,6 +463,33 @@ bool DesktopHostLinux::IsWindowManagerPresent() { |
return XGetSelectionOwner(xdisplay_, wm_s0_atom) != None; |
} |
+ui::InputMethod* DesktopHostLinux::GetInputMethod() { |
+ return &input_method_; |
+} |
+ |
+void DesktopHostLinux::DispatchKeyEventPostIME(Event* event) { |
+ DCHECK(event->type() == ui::ET_KEY_PRESSED || |
+ event->type() == ui::ET_KEY_RELEASED); |
+ const KeyEvent& key = *static_cast<KeyEvent*>(event); |
+ |
+ if (!key.native_event()) { |
+ // Dispatch a ui::VKEY_PROCESSKEY event generated by |input_method_|. |
+ KeyEvent aura_event(key.type(), key.key_code(), key.flags()); |
+ desktop_->DispatchKeyEvent(&aura_event); |
+ return; |
+ } |
+ |
+ if (key.type() == ui::ET_KEY_PRESSED) { |
+ KeyEvent keydown_event(key.native_event(), false); |
+ desktop_->DispatchKeyEvent(&keydown_event); |
+ // We don't send a Char event here since the input method in DesktopHost |
+ // takes care of it. |
+ } else { |
+ KeyEvent keyup_event(key.native_event(), false); |
+ desktop_->DispatchKeyEvent(&keyup_event); |
+ } |
+} |
+ |
} // namespace |
// static |