Index: ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc |
diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc b/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc |
index 0e1327357753795f40f74c544c30542ca65ecb6c..90158a291fe1569fb3d7e3391bfbdf133ac0c4bb 100644 |
--- a/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc |
+++ b/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc |
@@ -16,6 +16,7 @@ |
#include "ui/aura/focus_manager.h" |
#include "ui/aura/root_window.h" |
#include "ui/aura/window_property.h" |
+#include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" |
#include "ui/base/events/event_utils.h" |
#include "ui/base/touch/touch_factory_x11.h" |
#include "ui/base/x/x11_util.h" |
@@ -31,6 +32,7 @@ |
#include "ui/views/widget/desktop_aura/desktop_capture_client.h" |
#include "ui/views/widget/desktop_aura/desktop_cursor_loader_updater_aurax11.h" |
#include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h" |
+#include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" |
#include "ui/views/widget/desktop_aura/desktop_focus_rules.h" |
#include "ui/views/widget/desktop_aura/desktop_layout_manager.h" |
#include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" |
@@ -63,6 +65,7 @@ const int k_NET_WM_STATE_REMOVE = 0; |
const char* kAtomsToCache[] = { |
"WM_DELETE_WINDOW", |
+ "WM_PROTOCOLS", |
"WM_S0", |
"_NET_WM_PID", |
"_NET_WM_PING", |
@@ -71,6 +74,22 @@ const char* kAtomsToCache[] = { |
"_NET_WM_STATE_HIDDEN", |
"_NET_WM_STATE_MAXIMIZED_HORZ", |
"_NET_WM_STATE_MAXIMIZED_VERT", |
+ "XdndActionAsk", |
+ "XdndActionCopy" |
+ "XdndActionLink", |
+ "XdndActionList", |
+ "XdndActionMove", |
+ "XdndActionPrivate", |
+ "XdndAware", |
+ "XdndDrop", |
+ "XdndEnter", |
+ "XdndFinished", |
+ "XdndLeave", |
+ "XdndPosition", |
+ "XdndProxy", // Proxy windows? |
+ "XdndSelection", |
+ "XdndStatus", |
+ "XdndTypeList", |
NULL |
}; |
@@ -92,7 +111,8 @@ DesktopRootWindowHostX11::DesktopRootWindowHostX11( |
focus_when_shown_(false), |
current_cursor_(ui::kCursorNull), |
native_widget_delegate_(native_widget_delegate), |
- desktop_native_widget_aura_(desktop_native_widget_aura) { |
+ desktop_native_widget_aura_(desktop_native_widget_aura), |
+ drop_handler_(NULL) { |
} |
DesktopRootWindowHostX11::~DesktopRootWindowHostX11() { |
@@ -262,6 +282,10 @@ aura::RootWindow* DesktopRootWindowHostX11::InitRootWindow( |
desktop_native_widget_aura_->InstallInputMethodEventFilter(root_window_); |
+ drag_drop_client_.reset(new DesktopDragDropClientAuraX11( |
+ this, root_window_, xdisplay_, xwindow_)); |
+ aura::client::SetDragDropClient(root_window_, drag_drop_client_.get()); |
+ |
// TODO(erg): Unify this code once the other consumer goes away. |
x11_window_event_filter_.reset( |
new X11WindowEventFilter(root_window_, activation_client_.get())); |
@@ -885,6 +909,20 @@ void DesktopRootWindowHostX11::PrepareForShutdown() { |
} |
//////////////////////////////////////////////////////////////////////////////// |
+// DesktopRootWindowHostX11, ui::DesktopSelectionProviderAuraX11 implementation: |
+ |
+void DesktopRootWindowHostX11::SetDropHandler( |
+ ui::OSExchangeDataProviderAuraX11* handler) { |
+ if (handler) { |
+ DCHECK(!drop_handler_); |
+ drop_handler_ = handler; |
+ } else { |
+ DCHECK(drop_handler_); |
+ drop_handler_ = NULL; |
+ } |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
// DesktopRootWindowHostX11, MessageLoop::Dispatcher implementation: |
bool DesktopRootWindowHostX11::Dispatch(const base::NativeEvent& event) { |
@@ -1048,19 +1086,34 @@ bool DesktopRootWindowHostX11::Dispatch(const base::NativeEvent& event) { |
break; |
} |
case ClientMessage: { |
- Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]); |
- if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { |
- // We have received a close message from the window manager. |
- root_window_->OnRootWindowHostCloseRequested(); |
- } else if (message_type == atom_cache_.GetAtom("_NET_WM_PING")) { |
- XEvent reply_event = *xev; |
- reply_event.xclient.window = x_root_window_; |
- |
- XSendEvent(xdisplay_, |
- reply_event.xclient.window, |
- False, |
- SubstructureRedirectMask | SubstructureNotifyMask, |
- &reply_event); |
+ Atom message_type = xev->xclient.message_type; |
+ if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { |
+ Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); |
+ if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { |
+ // We have received a close message from the window manager. |
+ root_window_->OnRootWindowHostCloseRequested(); |
+ } else if (protocol == atom_cache_.GetAtom("_NET_WM_PING")) { |
+ XEvent reply_event = *xev; |
+ reply_event.xclient.window = x_root_window_; |
+ |
+ XSendEvent(xdisplay_, |
+ reply_event.xclient.window, |
+ False, |
+ SubstructureRedirectMask | SubstructureNotifyMask, |
+ &reply_event); |
+ } |
+ } else if (message_type == atom_cache_.GetAtom("XdndEnter")) { |
+ drag_drop_client_->OnXdndEnter(xev->xclient); |
+ } else if (message_type == atom_cache_.GetAtom("XdndLeave")) { |
+ drag_drop_client_->OnXdndLeave(xev->xclient); |
+ } else if (message_type == atom_cache_.GetAtom("XdndPosition")) { |
+ drag_drop_client_->OnXdndPosition(xev->xclient); |
+ } else if (message_type == atom_cache_.GetAtom("XdndStatus")) { |
+ drag_drop_client_->OnXdndStatus(xev->xclient); |
+ } else if (message_type == atom_cache_.GetAtom("XdndFinished")) { |
+ drag_drop_client_->OnXdndFinished(xev->xclient); |
+ } else if (message_type == atom_cache_.GetAtom("XdndDrop")) { |
+ drag_drop_client_->OnXdndDrop(xev->xclient); |
} |
break; |
} |
@@ -1131,6 +1184,12 @@ bool DesktopRootWindowHostX11::Dispatch(const base::NativeEvent& event) { |
} |
widget->GetRootView()->Layout(); |
} |
+ break; |
+ } |
+ case SelectionNotify: { |
+ if (drop_handler_) |
+ drop_handler_->OnSelectionNotify(xev->xselection); |
+ break; |
} |
} |
return true; |