diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-30 16:57:21 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-30 16:57:21 +0000 |
commit | 4168ad750ebe1bf59b29fd82dc9425c016a404e6 (patch) | |
tree | b2fafca54811b5206c182202cb4eb8148e147566 /base/message_pump_aurax11.cc | |
parent | 9002fe205e37e1cd08480e83987e36482945958a (diff) | |
download | chromium_src-4168ad750ebe1bf59b29fd82dc9425c016a404e6.zip chromium_src-4168ad750ebe1bf59b29fd82dc9425c016a404e6.tar.gz chromium_src-4168ad750ebe1bf59b29fd82dc9425c016a404e6.tar.bz2 |
Merge aura::DispatcherLinux into base::MessagePumpAuraX11.
The majority of incoming XEvents are related to specific XWindows and need to
be sent to a specific MessagePumpDispatcher. MessagePumpAuraX11 would pass the
XEvent to aura::DispatcherLinux, which would pass it to the next
dispatcher. Because of the chromeos unit tests, which spin up a new XDisplay on
each test, these two objects need to have equivalent lifetimes. Due to the
incoming clipboard support (which this patch was split off from),
DispatcherLinux can't live in aura:: anymore. The solution is to merge the two
objects that have to have equivalent lifetimes together.
The one ui:: specific check was split off into an MessagePumpObserver. This also got rid of those hacks where we would static downcast to DispatcherLinux
from MessagePumpDispatcher.
BUG=130805
Review URL: https://chromiumcodereview.appspot.com/10895020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154174 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/message_pump_aurax11.cc')
-rw-r--r-- | base/message_pump_aurax11.cc | 93 |
1 files changed, 77 insertions, 16 deletions
diff --git a/base/message_pump_aurax11.cc b/base/message_pump_aurax11.cc index 7f47fa6..2c53b59 100644 --- a/base/message_pump_aurax11.cc +++ b/base/message_pump_aurax11.cc @@ -39,13 +39,16 @@ GSourceFuncs XSourceFuncs = { NULL }; -// The message-pump opens a connection to the display and owns it. +// The connection is essentially a global that's accessed through a static +// method and destroyed whenever ~MessagePumpAuraX11() is called. We do this +// for historical reasons so user code can call +// MessagePumpForUI::GetDefaultXDisplay() where MessagePumpForUI is a typedef +// to whatever type in the current build. +// +// TODO(erg): This can be changed to something more sane like +// MessagePumpAuraX11::Current()->display() once MessagePumpGtk goes away. Display* g_xdisplay = NULL; -// The default dispatcher to process native events when no dispatcher -// is specified. -base::MessagePumpDispatcher* g_default_dispatcher = NULL; - bool InitializeXInput2Internal() { Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); if (!display) @@ -118,6 +121,10 @@ MessagePumpAuraX11::MessagePumpAuraX11() : MessagePumpGlib(), InitializeXInput2(); InitializeXkb(); InitXSource(); + + // Can't put this in the initializer list because g_xdisplay may not exist + // until after InitXSource(). + x_root_window_ = DefaultRootWindow(g_xdisplay); } // static @@ -133,23 +140,43 @@ bool MessagePumpAuraX11::HasXInput2() { } // static -void MessagePumpAuraX11::SetDefaultDispatcher( - MessagePumpDispatcher* dispatcher) { - DCHECK(!g_default_dispatcher || !dispatcher); - g_default_dispatcher = dispatcher; -} - -// static MessagePumpAuraX11* MessagePumpAuraX11::Current() { MessageLoopForUI* loop = MessageLoopForUI::current(); return static_cast<MessagePumpAuraX11*>(loop->pump_ui()); } +void MessagePumpAuraX11::AddDispatcherForWindow( + MessagePumpDispatcher* dispatcher, + unsigned long xid) { + dispatchers_.insert(std::make_pair(xid, dispatcher)); +} + +void MessagePumpAuraX11::RemoveDispatcherForWindow(unsigned long xid) { + dispatchers_.erase(xid); +} + +void MessagePumpAuraX11::AddDispatcherForRootWindow( + MessagePumpDispatcher* dispatcher) { + DCHECK(std::find(root_window_dispatchers_.begin(), + root_window_dispatchers_.end(), + dispatcher) == + root_window_dispatchers_.end()); + root_window_dispatchers_.push_back(dispatcher); +} + +void MessagePumpAuraX11::RemoveDispatcherForRootWindow( + MessagePumpDispatcher* dispatcher) { + root_window_dispatchers_.erase( + std::remove(root_window_dispatchers_.begin(), + root_window_dispatchers_.end(), + dispatcher)); +} + bool MessagePumpAuraX11::DispatchXEvents() { Display* display = GetDefaultXDisplay(); DCHECK(display); MessagePumpDispatcher* dispatcher = - GetDispatcher() ? GetDispatcher() : g_default_dispatcher; + GetDispatcher() ? GetDispatcher() : this; // In the general case, we want to handle all pending events before running // the tasks. This is what happens in the message_pump_glib case. @@ -162,19 +189,19 @@ bool MessagePumpAuraX11::DispatchXEvents() { return TRUE; } -void MessagePumpAuraX11::BlockUntilWindowMapped(unsigned long window) { +void MessagePumpAuraX11::BlockUntilWindowMapped(unsigned long xid) { XEvent event; Display* display = GetDefaultXDisplay(); DCHECK(display); MessagePumpDispatcher* dispatcher = - GetDispatcher() ? GetDispatcher() : g_default_dispatcher; + GetDispatcher() ? GetDispatcher() : this; do { // Block until there's a message of |event_mask| type on |w|. Then remove // it from the queue and stuff it in |event|. - XWindowEvent(display, window, StructureNotifyMask, &event); + XWindowEvent(display, xid, StructureNotifyMask, &event); ProcessXEvent(dispatcher, &event); } while (event.type != MapNotify); } @@ -244,4 +271,38 @@ void MessagePumpAuraX11::DidProcessXEvent(XEvent* xevent) { FOR_EACH_OBSERVER(MessagePumpObserver, observers(), DidProcessEvent(xevent)); } +MessagePumpDispatcher* MessagePumpAuraX11::GetDispatcherForXEvent( + const base::NativeEvent& xev) const { + ::Window x_window = xev->xany.window; + if (xev->type == GenericEvent) { + XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); + x_window = xievent->event; + } + DispatchersMap::const_iterator it = dispatchers_.find(x_window); + return it != dispatchers_.end() ? it->second : NULL; +} + +bool MessagePumpAuraX11::Dispatch(const base::NativeEvent& xev) { + // MappingNotify events (meaning that the keyboard or pointer buttons have + // been remapped) aren't associated with a window; send them to all + // dispatchers. + if (xev->type == MappingNotify) { + for (DispatchersMap::const_iterator it = dispatchers_.begin(); + it != dispatchers_.end(); ++it) { + it->second->Dispatch(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; + } + MessagePumpDispatcher* dispatcher = GetDispatcherForXEvent(xev); + return dispatcher ? dispatcher->Dispatch(xev) : true; +} + } // namespace base |