OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" | 5 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" |
6 | 6 |
7 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
8 | 8 |
9 #include "base/event_types.h" | 9 #include "base/event_types.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/message_loop/message_pump_dispatcher.h" | 12 #include "base/message_loop/message_pump_dispatcher.h" |
13 #include "ui/aura/window.h" | 13 #include "ui/aura/window.h" |
14 #include "ui/aura/window_tree_host.h" | 14 #include "ui/aura/window_tree_host.h" |
15 #include "ui/base/clipboard/clipboard.h" | 15 #include "ui/base/clipboard/clipboard.h" |
16 #include "ui/base/dragdrop/drag_drop_types.h" | 16 #include "ui/base/dragdrop/drag_drop_types.h" |
17 #include "ui/base/dragdrop/drop_target_event.h" | 17 #include "ui/base/dragdrop/drop_target_event.h" |
18 #include "ui/base/dragdrop/os_exchange_data.h" | 18 #include "ui/base/dragdrop/os_exchange_data.h" |
19 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" | 19 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" |
20 #include "ui/base/x/selection_utils.h" | 20 #include "ui/base/x/selection_utils.h" |
21 #include "ui/base/x/x11_util.h" | 21 #include "ui/base/x/x11_util.h" |
22 #include "ui/events/event.h" | 22 #include "ui/events/event.h" |
| 23 #include "ui/events/platform/platform_event_source.h" |
23 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" | 24 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" |
24 #include "ui/wm/public/drag_drop_client.h" | 25 #include "ui/wm/public/drag_drop_client.h" |
25 #include "ui/wm/public/drag_drop_delegate.h" | 26 #include "ui/wm/public/drag_drop_delegate.h" |
26 | 27 |
27 using aura::client::DragDropDelegate; | 28 using aura::client::DragDropDelegate; |
28 using ui::OSExchangeData; | 29 using ui::OSExchangeData; |
29 | 30 |
30 namespace { | 31 namespace { |
31 | 32 |
32 const int kMinXdndVersion = 5; | 33 const int kMinXdndVersion = 5; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 } | 153 } |
153 } | 154 } |
154 | 155 |
155 } // namespace | 156 } // namespace |
156 | 157 |
157 namespace views { | 158 namespace views { |
158 | 159 |
159 DesktopDragDropClientAuraX11* | 160 DesktopDragDropClientAuraX11* |
160 DesktopDragDropClientAuraX11::g_current_drag_drop_client = NULL; | 161 DesktopDragDropClientAuraX11::g_current_drag_drop_client = NULL; |
161 | 162 |
162 class DesktopDragDropClientAuraX11::X11DragContext : | 163 class DesktopDragDropClientAuraX11::X11DragContext |
163 public base::MessagePumpDispatcher { | 164 : public ui::PlatformEventDispatcher { |
164 public: | 165 public: |
165 X11DragContext(ui::X11AtomCache* atom_cache, | 166 X11DragContext(ui::X11AtomCache* atom_cache, |
166 ::Window local_window, | 167 ::Window local_window, |
167 const XClientMessageEvent& event); | 168 const XClientMessageEvent& event); |
168 virtual ~X11DragContext(); | 169 virtual ~X11DragContext(); |
169 | 170 |
170 // When we receive an XdndPosition message, we need to have all the data | 171 // When we receive an XdndPosition message, we need to have all the data |
171 // copied from the other window before we process the XdndPosition | 172 // copied from the other window before we process the XdndPosition |
172 // message. If we have that data already, dispatch immediately. Otherwise, | 173 // message. If we have that data already, dispatch immediately. Otherwise, |
173 // delay dispatching until we do. | 174 // delay dispatching until we do. |
(...skipping 19 matching lines...) Expand all Loading... |
193 | 194 |
194 // Creates a ui::DragDropTypes::DragOperation representation of the current | 195 // Creates a ui::DragDropTypes::DragOperation representation of the current |
195 // action list. | 196 // action list. |
196 int GetDragOperation() const; | 197 int GetDragOperation() const; |
197 | 198 |
198 private: | 199 private: |
199 // Masks the X11 atom |xdnd_operation|'s views representation onto | 200 // Masks the X11 atom |xdnd_operation|'s views representation onto |
200 // |drag_operation|. | 201 // |drag_operation|. |
201 void MaskOpeartion(::Atom xdnd_operation, int* drag_operation) const; | 202 void MaskOpeartion(::Atom xdnd_operation, int* drag_operation) const; |
202 | 203 |
203 // Overridden from MessagePumpDispatcher: | 204 // ui::PlatformEventDispatcher: |
204 virtual uint32_t Dispatch(const base::NativeEvent& event) OVERRIDE; | 205 virtual bool CanDispatchEvent(const ui::PlatformEvent& event) OVERRIDE; |
| 206 virtual uint32_t DispatchEvent(const ui::PlatformEvent& event) OVERRIDE; |
205 | 207 |
206 // The atom cache owned by our parent. | 208 // The atom cache owned by our parent. |
207 ui::X11AtomCache* atom_cache_; | 209 ui::X11AtomCache* atom_cache_; |
208 | 210 |
209 // The XID of our chrome local aura window handling our events. | 211 // The XID of our chrome local aura window handling our events. |
210 ::Window local_window_; | 212 ::Window local_window_; |
211 | 213 |
212 // The XID of the window that's initiated the drag. | 214 // The XID of the window that's initiated the drag. |
213 unsigned long source_window_; | 215 unsigned long source_window_; |
214 | 216 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 unfetched_targets_.push_back(event.data.l[2+i]); | 266 unfetched_targets_.push_back(event.data.l[2+i]); |
265 } | 267 } |
266 } | 268 } |
267 } | 269 } |
268 | 270 |
269 DesktopDragDropClientAuraX11* client = | 271 DesktopDragDropClientAuraX11* client = |
270 DesktopDragDropClientAuraX11::GetForWindow(source_window_); | 272 DesktopDragDropClientAuraX11::GetForWindow(source_window_); |
271 if (!client) { | 273 if (!client) { |
272 // The window doesn't have a DesktopDragDropClientAuraX11, that means it's | 274 // The window doesn't have a DesktopDragDropClientAuraX11, that means it's |
273 // created by some other process. Listen for messages on it. | 275 // created by some other process. Listen for messages on it. |
274 base::MessagePumpX11::Current()->AddDispatcherForWindow( | 276 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); |
275 this, source_window_); | |
276 XSelectInput(gfx::GetXDisplay(), source_window_, PropertyChangeMask); | 277 XSelectInput(gfx::GetXDisplay(), source_window_, PropertyChangeMask); |
277 | 278 |
278 // We must perform a full sync here because we could be racing | 279 // We must perform a full sync here because we could be racing |
279 // |source_window_|. | 280 // |source_window_|. |
280 XSync(gfx::GetXDisplay(), False); | 281 XSync(gfx::GetXDisplay(), False); |
281 } else { | 282 } else { |
282 // This drag originates from an aura window within our process. This means | 283 // This drag originates from an aura window within our process. This means |
283 // that we can shortcut the X11 server and ask the owning SelectionOwner | 284 // that we can shortcut the X11 server and ask the owning SelectionOwner |
284 // for the data it's offering. | 285 // for the data it's offering. |
285 fetched_targets_ = client->GetFormatMap(); | 286 fetched_targets_ = client->GetFormatMap(); |
286 unfetched_targets_.clear(); | 287 unfetched_targets_.clear(); |
287 } | 288 } |
288 | 289 |
289 ReadActions(); | 290 ReadActions(); |
290 } | 291 } |
291 | 292 |
292 DesktopDragDropClientAuraX11::X11DragContext::~X11DragContext() { | 293 DesktopDragDropClientAuraX11::X11DragContext::~X11DragContext() { |
293 DesktopDragDropClientAuraX11* client = | 294 DesktopDragDropClientAuraX11* client = |
294 DesktopDragDropClientAuraX11::GetForWindow(source_window_); | 295 DesktopDragDropClientAuraX11::GetForWindow(source_window_); |
295 if (!client) { | 296 if (!client) { |
296 // Unsubscribe from message events. | 297 // Unsubscribe from message events. |
297 base::MessagePumpX11::Current()->RemoveDispatcherForWindow( | 298 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); |
298 source_window_); | |
299 } | 299 } |
300 } | 300 } |
301 | 301 |
302 void DesktopDragDropClientAuraX11::X11DragContext::OnStartXdndPositionMessage( | 302 void DesktopDragDropClientAuraX11::X11DragContext::OnStartXdndPositionMessage( |
303 DesktopDragDropClientAuraX11* client, | 303 DesktopDragDropClientAuraX11* client, |
304 ::Atom suggested_action, | 304 ::Atom suggested_action, |
305 ::Window source_window, | 305 ::Window source_window, |
306 const gfx::Point& screen_point) { | 306 const gfx::Point& screen_point) { |
307 DCHECK_EQ(source_window_, source_window); | 307 DCHECK_EQ(source_window_, source_window); |
308 suggested_action_ = suggested_action; | 308 suggested_action_ = suggested_action; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 ::Atom xdnd_operation, | 391 ::Atom xdnd_operation, |
392 int* drag_operation) const { | 392 int* drag_operation) const { |
393 if (xdnd_operation == atom_cache_->GetAtom(kXdndActionCopy)) | 393 if (xdnd_operation == atom_cache_->GetAtom(kXdndActionCopy)) |
394 *drag_operation |= ui::DragDropTypes::DRAG_COPY; | 394 *drag_operation |= ui::DragDropTypes::DRAG_COPY; |
395 else if (xdnd_operation == atom_cache_->GetAtom(kXdndActionMove)) | 395 else if (xdnd_operation == atom_cache_->GetAtom(kXdndActionMove)) |
396 *drag_operation |= ui::DragDropTypes::DRAG_MOVE; | 396 *drag_operation |= ui::DragDropTypes::DRAG_MOVE; |
397 else if (xdnd_operation == atom_cache_->GetAtom(kXdndActionLink)) | 397 else if (xdnd_operation == atom_cache_->GetAtom(kXdndActionLink)) |
398 *drag_operation |= ui::DragDropTypes::DRAG_LINK; | 398 *drag_operation |= ui::DragDropTypes::DRAG_LINK; |
399 } | 399 } |
400 | 400 |
401 uint32_t DesktopDragDropClientAuraX11::X11DragContext::Dispatch( | 401 bool DesktopDragDropClientAuraX11::X11DragContext::CanDispatchEvent( |
402 const base::NativeEvent& event) { | 402 const ui::PlatformEvent& event) { |
| 403 return event->xany.window == source_window_; |
| 404 } |
| 405 |
| 406 uint32_t DesktopDragDropClientAuraX11::X11DragContext::DispatchEvent( |
| 407 const ui::PlatformEvent& event) { |
403 if (event->type == PropertyNotify && | 408 if (event->type == PropertyNotify && |
404 event->xproperty.atom == atom_cache_->GetAtom("XdndActionList")) { | 409 event->xproperty.atom == atom_cache_->GetAtom("XdndActionList")) { |
405 ReadActions(); | 410 ReadActions(); |
| 411 return ui::POST_DISPATCH_STOP_PROPAGATION; |
406 } | 412 } |
407 return POST_DISPATCH_NONE; | 413 return ui::POST_DISPATCH_NONE; |
408 } | 414 } |
409 | 415 |
410 /////////////////////////////////////////////////////////////////////////////// | 416 /////////////////////////////////////////////////////////////////////////////// |
411 | 417 |
412 DesktopDragDropClientAuraX11::DesktopDragDropClientAuraX11( | 418 DesktopDragDropClientAuraX11::DesktopDragDropClientAuraX11( |
413 aura::Window* root_window, | 419 aura::Window* root_window, |
414 views::DesktopNativeCursorManager* cursor_manager, | 420 views::DesktopNativeCursorManager* cursor_manager, |
415 Display* xdisplay, | 421 Display* xdisplay, |
416 ::Window xwindow) | 422 ::Window xwindow) |
417 : move_loop_(this), | 423 : move_loop_(this), |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 // GdkEvent about the failed drag. (And sending this message doesn't appear | 1031 // GdkEvent about the failed drag. (And sending this message doesn't appear |
1026 // to go through normal xlib machinery, but instead passes through the low | 1032 // to go through normal xlib machinery, but instead passes through the low |
1027 // level xProto (the x11 wire format) that I don't understand. | 1033 // level xProto (the x11 wire format) that I don't understand. |
1028 // | 1034 // |
1029 // I'm unsure if I have to jump through those hoops, or if XSendEvent is | 1035 // I'm unsure if I have to jump through those hoops, or if XSendEvent is |
1030 // sufficient. | 1036 // sufficient. |
1031 XSendEvent(xdisplay_, xid, False, 0, xev); | 1037 XSendEvent(xdisplay_, xid, False, 0, xev); |
1032 } | 1038 } |
1033 | 1039 |
1034 } // namespace views | 1040 } // namespace views |
OLD | NEW |