Merge lp:~azzar1/unity/other-dnd-fixes into lp:unity

Proposed by Andrea Azzarone
Status: Merged
Approved by: Jason Smith
Approved revision: no longer in the source branch.
Merged at revision: 1510
Proposed branch: lp:~azzar1/unity/other-dnd-fixes
Merge into: lp:unity
Diff against target: 255 lines (+74/-22)
6 files modified
plugins/unityshell/src/DNDCollectionWindow.cpp (+40/-7)
plugins/unityshell/src/DNDCollectionWindow.h (+10/-2)
plugins/unityshell/src/Launcher.cpp (+19/-12)
plugins/unityshell/src/Launcher.h (+1/-0)
plugins/unityshell/src/LauncherModel.cpp (+3/-0)
plugins/unityshell/src/PluginAdapter.h (+1/-1)
To merge this branch: bzr merge lp:~azzar1/unity/other-dnd-fixes
Reviewer Review Type Date Requested Status
Jason Smith (community) Approve
Review via email: mp+73167@code.launchpad.net

Commit message

This branch tries to solve some dnd bugs.

1) First it try to remove the extra mouse movement that sometimes is required by DNDCollectionWindow using another timeout of 50ms and the XWarpPointer function. To avoid the extra movement also when we are in "Dash View" we need to restack the window every time and not only inside the constructor.

2) Makes it possible to dnd a USB key even if it is the only device icon in launcher.

3) Makes it possible to add more .desktop file into the launcher at once (use /usr/share/applications to test it)

To post a comment you must log in.
Revision history for this message
Jason Smith (jassmith) wrote :

We can't leak CompScreen into more classes. This makes testing VERY difficult down the road. Try to minimize your actual dependencies in the class. Looks like what you really need is a Display* from Xlib.

review: Needs Fixing
Revision history for this message
Andrea Azzarone (azzar1) wrote :

Done... I've also removed timeout to makke way for something more correct IMHO.

Revision history for this message
Jason Smith (jassmith) wrote :

You made the default window manager implementation return null but did not do a null check in your code

review: Needs Fixing
Revision history for this message
Andrea Azzarone (azzar1) wrote :

Done.

Revision history for this message
Andrea Azzarone (azzar1) wrote :

It should improve dnd experience but it don't solve definitively bug #835362

Revision history for this message
Andrea Azzarone (azzar1) wrote :

Done

Revision history for this message
Jason Smith (jassmith) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/DNDCollectionWindow.cpp'
2--- plugins/unityshell/src/DNDCollectionWindow.cpp 2011-08-29 23:36:21 +0000
3+++ plugins/unityshell/src/DNDCollectionWindow.cpp 2011-08-31 20:55:32 +0000
4@@ -26,16 +26,21 @@
5
6 DNDCollectionWindow::DNDCollectionWindow()
7 : nux::BaseWindow("")
8+ , display(NULL)
9 {
10+ // Make it invisible...
11 SetBackgroundColor(nux::Color(0x00000000));
12- SetGeometry (WindowManager::Default()->GetScreenGeometry());
13+ // ... and as big as the whole screen.
14+ SetGeometry(WindowManager::Default()->GetScreenGeometry());
15
16 ShowWindow(true);
17 PushToBack();
18- // Hack
19+ // Hack to create the X Window as soon as possible.
20 EnableInputWindow(true, "DNDCollectionWindow");
21 EnableInputWindow(false, "DNDCollectionWindow");
22 SetDndEnabled(false, true);
23+
24+ WindowManager::Default()->window_moved.connect(sigc::mem_fun(this, &DNDCollectionWindow::OnWindowMoved));
25 }
26
27 DNDCollectionWindow::~DNDCollectionWindow()
28@@ -44,19 +49,47 @@
29 g_free(it);
30 }
31
32+/**
33+ * EnableInputWindow doesn't show the window immediately.
34+ * Since nux::EnableInputWindow uses XMoveResizeWindow the best way to know if
35+ * the X Window is really on/off screen is receiving WindowManager::window_moved
36+ * signal. Please don't hate me!
37+ **/
38+void DNDCollectionWindow::OnWindowMoved(guint32 xid)
39+{
40+ if (xid == GetInputWindowId() && display() != NULL)
41+ {
42+ // Create a fake mouse move because sometimes an extra one is required.
43+ XWarpPointer(display(), None, None, 0, 0, 0, 0, 0, 0);
44+ XFlush(display());
45+ }
46+}
47+
48+void DNDCollectionWindow::Collect()
49+{
50+ // Using PushToFront we're sure that the window is shown over the panel window,
51+ // the launcher window and the dash window. Don't forget to call PushToBack as
52+ // soon as possible.
53+ PushToFront();
54+ EnableInputWindow(true, "DndCollectionWindow");
55+}
56+
57 void DNDCollectionWindow::ProcessDndMove(int x, int y, std::list<char*> mimes)
58-{
59- // Hide the window as soon as possible
60+{
61+ // Hide the window as soon as possible.
62+ PushToBack();
63 EnableInputWindow(false, "DNDCollectionWindow");
64-
65+
66+ // Free mimes_ before fill it again.
67 for (auto it : mimes_)
68 g_free(it);
69 mimes_.clear();
70-
71- // Duplicate the list
72+
73+ // Duplicate the list.
74 for (auto it : mimes)
75 mimes_.push_back(g_strdup(it));
76
77+ // Emit the collected signal.
78 collected.emit(mimes_);
79 }
80
81
82=== modified file 'plugins/unityshell/src/DNDCollectionWindow.h'
83--- plugins/unityshell/src/DNDCollectionWindow.h 2011-08-29 23:36:21 +0000
84+++ plugins/unityshell/src/DNDCollectionWindow.h 2011-08-31 20:55:32 +0000
85@@ -22,12 +22,16 @@
86
87 #include <list>
88
89-#include <core/screen.h>
90 #include <Nux/Nux.h>
91 #include <Nux/BaseWindow.h>
92 #include <sigc++/sigc++.h>
93
94 namespace unity {
95+
96+/**
97+ * DNDCollectionWindow makes it possible to collect drag and drop (dnd) data as
98+ * soon as dnd starts and not when the mouse pointer enter the x window.
99+ **/
100
101 class DNDCollectionWindow : public nux::BaseWindow
102 {
103@@ -38,16 +42,20 @@
104 DNDCollectionWindow();
105 ~DNDCollectionWindow();
106
107+ void Collect();
108+
109 private:
110 void ProcessDndMove(int x, int y, std::list<char*> mimes);
111+ void OnWindowMoved(guint32 xid);
112
113 // Members
114 public:
115+ nux::Property<Display*> display;
116+
117 sigc::signal<void, const std::list<char*>&> collected;
118
119 private:
120 std::list<char*> mimes_;
121-
122 };
123
124 } // namespace unity
125
126=== modified file 'plugins/unityshell/src/Launcher.cpp'
127--- plugins/unityshell/src/Launcher.cpp 2011-08-30 21:01:27 +0000
128+++ plugins/unityshell/src/Launcher.cpp 2011-08-31 20:55:32 +0000
129@@ -191,6 +191,8 @@
130 adapter.drag_start.connect(sigc::mem_fun(this, &Launcher::OnDragStart));
131 adapter.drag_update.connect(sigc::mem_fun(this, &Launcher::OnDragUpdate));
132 adapter.drag_finish.connect(sigc::mem_fun(this, &Launcher::OnDragFinish));
133+
134+ display.changed.connect(sigc::mem_fun(this, &Launcher::OnDisplayChanged));
135
136 _current_icon = NULL;
137 _current_icon_index = -1;
138@@ -372,6 +374,12 @@
139 }
140
141 void
142+Launcher::OnDisplayChanged(Display* display)
143+{
144+ _collection_window->display = display;
145+}
146+
147+void
148 Launcher::OnDragStart(GeisAdapter::GeisDragData* data)
149 {
150 if (_drag_out_id && _drag_out_id == data->id)
151@@ -1588,13 +1596,14 @@
152 if (self->_data_checked == false)
153 {
154 self->_data_checked = true;
155- self->_collection_window->EnableInputWindow(true, "DNDCollectionWindow");
156+ self->_collection_window->Collect();
157 }
158
159 return true;
160 }
161
162 self->_data_checked = false;
163+ self->_collection_window->PushToBack();
164 self->_collection_window->EnableInputWindow(false, "DNDCollectionWindow");
165
166 self->DndLeave();
167@@ -2834,7 +2843,7 @@
168 }
169
170 void Launcher::OnDNDDataCollected(const std::list<char*>& mimes)
171-{
172+{
173 _dnd_data.Reset();
174
175 unity::glib::String uri_list_const(g_strdup("text/uri-list"));
176@@ -3061,32 +3070,30 @@
177 {
178 if (_steal_drag)
179 {
180- char* path = 0;
181-
182 for (auto it : _dnd_data.Uris())
183 {
184 if (g_str_has_suffix(it.c_str(), ".desktop"))
185 {
186+ char* path = 0;
187+
188 if (g_str_has_prefix(it.c_str(), "application://"))
189 {
190 const char* tmp = it.c_str() + strlen("application://");
191 unity::glib::String tmp2(g_strdup_printf("file:///usr/share/applications/%s", tmp));
192 path = g_filename_from_uri(tmp2.Value(), NULL, NULL);
193- break;
194 }
195 else if (g_str_has_prefix(it.c_str(), "file://"))
196 {
197 path = g_filename_from_uri(it.c_str(), NULL, NULL);
198- break;
199+ }
200+
201+ if (path)
202+ {
203+ launcher_addrequest.emit(path, _dnd_hovered_icon);
204+ g_free(path);
205 }
206 }
207 }
208-
209- if (path)
210- {
211- launcher_addrequest.emit(path, _dnd_hovered_icon);
212- g_free(path);
213- }
214 }
215 else if (_dnd_hovered_icon && _drag_action != nux::DNDACTION_NONE)
216 {
217
218=== modified file 'plugins/unityshell/src/Launcher.h'
219--- plugins/unityshell/src/Launcher.h 2011-08-30 16:48:12 +0000
220+++ plugins/unityshell/src/Launcher.h 2011-08-31 20:55:32 +0000
221@@ -369,6 +369,7 @@
222
223 gboolean TapOnSuper();
224
225+ void OnDisplayChanged(Display* display);
226 void OnDNDDataCollected(const std::list<char*>& mimes);
227
228 nux::HLayout* m_Layout;
229
230=== modified file 'plugins/unityshell/src/LauncherModel.cpp'
231--- plugins/unityshell/src/LauncherModel.cpp 2011-08-21 16:31:17 +0000
232+++ plugins/unityshell/src/LauncherModel.cpp 2011-08-31 20:55:32 +0000
233@@ -163,6 +163,9 @@
234 iterator(LauncherModel::*begin_it)(void);
235 iterator(LauncherModel::*end_it)(void);
236 iterator it;
237+
238+ if (icon && icon->Type() == AbstractLauncherIcon::TYPE_DEVICE)
239+ return true;
240
241 if (IconShouldShelf(icon))
242 {
243
244=== modified file 'plugins/unityshell/src/PluginAdapter.h'
245--- plugins/unityshell/src/PluginAdapter.h 2011-08-30 16:48:12 +0000
246+++ plugins/unityshell/src/PluginAdapter.h 2011-08-31 20:55:32 +0000
247@@ -135,7 +135,7 @@
248
249 nux::Geometry GetWindowGeometry(guint32 xid);
250 nux::Geometry GetScreenGeometry();
251-
252+
253 void CheckWindowIntersections(nux::Geometry const& region, bool &active, bool &any);
254
255 int WorkspaceCount();