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) { ...@@ -37,7 +37,9 @@ void PreprocessXEvent(XEvent* xevent) {
namespace aura { namespace aura {
DispatcherLinux::DispatcherLinux() { DispatcherLinux::DispatcherLinux()
: x_root_window_(
DefaultRootWindow(base::MessagePumpX::GetDefaultXDisplay())) {
base::MessagePumpX::SetDefaultDispatcher(this); base::MessagePumpX::SetDefaultDispatcher(this);
MessageLoopForUI::current()->AddObserver(this); MessageLoopForUI::current()->AddObserver(this);
} }
...@@ -47,14 +49,31 @@ DispatcherLinux::~DispatcherLinux() { ...@@ -47,14 +49,31 @@ DispatcherLinux::~DispatcherLinux() {
base::MessagePumpX::SetDefaultDispatcher(NULL); base::MessagePumpX::SetDefaultDispatcher(NULL);
} }
void DispatcherLinux::WindowDispatcherCreated( void DispatcherLinux::AddDispatcherForWindow(
::Window window, 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) { 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) { void DispatcherLinux::RemoveDispatcherForRootWindow(
dispatchers_.erase(window); 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) { bool DispatcherLinux::Dispatch(const base::NativeEvent& xev) {
...@@ -76,7 +95,14 @@ bool DispatcherLinux::Dispatch(const base::NativeEvent& xev) { ...@@ -76,7 +95,14 @@ bool DispatcherLinux::Dispatch(const base::NativeEvent& xev) {
} }
return true; 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); MessageLoop::Dispatcher* dispatcher = GetDispatcherForXEvent(xev);
return dispatcher ? dispatcher->Dispatch(xev) : true; return dispatcher ? dispatcher->Dispatch(xev) : true;
} }
...@@ -92,12 +118,12 @@ void DispatcherLinux::DidProcessEvent(const base::NativeEvent& event) { ...@@ -92,12 +118,12 @@ void DispatcherLinux::DidProcessEvent(const base::NativeEvent& event) {
MessageLoop::Dispatcher* DispatcherLinux::GetDispatcherForXEvent( MessageLoop::Dispatcher* DispatcherLinux::GetDispatcherForXEvent(
XEvent* xev) const { XEvent* xev) const {
::Window window = xev->xany.window; ::Window x_window = xev->xany.window;
if (xev->type == GenericEvent) { if (xev->type == GenericEvent) {
XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); 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; return it != dispatchers_.end() ? it->second : NULL;
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#pragma once #pragma once
#include <map> #include <map>
#include <vector>
#include <X11/Xlib.h> #include <X11/Xlib.h>
// Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class.
#undef RootWindow #undef RootWindow
...@@ -23,9 +24,15 @@ class DispatcherLinux : public MessageLoop::Dispatcher, ...@@ -23,9 +24,15 @@ class DispatcherLinux : public MessageLoop::Dispatcher,
DispatcherLinux(); DispatcherLinux();
virtual ~DispatcherLinux(); virtual ~DispatcherLinux();
void WindowDispatcherCreated(::Window window, // Adds/Removes |dispatcher| for the |x_window|.
MessageLoop::Dispatcher* dispatcher); void AddDispatcherForWindow(MessageLoop::Dispatcher* dispatcher,
void WindowDispatcherDestroying(::Window window); ::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: // Overridden from MessageLoop::Dispatcher:
virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE; virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE;
...@@ -37,10 +44,14 @@ class DispatcherLinux : public MessageLoop::Dispatcher, ...@@ -37,10 +44,14 @@ class DispatcherLinux : public MessageLoop::Dispatcher,
private: private:
typedef std::map< ::Window, MessageLoop::Dispatcher* > DispatchersMap; typedef std::map< ::Window, MessageLoop::Dispatcher* > DispatchersMap;
typedef std::vector<MessageLoop::Dispatcher*> Dispatchers;
MessageLoop::Dispatcher* GetDispatcherForXEvent(XEvent* xev) const; MessageLoop::Dispatcher* GetDispatcherForXEvent(XEvent* xev) const;
DispatchersMap dispatchers_; DispatchersMap dispatchers_;
Dispatchers root_window_dispatchers_;
::Window x_root_window_;
DISALLOW_COPY_AND_ASSIGN(DispatcherLinux); DISALLOW_COPY_AND_ASSIGN(DispatcherLinux);
}; };
......
...@@ -52,15 +52,13 @@ MonitorChangeObserverX11::MonitorChangeObserverX11() ...@@ -52,15 +52,13 @@ MonitorChangeObserverX11::MonitorChangeObserverX11()
XRRSelectInput(xdisplay_, x_root_window_, RRScreenChangeNotifyMask); XRRSelectInput(xdisplay_, x_root_window_, RRScreenChangeNotifyMask);
int error_base_ignored; int error_base_ignored;
XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored); XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored);
static_cast<DispatcherLinux*>( static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())->
Env::GetInstance()->GetDispatcher())-> AddDispatcherForRootWindow(this);
WindowDispatcherCreated(x_root_window_, this);
} }
MonitorChangeObserverX11::~MonitorChangeObserverX11() { MonitorChangeObserverX11::~MonitorChangeObserverX11() {
static_cast<DispatcherLinux*>( static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())->
Env::GetInstance()->GetDispatcher())-> RemoveDispatcherForRootWindow(this);
WindowDispatcherDestroying(x_root_window_);
} }
bool MonitorChangeObserverX11::Dispatch(const base::NativeEvent& event) { bool MonitorChangeObserverX11::Dispatch(const base::NativeEvent& event) {
......
...@@ -407,7 +407,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) ...@@ -407,7 +407,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds)
CWBackPixmap, CWBackPixmap,
&swa); &swa);
static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())-> static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())->
WindowDispatcherCreated(xwindow_, this); AddDispatcherForWindow(this, xwindow_);
prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this)); prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this));
...@@ -470,7 +470,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) ...@@ -470,7 +470,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds)
RootWindowHostLinux::~RootWindowHostLinux() { RootWindowHostLinux::~RootWindowHostLinux() {
static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())-> static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())->
WindowDispatcherDestroying(xwindow_); RemoveDispatcherForWindow(xwindow_);
UnConfineCursor(); 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