Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: ui/aura/desktop_host_linux.cc

Issue 8576005: IME (input method editor) support for Aura, part 3 of 3: Use ui::InputMethod in ash. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase, review Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/aura/desktop_host.h" 5 #include "ui/aura/desktop_host.h"
6 6
7 #include <X11/cursorfont.h> 7 #include <X11/cursorfont.h>
8 #include <X11/Xlib.h> 8 #include <X11/Xlib.h>
9 9
10 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. 10 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class.
11 #undef RootWindow 11 #undef RootWindow
12 12
13 #include <algorithm> 13 #include <algorithm>
14 14
15 #include "base/message_loop.h" 15 #include "base/message_loop.h"
16 #include "base/message_pump_x.h" 16 #include "base/message_pump_x.h"
17 #include "ui/aura/cursor.h" 17 #include "ui/aura/cursor.h"
18 #include "ui/aura/desktop.h" 18 #include "ui/aura/desktop.h"
19 #include "ui/aura/event.h" 19 #include "ui/aura/event.h"
20 #include "ui/base/ime/input_method_delegate.h"
20 #include "ui/base/keycodes/keyboard_codes.h" 21 #include "ui/base/keycodes/keyboard_codes.h"
21 #include "ui/base/touch/touch_factory.h" 22 #include "ui/base/touch/touch_factory.h"
22 #include "ui/base/x/x11_util.h" 23 #include "ui/base/x/x11_util.h"
23 #include "ui/gfx/compositor/layer.h" 24 #include "ui/gfx/compositor/layer.h"
24 25
25 #include <X11/cursorfont.h> 26 #include <X11/cursorfont.h>
26 #include <X11/extensions/XInput2.h> 27 #include <X11/extensions/XInput2.h>
27 #include <X11/Xlib.h> 28 #include <X11/Xlib.h>
28 29
30 #if defined(HAVE_IBUS)
31 #include "ui/base/ime/input_method_ibus_aura.h"
32 #else
33 #include "ui/base/ime/mock_input_method.h"
34 #endif
35
29 using std::max; 36 using std::max;
30 using std::min; 37 using std::min;
31 38
32 namespace aura { 39 namespace aura {
33 40
34 namespace { 41 namespace {
35 42
36 // Returns X font cursor shape from an Aura cursor. 43 // Returns X font cursor shape from an Aura cursor.
37 int CursorShapeFromNative(gfx::NativeCursor native_cursor) { 44 int CursorShapeFromNative(gfx::NativeCursor native_cursor) {
38 switch (native_cursor) { 45 switch (native_cursor) {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 } else { 181 } else {
175 // This isn't an event we want so free its cookie data. 182 // This isn't an event we want so free its cookie data.
176 XFreeEventData(display, &next_event.xcookie); 183 XFreeEventData(display, &next_event.xcookie);
177 } 184 }
178 } 185 }
179 break; 186 break;
180 } 187 }
181 return num_coalesed; 188 return num_coalesed;
182 } 189 }
183 190
184 // We emulate Windows' WM_KEYDOWN and WM_CHAR messages. WM_CHAR events are only 191 class DesktopHostLinux : public DesktopHost,
185 // generated for certain keys; see 192 public ui::internal::InputMethodDelegate {
186 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268.aspx.
187 bool ShouldSendCharEventForKeyboardCode(ui::KeyboardCode keycode) {
188 if ((keycode >= ui::VKEY_0 && keycode <= ui::VKEY_9) ||
189 (keycode >= ui::VKEY_A && keycode <= ui::VKEY_Z) ||
190 (keycode >= ui::VKEY_NUMPAD0 && keycode <= ui::VKEY_NUMPAD9)) {
191 return true;
192 }
193
194 switch (keycode) {
195 case ui::VKEY_BACK:
196 case ui::VKEY_RETURN:
197 case ui::VKEY_ESCAPE:
198 case ui::VKEY_SPACE:
199 case ui::VKEY_TAB:
200 // In addition to the keys listed at MSDN, we include other
201 // graphic-character and numpad keys.
202 case ui::VKEY_MULTIPLY:
203 case ui::VKEY_ADD:
204 case ui::VKEY_SUBTRACT:
205 case ui::VKEY_DECIMAL:
206 case ui::VKEY_DIVIDE:
207 case ui::VKEY_OEM_1:
208 case ui::VKEY_OEM_2:
209 case ui::VKEY_OEM_3:
210 case ui::VKEY_OEM_4:
211 case ui::VKEY_OEM_5:
212 case ui::VKEY_OEM_6:
213 case ui::VKEY_OEM_7:
214 case ui::VKEY_OEM_102:
215 case ui::VKEY_OEM_PLUS:
216 case ui::VKEY_OEM_COMMA:
217 case ui::VKEY_OEM_MINUS:
218 case ui::VKEY_OEM_PERIOD:
219 return true;
220 default:
221 return false;
222 }
223 }
224
225 class DesktopHostLinux : public DesktopHost {
226 public: 193 public:
227 explicit DesktopHostLinux(const gfx::Rect& bounds); 194 explicit DesktopHostLinux(const gfx::Rect& bounds);
228 virtual ~DesktopHostLinux(); 195 virtual ~DesktopHostLinux();
229 196
230 private: 197 private:
231 // base::MessageLoop::Dispatcher Override. 198 // base::MessageLoop::Dispatcher Override.
232 virtual DispatchStatus Dispatch(XEvent* xev) OVERRIDE; 199 virtual DispatchStatus Dispatch(XEvent* xev) OVERRIDE;
233 200
234 // DesktopHost Overrides. 201 // DesktopHost Overrides.
235 virtual void SetDesktop(Desktop* desktop) OVERRIDE; 202 virtual void SetDesktop(Desktop* desktop) OVERRIDE;
236 virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; 203 virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
237 virtual void Show() OVERRIDE; 204 virtual void Show() OVERRIDE;
238 virtual void ToggleFullScreen() OVERRIDE; 205 virtual void ToggleFullScreen() OVERRIDE;
239 virtual gfx::Size GetSize() const OVERRIDE; 206 virtual gfx::Size GetSize() const OVERRIDE;
240 virtual void SetSize(const gfx::Size& size) OVERRIDE; 207 virtual void SetSize(const gfx::Size& size) OVERRIDE;
241 virtual void SetCursor(gfx::NativeCursor cursor_type) OVERRIDE; 208 virtual void SetCursor(gfx::NativeCursor cursor_type) OVERRIDE;
242 virtual gfx::Point QueryMouseLocation() OVERRIDE; 209 virtual gfx::Point QueryMouseLocation() OVERRIDE;
210 virtual ui::InputMethod* GetInputMethod() OVERRIDE;
211
212 // ui::internal::InputMethodDelegate Override.
213 virtual void DispatchKeyEventPostIME(Event* event) OVERRIDE;
243 214
244 // Returns true if there's an X window manager present... in most cases. Some 215 // Returns true if there's an X window manager present... in most cases. Some
245 // window managers (notably, ion3) don't implement enough of ICCCM for us to 216 // window managers (notably, ion3) don't implement enough of ICCCM for us to
246 // detect that they're there. 217 // detect that they're there.
247 bool IsWindowManagerPresent(); 218 bool IsWindowManagerPresent();
248 219
249 Desktop* desktop_; 220 Desktop* desktop_;
250 221
251 // The display and the native X window hosting the desktop. 222 // The display and the native X window hosting the desktop.
252 Display* xdisplay_; 223 Display* xdisplay_;
253 ::Window xwindow_; 224 ::Window xwindow_;
254 225
226 // The input method for the desktop.
227 #if defined(HAVE_IBUS)
228 ui::InputMethodIBusAura input_method_;
229 #else
230 ui::MockInputMethod input_method_;
231 #endif
232
255 // Current Aura cursor. 233 // Current Aura cursor.
256 gfx::NativeCursor current_cursor_; 234 gfx::NativeCursor current_cursor_;
257 235
258 // The size of |xwindow_|. 236 // The size of |xwindow_|.
259 gfx::Size size_; 237 gfx::Size size_;
260 238
261 DISALLOW_COPY_AND_ASSIGN(DesktopHostLinux); 239 DISALLOW_COPY_AND_ASSIGN(DesktopHostLinux);
262 }; 240 };
263 241
264 DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds) 242 DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds)
265 : desktop_(NULL), 243 : desktop_(NULL),
266 xdisplay_(base::MessagePumpX::GetDefaultXDisplay()), 244 xdisplay_(base::MessagePumpX::GetDefaultXDisplay()),
267 xwindow_(0), 245 xwindow_(0),
246 ALLOW_THIS_IN_INITIALIZER_LIST(input_method_(this)),
268 current_cursor_(aura::kCursorNull), 247 current_cursor_(aura::kCursorNull),
269 size_(bounds.size()) { 248 size_(bounds.size()) {
270 xwindow_ = XCreateSimpleWindow(xdisplay_, DefaultRootWindow(xdisplay_), 249 xwindow_ = XCreateSimpleWindow(xdisplay_, DefaultRootWindow(xdisplay_),
271 bounds.x(), bounds.y(), 250 bounds.x(), bounds.y(),
272 bounds.width(), bounds.height(), 251 bounds.width(), bounds.height(),
273 0, 0, 0); 252 0, 0, 0);
274 253
275 long event_mask = ButtonPressMask | ButtonReleaseMask | 254 long event_mask = ButtonPressMask | ButtonReleaseMask |
276 KeyPressMask | KeyReleaseMask | 255 KeyPressMask | KeyReleaseMask |
277 ExposureMask | VisibilityChangeMask | 256 ExposureMask | VisibilityChangeMask |
278 StructureNotifyMask | PropertyChangeMask | 257 StructureNotifyMask | PropertyChangeMask |
279 PointerMotionMask; 258 PointerMotionMask;
280 XSelectInput(xdisplay_, xwindow_, event_mask); 259 XSelectInput(xdisplay_, xwindow_, event_mask);
281 XFlush(xdisplay_); 260 XFlush(xdisplay_);
282 261
283 // TODO(sadrul): reenable once 103981 is fixed. 262 // TODO(sadrul): reenable once 103981 is fixed.
284 #if defined(TOUCH_UI) 263 #if defined(TOUCH_UI)
285 if (base::MessagePumpForUI::HasXInput2()) 264 if (base::MessagePumpForUI::HasXInput2())
286 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); 265 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
287 #endif 266 #endif
267
268 // You can't call input_method_.Init() here since ui::InputMethod might depend
269 // on aura::Desktop, and this constructor might be called during the
270 // construction of the desktop singleton instance.
288 } 271 }
289 272
290 DesktopHostLinux::~DesktopHostLinux() { 273 DesktopHostLinux::~DesktopHostLinux() {
291 XDestroyWindow(xdisplay_, xwindow_); 274 XDestroyWindow(xdisplay_, xwindow_);
292 275
293 // Clears XCursorCache. 276 // Clears XCursorCache.
294 ui::GetXCursor(ui::kCursorClearXCursorCache); 277 ui::GetXCursor(ui::kCursorClearXCursorCache);
295 } 278 }
296 279
297 base::MessagePumpDispatcher::DispatchStatus DesktopHostLinux::Dispatch( 280 base::MessagePumpDispatcher::DispatchStatus DesktopHostLinux::Dispatch(
298 XEvent* xev) { 281 XEvent* xev) {
299 bool handled = false; 282 bool handled = false;
300 switch (xev->type) { 283 switch (xev->type) {
301 case Expose: 284 case Expose:
302 desktop_->Draw(); 285 desktop_->Draw();
303 handled = true; 286 handled = true;
304 break; 287 break;
305 case KeyPress: { 288 case KeyPress:
306 KeyEvent keydown_event(xev, false);
307 handled = desktop_->DispatchKeyEvent(&keydown_event);
308 if (ShouldSendCharEventForKeyboardCode(keydown_event.key_code())) {
309 KeyEvent char_event(xev, true);
310 handled |= desktop_->DispatchKeyEvent(&char_event);
311 }
312 break;
313 }
314 case KeyRelease: { 289 case KeyRelease: {
315 KeyEvent keyup_event(xev, false); 290 KeyEvent key_event(xev, false);
316 handled = desktop_->DispatchKeyEvent(&keyup_event); 291 input_method_.DispatchKeyEvent(&key_event);
317 break; 292 handled = true;
318 } 293 }
319 case ButtonPress: 294 case ButtonPress:
320 case ButtonRelease: { 295 case ButtonRelease: {
321 MouseEvent mouseev(xev); 296 MouseEvent mouseev(xev);
322 handled = desktop_->DispatchMouseEvent(&mouseev); 297 handled = desktop_->DispatchMouseEvent(&mouseev);
323 break; 298 break;
324 } 299 }
325 case ConfigureNotify: { 300 case ConfigureNotify: {
326 DCHECK_EQ(xdisplay_, xev->xconfigure.display); 301 DCHECK_EQ(xdisplay_, xev->xconfigure.display);
327 DCHECK_EQ(xwindow_, xev->xconfigure.window); 302 DCHECK_EQ(xwindow_, xev->xconfigure.window);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 max(0, min(size_.height(), win_y_return))); 456 max(0, min(size_.height(), win_y_return)));
482 } 457 }
483 458
484 bool DesktopHostLinux::IsWindowManagerPresent() { 459 bool DesktopHostLinux::IsWindowManagerPresent() {
485 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership 460 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
486 // of WM_Sn selections (where n is a screen number). 461 // of WM_Sn selections (where n is a screen number).
487 ::Atom wm_s0_atom = XInternAtom(xdisplay_, "WM_S0", False); 462 ::Atom wm_s0_atom = XInternAtom(xdisplay_, "WM_S0", False);
488 return XGetSelectionOwner(xdisplay_, wm_s0_atom) != None; 463 return XGetSelectionOwner(xdisplay_, wm_s0_atom) != None;
489 } 464 }
490 465
466 ui::InputMethod* DesktopHostLinux::GetInputMethod() {
467 return &input_method_;
468 }
469
470 void DesktopHostLinux::DispatchKeyEventPostIME(Event* event) {
471 DCHECK(event->type() == ui::ET_KEY_PRESSED ||
472 event->type() == ui::ET_KEY_RELEASED);
473 const KeyEvent& key = *static_cast<KeyEvent*>(event);
474
475 if (!key.native_event()) {
476 // Dispatch a ui::VKEY_PROCESSKEY event generated by |input_method_|.
477 KeyEvent aura_event(key.type(), key.key_code(), key.flags());
478 desktop_->DispatchKeyEvent(&aura_event);
479 return;
480 }
481
482 if (key.type() == ui::ET_KEY_PRESSED) {
483 KeyEvent keydown_event(key.native_event(), false);
484 desktop_->DispatchKeyEvent(&keydown_event);
485 // We don't send a Char event here since the input method in DesktopHost
486 // takes care of it.
487 } else {
488 KeyEvent keyup_event(key.native_event(), false);
489 desktop_->DispatchKeyEvent(&keyup_event);
490 }
491 }
492
491 } // namespace 493 } // namespace
492 494
493 // static 495 // static
494 DesktopHost* DesktopHost::Create(const gfx::Rect& bounds) { 496 DesktopHost* DesktopHost::Create(const gfx::Rect& bounds) {
495 return new DesktopHostLinux(bounds); 497 return new DesktopHostLinux(bounds);
496 } 498 }
497 499
498 // static 500 // static
499 gfx::Size DesktopHost::GetNativeDisplaySize() { 501 gfx::Size DesktopHost::GetNativeDisplaySize() {
500 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); 502 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay();
501 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); 503 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
502 } 504 }
503 505
504 } // namespace aura 506 } // namespace aura
OLDNEW
« no previous file with comments | « ui/aura/desktop_host.h ('k') | ui/aura/desktop_host_win.h » ('j') | ui/base/ime/input_method.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698