Commit c3f3d736 authored by oshima@chromium.org's avatar oshima@chromium.org

Multiple dispatchers for root windows

This allows ash to inject Dispatcher for root window without
a dispatcher being dependent of aura.

BUG=none
TEST=none

Review URL: https://chromiumcodereview.appspot.com/10407081

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138451 0039d316-1c4b-4281-b951-d872f2087c98
parent c9301e3d
......@@ -37,7 +37,9 @@ void PreprocessXEvent(XEvent* xevent) {
namespace aura {
DispatcherLinux::DispatcherLinux() {
DispatcherLinux::DispatcherLinux()
: x_root_window_(
DefaultRootWindow(base::MessagePumpX::GetDefaultXDisplay())) {
base::MessagePumpX::SetDefaultDispatcher(this);
MessageLoopForUI::current()->AddObserver(this);
}
......@@ -47,14 +49,31 @@ DispatcherLinux::~DispatcherLinux() {
base::MessagePumpX::SetDefaultDispatcher(NULL);
}
void DispatcherLinux::WindowDispatcherCreated(
::Window window,
void DispatcherLinux::AddDispatcherForWindow(
MessageLoop::Dispatcher* dispatcher,
::Window x_window) {
dispatchers_.insert(std::make_pair(x_window, dispatcher));
}
void DispatcherLinux::RemoveDispatcherForWindow(::Window x_window) {
dispatchers_.erase(x_window);
}
void DispatcherLinux::AddDispatcherForRootWindow(
MessageLoop::Dispatcher* dispatcher) {
dispatchers_.insert(std::make_pair(window, dispatcher));
DCHECK(std::find(root_window_dispatchers_.begin(),
root_window_dispatchers_.end(),
dispatcher) ==
root_window_dispatchers_.end());
root_window_dispatchers_.push_back(dispatcher);
}
void DispatcherLinux::WindowDispatcherDestroying(::Window window) {
dispatchers_.erase(window);
void DispatcherLinux::RemoveDispatcherForRootWindow(
MessageLoop::Dispatcher* dispatcher) {
root_window_dispatchers_.erase(
std::remove(root_window_dispatchers_.begin(),
root_window_dispatchers_.end(),
dispatcher));
}
bool DispatcherLinux::Dispatch(const base::NativeEvent& xev) {
......@@ -76,7 +95,14 @@ bool DispatcherLinux::Dispatch(const base::NativeEvent& xev) {
}
return true;
}
if (xev->xany.window == x_root_window_) {
for (Dispatchers::const_iterator it = root_window_dispatchers_.begin();
it != root_window_dispatchers_.end();
++it) {
(*it)->Dispatch(xev);
}
return true;
}
MessageLoop::Dispatcher* dispatcher = GetDispatcherForXEvent(xev);
return dispatcher ? dispatcher->Dispatch(xev) : true;
}
......@@ -92,12 +118,12 @@ void DispatcherLinux::DidProcessEvent(const base::NativeEvent& event) {
MessageLoop::Dispatcher* DispatcherLinux::GetDispatcherForXEvent(
XEvent* xev) const {
::Window window = xev->xany.window;
::Window x_window = xev->xany.window;
if (xev->type == GenericEvent) {
XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
window = xievent->event;
x_window = xievent->event;
}
DispatchersMap::const_iterator it = dispatchers_.find(window);
DispatchersMap::const_iterator it = dispatchers_.find(x_window);
return it != dispatchers_.end() ? it->second : NULL;
}
......
......@@ -7,6 +7,7 @@
#pragma once
#include <map>
#include <vector>
#include <X11/Xlib.h>
// Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class.
#undef RootWindow
......@@ -23,9 +24,15 @@ class DispatcherLinux : public MessageLoop::Dispatcher,
DispatcherLinux();
virtual ~DispatcherLinux();
void WindowDispatcherCreated(::Window window,
MessageLoop::Dispatcher* dispatcher);
void WindowDispatcherDestroying(::Window window);
// Adds/Removes |dispatcher| for the |x_window|.
void AddDispatcherForWindow(MessageLoop::Dispatcher* dispatcher,
::Window x_window);
void RemoveDispatcherForWindow(::Window x_window);
// Adds/Removes |dispatcher| to receive all events sent to the X
// root window.
void AddDispatcherForRootWindow(MessageLoop::Dispatcher* dispatcher);
void RemoveDispatcherForRootWindow(MessageLoop::Dispatcher* dispatcher);
// Overridden from MessageLoop::Dispatcher:
virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE;
......@@ -37,10 +44,14 @@ class DispatcherLinux : public MessageLoop::Dispatcher,
private:
typedef std::map< ::Window, MessageLoop::Dispatcher* > DispatchersMap;
typedef std::vector<MessageLoop::Dispatcher*> Dispatchers;
MessageLoop::Dispatcher* GetDispatcherForXEvent(XEvent* xev) const;
DispatchersMap dispatchers_;
Dispatchers root_window_dispatchers_;
::Window x_root_window_;
DISALLOW_COPY_AND_ASSIGN(DispatcherLinux);
};
......
......@@ -52,15 +52,13 @@ MonitorChangeObserverX11::MonitorChangeObserverX11()
XRRSelectInput(xdisplay_, x_root_window_, RRScreenChangeNotifyMask);
int error_base_ignored;
XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored);
static_cast<DispatcherLinux*>(
Env::GetInstance()->GetDispatcher())->
WindowDispatcherCreated(x_root_window_, this);
static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())->
AddDispatcherForRootWindow(this);
}
MonitorChangeObserverX11::~MonitorChangeObserverX11() {
static_cast<DispatcherLinux*>(
Env::GetInstance()->GetDispatcher())->
WindowDispatcherDestroying(x_root_window_);
static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())->
RemoveDispatcherForRootWindow(this);
}
bool MonitorChangeObserverX11::Dispatch(const base::NativeEvent& event) {
......
......@@ -407,7 +407,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds)
CWBackPixmap,
&swa);
static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())->
WindowDispatcherCreated(xwindow_, this);
AddDispatcherForWindow(this, xwindow_);
prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this));
......@@ -470,7 +470,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds)
RootWindowHostLinux::~RootWindowHostLinux() {
static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())->
WindowDispatcherDestroying(xwindow_);
RemoveDispatcherForWindow(xwindow_);
UnConfineCursor();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment