| Index: ui/aura/desktop_host_linux.cc
|
| diff --git a/ui/aura/desktop_host_linux.cc b/ui/aura/desktop_host_linux.cc
|
| index 7e9a5b110b073e12983307923cc62f8c27c31b27..7abfa4cd65d596eaba78cb0ad0bcc872d282ac71 100644
|
| --- a/ui/aura/desktop_host_linux.cc
|
| +++ b/ui/aura/desktop_host_linux.cc
|
| @@ -12,11 +12,13 @@
|
|
|
| #include <algorithm>
|
|
|
| +#include "base/event_types.h"
|
| #include "base/message_loop.h"
|
| #include "base/message_pump_x.h"
|
| #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 +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,48 +189,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();
|
| @@ -242,6 +210,12 @@ 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 ui::InputMethod* GetInputMethod() 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;
|
|
|
| // 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
|
| @@ -254,6 +228,13 @@ class DesktopHostLinux : public DesktopHost {
|
| Display* xdisplay_;
|
| ::Window xwindow_;
|
|
|
| + // The input method for the desktop.
|
| +#if defined(HAVE_IBUS)
|
| + ui::InputMethodIBus input_method_;
|
| +#else
|
| + ui::MockInputMethod input_method_;
|
| +#endif
|
| +
|
| // Current Aura cursor.
|
| gfx::NativeCursor current_cursor_;
|
|
|
| @@ -267,6 +248,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),
|
| bounds_(bounds) {
|
| xwindow_ = XCreateSimpleWindow(xdisplay_, DefaultRootWindow(xdisplay_),
|
| @@ -274,7 +256,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 |
|
| @@ -287,6 +269,8 @@ DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds)
|
| if (base::MessagePumpForUI::HasXInput2())
|
| ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
|
| #endif
|
| +
|
| + input_method_.Init(xwindow_);
|
| }
|
|
|
| DesktopHostLinux::~DesktopHostLinux() {
|
| @@ -304,19 +288,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: {
|
| @@ -388,6 +363,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.
|
| @@ -527,6 +510,23 @@ bool DesktopHostLinux::IsWindowManagerPresent() {
|
| return XGetSelectionOwner(xdisplay_, wm_s0_atom) != None;
|
| }
|
|
|
| +ui::InputMethod* DesktopHostLinux::GetInputMethod() {
|
| + return &input_method_;
|
| +}
|
| +
|
| +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
|
|
|