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

Side by Side Diff: ui/views/widget/desktop_root_window_host_linux.cc

Issue 10916349: linux_aura: Start implementing DesktopRootWindowHostLinux (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/views/widget/desktop_root_window_host_linux.h" 5 #include "ui/views/widget/desktop_root_window_host_linux.h"
6 6
7 #include <X11/extensions/XInput2.h>
8 #include <X11/Xatom.h>
9 #include <X11/Xutil.h>
10
11 #include "base/message_pump_aurax11.h"
12 #include "base/stringprintf.h"
13 #include "ui/aura/client/screen_position_client.h"
14 #include "ui/aura/client/user_action_client.h"
15 #include "ui/aura/desktop/desktop_activation_client.h"
16 #include "ui/aura/desktop/desktop_dispatcher_client.h"
17 #include "ui/aura/focus_manager.h"
7 #include "ui/aura/root_window.h" 18 #include "ui/aura/root_window.h"
19 #include "ui/aura/shared/compound_event_filter.h"
20 #include "ui/aura/shared/input_method_event_filter.h"
21 #include "ui/base/touch/touch_factory.h"
22 #include "ui/base/x/x11_util.h"
23 #include "ui/views/widget/desktop_capture_client.h"
24 #include "ui/views/widget/x11_desktop_handler.h"
25 #include "ui/views/widget/x11_window_event_filter.h"
8 26
9 namespace views { 27 namespace views {
10 28
29 namespace {
30
31 // Standard Linux mouse buttons for going back and forward.
32 const int kBackMouseButton = 8;
33 const int kForwardMouseButton = 9;
34
35 const char* kAtomsToCache[] = {
36 "WM_DELETE_WINDOW",
37 "_NET_WM_PING",
38 "_NET_WM_PID",
39 "WM_S0",
40 NULL
41 };
42
43 } // namespace
44
11 //////////////////////////////////////////////////////////////////////////////// 45 ////////////////////////////////////////////////////////////////////////////////
12 // DesktopRootWindowHostLinux, public: 46 // DesktopRootWindowHostLinux, public:
13 47
14 DesktopRootWindowHostLinux::DesktopRootWindowHostLinux() { 48 DesktopRootWindowHostLinux::DesktopRootWindowHostLinux()
49 : xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()),
50 xwindow_(0),
51 x_root_window_(DefaultRootWindow(xdisplay_)),
52 atom_cache_(xdisplay_, kAtomsToCache),
53 window_mapped_(false),
54 focus_when_shown_(false) {
15 } 55 }
16 56
17 DesktopRootWindowHostLinux::~DesktopRootWindowHostLinux() { 57 DesktopRootWindowHostLinux::~DesktopRootWindowHostLinux() {
58 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_);
59 XDestroyWindow(xdisplay_, xwindow_);
18 } 60 }
19 61
20 //////////////////////////////////////////////////////////////////////////////// 62 ////////////////////////////////////////////////////////////////////////////////
63 // DesktopRootWindowHostLinux, private:
64
65 void DesktopRootWindowHostLinux::InitX11Window(const gfx::Rect& bounds) {
66 XSetWindowAttributes swa;
67 memset(&swa, 0, sizeof(swa));
68 swa.background_pixmap = None;
69 xwindow_ = XCreateWindow(
70 xdisplay_, x_root_window_,
71 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
72 0, // border width
73 CopyFromParent, // depth
74 InputOutput,
75 CopyFromParent, // visual
76 CWBackPixmap,
77 &swa);
78 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_);
79
80 // TODO(erg): Maybe need to set a ViewProp here like in RWHL::RWHL().
81
82 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
83 KeyPressMask | KeyReleaseMask |
84 EnterWindowMask | LeaveWindowMask |
85 ExposureMask | VisibilityChangeMask |
86 StructureNotifyMask | PropertyChangeMask |
87 PointerMotionMask;
88 XSelectInput(xdisplay_, xwindow_, event_mask);
89 XFlush(xdisplay_);
90
91 // TODO(erg): Something about an invisible cursor here? Don't think I need
92 // it, but this is where it was.
93
94 // TODO(erg): We currently only request window deletion events. We also
95 // should listen for activation events and anything else that GTK+ listens
96 // for, and do something useful.
97 ::Atom protocols[2];
98 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
99 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
100 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
101
102 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
103 // the desktop environment.
104 XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL);
105
106 // Likewise, the X server needs to know this window's pid so it knows which
107 // program to kill if the window hangs.
108 pid_t pid = getpid();
109 XChangeProperty(xdisplay_,
110 xwindow_,
111 atom_cache_.GetAtom("_NET_WM_PID"),
112 XA_CARDINAL,
113 32,
114 PropModeReplace,
115 reinterpret_cast<unsigned char*>(&pid), 1);
116
117 // TODO(erg): Now that we're forked from RootWindowHostLinux, we should be
118 // doing a much better job about communicating things like the window title
119 // and icon to the window manager, which should replace this piece of copied
120 // code.
121 static int root_window_number = 0;
122 std::string name = StringPrintf("aura_root_%d", root_window_number++);
123 XStoreName(xdisplay_, xwindow_, name.c_str());
124 }
125
126 // TODO(erg): This method should basically be everything I need form
127 // RootWindowHostLinux::RootWindowHostLinux().
128 void DesktopRootWindowHostLinux::InitRootWindow(
129 const Widget::InitParams& params) {
130 aura::RootWindow::CreateParams rw_params(params.bounds);
131 rw_params.host = this;
132 root_window_.reset(new aura::RootWindow(rw_params));
133 root_window_->Init();
134 root_window_->AddChild(content_window_);
135 root_window_host_delegate_ = root_window_.get();
136
137 capture_client_.reset(new DesktopCaptureClient);
138 aura::client::SetCaptureClient(root_window_.get(), capture_client_.get());
139
140 root_window_->set_focus_manager(
141 X11DesktopHandler::get()->get_focus_manager());
142
143 aura::DesktopActivationClient* activation_client =
144 X11DesktopHandler::get()->get_activation_client();
145 aura::client::SetActivationClient(
146 root_window_.get(), activation_client);
147
148 dispatcher_client_.reset(new aura::DesktopDispatcherClient);
149 aura::client::SetDispatcherClient(root_window_.get(),
150 dispatcher_client_.get());
151
152 // No event filter for aura::Env. Create CompoundEvnetFilter per RootWindow.
153 root_window_event_filter_ = new aura::shared::CompoundEventFilter;
154 // Pass ownership of the filter to the root_window.
155 root_window_->SetEventFilter(root_window_event_filter_);
156
157 input_method_filter_.reset(new aura::shared::InputMethodEventFilter());
158 input_method_filter_->SetInputMethodPropertyInRootWindow(root_window_.get());
159 root_window_event_filter_->AddFilter(input_method_filter_.get());
160
161 // TODO(erg): Unify this code once the other consumer goes away.
162 x11_window_event_filter_.reset(
163 new X11WindowEventFilter(root_window_.get(), activation_client));
164 x11_window_event_filter_->SetUseHostWindowBorders(false);
165 root_window_event_filter_->AddFilter(x11_window_event_filter_.get());
166 }
167
168 bool DesktopRootWindowHostLinux::IsWindowManagerPresent() {
169 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
170 // of WM_Sn selections (where n is a screen number).
171 return XGetSelectionOwner(
172 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
173 }
174
175 ////////////////////////////////////////////////////////////////////////////////
21 // DesktopRootWindowHostLinux, DesktopRootWindowHost implementation: 176 // DesktopRootWindowHostLinux, DesktopRootWindowHost implementation:
22 177
23 void DesktopRootWindowHostLinux::Init(aura::Window* content_window, 178 void DesktopRootWindowHostLinux::Init(aura::Window* content_window,
24 const Widget::InitParams& params) { 179 const Widget::InitParams& params) {
25 // TODO(erg): 180 content_window_ = content_window;
26 NOTIMPLEMENTED(); 181
182 // TODO(erg): Check whether we *should* be building a RootWindowHost here, or
183 // whether we should be proxying requests to another DRWHL.
184
185 // TODO(erg): We can finally solve the role problem! Based on params, try to
186 // determine whether this is a utility window such as a menu.
187
188 InitX11Window(params.bounds);
189 InitRootWindow(params);
190
191 // TODO(erg): This should be done by a LayoutManager instead of being a
192 // one-off hack.
193 content_window_->SetBounds(params.bounds);
194
195 // This needs to be the intersection of:
196 // - NativeWidgetAura::InitNativeWidget()
197 // - DesktopNativeWidgetHelperAura::PreInitialize()
27 } 198 }
28 199
29 void DesktopRootWindowHostLinux::Close() { 200 void DesktopRootWindowHostLinux::Close() {
30 // TODO(erg): 201 // TODO(erg):
31 NOTIMPLEMENTED(); 202 NOTIMPLEMENTED();
32 } 203 }
33 204
34 void DesktopRootWindowHostLinux::CloseNow() { 205 void DesktopRootWindowHostLinux::CloseNow() {
35 // TODO(erg):
36 NOTIMPLEMENTED(); 206 NOTIMPLEMENTED();
37 } 207 }
38 208
39 aura::RootWindowHost* DesktopRootWindowHostLinux::AsRootWindowHost() { 209 aura::RootWindowHost* DesktopRootWindowHostLinux::AsRootWindowHost() {
40 // TODO(erg): 210 return this;
41 NOTIMPLEMENTED();
42 return NULL;
43 } 211 }
44 212
45 void DesktopRootWindowHostLinux::ShowWindowWithState( 213 void DesktopRootWindowHostLinux::ShowWindowWithState(
46 ui::WindowShowState show_state) { 214 ui::WindowShowState show_state) {
47 // TODO(erg): 215 if (show_state != ui::SHOW_STATE_DEFAULT &&
48 NOTIMPLEMENTED(); 216 show_state != ui::SHOW_STATE_NORMAL) {
217 // Only forwarding to Show().
218 NOTIMPLEMENTED();
219 }
220
221 Show();
49 } 222 }
50 223
51 void DesktopRootWindowHostLinux::ShowMaximizedWithBounds( 224 void DesktopRootWindowHostLinux::ShowMaximizedWithBounds(
52 const gfx::Rect& restored_bounds) { 225 const gfx::Rect& restored_bounds) {
53 // TODO(erg): 226 // TODO(erg):
54 NOTIMPLEMENTED(); 227 NOTIMPLEMENTED();
55 } 228 }
56 229
57 bool DesktopRootWindowHostLinux::IsVisible() const { 230 bool DesktopRootWindowHostLinux::IsVisible() const {
58 // TODO(erg): 231 return window_mapped_;
59 NOTIMPLEMENTED();
60 return true;
61 } 232 }
62 233
63 void DesktopRootWindowHostLinux::SetSize(const gfx::Size& size) { 234 void DesktopRootWindowHostLinux::SetSize(const gfx::Size& size) {
64 // TODO(erg): 235 // TODO(erg):
65 NOTIMPLEMENTED(); 236 NOTIMPLEMENTED();
66 } 237 }
67 238
68 void DesktopRootWindowHostLinux::CenterWindow(const gfx::Size& size) { 239 void DesktopRootWindowHostLinux::CenterWindow(const gfx::Size& size) {
69 // TODO(erg): 240 // TODO(erg):
70 NOTIMPLEMENTED(); 241 NOTIMPLEMENTED();
71 } 242 }
72 243
73 void DesktopRootWindowHostLinux::GetWindowPlacement( 244 void DesktopRootWindowHostLinux::GetWindowPlacement(
74 gfx::Rect* bounds, 245 gfx::Rect* bounds,
75 ui::WindowShowState* show_state) const { 246 ui::WindowShowState* show_state) const {
76 // TODO(erg): 247 // TODO(erg):
77 NOTIMPLEMENTED(); 248 NOTIMPLEMENTED();
78 } 249 }
79 250
80 gfx::Rect DesktopRootWindowHostLinux::GetWindowBoundsInScreen() const { 251 gfx::Rect DesktopRootWindowHostLinux::GetWindowBoundsInScreen() const {
81 // TODO(erg): 252 // TODO(erg):
82 NOTIMPLEMENTED(); 253 NOTIMPLEMENTED();
83 return gfx::Rect(); 254 return gfx::Rect();
84 } 255 }
85 256
86 gfx::Rect DesktopRootWindowHostLinux::GetClientAreaBoundsInScreen() const { 257 gfx::Rect DesktopRootWindowHostLinux::GetClientAreaBoundsInScreen() const {
87 // TODO(erg): 258 // TODO(erg):
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 NOTIMPLEMENTED(); 341 NOTIMPLEMENTED();
171 return NULL; 342 return NULL;
172 } 343 }
173 344
174 void DesktopRootWindowHostLinux::SetWindowTitle(const string16& title) { 345 void DesktopRootWindowHostLinux::SetWindowTitle(const string16& title) {
175 // TODO(erg): 346 // TODO(erg):
176 NOTIMPLEMENTED(); 347 NOTIMPLEMENTED();
177 } 348 }
178 349
179 //////////////////////////////////////////////////////////////////////////////// 350 ////////////////////////////////////////////////////////////////////////////////
351 // DesktopRootWindowHostLinux, aura::RootWindowHost implementation:
352
353 aura::RootWindow* DesktopRootWindowHostLinux::GetRootWindow() {
354 return root_window_.get();
355 }
356
357 gfx::AcceleratedWidget DesktopRootWindowHostLinux::GetAcceleratedWidget() {
358 return xwindow_;
359 }
360
361 void DesktopRootWindowHostLinux::Show() {
362 if (!window_mapped_) {
363 // Before we map the window, set size hints. Otherwise, some window managers
364 // will ignore toplevel XMoveWindow commands.
365 XSizeHints size_hints;
366 size_hints.flags = PPosition;
367 size_hints.x = bounds_.x();
368 size_hints.y = bounds_.y();
369 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
370
371 XMapWindow(xdisplay_, xwindow_);
372
373 // We now block until our window is mapped. Some X11 APIs will crash and
374 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is
375 // asynchronous.
376 base::MessagePumpAuraX11::Current()->BlockUntilWindowMapped(xwindow_);
377 window_mapped_ = true;
378 }
379 }
380
381 void DesktopRootWindowHostLinux::Hide() {
382 if (window_mapped_) {
383 XWithdrawWindow(xdisplay_, xwindow_, 0);
384 window_mapped_ = false;
385 }
386 }
387
388 void DesktopRootWindowHostLinux::ToggleFullScreen() {
389 }
390
391 gfx::Rect DesktopRootWindowHostLinux::GetBounds() const {
392 return gfx::Rect(100, 100);
393 }
394
395 void DesktopRootWindowHostLinux::SetBounds(const gfx::Rect& bounds) {
396 }
397
398 gfx::Point DesktopRootWindowHostLinux::GetLocationOnNativeScreen() const {
399 return gfx::Point(1, 1);
400 }
401
402 void DesktopRootWindowHostLinux::SetCapture() {
403 }
404
405 void DesktopRootWindowHostLinux::ReleaseCapture() {
406 }
407
408 void DesktopRootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) {
409 }
410
411 void DesktopRootWindowHostLinux::ShowCursor(bool show) {
412 }
413
414 bool DesktopRootWindowHostLinux::QueryMouseLocation(
415 gfx::Point* location_return) {
416 return false;
417 }
418
419 bool DesktopRootWindowHostLinux::ConfineCursorToRootWindow() {
420 return false;
421 }
422
423 void DesktopRootWindowHostLinux::UnConfineCursor() {
424 }
425
426 void DesktopRootWindowHostLinux::MoveCursorTo(const gfx::Point& location) {
427 }
428
429 void DesktopRootWindowHostLinux::SetFocusWhenShown(bool focus_when_shown) {
430 static const char* k_NET_WM_USER_TIME = "_NET_WM_USER_TIME";
431 focus_when_shown_ = focus_when_shown;
432 if (IsWindowManagerPresent() && !focus_when_shown_) {
433 ui::SetIntProperty(xwindow_,
434 k_NET_WM_USER_TIME,
435 k_NET_WM_USER_TIME,
436 0);
437 }
438 }
439
440 bool DesktopRootWindowHostLinux::GrabSnapshot(
441 const gfx::Rect& snapshot_bounds,
442 std::vector<unsigned char>* png_representation) {
443 return false;
444 }
445
446 void DesktopRootWindowHostLinux::PostNativeEvent(
447 const base::NativeEvent& native_event) {
448 DCHECK(xwindow_);
449 DCHECK(xdisplay_);
450 XEvent xevent = *native_event;
451 xevent.xany.display = xdisplay_;
452 xevent.xany.window = xwindow_;
453
454 switch (xevent.type) {
455 case EnterNotify:
456 case LeaveNotify:
457 case MotionNotify:
458 case KeyPress:
459 case KeyRelease:
460 case ButtonPress:
461 case ButtonRelease: {
462 // The fields used below are in the same place for all of events
463 // above. Using xmotion from XEvent's unions to avoid repeating
464 // the code.
465 xevent.xmotion.root = x_root_window_;
466 xevent.xmotion.time = CurrentTime;
467
468 gfx::Point point(xevent.xmotion.x, xevent.xmotion.y);
469 root_window_->ConvertPointToNativeScreen(&point);
470 xevent.xmotion.x_root = point.x();
471 xevent.xmotion.y_root = point.y();
472 }
473 default:
474 break;
475 }
476 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent);
477 }
478
479 void DesktopRootWindowHostLinux::OnDeviceScaleFactorChanged(
480 float device_scale_factor) {
481 }
482
483 void DesktopRootWindowHostLinux::PrepareForShutdown() {
484 }
485
486 ////////////////////////////////////////////////////////////////////////////////
487 // DesktopRootWindowHostLinux, MessageLoop::Dispatcher implementation:
488
489 bool DesktopRootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
490 XEvent* xev = event;
491
492 // May want to factor CheckXEventForConsistency(xev); into a common location
493 // since it is called here.
494 switch (xev->type) {
495 case Expose:
496 // TODO(erg): Can we only redraw the affected areas?
497 root_window_host_delegate_->OnHostPaint();
498 break;
499 case KeyPress: {
500 ui::KeyEvent keydown_event(xev, false);
501 root_window_host_delegate_->OnHostKeyEvent(&keydown_event);
502 break;
503 }
504 case KeyRelease: {
505 ui::KeyEvent keyup_event(xev, false);
506 root_window_host_delegate_->OnHostKeyEvent(&keyup_event);
507 break;
508 }
509 case ButtonPress: {
510 if (static_cast<int>(xev->xbutton.button) == kBackMouseButton ||
511 static_cast<int>(xev->xbutton.button) == kForwardMouseButton) {
512 aura::client::UserActionClient* gesture_client =
513 aura::client::GetUserActionClient(root_window_.get());
514 if (gesture_client) {
515 gesture_client->OnUserAction(
516 static_cast<int>(xev->xbutton.button) == kBackMouseButton ?
517 aura::client::UserActionClient::BACK :
518 aura::client::UserActionClient::FORWARD);
519 }
520 break;
521 }
522 } // fallthrough
523 case ButtonRelease: {
524 ui::MouseEvent mouseev(xev);
525 root_window_host_delegate_->OnHostMouseEvent(&mouseev);
526 break;
527 }
528 case FocusOut:
529 if (xev->xfocus.mode != NotifyGrab)
530 root_window_host_delegate_->OnHostLostCapture();
531 break;
532 case ConfigureNotify: {
533 DCHECK_EQ(xwindow_, xev->xconfigure.window);
534 DCHECK_EQ(xwindow_, xev->xconfigure.event);
535 // It's possible that the X window may be resized by some other means than
536 // from within aura (e.g. the X window manager can change the size). Make
537 // sure the root window size is maintained properly.
538 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
539 xev->xconfigure.width, xev->xconfigure.height);
540 bool size_changed = bounds_.size() != bounds.size();
541 bool origin_changed = bounds_.origin() != bounds.origin();
542 bounds_ = bounds;
543 if (size_changed)
544 root_window_host_delegate_->OnHostResized(bounds.size());
545 if (origin_changed)
546 root_window_host_delegate_->OnHostMoved(bounds_.origin());
547 break;
548 }
549 case GenericEvent: {
550 ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
551 if (!factory->ShouldProcessXI2Event(xev))
552 break;
553
554 ui::EventType type = ui::EventTypeFromNative(xev);
555 XEvent last_event;
556 int num_coalesced = 0;
557
558 switch (type) {
559 // case ui::ET_TOUCH_MOVED:
560 // num_coalesced = CoalescePendingMotionEvents(xev, &last_event);
561 // if (num_coalesced > 0)
562 // xev = &last_event;
563 // // fallthrough
564 // case ui::ET_TOUCH_PRESSED:
565 // case ui::ET_TOUCH_RELEASED: {
566 // ui::TouchEvent touchev(xev);
567 // root_window_host_delegate_->OnHostTouchEvent(&touchev);
568 // break;
569 // }
570 case ui::ET_MOUSE_MOVED:
571 case ui::ET_MOUSE_DRAGGED:
572 case ui::ET_MOUSE_PRESSED:
573 case ui::ET_MOUSE_RELEASED:
574 case ui::ET_MOUSE_ENTERED:
575 case ui::ET_MOUSE_EXITED: {
576 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) {
577 // If this is a motion event, we want to coalesce all pending motion
578 // events that are at the top of the queue.
579 // num_coalesced = CoalescePendingMotionEvents(xev, &last_event);
580 // if (num_coalesced > 0)
581 // xev = &last_event;
582 } else if (type == ui::ET_MOUSE_PRESSED) {
583 XIDeviceEvent* xievent =
584 static_cast<XIDeviceEvent*>(xev->xcookie.data);
585 int button = xievent->detail;
586 if (button == kBackMouseButton || button == kForwardMouseButton) {
587 aura::client::UserActionClient* gesture_client =
588 aura::client::GetUserActionClient(
589 root_window_host_delegate_->AsRootWindow());
590 if (gesture_client) {
591 bool reverse_direction =
592 ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled();
593 gesture_client->OnUserAction(
594 (button == kBackMouseButton && !reverse_direction) ||
595 (button == kForwardMouseButton && reverse_direction) ?
596 aura::client::UserActionClient::BACK :
597 aura::client::UserActionClient::FORWARD);
598 }
599 break;
600 }
601 }
602 ui::MouseEvent mouseev(xev);
603 root_window_host_delegate_->OnHostMouseEvent(&mouseev);
604 break;
605 }
606 case ui::ET_MOUSEWHEEL: {
607 ui::MouseWheelEvent mouseev(xev);
608 root_window_host_delegate_->OnHostMouseEvent(&mouseev);
609 break;
610 }
611 case ui::ET_SCROLL_FLING_START:
612 case ui::ET_SCROLL_FLING_CANCEL:
613 case ui::ET_SCROLL: {
614 ui::ScrollEvent scrollev(xev);
615 root_window_host_delegate_->OnHostScrollEvent(&scrollev);
616 break;
617 }
618 case ui::ET_UNKNOWN:
619 break;
620 default:
621 NOTREACHED();
622 }
623
624 // If we coalesced an event we need to free its cookie.
625 if (num_coalesced > 0)
626 XFreeEventData(xev->xgeneric.display, &last_event.xcookie);
627 break;
628 }
629 case MapNotify: {
630 // If there's no window manager running, we need to assign the X input
631 // focus to our host window.
632 if (!IsWindowManagerPresent() && focus_when_shown_)
633 XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime);
634 break;
635 }
636 case ClientMessage: {
637 Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]);
638 if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
639 // We have received a close message from the window manager.
640 root_window_->OnRootWindowHostCloseRequested();
641 } else if (message_type == atom_cache_.GetAtom("_NET_WM_PING")) {
642 XEvent reply_event = *xev;
643 reply_event.xclient.window = x_root_window_;
644
645 XSendEvent(xdisplay_,
646 reply_event.xclient.window,
647 False,
648 SubstructureRedirectMask | SubstructureNotifyMask,
649 &reply_event);
650 }
651 break;
652 }
653 case MappingNotify: {
654 switch (xev->xmapping.request) {
655 case MappingModifier:
656 case MappingKeyboard:
657 XRefreshKeyboardMapping(&xev->xmapping);
658 root_window_->OnKeyboardMappingChanged();
659 break;
660 case MappingPointer:
661 ui::UpdateButtonMap();
662 break;
663 default:
664 NOTIMPLEMENTED() << " Unknown request: " << xev->xmapping.request;
665 break;
666 }
667 break;
668 }
669 case MotionNotify: {
670 // Discard all but the most recent motion event that targets the same
671 // window with unchanged state.
672 XEvent last_event;
673 while (XPending(xev->xany.display)) {
674 XEvent next_event;
675 XPeekEvent(xev->xany.display, &next_event);
676 if (next_event.type == MotionNotify &&
677 next_event.xmotion.window == xev->xmotion.window &&
678 next_event.xmotion.subwindow == xev->xmotion.subwindow &&
679 next_event.xmotion.state == xev->xmotion.state) {
680 XNextEvent(xev->xany.display, &last_event);
681 xev = &last_event;
682 } else {
683 break;
684 }
685 }
686
687 ui::MouseEvent mouseev(xev);
688 root_window_host_delegate_->OnHostMouseEvent(&mouseev);
689 break;
690 }
691 }
692 return true;
693 }
694
695 ////////////////////////////////////////////////////////////////////////////////
180 // DesktopRootWindowHost, public: 696 // DesktopRootWindowHost, public:
181 697
182 // static 698 // static
183 DesktopRootWindowHost* DesktopRootWindowHost::Create( 699 DesktopRootWindowHost* DesktopRootWindowHost::Create(
184 internal::NativeWidgetDelegate* native_widget_delegate, 700 internal::NativeWidgetDelegate* native_widget_delegate,
185 const gfx::Rect& initial_bounds) { 701 const gfx::Rect& initial_bounds) {
186 return new DesktopRootWindowHostLinux; 702 return new DesktopRootWindowHostLinux;
187 } 703 }
188 704
189 } // namespace views 705 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/widget/desktop_root_window_host_linux.h ('k') | ui/views/widget/x11_window_event_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698