Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h

Issue 16271006: Drag on linux (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Document Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/views/views.gyp ('k') | ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_AURAX11_H_ 5 #ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_AURAX11_H_
6 #define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_AURAX11_H_ 6 #define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_AURAX11_H_
7 7
8 #include <X11/Xlib.h> 8 #include <X11/Xlib.h>
9 9
10 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. 10 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class.
11 #undef RootWindow 11 #undef RootWindow
12 12
13 #include <set>
14
13 #include "base/compiler_specific.h" 15 #include "base/compiler_specific.h"
14 #include "base/memory/ref_counted.h" 16 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/scoped_ptr.h"
16 #include "ui/aura/client/drag_drop_client.h" 18 #include "ui/aura/client/drag_drop_client.h"
17 #include "ui/aura/window_observer.h" 19 #include "ui/aura/window_observer.h"
18 #include "ui/base/x/x11_atom_cache.h" 20 #include "ui/base/x/x11_atom_cache.h"
19 #include "ui/gfx/point.h" 21 #include "ui/gfx/point.h"
20 #include "ui/views/views_export.h" 22 #include "ui/views/views_export.h"
23 #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h"
24 #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop_delegate.h"
21 25
22 namespace aura { 26 namespace aura {
23 class RootWindow; 27 class RootWindow;
24 namespace client { 28 namespace client {
25 class DragDropDelegate; 29 class DragDropDelegate;
26 } 30 }
27 } 31 }
28 32
29 namespace gfx { 33 namespace gfx {
30 class Point; 34 class Point;
31 } 35 }
32 36
33 namespace ui { 37 namespace ui {
34 class DragSource; 38 class DragSource;
35 class DropTargetEvent; 39 class DropTargetEvent;
36 class OSExchangeData; 40 class OSExchangeData;
41 class OSExchangeDataProviderAuraX11;
37 class RootWindow; 42 class RootWindow;
43 class SelectionFormatMap;
38 } 44 }
39 45
40 namespace views { 46 namespace views {
41 class DesktopRootWindowHostX11; 47 class DesktopRootWindowHostX11;
42 48
43 // Implements drag and drop on X11 for aura. On one side, this class takes raw 49 // Implements drag and drop on X11 for aura. On one side, this class takes raw
44 // X11 events forwarded from DesktopRootWindowHostLinux, while on the other, it 50 // X11 events forwarded from DesktopRootWindowHostLinux, while on the other, it
45 // handles the views drag events. 51 // handles the views drag events.
46 class VIEWS_EXPORT DesktopDragDropClientAuraX11 52 class VIEWS_EXPORT DesktopDragDropClientAuraX11
47 : public aura::client::DragDropClient, 53 : public aura::client::DragDropClient,
48 public aura::WindowObserver { 54 public aura::WindowObserver,
55 public X11WholeScreenMoveLoopDelegate {
49 public: 56 public:
50 DesktopDragDropClientAuraX11( 57 DesktopDragDropClientAuraX11(
51 views::DesktopRootWindowHostX11* root_window_host, 58 views::DesktopRootWindowHostX11* root_window_host,
52 aura::RootWindow* root_window, 59 aura::RootWindow* root_window,
53 Display* xdisplay, 60 Display* xdisplay,
54 ::Window xwindow); 61 ::Window xwindow);
55 virtual ~DesktopDragDropClientAuraX11(); 62 virtual ~DesktopDragDropClientAuraX11();
56 63
64 // We maintain a mapping of live DesktopDragDropClientAuraX11 objects to
65 // their ::Windows. We do this so that we're able to short circuit sending
66 // X11 messages to windows in our process.
67 static DesktopDragDropClientAuraX11* GetForWindow(::Window window);
68
57 // These methods handle the various X11 client messages from the platform. 69 // These methods handle the various X11 client messages from the platform.
58 void OnXdndEnter(const XClientMessageEvent& event); 70 void OnXdndEnter(const XClientMessageEvent& event);
59 void OnXdndLeave(const XClientMessageEvent& event); 71 void OnXdndLeave(const XClientMessageEvent& event);
60 void OnXdndPosition(const XClientMessageEvent& event); 72 void OnXdndPosition(const XClientMessageEvent& event);
61 void OnXdndStatus(const XClientMessageEvent& event); 73 void OnXdndStatus(const XClientMessageEvent& event);
62 void OnXdndFinished(const XClientMessageEvent& event); 74 void OnXdndFinished(const XClientMessageEvent& event);
63 void OnXdndDrop(const XClientMessageEvent& event); 75 void OnXdndDrop(const XClientMessageEvent& event);
64 76
77 // Called when XSelection data has been copied to our process.
78 void OnSelectionNotify(const XSelectionEvent& xselection);
79
65 // Overridden from aura::client::DragDropClient: 80 // Overridden from aura::client::DragDropClient:
66 virtual int StartDragAndDrop( 81 virtual int StartDragAndDrop(
67 const ui::OSExchangeData& data, 82 const ui::OSExchangeData& data,
68 aura::RootWindow* root_window, 83 aura::RootWindow* root_window,
69 aura::Window* source_window, 84 aura::Window* source_window,
70 const gfx::Point& root_location, 85 const gfx::Point& root_location,
71 int operation, 86 int operation,
72 ui::DragDropTypes::DragEventSource source) OVERRIDE; 87 ui::DragDropTypes::DragEventSource source) OVERRIDE;
73 virtual void DragUpdate(aura::Window* target, 88 virtual void DragUpdate(aura::Window* target,
74 const ui::LocatedEvent& event) OVERRIDE; 89 const ui::LocatedEvent& event) OVERRIDE;
75 virtual void Drop(aura::Window* target, 90 virtual void Drop(aura::Window* target,
76 const ui::LocatedEvent& event) OVERRIDE; 91 const ui::LocatedEvent& event) OVERRIDE;
77 virtual void DragCancel() OVERRIDE; 92 virtual void DragCancel() OVERRIDE;
78 virtual bool IsDragDropInProgress() OVERRIDE; 93 virtual bool IsDragDropInProgress() OVERRIDE;
79 94
80 // aura::WindowObserver implementation: 95 // Overridden from aura::WindowObserver:
81 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE; 96 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
82 97
98 // Overridden from X11WholeScreenMoveLoopDelegate:
99 virtual void OnMouseMovement(XMotionEvent* event) OVERRIDE;
100 virtual void OnMouseReleased() OVERRIDE;
101 virtual void OnMoveLoopEnded() OVERRIDE;
102
83 private: 103 private:
104 typedef std::map< ::Window, std::pair<gfx::Point, unsigned long> >
105 NextPositionMap;
106
84 // When we receive an position x11 message, we need to translate that into 107 // When we receive an position x11 message, we need to translate that into
85 // the underlying aura::Window representation, as moves internal to the X11 108 // the underlying aura::Window representation, as moves internal to the X11
86 // window can cause internal drag leave and enter messages. 109 // window can cause internal drag leave and enter messages.
87 void DragTranslate(const gfx::Point& root_window_location, 110 void DragTranslate(const gfx::Point& root_window_location,
88 scoped_ptr<ui::OSExchangeData>* data, 111 scoped_ptr<ui::OSExchangeData>* data,
89 scoped_ptr<ui::DropTargetEvent>* event, 112 scoped_ptr<ui::DropTargetEvent>* event,
90 aura::client::DragDropDelegate** delegate); 113 aura::client::DragDropDelegate** delegate);
91 114
92 // Called when we need to notify the current aura::Window that we're no 115 // Called when we need to notify the current aura::Window that we're no
93 // longer dragging over it. 116 // longer dragging over it.
94 void NotifyDragLeave(); 117 void NotifyDragLeave();
95 118
96 // Converts our bitfield of actions into an Atom that represents what action 119 // Converts our bitfield of actions into an Atom that represents what action
97 // we're most likely to take on drop. 120 // we're most likely to take on drop.
98 unsigned long DragOperationToAtom(int drag_operation); 121 ::Atom DragOperationToAtom(int drag_operation);
122
123 // Converts a single action atom to a drag operation.
124 int AtomToDragOperation(::Atom atom);
125
126 // During the blocking StartDragAndDrop() call, this converts the views-style
127 // |drag_operation_| bitfield into a vector of Atoms to offer to other
128 // processes.
129 std::vector< ::Atom> GetOfferedDragOperations();
130
131 // This returns a newly allocated copy of the data we're offering in this
132 // drag. This is done to bypass an asynchronous roundtrip with the X11
133 // server.
134 scoped_ptr<ui::SelectionFormatMap> CloneFormatMap() const;
135
136 // Handling XdndPosition can be paused while waiting for more data; this is
137 // called either synchronously from OnXdndPosition, or asynchronously after
138 // we've received data requested from the other window.
139 void CompleteXdndPosition(::Window source_window,
140 const gfx::Point& screen_point);
141
142 void SendXdndEnter(::Window dest_window);
143 void SendXdndLeave(::Window dest_window);
144 void SendXdndPosition(::Window dest_window,
145 const gfx::Point& screen_point,
146 unsigned long time);
147 void SendXdndDrop(::Window dest_window);
99 148
100 // Sends |xev| to |xid|, optionally short circuiting the round trip to the X 149 // Sends |xev| to |xid|, optionally short circuiting the round trip to the X
101 // server. 150 // server.
102 void SendXClientEvent(unsigned long xid, XEvent* xev); 151 void SendXClientEvent(::Window xid, XEvent* xev);
152
153 // A nested message loop that notifies this object of events through the
154 // X11WholeScreenMoveLoopDelegate interface.
155 X11WholeScreenMoveLoop move_loop_;
103 156
104 views::DesktopRootWindowHostX11* root_window_host_; 157 views::DesktopRootWindowHostX11* root_window_host_;
105 aura::RootWindow* root_window_; 158 aura::RootWindow* root_window_;
106 159
107 Display* xdisplay_; 160 Display* xdisplay_;
108 ::Window xwindow_; 161 ::Window xwindow_;
109 162
110 ui::X11AtomCache atom_cache_; 163 ui::X11AtomCache atom_cache_;
111 164
112 // Target side information. 165 // Target side information.
113
114 class X11DragContext; 166 class X11DragContext;
115 scoped_ptr<X11DragContext> current_context_; 167 scoped_ptr<X11DragContext> target_current_context_;
116 168
117 // The Aura window that is currently under the cursor. We need to manually 169 // The Aura window that is currently under the cursor. We need to manually
118 // keep track of this because Windows will only call our drag enter method 170 // keep track of this because Windows will only call our drag enter method
119 // once when the user enters the associated X Window. But inside that X 171 // once when the user enters the associated X Window. But inside that X
120 // Window there could be multiple aura windows, so we need to generate drag 172 // Window there could be multiple aura windows, so we need to generate drag
121 // enter events for them. 173 // enter events for them.
122 aura::Window* target_window_; 174 aura::Window* target_window_;
123 175
124 // Because Xdnd messages don't contain the position in messages other than 176 // Because Xdnd messages don't contain the position in messages other than
125 // the XdndPosition message, we must manually keep track of the last position 177 // the XdndPosition message, we must manually keep track of the last position
126 // change. 178 // change.
127 gfx::Point target_window_location_; 179 gfx::Point target_window_location_;
128 gfx::Point target_window_root_location_; 180 gfx::Point target_window_root_location_;
129 181
182 // In the Xdnd protocol, we aren't supposed to send another XdndPosition
183 // message until we have received a confirming XdndStatus message.
184 std::set< ::Window> waiting_on_status_;
185
186 // If we would send an XdndPosition message while we're waiting for an
187 // XdndStatus response, we need to cache the latest details we'd send.
188 NextPositionMap next_position_message_;
189
190 // Source side information.
191 ui::OSExchangeDataProviderAuraX11 const* source_provider_;
192 ::Window source_current_window_;
193
130 bool drag_drop_in_progress_; 194 bool drag_drop_in_progress_;
131 195
196 // The operation bitfield as requested by StartDragAndDrop.
132 int drag_operation_; 197 int drag_operation_;
133 198
199 // The operation performed. Is initialized to None at the start of
200 // StartDragAndDrop(), and is set only during the asynchronous XdndFinished
201 // message.
202 int resulting_operation_;
203
204 // This window will be receiving a drop as soon as we receive an XdndStatus
205 // from it.
206 std::set< ::Window> pending_drop_;
207
208 // We offer the other window a list of possible operations,
209 // XdndActionsList. This is the requested action from the other window. This
210 // is None if we haven't sent out an XdndPosition message yet, haven't yet
211 // received an XdndStatus or if the other window has told us that there's no
212 // action that we can agree on.
213 //
214 // This is a map instead of a simple variable because of the case where we
215 // put an XdndLeave in the queue at roughly the same time that the other
216 // window responds to an XdndStatus.
217 std::map< ::Window, ::Atom> negotiated_operation_;
218
219 static std::map< ::Window, DesktopDragDropClientAuraX11*> g_live_client_map;
220
134 DISALLOW_COPY_AND_ASSIGN(DesktopDragDropClientAuraX11); 221 DISALLOW_COPY_AND_ASSIGN(DesktopDragDropClientAuraX11);
135 }; 222 };
136 223
137 } // namespace views 224 } // namespace views
138 225
139 #endif // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_AURAX11_H_ 226 #endif // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_AURAX11_H_
OLDNEW
« no previous file with comments | « ui/views/views.gyp ('k') | ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698