| Index: base/message_pump_aurax11.cc
|
| diff --git a/base/message_pump_aurax11.cc b/base/message_pump_aurax11.cc
|
| index 7f47fa675fe6e655c403f6415704aa0d7ccf67a4..2c53b59d2b4e486375321bb58c2b57febab63557 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
|
|
|