| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ui/views/test/x11_property_change_waiter.h" | |
| 6 | |
| 7 #include <X11/Xlib.h> | |
| 8 | |
| 9 #include "base/run_loop.h" | |
| 10 #include "ui/events/platform/platform_event_source.h" | |
| 11 #include "ui/events/platform/scoped_event_dispatcher.h" | |
| 12 #include "ui/gfx/x/x11_atom_cache.h" | |
| 13 | |
| 14 namespace views { | |
| 15 | |
| 16 X11PropertyChangeWaiter::X11PropertyChangeWaiter(XID window, | |
| 17 const char* property) | |
| 18 : x_window_(window), | |
| 19 property_(property), | |
| 20 wait_(true), | |
| 21 old_event_mask_(0) { | |
| 22 Display* display = gfx::GetXDisplay(); | |
| 23 | |
| 24 // Ensure that we are listening to PropertyNotify events for |window|. This | |
| 25 // is not the case for windows which were not created by | |
| 26 // DesktopWindowTreeHostX11. | |
| 27 XWindowAttributes attributes; | |
| 28 XGetWindowAttributes(display, x_window_, &attributes); | |
| 29 old_event_mask_ = attributes.your_event_mask; | |
| 30 XSelectInput(display, x_window_, old_event_mask_ | PropertyChangeMask); | |
| 31 | |
| 32 const char* kAtomsToCache[] = { property, NULL }; | |
| 33 atom_cache_.reset(new ui::X11AtomCache(display, kAtomsToCache)); | |
| 34 | |
| 35 // Override the dispatcher so that we get events before | |
| 36 // DesktopWindowTreeHostX11 does. We must do this because | |
| 37 // DesktopWindowTreeHostX11 stops propagation. | |
| 38 dispatcher_ = ui::PlatformEventSource::GetInstance()-> | |
| 39 OverrideDispatcher(this).Pass(); | |
| 40 } | |
| 41 | |
| 42 X11PropertyChangeWaiter::~X11PropertyChangeWaiter() { | |
| 43 XSelectInput(gfx::GetXDisplay(), x_window_, old_event_mask_); | |
| 44 } | |
| 45 | |
| 46 void X11PropertyChangeWaiter::Wait() { | |
| 47 if (!wait_) | |
| 48 return; | |
| 49 | |
| 50 base::RunLoop run_loop; | |
| 51 quit_closure_ = run_loop.QuitClosure(); | |
| 52 run_loop.Run(); | |
| 53 | |
| 54 dispatcher_.reset(); | |
| 55 } | |
| 56 | |
| 57 bool X11PropertyChangeWaiter::ShouldKeepOnWaiting( | |
| 58 const ui::PlatformEvent& event) { | |
| 59 // Stop waiting once we get a property change. | |
| 60 return true; | |
| 61 } | |
| 62 | |
| 63 bool X11PropertyChangeWaiter::CanDispatchEvent(const ui::PlatformEvent& event) { | |
| 64 NOTREACHED(); | |
| 65 return true; | |
| 66 } | |
| 67 | |
| 68 uint32_t X11PropertyChangeWaiter::DispatchEvent( | |
| 69 const ui::PlatformEvent& event) { | |
| 70 if (!wait_ || | |
| 71 event->type != PropertyNotify || | |
| 72 event->xproperty.window != x_window_ || | |
| 73 event->xproperty.atom != atom_cache_->GetAtom(property_) || | |
| 74 ShouldKeepOnWaiting(event)) { | |
| 75 return ui::POST_DISPATCH_PERFORM_DEFAULT; | |
| 76 } | |
| 77 | |
| 78 wait_ = false; | |
| 79 if (!quit_closure_.is_null()) | |
| 80 quit_closure_.Run(); | |
| 81 return ui::POST_DISPATCH_PERFORM_DEFAULT; | |
| 82 } | |
| 83 | |
| 84 } // namespace views | |
| OLD | NEW |