| Index: ui/views/test/x11_property_change_waiter.cc
|
| diff --git a/ui/views/test/x11_property_change_waiter.cc b/ui/views/test/x11_property_change_waiter.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c6208e1484ce803cb38d7c1c218f15fcc7d4855e
|
| --- /dev/null
|
| +++ b/ui/views/test/x11_property_change_waiter.cc
|
| @@ -0,0 +1,91 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ui/views/test/x11_property_change_waiter.h"
|
| +
|
| +#include <X11/Xlib.h>
|
| +
|
| +#include "base/run_loop.h"
|
| +#include "ui/events/platform/platform_event_source.h"
|
| +#include "ui/events/platform/scoped_event_dispatcher.h"
|
| +#include "ui/gfx/x/x11_atom_cache.h"
|
| +
|
| +namespace views {
|
| +
|
| +X11PropertyChangeWaiter::X11PropertyChangeWaiter(XID window,
|
| + const char* property)
|
| + : x_window_(window),
|
| + property_(property),
|
| + wait_(true),
|
| + old_event_mask_(0) {
|
| + Display* display = gfx::GetXDisplay();
|
| +
|
| + // Ensure that we are listening to PropertyNotify events for |window|. This
|
| + // is not the case for windows which were not created by
|
| + // DesktopWindowTreeHostX11.
|
| + XWindowAttributes attributes;
|
| + XGetWindowAttributes(display, x_window_, &attributes);
|
| + old_event_mask_ = attributes.your_event_mask;
|
| + XSelectInput(display, x_window_, old_event_mask_ | PropertyChangeMask);
|
| +
|
| + const char* kAtomsToCache[] = { property, NULL };
|
| + atom_cache_.reset(new ui::X11AtomCache(display, kAtomsToCache));
|
| +
|
| + // Override the dispatcher so that we get events before
|
| + // DesktopWindowTreeHostX11 does. We must do this because
|
| + // DesktopWindowTreeHostX11 stops propagation.
|
| + dispatcher_ = ui::PlatformEventSource::GetInstance()->
|
| + OverrideDispatcher(this).Pass();
|
| +}
|
| +
|
| +X11PropertyChangeWaiter::~X11PropertyChangeWaiter() {
|
| + XSelectInput(gfx::GetXDisplay(), x_window_, old_event_mask_);
|
| +}
|
| +
|
| +void X11PropertyChangeWaiter::Wait() {
|
| + if (!wait_)
|
| + return;
|
| +
|
| + // PropertyChangeWaiter (or one of its subclasses) may be constructed after
|
| + // the property change has occurred.
|
| + if (!ShouldKeepOnWaiting(NULL)) {
|
| + wait_ = false;
|
| + return;
|
| + }
|
| +
|
| + base::RunLoop run_loop;
|
| + quit_closure_ = run_loop.QuitClosure();
|
| + run_loop.Run();
|
| +
|
| + dispatcher_.reset();
|
| +}
|
| +
|
| +bool X11PropertyChangeWaiter::ShouldKeepOnWaiting(
|
| + const ui::PlatformEvent& event) {
|
| + // Stop waiting once we get a property change.
|
| + return event != NULL;
|
| +}
|
| +
|
| +bool X11PropertyChangeWaiter::CanDispatchEvent(const ui::PlatformEvent& event) {
|
| + NOTREACHED();
|
| + return true;
|
| +}
|
| +
|
| +uint32_t X11PropertyChangeWaiter::DispatchEvent(
|
| + const ui::PlatformEvent& event) {
|
| + if (!wait_ ||
|
| + event->type != PropertyNotify ||
|
| + event->xproperty.window != x_window_ ||
|
| + event->xproperty.atom != atom_cache_->GetAtom(property_) ||
|
| + ShouldKeepOnWaiting(event)) {
|
| + return ui::POST_DISPATCH_PERFORM_DEFAULT;
|
| + }
|
| +
|
| + wait_ = false;
|
| + if (!quit_closure_.is_null())
|
| + quit_closure_.Run();
|
| + return ui::POST_DISPATCH_PERFORM_DEFAULT;
|
| +}
|
| +
|
| +} // namespace views
|
|
|