Merge lp:~azzar1/unity/fix-1035301 into lp:unity
- fix-1035301
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Andrea Azzarone |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2929 |
Proposed branch: | lp:~azzar1/unity/fix-1035301 |
Merge into: | lp:unity |
Diff against target: |
1934 lines (+1075/-316) 31 files modified
launcher/AbstractLauncherIcon.h (+1/-0) launcher/CMakeLists.txt (+4/-1) launcher/DNDCollectionWindow.cpp (+0/-99) launcher/DNDCollectionWindow.h (+0/-63) launcher/Launcher.cpp (+86/-121) launcher/Launcher.h (+7/-8) launcher/LauncherController.cpp (+45/-4) launcher/LauncherController.h (+2/-1) launcher/LauncherControllerPrivate.h (+8/-1) launcher/LauncherIcon.cpp (+2/-0) launcher/StandaloneLauncher.cpp (+2/-2) launcher/XdndCollectionWindow.h (+51/-0) launcher/XdndCollectionWindowImp.cpp (+112/-0) launcher/XdndCollectionWindowImp.h (+44/-0) launcher/XdndManager.h (+43/-0) launcher/XdndManagerImp.cpp (+98/-0) launcher/XdndManagerImp.h (+54/-0) launcher/XdndStartStopNotifier.cpp (+27/-0) launcher/XdndStartStopNotifier.h (+41/-0) launcher/XdndStartStopNotifierImp.cpp (+77/-0) launcher/XdndStartStopNotifierImp.h (+47/-0) plugins/unityshell/src/unitya11ytests.cpp (+1/-1) plugins/unityshell/src/unityshell.cpp (+9/-1) tests/CMakeLists.txt (+2/-0) tests/test_launcher.cpp (+4/-9) tests/test_launcher_controller.cpp (+56/-0) tests/test_xdnd_manager_imp.cpp (+130/-0) tests/test_xdnd_start_stop_notifier_imp.cpp (+107/-0) unity-shared/UScreen.cpp (+7/-0) unity-shared/UScreen.h (+1/-0) unity-standalone/StandaloneUnity.cpp (+7/-5) |
To merge this branch: | bzr merge lp:~azzar1/unity/fix-1035301 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Brandon Schaefer (community) | Approve | ||
Review via email: mp+134533@code.launchpad.net |
Commit message
Refactor xdnd launcher code.
Description of the change
== Problem ==
Dash, Multi-monitor - When Launcher is set to auto-hide, and the user starts dragging a item, only the Launcher on the monitor which currently contains the dragged item should reveal.
== Fix ==
Move xdnd launcher code from Launcher.cpp to different classes/files:
# XdndStartStopNo
# XdndCollectionW
# XdndManager*
== Test ==
Unit test added.
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Andrea Azzarone (azzar1) wrote : | # |
Ok thank you for the review :) Just one comment:
> 900 + std::vector<
> 901 + for (auto mime : mimes)
> 902 + data.push_
> Can't be happen that std::list<char>
What? :)
Andrea Azzarone (azzar1) wrote : | # |
>
> 1096 + char target[] = "text/uri-list";
>
No we can't. Because nux::..
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
> > Can't be happen that std::list<char>
>
> What? :)
Contains a nullptr?
> No we can't. Because nux::..
Ok, we need to fix the API then.
Andrea Azzarone (azzar1) wrote : | # |
> > > Can't be happen that std::list<char>
> >
> > What? :)
>
> Contains a nullptr?
Hmmm, it should not happen but it's better to check for null.
Brandon Schaefer (brandontschaefer) wrote : | # |
784 + controller.
Could we do a make_shared?
883 + SetBackgroundCo
Could you make that nux::color:
884 + SetOpacity(0.0f);
Do we need to set this if it is already transparent?
Andrea Azzarone (azzar1) wrote : | # |
>
> 884 + SetOpacity(0.0f);
>
> Do we need to set this if it is already transparent?
Yeah there was a nvidia bug few month ago. Can't remember the bug number.
Brandon Schaefer (brandontschaefer) wrote : | # |
Test pass now :). Looks good code wise, and works! +1
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Preview Diff
1 | === modified file 'launcher/AbstractLauncherIcon.h' | |||
2 | --- launcher/AbstractLauncherIcon.h 2012-11-15 17:56:23 +0000 | |||
3 | +++ launcher/AbstractLauncherIcon.h 2012-11-24 14:30:27 +0000 | |||
4 | @@ -103,6 +103,7 @@ | |||
5 | 103 | RUNNING, | 103 | RUNNING, |
6 | 104 | URGENT, | 104 | URGENT, |
7 | 105 | PRESENTED, | 105 | PRESENTED, |
8 | 106 | UNFOLDED, | ||
9 | 106 | STARTING, | 107 | STARTING, |
10 | 107 | SHIMMER, | 108 | SHIMMER, |
11 | 108 | CENTER_SAVED, | 109 | CENTER_SAVED, |
12 | 109 | 110 | ||
13 | === modified file 'launcher/CMakeLists.txt' | |||
14 | --- launcher/CMakeLists.txt 2012-11-15 18:44:55 +0000 | |||
15 | +++ launcher/CMakeLists.txt 2012-11-24 14:30:27 +0000 | |||
16 | @@ -33,7 +33,6 @@ | |||
17 | 33 | ApplicationLauncherIcon.cpp | 33 | ApplicationLauncherIcon.cpp |
18 | 34 | BFBLauncherIcon.cpp | 34 | BFBLauncherIcon.cpp |
19 | 35 | CairoBaseWindow.cpp | 35 | CairoBaseWindow.cpp |
20 | 36 | DNDCollectionWindow.cpp | ||
21 | 37 | Decaymulator.cpp | 36 | Decaymulator.cpp |
22 | 38 | DesktopLauncherIcon.cpp | 37 | DesktopLauncherIcon.cpp |
23 | 39 | DeviceLauncherSection.cpp | 38 | DeviceLauncherSection.cpp |
24 | @@ -73,6 +72,10 @@ | |||
25 | 73 | VolumeImp.cpp | 72 | VolumeImp.cpp |
26 | 74 | VolumeLauncherIcon.cpp | 73 | VolumeLauncherIcon.cpp |
27 | 75 | VolumeMonitorWrapper.cpp | 74 | VolumeMonitorWrapper.cpp |
28 | 75 | XdndCollectionWindowImp.cpp | ||
29 | 76 | XdndManagerImp.cpp | ||
30 | 77 | XdndStartStopNotifier.cpp | ||
31 | 78 | XdndStartStopNotifierImp.cpp | ||
32 | 76 | ) | 79 | ) |
33 | 77 | 80 | ||
34 | 78 | if (ENABLE_X_SUPPORT) | 81 | if (ENABLE_X_SUPPORT) |
35 | 79 | 82 | ||
36 | === removed file 'launcher/DNDCollectionWindow.cpp' | |||
37 | --- launcher/DNDCollectionWindow.cpp 2012-10-11 01:44:15 +0000 | |||
38 | +++ launcher/DNDCollectionWindow.cpp 1970-01-01 00:00:00 +0000 | |||
39 | @@ -1,99 +0,0 @@ | |||
40 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
41 | 2 | /* | ||
42 | 3 | * Copyright (C) 2011 Canonical Ltd | ||
43 | 4 | * | ||
44 | 5 | * This program is free software: you can redistribute it and/or modify | ||
45 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
46 | 7 | * published by the Free Software Foundation. | ||
47 | 8 | * | ||
48 | 9 | * This program is distributed in the hope that it will be useful, | ||
49 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
50 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
51 | 12 | * GNU General Public License for more details. | ||
52 | 13 | * | ||
53 | 14 | * You should have received a copy of the GNU General Public License | ||
54 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
55 | 16 | * | ||
56 | 17 | * Authored by: Andrea Azzarone <azzaronea@gmail.com> | ||
57 | 18 | */ | ||
58 | 19 | |||
59 | 20 | #include "DNDCollectionWindow.h" | ||
60 | 21 | |||
61 | 22 | #include "unity-shared/WindowManager.h" | ||
62 | 23 | |||
63 | 24 | namespace unity { | ||
64 | 25 | |||
65 | 26 | NUX_IMPLEMENT_OBJECT_TYPE(DNDCollectionWindow); | ||
66 | 27 | |||
67 | 28 | DNDCollectionWindow::DNDCollectionWindow() | ||
68 | 29 | : nux::BaseWindow("") | ||
69 | 30 | , display(NULL) | ||
70 | 31 | { | ||
71 | 32 | // Make it invisible... | ||
72 | 33 | SetBackgroundColor(nux::Color(0x00000000)); | ||
73 | 34 | SetOpacity(0.0f); | ||
74 | 35 | // ... and as big as the whole screen. | ||
75 | 36 | WindowManager& wm = WindowManager::Default(); | ||
76 | 37 | SetGeometry(wm.GetScreenGeometry()); | ||
77 | 38 | |||
78 | 39 | ShowWindow(true); | ||
79 | 40 | PushToBack(); | ||
80 | 41 | // Hack to create the X Window as soon as possible. | ||
81 | 42 | EnableInputWindow(true, "DNDCollectionWindow"); | ||
82 | 43 | EnableInputWindow(false, "DNDCollectionWindow"); | ||
83 | 44 | SetDndEnabled(false, true); | ||
84 | 45 | |||
85 | 46 | wm.window_moved.connect(sigc::mem_fun(this, &DNDCollectionWindow::OnWindowMoved)); | ||
86 | 47 | } | ||
87 | 48 | |||
88 | 49 | DNDCollectionWindow::~DNDCollectionWindow() | ||
89 | 50 | { | ||
90 | 51 | for (auto it : mimes_) | ||
91 | 52 | g_free(it); | ||
92 | 53 | } | ||
93 | 54 | |||
94 | 55 | /** | ||
95 | 56 | * EnableInputWindow doesn't show the window immediately. | ||
96 | 57 | * Since nux::EnableInputWindow uses XMoveResizeWindow the best way to know if | ||
97 | 58 | * the X Window is really on/off screen is receiving WindowManager::window_moved | ||
98 | 59 | * signal. Please don't hate me! | ||
99 | 60 | **/ | ||
100 | 61 | void DNDCollectionWindow::OnWindowMoved(Window window_id) | ||
101 | 62 | { | ||
102 | 63 | if (window_id == GetInputWindowId() && display() != NULL) | ||
103 | 64 | { | ||
104 | 65 | // Create a fake mouse move because sometimes an extra one is required. | ||
105 | 66 | XWarpPointer(display(), None, None, 0, 0, 0, 0, 0, 0); | ||
106 | 67 | XFlush(display()); | ||
107 | 68 | } | ||
108 | 69 | } | ||
109 | 70 | |||
110 | 71 | void DNDCollectionWindow::Collect() | ||
111 | 72 | { | ||
112 | 73 | // Using PushToFront we're sure that the window is shown over the panel window, | ||
113 | 74 | // the launcher window and the dash window. Don't forget to call PushToBack as | ||
114 | 75 | // soon as possible. | ||
115 | 76 | PushToFront(); | ||
116 | 77 | EnableInputWindow(true, "DndCollectionWindow"); | ||
117 | 78 | } | ||
118 | 79 | |||
119 | 80 | void DNDCollectionWindow::ProcessDndMove(int x, int y, std::list<char*> mimes) | ||
120 | 81 | { | ||
121 | 82 | // Hide the window as soon as possible. | ||
122 | 83 | PushToBack(); | ||
123 | 84 | EnableInputWindow(false, "DNDCollectionWindow"); | ||
124 | 85 | |||
125 | 86 | // Free mimes_ before fill it again. | ||
126 | 87 | for (auto it : mimes_) | ||
127 | 88 | g_free(it); | ||
128 | 89 | mimes_.clear(); | ||
129 | 90 | |||
130 | 91 | // Duplicate the list. | ||
131 | 92 | for (auto it : mimes) | ||
132 | 93 | mimes_.push_back(g_strdup(it)); | ||
133 | 94 | |||
134 | 95 | // Emit the collected signal. | ||
135 | 96 | collected.emit(mimes_); | ||
136 | 97 | } | ||
137 | 98 | |||
138 | 99 | } // namespace unity | ||
139 | 100 | 0 | ||
140 | === removed file 'launcher/DNDCollectionWindow.h' | |||
141 | --- launcher/DNDCollectionWindow.h 2012-10-11 01:44:15 +0000 | |||
142 | +++ launcher/DNDCollectionWindow.h 1970-01-01 00:00:00 +0000 | |||
143 | @@ -1,63 +0,0 @@ | |||
144 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
145 | 2 | /* | ||
146 | 3 | * Copyright (C) 2011 Canonical Ltd | ||
147 | 4 | * | ||
148 | 5 | * This program is free software: you can redistribute it and/or modify | ||
149 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
150 | 7 | * published by the Free Software Foundation. | ||
151 | 8 | * | ||
152 | 9 | * This program is distributed in the hope that it will be useful, | ||
153 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
154 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
155 | 12 | * GNU General Public License for more details. | ||
156 | 13 | * | ||
157 | 14 | * You should have received a copy of the GNU General Public License | ||
158 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
159 | 16 | * | ||
160 | 17 | * Authored by: Andrea Azzarone <azzaronea@gmail.com> | ||
161 | 18 | */ | ||
162 | 19 | |||
163 | 20 | #ifndef DNDCOLLECTIONWINDOW_H | ||
164 | 21 | #define DNDCOLLECTIONWINDOW_H | ||
165 | 22 | |||
166 | 23 | #include <list> | ||
167 | 24 | |||
168 | 25 | #include <Nux/Nux.h> | ||
169 | 26 | #include <Nux/BaseWindow.h> | ||
170 | 27 | #include <sigc++/sigc++.h> | ||
171 | 28 | |||
172 | 29 | namespace unity { | ||
173 | 30 | |||
174 | 31 | /** | ||
175 | 32 | * DNDCollectionWindow makes it possible to collect drag and drop (dnd) data as | ||
176 | 33 | * soon as dnd starts and not when the mouse pointer enter the x window. | ||
177 | 34 | **/ | ||
178 | 35 | |||
179 | 36 | class DNDCollectionWindow : public nux::BaseWindow | ||
180 | 37 | { | ||
181 | 38 | NUX_DECLARE_OBJECT_TYPE(DNDCollectionWindow, nux::BaseWindow); | ||
182 | 39 | |||
183 | 40 | // Methods | ||
184 | 41 | public: | ||
185 | 42 | DNDCollectionWindow(); | ||
186 | 43 | ~DNDCollectionWindow(); | ||
187 | 44 | |||
188 | 45 | void Collect(); | ||
189 | 46 | |||
190 | 47 | private: | ||
191 | 48 | void ProcessDndMove(int x, int y, std::list<char*> mimes); | ||
192 | 49 | void OnWindowMoved(Window window_id); | ||
193 | 50 | |||
194 | 51 | // Members | ||
195 | 52 | public: | ||
196 | 53 | nux::Property<Display*> display; | ||
197 | 54 | |||
198 | 55 | sigc::signal<void, const std::list<char*>&> collected; | ||
199 | 56 | |||
200 | 57 | private: | ||
201 | 58 | std::list<char*> mimes_; | ||
202 | 59 | }; | ||
203 | 60 | |||
204 | 61 | } // namespace unity | ||
205 | 62 | |||
206 | 63 | #endif // DNDCOLLECTIONWINDOW_H | ||
207 | 64 | 0 | ||
208 | === modified file 'launcher/Launcher.cpp' | |||
209 | --- launcher/Launcher.cpp 2012-11-16 15:58:49 +0000 | |||
210 | +++ launcher/Launcher.cpp 2012-11-24 14:30:27 +0000 | |||
211 | @@ -91,7 +91,6 @@ | |||
212 | 91 | const int MOUSE_DEADZONE = 15; | 91 | const int MOUSE_DEADZONE = 15; |
213 | 92 | const float DRAG_OUT_PIXELS = 300.0f; | 92 | const float DRAG_OUT_PIXELS = 300.0f; |
214 | 93 | 93 | ||
215 | 94 | const std::string DND_CHECK_TIMEOUT = "dnd-check-timeout"; | ||
216 | 95 | const std::string START_DRAGICON_TIMEOUT = "start-dragicon-timeout"; | 94 | const std::string START_DRAGICON_TIMEOUT = "start-dragicon-timeout"; |
217 | 96 | const std::string SCROLL_TIMEOUT = "scroll-timeout"; | 95 | const std::string SCROLL_TIMEOUT = "scroll-timeout"; |
218 | 97 | const std::string ANIMATION_IDLE = "animation-idle"; | 96 | const std::string ANIMATION_IDLE = "animation-idle"; |
219 | @@ -103,7 +102,6 @@ | |||
220 | 103 | const int Launcher::Launcher::ANIM_DURATION_SHORT = 125; | 102 | const int Launcher::Launcher::ANIM_DURATION_SHORT = 125; |
221 | 104 | 103 | ||
222 | 105 | Launcher::Launcher(nux::BaseWindow* parent, | 104 | Launcher::Launcher(nux::BaseWindow* parent, |
223 | 106 | nux::ObjectPtr<DNDCollectionWindow> const& collection_window, | ||
224 | 107 | NUX_FILE_LINE_DECL) | 105 | NUX_FILE_LINE_DECL) |
225 | 108 | : View(NUX_FILE_LINE_PARAM) | 106 | : View(NUX_FILE_LINE_PARAM) |
226 | 109 | #ifdef USE_X11 | 107 | #ifdef USE_X11 |
227 | @@ -145,14 +143,11 @@ | |||
228 | 145 | , _drag_out_delta_x(0.0f) | 143 | , _drag_out_delta_x(0.0f) |
229 | 146 | , _drag_gesture_ongoing(false) | 144 | , _drag_gesture_ongoing(false) |
230 | 147 | , _last_reveal_progress(0.0f) | 145 | , _last_reveal_progress(0.0f) |
231 | 148 | , _collection_window(collection_window) | ||
232 | 149 | , _selection_atom(0) | 146 | , _selection_atom(0) |
233 | 150 | , _background_color(nux::color::DimGray) | 147 | , _background_color(nux::color::DimGray) |
234 | 151 | { | 148 | { |
235 | 152 | m_Layout = new nux::HLayout(NUX_TRACKER_LOCATION); | 149 | m_Layout = new nux::HLayout(NUX_TRACKER_LOCATION); |
236 | 153 | 150 | ||
237 | 154 | _collection_window->collected.connect(sigc::mem_fun(this, &Launcher::OnDNDDataCollected)); | ||
238 | 155 | |||
239 | 156 | bg_effect_helper_.owner = this; | 151 | bg_effect_helper_.owner = this; |
240 | 157 | bg_effect_helper_.enabled = false; | 152 | bg_effect_helper_.enabled = false; |
241 | 158 | 153 | ||
242 | @@ -180,18 +175,12 @@ | |||
243 | 180 | ql_manager.quicklist_closed.connect(sigc::mem_fun(this, &Launcher::RecvQuicklistClosed)); | 175 | ql_manager.quicklist_closed.connect(sigc::mem_fun(this, &Launcher::RecvQuicklistClosed)); |
244 | 181 | 176 | ||
245 | 182 | WindowManager& wm = WindowManager::Default(); | 177 | WindowManager& wm = WindowManager::Default(); |
246 | 183 | wm.window_mapped.connect(sigc::hide(sigc::mem_fun(this, &Launcher::DndTimeoutSetup))); | ||
247 | 184 | wm.window_unmapped.connect(sigc::hide(sigc::mem_fun(this, &Launcher::DndTimeoutSetup))); | ||
248 | 185 | wm.initiate_spread.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); | 178 | wm.initiate_spread.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); |
249 | 186 | wm.initiate_expo.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); | 179 | wm.initiate_expo.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); |
250 | 187 | wm.terminate_spread.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); | 180 | wm.terminate_spread.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); |
251 | 188 | wm.terminate_expo.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); | 181 | wm.terminate_expo.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); |
252 | 189 | wm.screen_viewport_switch_ended.connect(sigc::mem_fun(this, &Launcher::EnsureAnimation)); | 182 | wm.screen_viewport_switch_ended.connect(sigc::mem_fun(this, &Launcher::EnsureAnimation)); |
253 | 190 | 183 | ||
254 | 191 | #ifdef USE_X11 | ||
255 | 192 | display.changed.connect(sigc::mem_fun(this, &Launcher::OnDisplayChanged)); | ||
256 | 193 | #endif | ||
257 | 194 | |||
258 | 195 | // 0 out timers to avoid wonky startups | 184 | // 0 out timers to avoid wonky startups |
259 | 196 | for (int i = 0; i < TIME_LAST; ++i) | 185 | for (int i = 0; i < TIME_LAST; ++i) |
260 | 197 | { | 186 | { |
261 | @@ -227,11 +216,6 @@ | |||
262 | 227 | return "Launcher"; | 216 | return "Launcher"; |
263 | 228 | } | 217 | } |
264 | 229 | 218 | ||
265 | 230 | void Launcher::OnDisplayChanged(Display* display) | ||
266 | 231 | { | ||
267 | 232 | _collection_window->display = display; | ||
268 | 233 | } | ||
269 | 234 | |||
270 | 235 | #ifdef NUX_GESTURES_SUPPORT | 219 | #ifdef NUX_GESTURES_SUPPORT |
271 | 236 | void Launcher::OnDragStart(const nux::GestureEvent &event) | 220 | void Launcher::OnDragStart(const nux::GestureEvent &event) |
272 | 237 | { | 221 | { |
273 | @@ -399,6 +383,10 @@ | |||
274 | 399 | if (unity::TimeUtil::TimeDelta(¤t, &time) < ANIM_DURATION) | 383 | if (unity::TimeUtil::TimeDelta(¤t, &time) < ANIM_DURATION) |
275 | 400 | return true; | 384 | return true; |
276 | 401 | 385 | ||
277 | 386 | time = icon->GetQuirkTime(AbstractLauncherIcon::Quirk::UNFOLDED); | ||
278 | 387 | if (unity::TimeUtil::TimeDelta(¤t, &time) < ANIM_DURATION) | ||
279 | 388 | return true; | ||
280 | 389 | |||
281 | 402 | time = icon->GetQuirkTime(AbstractLauncherIcon::Quirk::SHIMMER); | 390 | time = icon->GetQuirkTime(AbstractLauncherIcon::Quirk::SHIMMER); |
282 | 403 | if (unity::TimeUtil::TimeDelta(¤t, &time) < ANIM_DURATION_LONG) | 391 | if (unity::TimeUtil::TimeDelta(¤t, &time) < ANIM_DURATION_LONG) |
283 | 404 | return true; | 392 | return true; |
284 | @@ -552,6 +540,18 @@ | |||
285 | 552 | return 1.0f - result; | 540 | return 1.0f - result; |
286 | 553 | } | 541 | } |
287 | 554 | 542 | ||
288 | 543 | float Launcher::IconUnfoldProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const | ||
289 | 544 | { | ||
290 | 545 | struct timespec icon_unfold_time = icon->GetQuirkTime(AbstractLauncherIcon::Quirk::UNFOLDED); | ||
291 | 546 | int ms = unity::TimeUtil::TimeDelta(¤t, &icon_unfold_time); | ||
292 | 547 | float result = CLAMP((float) ms / (float) ANIM_DURATION, 0.0f, 1.0f); | ||
293 | 548 | |||
294 | 549 | if (icon->GetQuirk(AbstractLauncherIcon::Quirk::UNFOLDED)) | ||
295 | 550 | return result; | ||
296 | 551 | else | ||
297 | 552 | return 1.0f - result; | ||
298 | 553 | } | ||
299 | 554 | |||
300 | 555 | float Launcher::IconUrgentProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const | 555 | float Launcher::IconUrgentProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const |
301 | 556 | { | 556 | { |
302 | 557 | struct timespec urgent_time = icon->GetQuirkTime(AbstractLauncherIcon::Quirk::URGENT); | 557 | struct timespec urgent_time = icon->GetQuirkTime(AbstractLauncherIcon::Quirk::URGENT); |
303 | @@ -919,13 +919,14 @@ | |||
304 | 919 | 919 | ||
305 | 920 | // goes for 0.0f when fully unfolded, to 1.0f folded | 920 | // goes for 0.0f when fully unfolded, to 1.0f folded |
306 | 921 | float folding_progress = CLAMP((center.y + _icon_size - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); | 921 | float folding_progress = CLAMP((center.y + _icon_size - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); |
308 | 922 | float present_progress = IconPresentProgress(icon, current); | 922 | float unfold_progress = IconUnfoldProgress(icon, current); |
309 | 923 | 923 | ||
311 | 924 | folding_progress *= 1.0f - present_progress; | 924 | folding_progress *= 1.0f - unfold_progress; |
312 | 925 | 925 | ||
313 | 926 | float half_size = (folded_size / 2.0f) + (_icon_size / 2.0f - folded_size / 2.0f) * (1.0f - folding_progress); | 926 | float half_size = (folded_size / 2.0f) + (_icon_size / 2.0f - folded_size / 2.0f) * (1.0f - folding_progress); |
314 | 927 | float icon_hide_offset = autohide_offset; | 927 | float icon_hide_offset = autohide_offset; |
315 | 928 | 928 | ||
316 | 929 | float present_progress = IconPresentProgress(icon, current); | ||
317 | 929 | icon_hide_offset *= 1.0f - (present_progress * icon->PresentUrgency()); | 930 | icon_hide_offset *= 1.0f - (present_progress * icon->PresentUrgency()); |
318 | 930 | 931 | ||
319 | 931 | // icon is crossing threshold, start folding | 932 | // icon is crossing threshold, start folding |
320 | @@ -1017,8 +1018,8 @@ | |||
321 | 1017 | // magic constant must some day be explained, for now suffice to say this constant prevents the bottom from "marching"; | 1018 | // magic constant must some day be explained, for now suffice to say this constant prevents the bottom from "marching"; |
322 | 1018 | float magic_constant = 1.3f; | 1019 | float magic_constant = 1.3f; |
323 | 1019 | 1020 | ||
326 | 1020 | float present_progress = IconPresentProgress(*it, current); | 1021 | float unfold_progress = IconUnfoldProgress(*it, current); |
327 | 1021 | folding_threshold -= CLAMP(sum - launcher_height, 0.0f, height * magic_constant) * (folding_constant + (1.0f - folding_constant) * present_progress); | 1022 | folding_threshold -= CLAMP(sum - launcher_height, 0.0f, height * magic_constant) * (folding_constant + (1.0f - folding_constant) * unfold_progress); |
328 | 1022 | } | 1023 | } |
329 | 1023 | 1024 | ||
330 | 1024 | if (sum - _space_between_icons <= launcher_height) | 1025 | if (sum - _space_between_icons <= launcher_height) |
331 | @@ -1366,59 +1367,6 @@ | |||
332 | 1366 | return _mouse_position.y; | 1367 | return _mouse_position.y; |
333 | 1367 | } | 1368 | } |
334 | 1368 | 1369 | ||
335 | 1369 | bool Launcher::OnUpdateDragManagerTimeout() | ||
336 | 1370 | { | ||
337 | 1371 | #ifdef USE_X11 | ||
338 | 1372 | if (!display()) | ||
339 | 1373 | return false; | ||
340 | 1374 | |||
341 | 1375 | if (!_selection_atom) | ||
342 | 1376 | _selection_atom = XInternAtom(display(), "XdndSelection", false); | ||
343 | 1377 | |||
344 | 1378 | Window drag_owner = XGetSelectionOwner(display(), _selection_atom); | ||
345 | 1379 | |||
346 | 1380 | // evil hack because Qt does not release the seelction owner on drag finished | ||
347 | 1381 | Window root_r, child_r; | ||
348 | 1382 | int root_x_r, root_y_r, win_x_r, win_y_r; | ||
349 | 1383 | unsigned int mask; | ||
350 | 1384 | XQueryPointer(display(), DefaultRootWindow(display()), &root_r, &child_r, &root_x_r, &root_y_r, &win_x_r, &win_y_r, &mask); | ||
351 | 1385 | |||
352 | 1386 | if (drag_owner && (mask & (Button1Mask | Button2Mask | Button3Mask))) | ||
353 | 1387 | { | ||
354 | 1388 | if (_data_checked == false) | ||
355 | 1389 | { | ||
356 | 1390 | _data_checked = true; | ||
357 | 1391 | _collection_window->Collect(); | ||
358 | 1392 | } | ||
359 | 1393 | |||
360 | 1394 | return true; | ||
361 | 1395 | } | ||
362 | 1396 | |||
363 | 1397 | _data_checked = false; | ||
364 | 1398 | _collection_window->PushToBack(); | ||
365 | 1399 | _collection_window->EnableInputWindow(false, "DNDCollectionWindow"); | ||
366 | 1400 | |||
367 | 1401 | if (IsOverlayOpen() && !_hovered) | ||
368 | 1402 | DesaturateIcons(); | ||
369 | 1403 | |||
370 | 1404 | DndReset(); | ||
371 | 1405 | _hide_machine.SetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE, false); | ||
372 | 1406 | _hide_machine.SetQuirk(LauncherHideMachine::DND_PUSHED_OFF, false); | ||
373 | 1407 | #endif | ||
374 | 1408 | return false; | ||
375 | 1409 | } | ||
376 | 1410 | |||
377 | 1411 | void Launcher::DndTimeoutSetup() | ||
378 | 1412 | { | ||
379 | 1413 | #ifdef USE_X11 | ||
380 | 1414 | if (sources_.GetSource(DND_CHECK_TIMEOUT)) | ||
381 | 1415 | return; | ||
382 | 1416 | |||
383 | 1417 | auto cb_func = sigc::mem_fun(this, &Launcher::OnUpdateDragManagerTimeout); | ||
384 | 1418 | sources_.AddTimeout(200, cb_func, DND_CHECK_TIMEOUT); | ||
385 | 1419 | #endif | ||
386 | 1420 | } | ||
387 | 1421 | |||
388 | 1422 | void Launcher::OnPluginStateChanged() | 1370 | void Launcher::OnPluginStateChanged() |
389 | 1423 | { | 1371 | { |
390 | 1424 | WindowManager& wm = WindowManager::Default(); | 1372 | WindowManager& wm = WindowManager::Default(); |
391 | @@ -2566,53 +2514,6 @@ | |||
392 | 2566 | return (boost::algorithm::ends_with(uri, ".desktop") || uri.find("device://") == 0); | 2514 | return (boost::algorithm::ends_with(uri, ".desktop") || uri.find("device://") == 0); |
393 | 2567 | } | 2515 | } |
394 | 2568 | 2516 | ||
395 | 2569 | void Launcher::OnDNDDataCollected(const std::list<char*>& mimes) | ||
396 | 2570 | { | ||
397 | 2571 | #ifdef USE_X11 | ||
398 | 2572 | _dnd_data.Reset(); | ||
399 | 2573 | |||
400 | 2574 | const std::string uri_list = "text/uri-list"; | ||
401 | 2575 | auto& display = nux::GetWindowThread()->GetGraphicsDisplay(); | ||
402 | 2576 | |||
403 | 2577 | for (auto const& mime : mimes) | ||
404 | 2578 | { | ||
405 | 2579 | if (mime != uri_list) | ||
406 | 2580 | continue; | ||
407 | 2581 | |||
408 | 2582 | _dnd_data.Fill(display.GetDndData(const_cast<char*>(uri_list.c_str()))); | ||
409 | 2583 | break; | ||
410 | 2584 | } | ||
411 | 2585 | |||
412 | 2586 | _hide_machine.SetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE, true); | ||
413 | 2587 | |||
414 | 2588 | auto const& uris = _dnd_data.Uris(); | ||
415 | 2589 | if (std::find_if(uris.begin(), uris.end(), [this] (std::string const& uri) | ||
416 | 2590 | {return DndIsSpecialRequest(uri);}) != uris.end()) | ||
417 | 2591 | { | ||
418 | 2592 | _steal_drag = true; | ||
419 | 2593 | |||
420 | 2594 | if (IsOverlayOpen()) | ||
421 | 2595 | SaturateIcons(); | ||
422 | 2596 | } | ||
423 | 2597 | else | ||
424 | 2598 | { | ||
425 | 2599 | for (auto const& it : *_model) | ||
426 | 2600 | { | ||
427 | 2601 | if (it->ShouldHighlightOnDrag(_dnd_data)) | ||
428 | 2602 | { | ||
429 | 2603 | it->SetQuirk(AbstractLauncherIcon::Quirk::DESAT, false); | ||
430 | 2604 | it->SetQuirk(AbstractLauncherIcon::Quirk::PRESENTED, true); | ||
431 | 2605 | } | ||
432 | 2606 | else | ||
433 | 2607 | { | ||
434 | 2608 | it->SetQuirk(AbstractLauncherIcon::Quirk::DESAT, true); | ||
435 | 2609 | it->SetQuirk(AbstractLauncherIcon::Quirk::PRESENTED, false); | ||
436 | 2610 | } | ||
437 | 2611 | } | ||
438 | 2612 | } | ||
439 | 2613 | #endif | ||
440 | 2614 | } | ||
441 | 2615 | |||
442 | 2616 | void Launcher::ProcessDndEnter() | 2517 | void Launcher::ProcessDndEnter() |
443 | 2617 | { | 2518 | { |
444 | 2618 | #ifdef USE_X11 | 2519 | #ifdef USE_X11 |
445 | @@ -2648,7 +2549,7 @@ | |||
446 | 2648 | it->SetQuirk(AbstractLauncherIcon::Quirk::DESAT, is_overlay_open && !_hovered); | 2549 | it->SetQuirk(AbstractLauncherIcon::Quirk::DESAT, is_overlay_open && !_hovered); |
447 | 2649 | } | 2550 | } |
448 | 2650 | 2551 | ||
450 | 2651 | it->SetQuirk(AbstractLauncherIcon::Quirk::PRESENTED, false); | 2552 | it->SetQuirk(AbstractLauncherIcon::Quirk::UNFOLDED, false); |
451 | 2652 | } | 2553 | } |
452 | 2653 | 2554 | ||
453 | 2654 | DndHoveredIconReset(); | 2555 | DndHoveredIconReset(); |
454 | @@ -2873,5 +2774,69 @@ | |||
455 | 2873 | return _launcher_drag_delta; | 2774 | return _launcher_drag_delta; |
456 | 2874 | } | 2775 | } |
457 | 2875 | 2776 | ||
458 | 2777 | void Launcher::DndStarted(std::string const& data) | ||
459 | 2778 | { | ||
460 | 2779 | #ifdef USE_X11 | ||
461 | 2780 | SetDndQuirk(); | ||
462 | 2781 | |||
463 | 2782 | _dnd_data.Fill(data.c_str()); | ||
464 | 2783 | |||
465 | 2784 | auto const& uris = _dnd_data.Uris(); | ||
466 | 2785 | if (std::find_if(uris.begin(), uris.end(), [this] (std::string const& uri) | ||
467 | 2786 | {return DndIsSpecialRequest(uri);}) != uris.end()) | ||
468 | 2787 | { | ||
469 | 2788 | _steal_drag = true; | ||
470 | 2789 | |||
471 | 2790 | if (IsOverlayOpen()) | ||
472 | 2791 | SaturateIcons(); | ||
473 | 2792 | } | ||
474 | 2793 | else | ||
475 | 2794 | { | ||
476 | 2795 | for (auto const& it : *_model) | ||
477 | 2796 | { | ||
478 | 2797 | if (it->ShouldHighlightOnDrag(_dnd_data)) | ||
479 | 2798 | { | ||
480 | 2799 | it->SetQuirk(AbstractLauncherIcon::Quirk::DESAT, false); | ||
481 | 2800 | it->SetQuirk(AbstractLauncherIcon::Quirk::UNFOLDED, true); | ||
482 | 2801 | } | ||
483 | 2802 | else | ||
484 | 2803 | { | ||
485 | 2804 | it->SetQuirk(AbstractLauncherIcon::Quirk::DESAT, true); | ||
486 | 2805 | it->SetQuirk(AbstractLauncherIcon::Quirk::UNFOLDED, false); | ||
487 | 2806 | } | ||
488 | 2807 | } | ||
489 | 2808 | } | ||
490 | 2809 | #endif | ||
491 | 2810 | } | ||
492 | 2811 | |||
493 | 2812 | void Launcher::DndFinished() | ||
494 | 2813 | { | ||
495 | 2814 | #ifdef USE_X11 | ||
496 | 2815 | UnsetDndQuirk(); | ||
497 | 2816 | |||
498 | 2817 | _data_checked = false; | ||
499 | 2818 | |||
500 | 2819 | if (IsOverlayOpen() && !_hovered) | ||
501 | 2820 | DesaturateIcons(); | ||
502 | 2821 | |||
503 | 2822 | DndReset(); | ||
504 | 2823 | #endif | ||
505 | 2824 | } | ||
506 | 2825 | |||
507 | 2826 | void Launcher::SetDndQuirk() | ||
508 | 2827 | { | ||
509 | 2828 | #ifdef USE_X11 | ||
510 | 2829 | _hide_machine.SetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE, true); | ||
511 | 2830 | #endif | ||
512 | 2831 | } | ||
513 | 2832 | |||
514 | 2833 | void Launcher::UnsetDndQuirk() | ||
515 | 2834 | { | ||
516 | 2835 | #ifdef USE_X11 | ||
517 | 2836 | _hide_machine.SetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE, false); | ||
518 | 2837 | _hide_machine.SetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE, false); | ||
519 | 2838 | #endif | ||
520 | 2839 | } | ||
521 | 2840 | |||
522 | 2876 | } // namespace launcher | 2841 | } // namespace launcher |
523 | 2877 | } // namespace unity | 2842 | } // namespace unity |
524 | 2878 | 2843 | ||
525 | === modified file 'launcher/Launcher.h' | |||
526 | --- launcher/Launcher.h 2012-11-13 22:39:49 +0000 | |||
527 | +++ launcher/Launcher.h 2012-11-24 14:30:27 +0000 | |||
528 | @@ -32,7 +32,6 @@ | |||
529 | 32 | #include "unity-shared/AbstractIconRenderer.h" | 32 | #include "unity-shared/AbstractIconRenderer.h" |
530 | 33 | #include "unity-shared/BackgroundEffectHelper.h" | 33 | #include "unity-shared/BackgroundEffectHelper.h" |
531 | 34 | #include "DevicesSettings.h" | 34 | #include "DevicesSettings.h" |
532 | 35 | #include "DNDCollectionWindow.h" | ||
533 | 36 | #include "DndData.h" | 35 | #include "DndData.h" |
534 | 37 | #include "unity-shared/Introspectable.h" | 36 | #include "unity-shared/Introspectable.h" |
535 | 38 | #include "LauncherModel.h" | 37 | #include "LauncherModel.h" |
536 | @@ -66,7 +65,7 @@ | |||
537 | 66 | NUX_DECLARE_OBJECT_TYPE(Launcher, nux::View); | 65 | NUX_DECLARE_OBJECT_TYPE(Launcher, nux::View); |
538 | 67 | public: | 66 | public: |
539 | 68 | 67 | ||
541 | 69 | Launcher(nux::BaseWindow* parent, nux::ObjectPtr<DNDCollectionWindow> const& collection_window, NUX_FILE_LINE_PROTO); | 68 | Launcher(nux::BaseWindow* parent, NUX_FILE_LINE_PROTO); |
542 | 70 | 69 | ||
543 | 71 | nux::Property<Display*> display; | 70 | nux::Property<Display*> display; |
544 | 72 | nux::Property<int> monitor; | 71 | nux::Property<int> monitor; |
545 | @@ -127,6 +126,11 @@ | |||
546 | 127 | int GetDragDelta() const; | 126 | int GetDragDelta() const; |
547 | 128 | void SetHover(bool hovered); | 127 | void SetHover(bool hovered); |
548 | 129 | 128 | ||
549 | 129 | void DndStarted(std::string const& mimes); | ||
550 | 130 | void DndFinished(); | ||
551 | 131 | void SetDndQuirk(); | ||
552 | 132 | void UnsetDndQuirk(); | ||
553 | 133 | |||
554 | 130 | sigc::signal<void, std::string const&, AbstractLauncherIcon::Ptr const&> add_request; | 134 | sigc::signal<void, std::string const&, AbstractLauncherIcon::Ptr const&> add_request; |
555 | 131 | sigc::signal<void, AbstractLauncherIcon::Ptr const&> remove_request; | 135 | sigc::signal<void, AbstractLauncherIcon::Ptr const&> remove_request; |
556 | 132 | sigc::signal<void> selection_change; | 136 | sigc::signal<void> selection_change; |
557 | @@ -213,7 +217,6 @@ | |||
558 | 213 | bool StrutHack(); | 217 | bool StrutHack(); |
559 | 214 | bool StartIconDragTimeout(int x, int y); | 218 | bool StartIconDragTimeout(int x, int y); |
560 | 215 | bool OnScrollTimeout(); | 219 | bool OnScrollTimeout(); |
561 | 216 | bool OnUpdateDragManagerTimeout(); | ||
562 | 217 | 220 | ||
563 | 218 | void SetMousePosition(int x, int y); | 221 | void SetMousePosition(int x, int y); |
564 | 219 | 222 | ||
565 | @@ -248,6 +251,7 @@ | |||
566 | 248 | float DragOutProgress(struct timespec const& current) const; | 251 | float DragOutProgress(struct timespec const& current) const; |
567 | 249 | float IconDesatValue(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const; | 252 | float IconDesatValue(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const; |
568 | 250 | float IconPresentProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const; | 253 | float IconPresentProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const; |
569 | 254 | float IconUnfoldProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const; | ||
570 | 251 | float IconUrgentProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const; | 255 | float IconUrgentProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const; |
571 | 252 | float IconShimmerProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const; | 256 | float IconShimmerProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const; |
572 | 253 | float IconUrgentPulseValue(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const; | 257 | float IconUrgentPulseValue(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const; |
573 | @@ -322,12 +326,8 @@ | |||
574 | 322 | 326 | ||
575 | 323 | virtual long PostLayoutManagement(long LayoutResult); | 327 | virtual long PostLayoutManagement(long LayoutResult); |
576 | 324 | 328 | ||
577 | 325 | void OnDisplayChanged(Display* display); | ||
578 | 326 | void OnDNDDataCollected(const std::list<char*>& mimes); | ||
579 | 327 | |||
580 | 328 | void DndReset(); | 329 | void DndReset(); |
581 | 329 | void DndHoveredIconReset(); | 330 | void DndHoveredIconReset(); |
582 | 330 | void DndTimeoutSetup(); | ||
583 | 331 | bool DndIsSpecialRequest(std::string const& uri) const; | 331 | bool DndIsSpecialRequest(std::string const& uri) const; |
584 | 332 | 332 | ||
585 | 333 | LauncherModel::Ptr _model; | 333 | LauncherModel::Ptr _model; |
586 | @@ -383,7 +383,6 @@ | |||
587 | 383 | nux::Point2 _mouse_position; | 383 | nux::Point2 _mouse_position; |
588 | 384 | nux::ObjectPtr<nux::IOpenGLBaseTexture> _offscreen_drag_texture; | 384 | nux::ObjectPtr<nux::IOpenGLBaseTexture> _offscreen_drag_texture; |
589 | 385 | nux::ObjectPtr<LauncherDragWindow> _drag_window; | 385 | nux::ObjectPtr<LauncherDragWindow> _drag_window; |
590 | 386 | nux::ObjectPtr<unity::DNDCollectionWindow> _collection_window; | ||
591 | 387 | LauncherHideMachine _hide_machine; | 386 | LauncherHideMachine _hide_machine; |
592 | 388 | LauncherHoverMachine _hover_machine; | 387 | LauncherHoverMachine _hover_machine; |
593 | 389 | 388 | ||
594 | 390 | 389 | ||
595 | === modified file 'launcher/LauncherController.cpp' | |||
596 | --- launcher/LauncherController.cpp 2012-11-15 17:56:23 +0000 | |||
597 | +++ launcher/LauncherController.cpp 2012-11-24 14:30:27 +0000 | |||
598 | @@ -95,10 +95,11 @@ | |||
599 | 95 | { Controller::Impl::OnDBusMethodCall, NULL, NULL}; | 95 | { Controller::Impl::OnDBusMethodCall, NULL, NULL}; |
600 | 96 | 96 | ||
601 | 97 | 97 | ||
603 | 98 | Controller::Impl::Impl(Controller* parent) | 98 | Controller::Impl::Impl(Controller* parent, XdndManager::Ptr const& xdnd_manager) |
604 | 99 | : parent_(parent) | 99 | : parent_(parent) |
605 | 100 | , model_(std::make_shared<LauncherModel>()) | 100 | , model_(std::make_shared<LauncherModel>()) |
606 | 101 | , matcher_(bamf_matcher_get_default()) | 101 | , matcher_(bamf_matcher_get_default()) |
607 | 102 | , xdnd_manager_(xdnd_manager) | ||
608 | 102 | , device_section_(std::make_shared<VolumeMonitorWrapper>(), std::make_shared<DevicesSettingsImp>()) | 103 | , device_section_(std::make_shared<VolumeMonitorWrapper>(), std::make_shared<DevicesSettingsImp>()) |
609 | 103 | , expo_icon_(new ExpoLauncherIcon()) | 104 | , expo_icon_(new ExpoLauncherIcon()) |
610 | 104 | , desktop_icon_(new DesktopLauncherIcon()) | 105 | , desktop_icon_(new DesktopLauncherIcon()) |
611 | @@ -161,6 +162,10 @@ | |||
612 | 161 | }); | 162 | }); |
613 | 162 | 163 | ||
614 | 163 | parent_->AddChild(model_.get()); | 164 | parent_->AddChild(model_.get()); |
615 | 165 | |||
616 | 166 | xdnd_manager_->dnd_started.connect(sigc::mem_fun(this, &Impl::OnDndStarted)); | ||
617 | 167 | xdnd_manager_->dnd_finished.connect(sigc::mem_fun(this, &Impl::OnDndFinished)); | ||
618 | 168 | xdnd_manager_->monitor_changed.connect(sigc::mem_fun(this, &Impl::OnDndMonitorChanged)); | ||
619 | 164 | } | 169 | } |
620 | 165 | 170 | ||
621 | 166 | Controller::Impl::~Impl() | 171 | Controller::Impl::~Impl() |
622 | @@ -255,11 +260,47 @@ | |||
623 | 255 | } | 260 | } |
624 | 256 | } | 261 | } |
625 | 257 | 262 | ||
626 | 263 | void Controller::Impl::OnDndStarted(std::string const& data, int monitor) | ||
627 | 264 | { | ||
628 | 265 | if (parent_->multiple_launchers) | ||
629 | 266 | { | ||
630 | 267 | last_dnd_monitor_ = monitor; | ||
631 | 268 | launchers[last_dnd_monitor_]->DndStarted(data); | ||
632 | 269 | } | ||
633 | 270 | else | ||
634 | 271 | { | ||
635 | 272 | launcher_->DndStarted(data); | ||
636 | 273 | } | ||
637 | 274 | } | ||
638 | 275 | |||
639 | 276 | void Controller::Impl::OnDndFinished() | ||
640 | 277 | { | ||
641 | 278 | if (parent_->multiple_launchers) | ||
642 | 279 | { | ||
643 | 280 | launchers[last_dnd_monitor_]->DndFinished(); | ||
644 | 281 | last_dnd_monitor_ = -1; | ||
645 | 282 | } | ||
646 | 283 | else | ||
647 | 284 | { | ||
648 | 285 | launcher_->DndFinished(); | ||
649 | 286 | } | ||
650 | 287 | } | ||
651 | 288 | |||
652 | 289 | void Controller::Impl::OnDndMonitorChanged(int monitor) | ||
653 | 290 | { | ||
654 | 291 | if (parent_->multiple_launchers) | ||
655 | 292 | { | ||
656 | 293 | launchers[last_dnd_monitor_]->UnsetDndQuirk(); | ||
657 | 294 | last_dnd_monitor_ = monitor; | ||
658 | 295 | launchers[last_dnd_monitor_]->SetDndQuirk(); | ||
659 | 296 | } | ||
660 | 297 | } | ||
661 | 298 | |||
662 | 258 | Launcher* Controller::Impl::CreateLauncher(int monitor) | 299 | Launcher* Controller::Impl::CreateLauncher(int monitor) |
663 | 259 | { | 300 | { |
664 | 260 | nux::BaseWindow* launcher_window = new nux::BaseWindow(TEXT("LauncherWindow")); | 301 | nux::BaseWindow* launcher_window = new nux::BaseWindow(TEXT("LauncherWindow")); |
665 | 261 | 302 | ||
667 | 262 | Launcher* launcher = new Launcher(launcher_window, nux::ObjectPtr<DNDCollectionWindow>(new DNDCollectionWindow)); | 303 | Launcher* launcher = new Launcher(launcher_window); |
668 | 263 | launcher->monitor = monitor; | 304 | launcher->monitor = monitor; |
669 | 264 | launcher->options = parent_->options(); | 305 | launcher->options = parent_->options(); |
670 | 265 | launcher->SetModel(model_); | 306 | launcher->SetModel(model_); |
671 | @@ -974,10 +1015,10 @@ | |||
672 | 974 | g_variant_new("(sus)", "home.lens", dash::NOT_HANDLED, "")); | 1015 | g_variant_new("(sus)", "home.lens", dash::NOT_HANDLED, "")); |
673 | 975 | } | 1016 | } |
674 | 976 | 1017 | ||
676 | 977 | Controller::Controller() | 1018 | Controller::Controller(XdndManager::Ptr const& xdnd_manager) |
677 | 978 | : options(Options::Ptr(new Options())) | 1019 | : options(Options::Ptr(new Options())) |
678 | 979 | , multiple_launchers(true) | 1020 | , multiple_launchers(true) |
680 | 980 | , pimpl(new Impl(this)) | 1021 | , pimpl(new Impl(this, xdnd_manager)) |
681 | 981 | { | 1022 | { |
682 | 982 | multiple_launchers.changed.connect([&](bool value) -> void { | 1023 | multiple_launchers.changed.connect([&](bool value) -> void { |
683 | 983 | UScreen* uscreen = UScreen::GetDefault(); | 1024 | UScreen* uscreen = UScreen::GetDefault(); |
684 | 984 | 1025 | ||
685 | === modified file 'launcher/LauncherController.h' | |||
686 | --- launcher/LauncherController.h 2012-11-06 18:19:09 +0000 | |||
687 | +++ launcher/LauncherController.h 2012-11-24 14:30:27 +0000 | |||
688 | @@ -27,6 +27,7 @@ | |||
689 | 27 | 27 | ||
690 | 28 | #include "LauncherOptions.h" | 28 | #include "LauncherOptions.h" |
691 | 29 | #include "SoftwareCenterLauncherIcon.h" | 29 | #include "SoftwareCenterLauncherIcon.h" |
692 | 30 | #include "XdndManager.h" | ||
693 | 30 | 31 | ||
694 | 31 | namespace unity | 32 | namespace unity |
695 | 32 | { | 33 | { |
696 | @@ -47,7 +48,7 @@ | |||
697 | 47 | nux::Property<Options::Ptr> options; | 48 | nux::Property<Options::Ptr> options; |
698 | 48 | nux::Property<bool> multiple_launchers; | 49 | nux::Property<bool> multiple_launchers; |
699 | 49 | 50 | ||
701 | 50 | Controller(); | 51 | Controller(XdndManager::Ptr const& xdnd_manager); |
702 | 51 | ~Controller(); | 52 | ~Controller(); |
703 | 52 | 53 | ||
704 | 53 | Launcher& launcher() const; | 54 | Launcher& launcher() const; |
705 | 54 | 55 | ||
706 | === modified file 'launcher/LauncherControllerPrivate.h' | |||
707 | --- launcher/LauncherControllerPrivate.h 2012-11-15 17:56:23 +0000 | |||
708 | +++ launcher/LauncherControllerPrivate.h 2012-11-24 14:30:27 +0000 | |||
709 | @@ -39,6 +39,7 @@ | |||
710 | 39 | #include "SoftwareCenterLauncherIcon.h" | 39 | #include "SoftwareCenterLauncherIcon.h" |
711 | 40 | #include "unity-shared/UBusWrapper.h" | 40 | #include "unity-shared/UBusWrapper.h" |
712 | 41 | #include "VolumeMonitorWrapper.h" | 41 | #include "VolumeMonitorWrapper.h" |
713 | 42 | #include "XdndManager.h" | ||
714 | 42 | 43 | ||
715 | 43 | namespace unity | 44 | namespace unity |
716 | 44 | { | 45 | { |
717 | @@ -48,7 +49,7 @@ | |||
718 | 48 | class Controller::Impl | 49 | class Controller::Impl |
719 | 49 | { | 50 | { |
720 | 50 | public: | 51 | public: |
722 | 51 | Impl(Controller* parent); | 52 | Impl(Controller* parent, XdndManager::Ptr const& xdnd_manager); |
723 | 52 | ~Impl(); | 53 | ~Impl(); |
724 | 53 | 54 | ||
725 | 54 | void UpdateNumWorkspaces(int workspaces); | 55 | void UpdateNumWorkspaces(int workspaces); |
726 | @@ -111,6 +112,10 @@ | |||
727 | 111 | 112 | ||
728 | 112 | void OpenQuicklist(); | 113 | void OpenQuicklist(); |
729 | 113 | 114 | ||
730 | 115 | void OnDndStarted(std::string const& data, int monitor); | ||
731 | 116 | void OnDndFinished(); | ||
732 | 117 | void OnDndMonitorChanged(int monitor); | ||
733 | 118 | |||
734 | 114 | static void OnBusAcquired(GDBusConnection* connection, const gchar* name, gpointer user_data); | 119 | static void OnBusAcquired(GDBusConnection* connection, const gchar* name, gpointer user_data); |
735 | 115 | static void OnDBusMethodCall(GDBusConnection* connection, const gchar* sender, const gchar* object_path, | 120 | static void OnDBusMethodCall(GDBusConnection* connection, const gchar* sender, const gchar* object_path, |
736 | 116 | const gchar* interface_name, const gchar* method_name, | 121 | const gchar* interface_name, const gchar* method_name, |
737 | @@ -124,6 +129,7 @@ | |||
738 | 124 | glib::Object<BamfMatcher> matcher_; | 129 | glib::Object<BamfMatcher> matcher_; |
739 | 125 | nux::ObjectPtr<Launcher> launcher_; | 130 | nux::ObjectPtr<Launcher> launcher_; |
740 | 126 | nux::ObjectPtr<Launcher> keyboard_launcher_; | 131 | nux::ObjectPtr<Launcher> keyboard_launcher_; |
741 | 132 | XdndManager::Ptr xdnd_manager_; | ||
742 | 127 | DeviceLauncherSection device_section_; | 133 | DeviceLauncherSection device_section_; |
743 | 128 | LauncherEntryRemoteModel remote_model_; | 134 | LauncherEntryRemoteModel remote_model_; |
744 | 129 | AbstractLauncherIcon::Ptr expo_icon_; | 135 | AbstractLauncherIcon::Ptr expo_icon_; |
745 | @@ -143,6 +149,7 @@ | |||
746 | 143 | int reactivate_index; | 149 | int reactivate_index; |
747 | 144 | bool keynav_restore_window_; | 150 | bool keynav_restore_window_; |
748 | 145 | int launcher_key_press_time_; | 151 | int launcher_key_press_time_; |
749 | 152 | int last_dnd_monitor_; | ||
750 | 146 | 153 | ||
751 | 147 | unsigned dbus_owner_; | 154 | unsigned dbus_owner_; |
752 | 148 | GDBusConnection* gdbus_connection_; | 155 | GDBusConnection* gdbus_connection_; |
753 | 149 | 156 | ||
754 | === modified file 'launcher/LauncherIcon.cpp' | |||
755 | --- launcher/LauncherIcon.cpp 2012-11-15 17:56:23 +0000 | |||
756 | +++ launcher/LauncherIcon.cpp 2012-11-24 14:30:27 +0000 | |||
757 | @@ -801,6 +801,7 @@ | |||
758 | 801 | 801 | ||
759 | 802 | _present_urgency = CLAMP(present_urgency, 0.0f, 1.0f); | 802 | _present_urgency = CLAMP(present_urgency, 0.0f, 1.0f); |
760 | 803 | SetQuirk(Quirk::PRESENTED, true); | 803 | SetQuirk(Quirk::PRESENTED, true); |
761 | 804 | SetQuirk(Quirk::UNFOLDED, true); | ||
762 | 804 | } | 805 | } |
763 | 805 | 806 | ||
764 | 806 | void | 807 | void |
765 | @@ -811,6 +812,7 @@ | |||
766 | 811 | 812 | ||
767 | 812 | _source_manager.Remove(PRESENT_TIMEOUT); | 813 | _source_manager.Remove(PRESENT_TIMEOUT); |
768 | 813 | SetQuirk(Quirk::PRESENTED, false); | 814 | SetQuirk(Quirk::PRESENTED, false); |
769 | 815 | SetQuirk(Quirk::UNFOLDED, false); | ||
770 | 814 | } | 816 | } |
771 | 815 | 817 | ||
772 | 816 | void | 818 | void |
773 | 817 | 819 | ||
774 | === modified file 'launcher/StandaloneLauncher.cpp' | |||
775 | --- launcher/StandaloneLauncher.cpp 2012-10-17 22:16:48 +0000 | |||
776 | +++ launcher/StandaloneLauncher.cpp 2012-11-24 14:30:27 +0000 | |||
777 | @@ -35,8 +35,8 @@ | |||
778 | 35 | 35 | ||
779 | 36 | void ThreadWidgetInit(nux::NThread* thread, void* InitData) | 36 | void ThreadWidgetInit(nux::NThread* thread, void* InitData) |
780 | 37 | { | 37 | { |
783 | 38 | // launcherWindow->SetGeometry (nux::Geometry(0, 0, 300, 800)); | 38 | auto xdnd_manager = std::make_shared<XdndManager>(); |
784 | 39 | controller.reset(new launcher::Controller()); | 39 | controller = std::make_shared<launcher::Controller>(xdnd_manager); |
785 | 40 | } | 40 | } |
786 | 41 | 41 | ||
787 | 42 | int main(int argc, char** argv) | 42 | int main(int argc, char** argv) |
788 | 43 | 43 | ||
789 | === added file 'launcher/XdndCollectionWindow.h' | |||
790 | --- launcher/XdndCollectionWindow.h 1970-01-01 00:00:00 +0000 | |||
791 | +++ launcher/XdndCollectionWindow.h 2012-11-24 14:30:27 +0000 | |||
792 | @@ -0,0 +1,51 @@ | |||
793 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
794 | 2 | /* | ||
795 | 3 | * Copyright (C) 2012 Canonical Ltd | ||
796 | 4 | * | ||
797 | 5 | * This program is free software: you can redistribute it and/or modify | ||
798 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
799 | 7 | * published by the Free Software Foundation. | ||
800 | 8 | * | ||
801 | 9 | * This program is distributed in the hope that it will be useful, | ||
802 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
803 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
804 | 12 | * GNU General Public License for more details. | ||
805 | 13 | * | ||
806 | 14 | * You should have received a copy of the GNU General Public License | ||
807 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
808 | 16 | * | ||
809 | 17 | * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
810 | 18 | */ | ||
811 | 19 | |||
812 | 20 | #ifndef UNITYSHELL_XDND_COLLECTION_WINDOW_H | ||
813 | 21 | #define UNITYSHELL_XDND_COLLECTION_WINDOW_H | ||
814 | 22 | |||
815 | 23 | #include <boost/noncopyable.hpp> | ||
816 | 24 | #include <memory> | ||
817 | 25 | #include <sigc++/signal.h> | ||
818 | 26 | #include <string> | ||
819 | 27 | #include <vector> | ||
820 | 28 | |||
821 | 29 | namespace unity { | ||
822 | 30 | |||
823 | 31 | /** | ||
824 | 32 | * XdndCollectionWindow makes it possible to collect drag and drop data as | ||
825 | 33 | * soon as dnd starts and not when the mouse pointer enter the x window. | ||
826 | 34 | **/ | ||
827 | 35 | |||
828 | 36 | class XdndCollectionWindow : boost::noncopyable | ||
829 | 37 | { | ||
830 | 38 | public: | ||
831 | 39 | typedef std::shared_ptr<XdndCollectionWindow> Ptr; | ||
832 | 40 | |||
833 | 41 | virtual ~XdndCollectionWindow() {} | ||
834 | 42 | |||
835 | 43 | virtual void Collect() = 0; | ||
836 | 44 | virtual void Deactivate() = 0; | ||
837 | 45 | |||
838 | 46 | sigc::signal<void, std::vector<std::string>> collected; | ||
839 | 47 | }; | ||
840 | 48 | |||
841 | 49 | } | ||
842 | 50 | |||
843 | 51 | #endif | ||
844 | 0 | 52 | ||
845 | === added file 'launcher/XdndCollectionWindowImp.cpp' | |||
846 | --- launcher/XdndCollectionWindowImp.cpp 1970-01-01 00:00:00 +0000 | |||
847 | +++ launcher/XdndCollectionWindowImp.cpp 2012-11-24 14:30:27 +0000 | |||
848 | @@ -0,0 +1,112 @@ | |||
849 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
850 | 2 | /* | ||
851 | 3 | * Copyright (C) 2011 Canonical Ltd | ||
852 | 4 | * | ||
853 | 5 | * This program is free software: you can redistribute it and/or modify | ||
854 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
855 | 7 | * published by the Free Software Foundation. | ||
856 | 8 | * | ||
857 | 9 | * This program is distributed in the hope that it will be useful, | ||
858 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
859 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
860 | 12 | * GNU General Public License for more details. | ||
861 | 13 | * | ||
862 | 14 | * You should have received a copy of the GNU General Public License | ||
863 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
864 | 16 | * | ||
865 | 17 | * Authored by: Andrea Azzarone <azzaronea@gmail.com> | ||
866 | 18 | */ | ||
867 | 19 | |||
868 | 20 | #include "XdndCollectionWindowImp.h" | ||
869 | 21 | #include "unity-shared/UScreen.h" | ||
870 | 22 | #include "unity-shared/WindowManager.h" | ||
871 | 23 | |||
872 | 24 | namespace unity { | ||
873 | 25 | namespace { | ||
874 | 26 | |||
875 | 27 | class PrivateWindow : public nux::BaseWindow | ||
876 | 28 | { | ||
877 | 29 | public: | ||
878 | 30 | PrivateWindow(XdndCollectionWindowImp* parent) | ||
879 | 31 | : nux::BaseWindow("") | ||
880 | 32 | , parent_(parent) | ||
881 | 33 | { | ||
882 | 34 | // Make it invisible... | ||
883 | 35 | SetBackgroundColor(nux::color::Transparent); | ||
884 | 36 | SetOpacity(0.0f); | ||
885 | 37 | // ... and as big as the whole screen. | ||
886 | 38 | auto uscreen = UScreen::GetDefault(); | ||
887 | 39 | SetGeometry(uscreen->GetScreenGeometry()); | ||
888 | 40 | |||
889 | 41 | ShowWindow(true); | ||
890 | 42 | PushToBack(); | ||
891 | 43 | // Hack to create the X Window as soon as possible. | ||
892 | 44 | EnableInputWindow(true, "XdndCollectionWindowImp"); | ||
893 | 45 | EnableInputWindow(false, "XdndCollectionWindowImp"); | ||
894 | 46 | SetDndEnabled(false, true); | ||
895 | 47 | |||
896 | 48 | uscreen->changed.connect(sigc::mem_fun(this, &PrivateWindow::OnScreenChanged)); | ||
897 | 49 | WindowManager::Default().window_moved.connect(sigc::mem_fun(this, &PrivateWindow::OnWindowMoved)); | ||
898 | 50 | } | ||
899 | 51 | |||
900 | 52 | void OnScreenChanged(int /*primary*/, std::vector<nux::Geometry>& /*monitors*/) | ||
901 | 53 | { | ||
902 | 54 | auto uscreen = UScreen::GetDefault(); | ||
903 | 55 | SetGeometry(uscreen->GetScreenGeometry()); | ||
904 | 56 | } | ||
905 | 57 | |||
906 | 58 | /** | ||
907 | 59 | * EnableInputWindow doesn't show the window immediately. | ||
908 | 60 | * Since nux::EnableInputWindow uses XMoveResizeWindow the best way to know if | ||
909 | 61 | * the X Window is really on/off screen is receiving WindowManager::window_moved | ||
910 | 62 | * signal. Please don't hate me! | ||
911 | 63 | **/ | ||
912 | 64 | void OnWindowMoved(Window window_id) | ||
913 | 65 | { | ||
914 | 66 | if (G_LIKELY(window_id != GetInputWindowId())) | ||
915 | 67 | return; | ||
916 | 68 | |||
917 | 69 | // Create a fake mouse move because sometimes an extra one is required. | ||
918 | 70 | auto display = nux::GetGraphicsDisplay()->GetX11Display(); | ||
919 | 71 | XWarpPointer(display, None, None, 0, 0, 0, 0, 0, 0); | ||
920 | 72 | XFlush(display); | ||
921 | 73 | } | ||
922 | 74 | |||
923 | 75 | void ProcessDndMove(int x, int y, std::list<char*> mimes) | ||
924 | 76 | { | ||
925 | 77 | // Hide the window as soon as possible. | ||
926 | 78 | PushToBack(); | ||
927 | 79 | EnableInputWindow(false, "XdndCollectionWindowImp"); | ||
928 | 80 | |||
929 | 81 | std::vector<std::string> data; | ||
930 | 82 | for (auto mime : mimes) | ||
931 | 83 | if (mime) data.push_back(mime); | ||
932 | 84 | |||
933 | 85 | parent_->collected.emit(data); | ||
934 | 86 | } | ||
935 | 87 | |||
936 | 88 | XdndCollectionWindowImp* parent_; | ||
937 | 89 | }; | ||
938 | 90 | |||
939 | 91 | } | ||
940 | 92 | |||
941 | 93 | XdndCollectionWindowImp::XdndCollectionWindowImp() | ||
942 | 94 | : window_(new PrivateWindow(this)) | ||
943 | 95 | {} | ||
944 | 96 | |||
945 | 97 | void XdndCollectionWindowImp::Collect() | ||
946 | 98 | { | ||
947 | 99 | // Using PushToFront we're sure that the window is shown over the panel window, | ||
948 | 100 | // the launcher window and the dash window. Don't forget to call PushToBack as | ||
949 | 101 | // soon as possible. | ||
950 | 102 | window_->PushToFront(); | ||
951 | 103 | window_->EnableInputWindow(true, "XdndCollectionWindowImp"); | ||
952 | 104 | } | ||
953 | 105 | |||
954 | 106 | void XdndCollectionWindowImp::Deactivate() | ||
955 | 107 | { | ||
956 | 108 | window_->PushToBack(); | ||
957 | 109 | window_->EnableInputWindow(false, "XdndCollectionWindowImp"); | ||
958 | 110 | } | ||
959 | 111 | |||
960 | 112 | } | ||
961 | 0 | 113 | ||
962 | === added file 'launcher/XdndCollectionWindowImp.h' | |||
963 | --- launcher/XdndCollectionWindowImp.h 1970-01-01 00:00:00 +0000 | |||
964 | +++ launcher/XdndCollectionWindowImp.h 2012-11-24 14:30:27 +0000 | |||
965 | @@ -0,0 +1,44 @@ | |||
966 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
967 | 2 | /* | ||
968 | 3 | * Copyright (C) 2011-2012 Canonical Ltd | ||
969 | 4 | * | ||
970 | 5 | * This program is free software: you can redistribute it and/or modify | ||
971 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
972 | 7 | * published by the Free Software Foundation. | ||
973 | 8 | * | ||
974 | 9 | * This program is distributed in the hope that it will be useful, | ||
975 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
976 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
977 | 12 | * GNU General Public License for more details. | ||
978 | 13 | * | ||
979 | 14 | * You should have received a copy of the GNU General Public License | ||
980 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
981 | 16 | * | ||
982 | 17 | * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
983 | 18 | */ | ||
984 | 19 | |||
985 | 20 | #ifndef UNITYSHELL_XDND_COLLECTION_WINDOW_IMP_H | ||
986 | 21 | #define UNITYSHELL_XDND_COLLECTION_WINDOW_IMP_H | ||
987 | 22 | |||
988 | 23 | #include "XdndCollectionWindow.h" | ||
989 | 24 | |||
990 | 25 | #include <Nux/Nux.h> | ||
991 | 26 | #include <Nux/BaseWindow.h> | ||
992 | 27 | |||
993 | 28 | namespace unity { | ||
994 | 29 | |||
995 | 30 | class XdndCollectionWindowImp : public XdndCollectionWindow | ||
996 | 31 | { | ||
997 | 32 | public: | ||
998 | 33 | XdndCollectionWindowImp(); | ||
999 | 34 | |||
1000 | 35 | void Collect(); | ||
1001 | 36 | void Deactivate(); | ||
1002 | 37 | |||
1003 | 38 | private: | ||
1004 | 39 | nux::ObjectPtr<nux::BaseWindow> window_; | ||
1005 | 40 | }; | ||
1006 | 41 | |||
1007 | 42 | } | ||
1008 | 43 | |||
1009 | 44 | #endif | ||
1010 | 0 | 45 | ||
1011 | === added file 'launcher/XdndManager.h' | |||
1012 | --- launcher/XdndManager.h 1970-01-01 00:00:00 +0000 | |||
1013 | +++ launcher/XdndManager.h 2012-11-24 14:30:27 +0000 | |||
1014 | @@ -0,0 +1,43 @@ | |||
1015 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
1016 | 2 | /* | ||
1017 | 3 | * Copyright (C) 2012 Canonical Ltd | ||
1018 | 4 | * | ||
1019 | 5 | * This program is free software: you can redistribute it and/or modify | ||
1020 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
1021 | 7 | * published by the Free Software Foundation. | ||
1022 | 8 | * | ||
1023 | 9 | * This program is distributed in the hope that it will be useful, | ||
1024 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1025 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1026 | 12 | * GNU General Public License for more details. | ||
1027 | 13 | * | ||
1028 | 14 | * You should have received a copy of the GNU General Public License | ||
1029 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1030 | 16 | * | ||
1031 | 17 | * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
1032 | 18 | */ | ||
1033 | 19 | |||
1034 | 20 | #ifndef UNITYSHELL_XDND_MANAGER_H | ||
1035 | 21 | #define UNITYSHELL_XDND_MANAGER_H | ||
1036 | 22 | |||
1037 | 23 | #include <boost/noncopyable.hpp> | ||
1038 | 24 | #include <memory> | ||
1039 | 25 | #include <sigc++/signal.h> | ||
1040 | 26 | #include <string> | ||
1041 | 27 | |||
1042 | 28 | namespace unity { | ||
1043 | 29 | |||
1044 | 30 | class XdndManager : boost::noncopyable { | ||
1045 | 31 | public: | ||
1046 | 32 | typedef std::shared_ptr<XdndManager> Ptr; | ||
1047 | 33 | |||
1048 | 34 | virtual ~XdndManager() {} | ||
1049 | 35 | |||
1050 | 36 | sigc::signal<void, std::string, int> dnd_started; | ||
1051 | 37 | sigc::signal<void> dnd_finished; | ||
1052 | 38 | sigc::signal<void, int> monitor_changed; | ||
1053 | 39 | }; | ||
1054 | 40 | |||
1055 | 41 | } | ||
1056 | 42 | |||
1057 | 43 | #endif | ||
1058 | 0 | 44 | ||
1059 | === added file 'launcher/XdndManagerImp.cpp' | |||
1060 | --- launcher/XdndManagerImp.cpp 1970-01-01 00:00:00 +0000 | |||
1061 | +++ launcher/XdndManagerImp.cpp 2012-11-24 14:30:27 +0000 | |||
1062 | @@ -0,0 +1,98 @@ | |||
1063 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
1064 | 2 | /* | ||
1065 | 3 | * Copyright (C) 2012 Canonical Ltd | ||
1066 | 4 | * | ||
1067 | 5 | * This program is free software: you can redistribute it and/or modify | ||
1068 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
1069 | 7 | * published by the Free Software Foundation. | ||
1070 | 8 | * | ||
1071 | 9 | * This program is distributed in the hope that it will be useful, | ||
1072 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1073 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1074 | 12 | * GNU General Public License for more details. | ||
1075 | 13 | * | ||
1076 | 14 | * You should have received a copy of the GNU General Public License | ||
1077 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1078 | 16 | * | ||
1079 | 17 | * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
1080 | 18 | */ | ||
1081 | 19 | |||
1082 | 20 | #include "XdndManagerImp.h" | ||
1083 | 21 | |||
1084 | 22 | #include "unity-shared/UScreen.h" | ||
1085 | 23 | |||
1086 | 24 | namespace unity { | ||
1087 | 25 | |||
1088 | 26 | XdndManagerImp::XdndManagerImp(XdndStartStopNotifier::Ptr const& xdnd_start_stop_notifier, | ||
1089 | 27 | XdndCollectionWindow::Ptr const& xdnd_collection_window) | ||
1090 | 28 | : xdnd_start_stop_notifier_(xdnd_start_stop_notifier) | ||
1091 | 29 | , xdnd_collection_window_(xdnd_collection_window) | ||
1092 | 30 | , last_monitor_(-1) | ||
1093 | 31 | , valid_dnd_in_progress_(false) | ||
1094 | 32 | { | ||
1095 | 33 | xdnd_start_stop_notifier_->started.connect(sigc::mem_fun(this, &XdndManagerImp::OnDndStarted)); | ||
1096 | 34 | xdnd_start_stop_notifier_->finished.connect(sigc::mem_fun(this, &XdndManagerImp::OnDndFinished)); | ||
1097 | 35 | |||
1098 | 36 | xdnd_collection_window_->collected.connect(sigc::mem_fun(this, &XdndManagerImp::OnDndDataCollected)); | ||
1099 | 37 | } | ||
1100 | 38 | |||
1101 | 39 | void XdndManagerImp::OnDndStarted() | ||
1102 | 40 | { | ||
1103 | 41 | xdnd_collection_window_->Collect(); | ||
1104 | 42 | } | ||
1105 | 43 | |||
1106 | 44 | void XdndManagerImp::OnDndFinished() | ||
1107 | 45 | { | ||
1108 | 46 | xdnd_collection_window_->Deactivate(); | ||
1109 | 47 | mouse_poller_timeout_.reset(); | ||
1110 | 48 | |||
1111 | 49 | if (valid_dnd_in_progress_) | ||
1112 | 50 | { | ||
1113 | 51 | valid_dnd_in_progress_ = false; | ||
1114 | 52 | dnd_finished.emit(); | ||
1115 | 53 | } | ||
1116 | 54 | } | ||
1117 | 55 | |||
1118 | 56 | void XdndManagerImp::OnDndDataCollected(std::vector<std::string> const& mimes) | ||
1119 | 57 | { | ||
1120 | 58 | if (!IsAValidDnd(mimes)) | ||
1121 | 59 | return; | ||
1122 | 60 | |||
1123 | 61 | valid_dnd_in_progress_ = true; | ||
1124 | 62 | |||
1125 | 63 | auto& gp_display = nux::GetWindowThread()->GetGraphicsDisplay(); | ||
1126 | 64 | char target[] = "text/uri-list"; | ||
1127 | 65 | glib::String data(gp_display.GetDndData(target)); | ||
1128 | 66 | |||
1129 | 67 | auto uscreen = UScreen::GetDefault(); | ||
1130 | 68 | last_monitor_ = uscreen->GetMonitorWithMouse(); | ||
1131 | 69 | |||
1132 | 70 | mouse_poller_timeout_.reset(new glib::Timeout(20, sigc::mem_fun(this, &XdndManagerImp::CheckMousePosition))); | ||
1133 | 71 | |||
1134 | 72 | dnd_started.emit(data.Str(), last_monitor_); | ||
1135 | 73 | } | ||
1136 | 74 | |||
1137 | 75 | bool XdndManagerImp::IsAValidDnd(std::vector<std::string> const& mimes) | ||
1138 | 76 | { | ||
1139 | 77 | auto end = std::end(mimes); | ||
1140 | 78 | auto it = std::find(std::begin(mimes), end, "text/uri-list"); | ||
1141 | 79 | |||
1142 | 80 | return it != end; | ||
1143 | 81 | } | ||
1144 | 82 | |||
1145 | 83 | bool XdndManagerImp::CheckMousePosition() | ||
1146 | 84 | { | ||
1147 | 85 | auto uscreen = UScreen::GetDefault(); | ||
1148 | 86 | auto monitor = uscreen->GetMonitorWithMouse(); | ||
1149 | 87 | |||
1150 | 88 | if (valid_dnd_in_progress_ && monitor != last_monitor_) | ||
1151 | 89 | { | ||
1152 | 90 | last_monitor_ = monitor; | ||
1153 | 91 | monitor_changed.emit(last_monitor_); | ||
1154 | 92 | } | ||
1155 | 93 | |||
1156 | 94 | return true; | ||
1157 | 95 | } | ||
1158 | 96 | |||
1159 | 97 | } | ||
1160 | 98 | |||
1161 | 0 | 99 | ||
1162 | === added file 'launcher/XdndManagerImp.h' | |||
1163 | --- launcher/XdndManagerImp.h 1970-01-01 00:00:00 +0000 | |||
1164 | +++ launcher/XdndManagerImp.h 2012-11-24 14:30:27 +0000 | |||
1165 | @@ -0,0 +1,54 @@ | |||
1166 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
1167 | 2 | /* | ||
1168 | 3 | * Copyright (C) 2012 Canonical Ltd | ||
1169 | 4 | * | ||
1170 | 5 | * This program is free software: you can redistribute it and/or modify | ||
1171 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
1172 | 7 | * published by the Free Software Foundation. | ||
1173 | 8 | * | ||
1174 | 9 | * This program is distributed in the hope that it will be useful, | ||
1175 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1176 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1177 | 12 | * GNU General Public License for more details. | ||
1178 | 13 | * | ||
1179 | 14 | * You should have received a copy of the GNU General Public License | ||
1180 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1181 | 16 | * | ||
1182 | 17 | * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
1183 | 18 | */ | ||
1184 | 19 | |||
1185 | 20 | #ifndef UNITYSHELL_XDND_MANAGER_IMP_H | ||
1186 | 21 | #define UNITYSHELL_XDND_MANAGER_IMP_H | ||
1187 | 22 | |||
1188 | 23 | #include <sigc++/trackable.h> | ||
1189 | 24 | |||
1190 | 25 | #include "XdndManager.h" | ||
1191 | 26 | |||
1192 | 27 | #include "XdndCollectionWindow.h" | ||
1193 | 28 | #include "XdndStartStopNotifier.h" | ||
1194 | 29 | #include "UnityCore/GLibSource.h" | ||
1195 | 30 | |||
1196 | 31 | namespace unity { | ||
1197 | 32 | |||
1198 | 33 | class XdndManagerImp : public XdndManager, public sigc::trackable { | ||
1199 | 34 | public: | ||
1200 | 35 | XdndManagerImp(XdndStartStopNotifier::Ptr const&, XdndCollectionWindow::Ptr const&); | ||
1201 | 36 | |||
1202 | 37 | private: | ||
1203 | 38 | void OnDndStarted(); | ||
1204 | 39 | void OnDndFinished(); | ||
1205 | 40 | void OnDndDataCollected(std::vector<std::string> const& mimes); | ||
1206 | 41 | bool IsAValidDnd(std::vector<std::string> const& mimes); | ||
1207 | 42 | bool CheckMousePosition(); | ||
1208 | 43 | |||
1209 | 44 | XdndStartStopNotifier::Ptr xdnd_start_stop_notifier_; | ||
1210 | 45 | XdndCollectionWindow::Ptr xdnd_collection_window_; | ||
1211 | 46 | int last_monitor_; | ||
1212 | 47 | bool valid_dnd_in_progress_; | ||
1213 | 48 | |||
1214 | 49 | glib::Source::UniquePtr mouse_poller_timeout_; | ||
1215 | 50 | }; | ||
1216 | 51 | |||
1217 | 52 | } | ||
1218 | 53 | |||
1219 | 54 | #endif | ||
1220 | 0 | 55 | ||
1221 | === added file 'launcher/XdndStartStopNotifier.cpp' | |||
1222 | --- launcher/XdndStartStopNotifier.cpp 1970-01-01 00:00:00 +0000 | |||
1223 | +++ launcher/XdndStartStopNotifier.cpp 2012-11-24 14:30:27 +0000 | |||
1224 | @@ -0,0 +1,27 @@ | |||
1225 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
1226 | 2 | /* | ||
1227 | 3 | * Copyright (C) 2012 Canonical Ltd | ||
1228 | 4 | * | ||
1229 | 5 | * This program is free software: you can redistribute it and/or modify | ||
1230 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
1231 | 7 | * published by the Free Software Foundation. | ||
1232 | 8 | * | ||
1233 | 9 | * This program is distributed in the hope that it will be useful, | ||
1234 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1235 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1236 | 12 | * GNU General Public License for more details. | ||
1237 | 13 | * | ||
1238 | 14 | * You should have received a copy of the GNU General Public License | ||
1239 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1240 | 16 | * | ||
1241 | 17 | * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
1242 | 18 | */ | ||
1243 | 19 | |||
1244 | 20 | #include "XdndStartStopNotifier.h" | ||
1245 | 21 | |||
1246 | 22 | namespace unity { | ||
1247 | 23 | |||
1248 | 24 | XdndStartStopNotifier::~XdndStartStopNotifier() | ||
1249 | 25 | {} | ||
1250 | 26 | |||
1251 | 27 | } | ||
1252 | 0 | \ No newline at end of file | 28 | \ No newline at end of file |
1253 | 1 | 29 | ||
1254 | === added file 'launcher/XdndStartStopNotifier.h' | |||
1255 | --- launcher/XdndStartStopNotifier.h 1970-01-01 00:00:00 +0000 | |||
1256 | +++ launcher/XdndStartStopNotifier.h 2012-11-24 14:30:27 +0000 | |||
1257 | @@ -0,0 +1,41 @@ | |||
1258 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
1259 | 2 | /* | ||
1260 | 3 | * Copyright (C) 2012 Canonical Ltd | ||
1261 | 4 | * | ||
1262 | 5 | * This program is free software: you can redistribute it and/or modify | ||
1263 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
1264 | 7 | * published by the Free Software Foundation. | ||
1265 | 8 | * | ||
1266 | 9 | * This program is distributed in the hope that it will be useful, | ||
1267 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1268 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1269 | 12 | * GNU General Public License for more details. | ||
1270 | 13 | * | ||
1271 | 14 | * You should have received a copy of the GNU General Public License | ||
1272 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1273 | 16 | * | ||
1274 | 17 | * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
1275 | 18 | */ | ||
1276 | 19 | |||
1277 | 20 | #ifndef UNITYSHELL_XDND_START_STOP_NOTIFIER_H | ||
1278 | 21 | #define UNITYSHELL_XDND_START_STOP_NOTIFIER_H | ||
1279 | 22 | |||
1280 | 23 | #include <boost/noncopyable.hpp> | ||
1281 | 24 | #include <memory> | ||
1282 | 25 | #include <sigc++/signal.h> | ||
1283 | 26 | |||
1284 | 27 | namespace unity { | ||
1285 | 28 | |||
1286 | 29 | class XdndStartStopNotifier : boost::noncopyable { | ||
1287 | 30 | public: | ||
1288 | 31 | typedef std::shared_ptr<XdndStartStopNotifier> Ptr; | ||
1289 | 32 | |||
1290 | 33 | virtual ~XdndStartStopNotifier() = 0; | ||
1291 | 34 | |||
1292 | 35 | sigc::signal<void> started; | ||
1293 | 36 | sigc::signal<void> finished; | ||
1294 | 37 | }; | ||
1295 | 38 | |||
1296 | 39 | } | ||
1297 | 40 | |||
1298 | 41 | #endif | ||
1299 | 0 | 42 | ||
1300 | === added file 'launcher/XdndStartStopNotifierImp.cpp' | |||
1301 | --- launcher/XdndStartStopNotifierImp.cpp 1970-01-01 00:00:00 +0000 | |||
1302 | +++ launcher/XdndStartStopNotifierImp.cpp 2012-11-24 14:30:27 +0000 | |||
1303 | @@ -0,0 +1,77 @@ | |||
1304 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
1305 | 2 | /* | ||
1306 | 3 | * Copyright (C) 2012 Canonical Ltd | ||
1307 | 4 | * | ||
1308 | 5 | * This program is free software: you can redistribute it and/or modify | ||
1309 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
1310 | 7 | * published by the Free Software Foundation. | ||
1311 | 8 | * | ||
1312 | 9 | * This program is distributed in the hope that it will be useful, | ||
1313 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1314 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1315 | 12 | * GNU General Public License for more details. | ||
1316 | 13 | * | ||
1317 | 14 | * You should have received a copy of the GNU General Public License | ||
1318 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1319 | 16 | * | ||
1320 | 17 | * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
1321 | 18 | */ | ||
1322 | 19 | |||
1323 | 20 | #include "XdndStartStopNotifierImp.h" | ||
1324 | 21 | |||
1325 | 22 | #include <Nux/Nux.h> | ||
1326 | 23 | |||
1327 | 24 | #include "unity-shared/WindowManager.h" | ||
1328 | 25 | |||
1329 | 26 | namespace unity { | ||
1330 | 27 | |||
1331 | 28 | XdndStartStopNotifierImp::XdndStartStopNotifierImp() | ||
1332 | 29 | : display_(nux::GetGraphicsDisplay()->GetX11Display()) | ||
1333 | 30 | , selection_(XInternAtom(display_, "XdndSelection", false)) | ||
1334 | 31 | , dnd_in_progress_(false) | ||
1335 | 32 | { | ||
1336 | 33 | WindowManager& wm = WindowManager::Default(); | ||
1337 | 34 | wm.window_mapped.connect(sigc::hide(sigc::mem_fun(this, &XdndStartStopNotifierImp::DndTimeoutSetup))); | ||
1338 | 35 | wm.window_unmapped.connect(sigc::hide(sigc::mem_fun(this, &XdndStartStopNotifierImp::DndTimeoutSetup))); | ||
1339 | 36 | } | ||
1340 | 37 | |||
1341 | 38 | void XdndStartStopNotifierImp::DndTimeoutSetup() | ||
1342 | 39 | { | ||
1343 | 40 | if (timeout_ && timeout_->IsRunning()) | ||
1344 | 41 | return; | ||
1345 | 42 | |||
1346 | 43 | auto cb_func = sigc::mem_fun(this, &XdndStartStopNotifierImp::OnTimeout); | ||
1347 | 44 | timeout_.reset(new glib::Timeout(200, cb_func)); | ||
1348 | 45 | } | ||
1349 | 46 | |||
1350 | 47 | bool XdndStartStopNotifierImp::OnTimeout() | ||
1351 | 48 | { | ||
1352 | 49 | Window drag_owner = XGetSelectionOwner(display_, selection_); | ||
1353 | 50 | |||
1354 | 51 | // evil hack because Qt does not release the selction owner on drag finished | ||
1355 | 52 | Window root_r, child_r; | ||
1356 | 53 | int root_x_r, root_y_r, win_x_r, win_y_r; | ||
1357 | 54 | unsigned int mask; | ||
1358 | 55 | XQueryPointer(display_, DefaultRootWindow(display_), &root_r, &child_r, &root_x_r, &root_y_r, &win_x_r, &win_y_r, &mask); | ||
1359 | 56 | |||
1360 | 57 | if (drag_owner && (mask & (Button1Mask | Button2Mask | Button3Mask))) | ||
1361 | 58 | { | ||
1362 | 59 | if (!dnd_in_progress_) | ||
1363 | 60 | { | ||
1364 | 61 | started.emit(); | ||
1365 | 62 | dnd_in_progress_ = true; | ||
1366 | 63 | } | ||
1367 | 64 | |||
1368 | 65 | return true; | ||
1369 | 66 | } | ||
1370 | 67 | |||
1371 | 68 | if (dnd_in_progress_) | ||
1372 | 69 | { | ||
1373 | 70 | finished.emit(); | ||
1374 | 71 | dnd_in_progress_ = false; | ||
1375 | 72 | } | ||
1376 | 73 | |||
1377 | 74 | return false; | ||
1378 | 75 | } | ||
1379 | 76 | |||
1380 | 77 | } | ||
1381 | 0 | 78 | ||
1382 | === added file 'launcher/XdndStartStopNotifierImp.h' | |||
1383 | --- launcher/XdndStartStopNotifierImp.h 1970-01-01 00:00:00 +0000 | |||
1384 | +++ launcher/XdndStartStopNotifierImp.h 2012-11-24 14:30:27 +0000 | |||
1385 | @@ -0,0 +1,47 @@ | |||
1386 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
1387 | 2 | /* | ||
1388 | 3 | * Copyright (C) 2012 Canonical Ltd | ||
1389 | 4 | * | ||
1390 | 5 | * This program is free software: you can redistribute it and/or modify | ||
1391 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
1392 | 7 | * published by the Free Software Foundation. | ||
1393 | 8 | * | ||
1394 | 9 | * This program is distributed in the hope that it will be useful, | ||
1395 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1396 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1397 | 12 | * GNU General Public License for more details. | ||
1398 | 13 | * | ||
1399 | 14 | * You should have received a copy of the GNU General Public License | ||
1400 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1401 | 16 | * | ||
1402 | 17 | * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
1403 | 18 | */ | ||
1404 | 19 | |||
1405 | 20 | #ifndef UNITYSHELL_XDND_START_STOP_NOTIFIER_IMP_H | ||
1406 | 21 | #define UNITYSHELL_XDND_START_STOP_NOTIFIER_IMP_H | ||
1407 | 22 | |||
1408 | 23 | #include "XdndStartStopNotifier.h" | ||
1409 | 24 | |||
1410 | 25 | #include <UnityCore/GLibSource.h> | ||
1411 | 26 | #include <X11/Xlib.h> | ||
1412 | 27 | |||
1413 | 28 | namespace unity { | ||
1414 | 29 | |||
1415 | 30 | class XdndStartStopNotifierImp : public XdndStartStopNotifier { | ||
1416 | 31 | public: | ||
1417 | 32 | XdndStartStopNotifierImp(); | ||
1418 | 33 | |||
1419 | 34 | private: | ||
1420 | 35 | void DndTimeoutSetup(); | ||
1421 | 36 | bool OnTimeout(); | ||
1422 | 37 | |||
1423 | 38 | Display* display_; | ||
1424 | 39 | Atom selection_; | ||
1425 | 40 | bool dnd_in_progress_; | ||
1426 | 41 | |||
1427 | 42 | glib::Source::UniquePtr timeout_; | ||
1428 | 43 | }; | ||
1429 | 44 | |||
1430 | 45 | } | ||
1431 | 46 | |||
1432 | 47 | #endif | ||
1433 | 0 | \ No newline at end of file | 48 | \ No newline at end of file |
1434 | 1 | 49 | ||
1435 | === modified file 'plugins/unityshell/src/unitya11ytests.cpp' | |||
1436 | --- plugins/unityshell/src/unitya11ytests.cpp 2012-08-15 14:05:18 +0000 | |||
1437 | +++ plugins/unityshell/src/unitya11ytests.cpp 2012-11-24 14:30:27 +0000 | |||
1438 | @@ -210,7 +210,7 @@ | |||
1439 | 210 | AtkObject* launcher_icon_accessible = NULL; | 210 | AtkObject* launcher_icon_accessible = NULL; |
1440 | 211 | 211 | ||
1441 | 212 | window = new nux::BaseWindow(TEXT("")); | 212 | window = new nux::BaseWindow(TEXT("")); |
1443 | 213 | launcher = new Launcher(window, nux::ObjectPtr<unity::DNDCollectionWindow>(new unity::DNDCollectionWindow), NULL); | 213 | launcher = new Launcher(window, NULL); |
1444 | 214 | launcher->SinkReference(); | 214 | launcher->SinkReference(); |
1445 | 215 | launcher_accessible = unity_a11y_get_accessible(launcher); | 215 | launcher_accessible = unity_a11y_get_accessible(launcher); |
1446 | 216 | 216 | ||
1447 | 217 | 217 | ||
1448 | === modified file 'plugins/unityshell/src/unityshell.cpp' | |||
1449 | --- plugins/unityshell/src/unityshell.cpp 2012-11-21 23:44:37 +0000 | |||
1450 | +++ plugins/unityshell/src/unityshell.cpp 2012-11-24 14:30:27 +0000 | |||
1451 | @@ -41,6 +41,9 @@ | |||
1452 | 41 | #include "unityshell.h" | 41 | #include "unityshell.h" |
1453 | 42 | #include "BackgroundEffectHelper.h" | 42 | #include "BackgroundEffectHelper.h" |
1454 | 43 | #include "UnityGestureBroker.h" | 43 | #include "UnityGestureBroker.h" |
1455 | 44 | #include "launcher/XdndCollectionWindowImp.h" | ||
1456 | 45 | #include "launcher/XdndManagerImp.h" | ||
1457 | 46 | #include "launcher/XdndStartStopNotifierImp.h" | ||
1458 | 44 | 47 | ||
1459 | 45 | #include <glib/gi18n-lib.h> | 48 | #include <glib/gi18n-lib.h> |
1460 | 46 | #include <gtk/gtk.h> | 49 | #include <gtk/gtk.h> |
1461 | @@ -3096,7 +3099,12 @@ | |||
1462 | 3096 | void UnityScreen::initLauncher() | 3099 | void UnityScreen::initLauncher() |
1463 | 3097 | { | 3100 | { |
1464 | 3098 | Timer timer; | 3101 | Timer timer; |
1466 | 3099 | launcher_controller_ = std::make_shared<launcher::Controller>(); | 3102 | |
1467 | 3103 | auto xdnd_collection_window = std::make_shared<XdndCollectionWindowImp>(); | ||
1468 | 3104 | auto xdnd_start_stop_notifier = std::make_shared<XdndStartStopNotifierImp>(); | ||
1469 | 3105 | auto xdnd_manager = std::make_shared<XdndManagerImp>(xdnd_start_stop_notifier, xdnd_collection_window); | ||
1470 | 3106 | |||
1471 | 3107 | launcher_controller_ = std::make_shared<launcher::Controller>(xdnd_manager); | ||
1472 | 3100 | AddChild(launcher_controller_.get()); | 3108 | AddChild(launcher_controller_.get()); |
1473 | 3101 | 3109 | ||
1474 | 3102 | switcher_controller_ = std::make_shared<switcher::Controller>(); | 3110 | switcher_controller_ = std::make_shared<switcher::Controller>(); |
1475 | 3103 | 3111 | ||
1476 | === modified file 'tests/CMakeLists.txt' | |||
1477 | --- tests/CMakeLists.txt 2012-11-23 23:49:46 +0000 | |||
1478 | +++ tests/CMakeLists.txt 2012-11-24 14:30:27 +0000 | |||
1479 | @@ -251,6 +251,8 @@ | |||
1480 | 251 | test_unity_settings.cpp | 251 | test_unity_settings.cpp |
1481 | 252 | test_volume_imp.cpp | 252 | test_volume_imp.cpp |
1482 | 253 | test_volume_launcher_icon.cpp | 253 | test_volume_launcher_icon.cpp |
1483 | 254 | test_xdnd_manager_imp.cpp | ||
1484 | 255 | test_xdnd_start_stop_notifier_imp.cpp | ||
1485 | 254 | bamf-mock-application.c | 256 | bamf-mock-application.c |
1486 | 255 | gmockmount.c | 257 | gmockmount.c |
1487 | 256 | gmockvolume.c | 258 | gmockvolume.c |
1488 | 257 | 259 | ||
1489 | === modified file 'tests/test_launcher.cpp' | |||
1490 | --- tests/test_launcher.cpp 2012-11-09 09:18:37 +0000 | |||
1491 | +++ tests/test_launcher.cpp 2012-11-24 14:30:27 +0000 | |||
1492 | @@ -26,7 +26,6 @@ | |||
1493 | 26 | #include <Nux/Nux.h> | 26 | #include <Nux/Nux.h> |
1494 | 27 | #include <Nux/BaseWindow.h> | 27 | #include <Nux/BaseWindow.h> |
1495 | 28 | 28 | ||
1496 | 29 | #include "launcher/DNDCollectionWindow.h" | ||
1497 | 30 | #include "launcher/MockLauncherIcon.h" | 29 | #include "launcher/MockLauncherIcon.h" |
1498 | 31 | #include "launcher/Launcher.h" | 30 | #include "launcher/Launcher.h" |
1499 | 32 | #include "unity-shared/PanelStyle.h" | 31 | #include "unity-shared/PanelStyle.h" |
1500 | @@ -63,8 +62,8 @@ | |||
1501 | 63 | class MockLauncher : public Launcher | 62 | class MockLauncher : public Launcher |
1502 | 64 | { | 63 | { |
1503 | 65 | public: | 64 | public: |
1506 | 66 | MockLauncher(nux::BaseWindow* parent, nux::ObjectPtr<DNDCollectionWindow> const& collection_window) | 65 | MockLauncher(nux::BaseWindow* parent) |
1507 | 67 | : Launcher(parent, collection_window) | 66 | : Launcher(parent) |
1508 | 68 | {} | 67 | {} |
1509 | 69 | 68 | ||
1510 | 70 | AbstractLauncherIcon::Ptr MouseIconIntersection(int x, int y) const | 69 | AbstractLauncherIcon::Ptr MouseIconIntersection(int x, int y) const |
1511 | @@ -119,10 +118,9 @@ | |||
1512 | 119 | 118 | ||
1513 | 120 | TestLauncher() | 119 | TestLauncher() |
1514 | 121 | : parent_window_(new nux::BaseWindow("TestLauncherWindow")) | 120 | : parent_window_(new nux::BaseWindow("TestLauncherWindow")) |
1515 | 122 | , dnd_collection_window_(new DNDCollectionWindow) | ||
1516 | 123 | , model_(new LauncherModel) | 121 | , model_(new LauncherModel) |
1517 | 124 | , options_(new Options) | 122 | , options_(new Options) |
1519 | 125 | , launcher_(new MockLauncher(parent_window_, dnd_collection_window_)) | 123 | , launcher_(new MockLauncher(parent_window_)) |
1520 | 126 | { | 124 | { |
1521 | 127 | launcher_->options = options_; | 125 | launcher_->options = options_; |
1522 | 128 | launcher_->SetModel(model_); | 126 | launcher_->SetModel(model_); |
1523 | @@ -153,7 +151,6 @@ | |||
1524 | 153 | 151 | ||
1525 | 154 | MockUScreen uscreen; | 152 | MockUScreen uscreen; |
1526 | 155 | nux::BaseWindow* parent_window_; | 153 | nux::BaseWindow* parent_window_; |
1527 | 156 | nux::ObjectPtr<DNDCollectionWindow> dnd_collection_window_; | ||
1528 | 157 | Settings settings; | 154 | Settings settings; |
1529 | 158 | panel::Style panel_style; | 155 | panel::Style panel_style; |
1530 | 159 | LauncherModel::Ptr model_; | 156 | LauncherModel::Ptr model_; |
1531 | @@ -189,9 +186,7 @@ | |||
1532 | 189 | EXPECT_CALL(*third, ShouldHighlightOnDrag(_)) | 186 | EXPECT_CALL(*third, ShouldHighlightOnDrag(_)) |
1533 | 190 | .WillRepeatedly(Return(false)); | 187 | .WillRepeatedly(Return(false)); |
1534 | 191 | 188 | ||
1538 | 192 | std::list<char*> uris; | 189 | launcher_->DndStarted(""); |
1536 | 193 | dnd_collection_window_->collected.emit(uris); | ||
1537 | 194 | |||
1539 | 195 | Utils::WaitForTimeout(1); | 190 | Utils::WaitForTimeout(1); |
1540 | 196 | 191 | ||
1541 | 197 | EXPECT_FALSE(first->GetQuirk(launcher::AbstractLauncherIcon::Quirk::DESAT)); | 192 | EXPECT_FALSE(first->GetQuirk(launcher::AbstractLauncherIcon::Quirk::DESAT)); |
1542 | 198 | 193 | ||
1543 | === modified file 'tests/test_launcher_controller.cpp' | |||
1544 | --- tests/test_launcher_controller.cpp 2012-11-15 17:56:23 +0000 | |||
1545 | +++ tests/test_launcher_controller.cpp 2012-11-24 14:30:27 +0000 | |||
1546 | @@ -200,6 +200,11 @@ | |||
1547 | 200 | { | 200 | { |
1548 | 201 | struct TestLauncherController : public testing::Test | 201 | struct TestLauncherController : public testing::Test |
1549 | 202 | { | 202 | { |
1550 | 203 | TestLauncherController() | ||
1551 | 204 | : xdnd_manager_(std::make_shared<XdndManager>()) | ||
1552 | 205 | , lc(xdnd_manager_) | ||
1553 | 206 | {} | ||
1554 | 207 | |||
1555 | 203 | virtual void SetUp() | 208 | virtual void SetUp() |
1556 | 204 | { | 209 | { |
1557 | 205 | lc.multiple_launchers = true; | 210 | lc.multiple_launchers = true; |
1558 | @@ -216,6 +221,10 @@ | |||
1559 | 216 | protected: | 221 | protected: |
1560 | 217 | struct MockLauncherController : Controller | 222 | struct MockLauncherController : Controller |
1561 | 218 | { | 223 | { |
1562 | 224 | MockLauncherController(XdndManager::Ptr const& xdnd_manager) | ||
1563 | 225 | : Controller(xdnd_manager) | ||
1564 | 226 | {} | ||
1565 | 227 | |||
1566 | 219 | Controller::Impl* Impl() const { return pimpl.get(); } | 228 | Controller::Impl* Impl() const { return pimpl.get(); } |
1567 | 220 | 229 | ||
1568 | 221 | AbstractLauncherIcon::Ptr GetIconByDesktop(std::string const& path) const | 230 | AbstractLauncherIcon::Ptr GetIconByDesktop(std::string const& path) const |
1569 | @@ -258,6 +267,7 @@ | |||
1570 | 258 | Settings settings; | 267 | Settings settings; |
1571 | 259 | panel::Style panel_style; | 268 | panel::Style panel_style; |
1572 | 260 | MockFavoriteStore favorite_store; | 269 | MockFavoriteStore favorite_store; |
1573 | 270 | XdndManager::Ptr xdnd_manager_; | ||
1574 | 261 | MockLauncherController lc; | 271 | MockLauncherController lc; |
1575 | 262 | }; | 272 | }; |
1576 | 263 | } | 273 | } |
1577 | @@ -1544,4 +1554,50 @@ | |||
1578 | 1544 | ASSERT_EQ(lc.Impl()->model_->Selection()->tooltip_text(), last_selection_change); | 1554 | ASSERT_EQ(lc.Impl()->model_->Selection()->tooltip_text(), last_selection_change); |
1579 | 1545 | } | 1555 | } |
1580 | 1546 | 1556 | ||
1581 | 1557 | TEST_F(TestLauncherController, DragAndDrop_MultipleLaunchers) | ||
1582 | 1558 | { | ||
1583 | 1559 | lc.multiple_launchers = true; | ||
1584 | 1560 | uscreen.SetupFakeMultiMonitor(); | ||
1585 | 1561 | lc.options()->hide_mode = LAUNCHER_HIDE_AUTOHIDE; | ||
1586 | 1562 | |||
1587 | 1563 | auto check_fn = [this](int index) { | ||
1588 | 1564 | return lc.launchers()[index]->Hidden(); | ||
1589 | 1565 | }; | ||
1590 | 1566 | |||
1591 | 1567 | xdnd_manager_->dnd_started.emit("my_awesome_file", 0); | ||
1592 | 1568 | |||
1593 | 1569 | for (int i = 0; i < max_num_monitors; ++i) | ||
1594 | 1570 | Utils::WaitUntil(std::bind(check_fn, i), i != 0); | ||
1595 | 1571 | |||
1596 | 1572 | xdnd_manager_->monitor_changed.emit(3); | ||
1597 | 1573 | |||
1598 | 1574 | for (int i = 0; i < max_num_monitors; ++i) | ||
1599 | 1575 | Utils::WaitUntil(std::bind(check_fn, i), i != 3); | ||
1600 | 1576 | |||
1601 | 1577 | xdnd_manager_->dnd_finished.emit(); | ||
1602 | 1578 | |||
1603 | 1579 | for (int i = 0; i < max_num_monitors; ++i) | ||
1604 | 1580 | Utils::WaitUntil(std::bind(check_fn, i), true); | ||
1605 | 1581 | } | ||
1606 | 1582 | |||
1607 | 1583 | TEST_F(TestLauncherController, DragAndDrop_SingleLauncher) | ||
1608 | 1584 | { | ||
1609 | 1585 | lc.multiple_launchers = false; | ||
1610 | 1586 | uscreen.SetupFakeMultiMonitor(2); | ||
1611 | 1587 | lc.options()->hide_mode = LAUNCHER_HIDE_AUTOHIDE; | ||
1612 | 1588 | |||
1613 | 1589 | auto check_fn = [this]() { | ||
1614 | 1590 | return lc.launcher().Hidden(); | ||
1615 | 1591 | }; | ||
1616 | 1592 | |||
1617 | 1593 | xdnd_manager_->dnd_started.emit("my_awesome_file", 0); | ||
1618 | 1594 | Utils::WaitUntil(check_fn, false); | ||
1619 | 1595 | |||
1620 | 1596 | xdnd_manager_->monitor_changed.emit(2); | ||
1621 | 1597 | Utils::WaitUntil(check_fn, false); | ||
1622 | 1598 | |||
1623 | 1599 | xdnd_manager_->dnd_finished.emit(); | ||
1624 | 1600 | Utils::WaitUntil(check_fn, true); | ||
1625 | 1601 | } | ||
1626 | 1602 | |||
1627 | 1547 | } | 1603 | } |
1628 | 1548 | 1604 | ||
1629 | === added file 'tests/test_xdnd_manager_imp.cpp' | |||
1630 | --- tests/test_xdnd_manager_imp.cpp 1970-01-01 00:00:00 +0000 | |||
1631 | +++ tests/test_xdnd_manager_imp.cpp 2012-11-24 14:30:27 +0000 | |||
1632 | @@ -0,0 +1,130 @@ | |||
1633 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
1634 | 2 | /* | ||
1635 | 3 | * Copyright (C) 2012 Canonical Ltd | ||
1636 | 4 | * | ||
1637 | 5 | * This program is free software: you can redistribute it and/or modify | ||
1638 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
1639 | 7 | * published by the Free Software Foundation. | ||
1640 | 8 | * | ||
1641 | 9 | * This program is distributed in the hope that it will be useful, | ||
1642 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1643 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1644 | 12 | * GNU General Public License for more details. | ||
1645 | 13 | * | ||
1646 | 14 | * You should have received a copy of the GNU General Public License | ||
1647 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1648 | 16 | * | ||
1649 | 17 | * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
1650 | 18 | */ | ||
1651 | 19 | |||
1652 | 20 | #include <gmock/gmock.h> | ||
1653 | 21 | using namespace testing; | ||
1654 | 22 | |||
1655 | 23 | #include "launcher/XdndManagerImp.h" | ||
1656 | 24 | #include "launcher/XdndCollectionWindow.h" | ||
1657 | 25 | #include "launcher/XdndStartStopNotifier.h" | ||
1658 | 26 | |||
1659 | 27 | #include "test_utils.h" | ||
1660 | 28 | |||
1661 | 29 | #include <Nux/Nux.h> | ||
1662 | 30 | #include <X11/Xlib.h> | ||
1663 | 31 | |||
1664 | 32 | namespace { | ||
1665 | 33 | |||
1666 | 34 | class MockXdndStartStopNotifier : public unity::XdndStartStopNotifier { | ||
1667 | 35 | public: | ||
1668 | 36 | typedef std::shared_ptr<MockXdndStartStopNotifier> Ptr; | ||
1669 | 37 | }; | ||
1670 | 38 | |||
1671 | 39 | class MockXdndCollectionWindow : public unity::XdndCollectionWindow { | ||
1672 | 40 | public: | ||
1673 | 41 | typedef std::shared_ptr<MockXdndCollectionWindow> Ptr; | ||
1674 | 42 | |||
1675 | 43 | MOCK_METHOD0(Collect, void(void)); | ||
1676 | 44 | MOCK_METHOD0(Deactivate, void(void)); | ||
1677 | 45 | }; | ||
1678 | 46 | |||
1679 | 47 | class TestXdndManager : public Test { | ||
1680 | 48 | public: | ||
1681 | 49 | TestXdndManager() | ||
1682 | 50 | : xdnd_start_stop_notifier_(new MockXdndStartStopNotifier()) | ||
1683 | 51 | , xdnd_collection_window_(new MockXdndCollectionWindow()) | ||
1684 | 52 | , xdnd_manager(xdnd_start_stop_notifier_, xdnd_collection_window_) | ||
1685 | 53 | {} | ||
1686 | 54 | |||
1687 | 55 | void SetUp() | ||
1688 | 56 | { | ||
1689 | 57 | // Evil hack to avoid crashes. | ||
1690 | 58 | XEvent xevent; | ||
1691 | 59 | xevent.type = ClientMessage; | ||
1692 | 60 | xevent.xany.display = nux::GetGraphicsDisplay()->GetX11Display(); | ||
1693 | 61 | xevent.xclient.message_type = XInternAtom(xevent.xany.display, "XdndEnter", false); | ||
1694 | 62 | xevent.xclient.data.l[1] = 5 >> 24; | ||
1695 | 63 | |||
1696 | 64 | nux::GetGraphicsDisplay()->ProcessXEvent(xevent, true); | ||
1697 | 65 | } | ||
1698 | 66 | |||
1699 | 67 | MockXdndStartStopNotifier::Ptr xdnd_start_stop_notifier_; | ||
1700 | 68 | MockXdndCollectionWindow::Ptr xdnd_collection_window_; | ||
1701 | 69 | unity::XdndManagerImp xdnd_manager; | ||
1702 | 70 | }; | ||
1703 | 71 | |||
1704 | 72 | TEST_F(TestXdndManager, SignalDndStartedAndFinished) | ||
1705 | 73 | { | ||
1706 | 74 | std::vector<std::string> mimes; | ||
1707 | 75 | mimes.push_back("text/uri-list"); | ||
1708 | 76 | mimes.push_back("hello/world"); | ||
1709 | 77 | |||
1710 | 78 | auto emit_collected_signal = [&] () { | ||
1711 | 79 | xdnd_collection_window_->collected.emit(mimes); | ||
1712 | 80 | }; | ||
1713 | 81 | |||
1714 | 82 | EXPECT_CALL(*xdnd_collection_window_, Collect()) | ||
1715 | 83 | .Times(1) | ||
1716 | 84 | .WillOnce(Invoke(emit_collected_signal)); | ||
1717 | 85 | |||
1718 | 86 | bool dnd_started_emitted = false; | ||
1719 | 87 | xdnd_manager.dnd_started.connect([&] (std::string const& /*data*/, int /*monitor*/) { | ||
1720 | 88 | dnd_started_emitted = true; | ||
1721 | 89 | }); | ||
1722 | 90 | |||
1723 | 91 | xdnd_start_stop_notifier_->started.emit(); | ||
1724 | 92 | Utils::WaitUntil(dnd_started_emitted); | ||
1725 | 93 | |||
1726 | 94 | EXPECT_CALL(*xdnd_collection_window_, Deactivate()) | ||
1727 | 95 | .Times(1); | ||
1728 | 96 | |||
1729 | 97 | bool dnd_finished_emitted = false; | ||
1730 | 98 | xdnd_manager.dnd_finished.connect([&] () { | ||
1731 | 99 | dnd_finished_emitted = true; | ||
1732 | 100 | }); | ||
1733 | 101 | |||
1734 | 102 | xdnd_start_stop_notifier_->finished.emit(); | ||
1735 | 103 | Utils::WaitUntil(dnd_finished_emitted); | ||
1736 | 104 | } | ||
1737 | 105 | |||
1738 | 106 | TEST_F(TestXdndManager, SignalDndStarted_InvalidMimes) | ||
1739 | 107 | { | ||
1740 | 108 | std::vector<std::string> mimes; | ||
1741 | 109 | mimes.push_back("hello/world"); | ||
1742 | 110 | mimes.push_back("invalid/mimes"); | ||
1743 | 111 | |||
1744 | 112 | auto emit_collected_signal = [&] () { | ||
1745 | 113 | xdnd_collection_window_->collected.emit(mimes); | ||
1746 | 114 | }; | ||
1747 | 115 | |||
1748 | 116 | EXPECT_CALL(*xdnd_collection_window_, Collect()) | ||
1749 | 117 | .Times(1) | ||
1750 | 118 | .WillOnce(Invoke(emit_collected_signal)); | ||
1751 | 119 | |||
1752 | 120 | bool dnd_started_emitted = false; | ||
1753 | 121 | xdnd_manager.dnd_started.connect([&] (std::string const& /*data*/, int /*monitor*/) { | ||
1754 | 122 | dnd_started_emitted = true; | ||
1755 | 123 | }); | ||
1756 | 124 | |||
1757 | 125 | xdnd_start_stop_notifier_->started.emit(); | ||
1758 | 126 | |||
1759 | 127 | EXPECT_FALSE(dnd_started_emitted); | ||
1760 | 128 | } | ||
1761 | 129 | |||
1762 | 130 | } | ||
1763 | 0 | 131 | ||
1764 | === added file 'tests/test_xdnd_start_stop_notifier_imp.cpp' | |||
1765 | --- tests/test_xdnd_start_stop_notifier_imp.cpp 1970-01-01 00:00:00 +0000 | |||
1766 | +++ tests/test_xdnd_start_stop_notifier_imp.cpp 2012-11-24 14:30:27 +0000 | |||
1767 | @@ -0,0 +1,107 @@ | |||
1768 | 1 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- | ||
1769 | 2 | /* | ||
1770 | 3 | * Copyright (C) 2012 Canonical Ltd | ||
1771 | 4 | * | ||
1772 | 5 | * This program is free software: you can redistribute it and/or modify | ||
1773 | 6 | * it under the terms of the GNU General Public License version 3 as | ||
1774 | 7 | * published by the Free Software Foundation. | ||
1775 | 8 | * | ||
1776 | 9 | * This program is distributed in the hope that it will be useful, | ||
1777 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1778 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1779 | 12 | * GNU General Public License for more details. | ||
1780 | 13 | * | ||
1781 | 14 | * You should have received a copy of the GNU General Public License | ||
1782 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1783 | 16 | * | ||
1784 | 17 | * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> | ||
1785 | 18 | */ | ||
1786 | 19 | |||
1787 | 20 | #include <gmock/gmock.h> | ||
1788 | 21 | using namespace testing; | ||
1789 | 22 | |||
1790 | 23 | #include "XdndStartStopNotifierImp.h" | ||
1791 | 24 | |||
1792 | 25 | #include <Nux/Nux.h> | ||
1793 | 26 | #include <X11/Xlib.h> | ||
1794 | 27 | //#include <X11/extensions/XTest.h> | ||
1795 | 28 | |||
1796 | 29 | #include "unity-shared/WindowManager.h" | ||
1797 | 30 | #include "test_utils.h" | ||
1798 | 31 | |||
1799 | 32 | namespace { | ||
1800 | 33 | |||
1801 | 34 | struct TestXdndStartStopNotifierImp : public Test { | ||
1802 | 35 | TestXdndStartStopNotifierImp() | ||
1803 | 36 | : display_(nux::GetGraphicsDisplay()->GetX11Display()) | ||
1804 | 37 | , selection_(XInternAtom(display_, "XdndSelection", false)) | ||
1805 | 38 | { | ||
1806 | 39 | Window root = DefaultRootWindow(display_); | ||
1807 | 40 | owner_= XCreateSimpleWindow(display_, root, -1000, -1000, 10, 10, 0, 0, 0); | ||
1808 | 41 | } | ||
1809 | 42 | |||
1810 | 43 | Display* display_; | ||
1811 | 44 | Atom selection_; | ||
1812 | 45 | Window owner_; | ||
1813 | 46 | |||
1814 | 47 | unity::XdndStartStopNotifierImp xdnd_start_stop_notifier; | ||
1815 | 48 | }; | ||
1816 | 49 | |||
1817 | 50 | TEST_F(TestXdndStartStopNotifierImp, DISABLED_SignalStarted) | ||
1818 | 51 | { | ||
1819 | 52 | bool signal_received = false; | ||
1820 | 53 | xdnd_start_stop_notifier.started.connect([&](){ | ||
1821 | 54 | signal_received = true; | ||
1822 | 55 | }); | ||
1823 | 56 | |||
1824 | 57 | XSetSelectionOwner(display_, selection_, owner_, CurrentTime); | ||
1825 | 58 | //XTestFakeButtonEvent(display_, 1, True, CurrentTime); | ||
1826 | 59 | auto& wm = unity::WindowManager::Default(); | ||
1827 | 60 | wm.window_mapped.emit(0); | ||
1828 | 61 | |||
1829 | 62 | Utils::WaitUntil(signal_received); | ||
1830 | 63 | //XTestFakeButtonEvent(display_, 1, False, CurrentTime); | ||
1831 | 64 | } | ||
1832 | 65 | |||
1833 | 66 | TEST_F(TestXdndStartStopNotifierImp, DISABLED_SignalFinished) | ||
1834 | 67 | { | ||
1835 | 68 | bool signal_received = false; | ||
1836 | 69 | xdnd_start_stop_notifier.finished.connect([&](){ | ||
1837 | 70 | signal_received = true; | ||
1838 | 71 | }); | ||
1839 | 72 | |||
1840 | 73 | XSetSelectionOwner(display_, selection_, owner_, CurrentTime); | ||
1841 | 74 | //XTestFakeButtonEvent(display_, 1, True, CurrentTime); | ||
1842 | 75 | auto& wm = unity::WindowManager::Default(); | ||
1843 | 76 | wm.window_mapped.emit(0); | ||
1844 | 77 | |||
1845 | 78 | Utils::WaitForTimeoutMSec(500); | ||
1846 | 79 | |||
1847 | 80 | XSetSelectionOwner(display_, selection_, None, CurrentTime); | ||
1848 | 81 | //XTestFakeButtonEvent(display_, 1, False, CurrentTime); | ||
1849 | 82 | wm.window_unmapped.emit(0); | ||
1850 | 83 | |||
1851 | 84 | Utils::WaitUntil(signal_received); | ||
1852 | 85 | } | ||
1853 | 86 | |||
1854 | 87 | TEST_F(TestXdndStartStopNotifierImp, DISABLED_SignalFinished_QT) | ||
1855 | 88 | { | ||
1856 | 89 | bool signal_received = false; | ||
1857 | 90 | xdnd_start_stop_notifier.finished.connect([&](){ | ||
1858 | 91 | signal_received = true; | ||
1859 | 92 | }); | ||
1860 | 93 | |||
1861 | 94 | XSetSelectionOwner(display_, selection_, owner_, CurrentTime); | ||
1862 | 95 | //XTestFakeButtonEvent(display_, 1, True, CurrentTime); | ||
1863 | 96 | auto& wm = unity::WindowManager::Default(); | ||
1864 | 97 | wm.window_mapped.emit(0); | ||
1865 | 98 | |||
1866 | 99 | Utils::WaitForTimeoutMSec(500); | ||
1867 | 100 | |||
1868 | 101 | //XTestFakeButtonEvent(display_, 1, False, CurrentTime); | ||
1869 | 102 | wm.window_unmapped.emit(0); | ||
1870 | 103 | |||
1871 | 104 | Utils::WaitUntil(signal_received); | ||
1872 | 105 | } | ||
1873 | 106 | |||
1874 | 107 | } | ||
1875 | 0 | 108 | ||
1876 | === modified file 'unity-shared/UScreen.cpp' | |||
1877 | --- unity-shared/UScreen.cpp 2012-10-29 09:34:54 +0000 | |||
1878 | +++ unity-shared/UScreen.cpp 2012-11-24 14:30:27 +0000 | |||
1879 | @@ -89,6 +89,13 @@ | |||
1880 | 89 | return monitors_; | 89 | return monitors_; |
1881 | 90 | } | 90 | } |
1882 | 91 | 91 | ||
1883 | 92 | nux::Geometry UScreen::GetScreenGeometry() | ||
1884 | 93 | { | ||
1885 | 94 | int width = gdk_screen_get_width(screen_); | ||
1886 | 95 | int height = gdk_screen_get_height(screen_); | ||
1887 | 96 | return nux::Geometry(0, 0, width, height); | ||
1888 | 97 | } | ||
1889 | 98 | |||
1890 | 92 | void UScreen::Changed(GdkScreen* screen) | 99 | void UScreen::Changed(GdkScreen* screen) |
1891 | 93 | { | 100 | { |
1892 | 94 | if (refresh_idle_) | 101 | if (refresh_idle_) |
1893 | 95 | 102 | ||
1894 | === modified file 'unity-shared/UScreen.h' | |||
1895 | --- unity-shared/UScreen.h 2012-07-24 01:07:58 +0000 | |||
1896 | +++ unity-shared/UScreen.h 2012-11-24 14:30:27 +0000 | |||
1897 | @@ -46,6 +46,7 @@ | |||
1898 | 46 | nux::Geometry& GetMonitorGeometry(int monitor); | 46 | nux::Geometry& GetMonitorGeometry(int monitor); |
1899 | 47 | 47 | ||
1900 | 48 | std::vector<nux::Geometry>& GetMonitors(); | 48 | std::vector<nux::Geometry>& GetMonitors(); |
1901 | 49 | nux::Geometry GetScreenGeometry(); | ||
1902 | 49 | 50 | ||
1903 | 50 | // <void, primary_monitor, monitors> | 51 | // <void, primary_monitor, monitors> |
1904 | 51 | sigc::signal<void, int, std::vector<nux::Geometry>&> changed; | 52 | sigc::signal<void, int, std::vector<nux::Geometry>&> changed; |
1905 | 52 | 53 | ||
1906 | === modified file 'unity-standalone/StandaloneUnity.cpp' | |||
1907 | --- unity-standalone/StandaloneUnity.cpp 2012-10-11 01:44:15 +0000 | |||
1908 | +++ unity-standalone/StandaloneUnity.cpp 2012-11-24 14:30:27 +0000 | |||
1909 | @@ -86,9 +86,10 @@ | |||
1910 | 86 | 86 | ||
1911 | 87 | void UnityStandalone::Init () | 87 | void UnityStandalone::Init () |
1912 | 88 | { | 88 | { |
1916 | 89 | launcher_controller.reset(new launcher::Controller()); | 89 | auto xdnd_manager = std::make_shared<XdndManager>(); |
1917 | 90 | panel_controller.reset(new panel::Controller()); | 90 | launcher_controller = std::make_shared<launcher::Controller>(xdnd_manager); |
1918 | 91 | dash_controller.reset(new dash::Controller()); | 91 | panel_controller = std::make_shared<panel::Controller>(); |
1919 | 92 | dash_controller = std::make_shared<dash::Controller>(); | ||
1920 | 92 | 93 | ||
1921 | 93 | dash_controller->launcher_width = launcher_controller->launcher().GetAbsoluteWidth() - 1; | 94 | dash_controller->launcher_width = launcher_controller->launcher().GetAbsoluteWidth() - 1; |
1922 | 94 | panel_controller->launcher_width = launcher_controller->launcher().GetAbsoluteWidth() - 1; | 95 | panel_controller->launcher_width = launcher_controller->launcher().GetAbsoluteWidth() - 1; |
1923 | @@ -119,8 +120,9 @@ | |||
1924 | 119 | 120 | ||
1925 | 120 | void UnityStandaloneTV::Init() | 121 | void UnityStandaloneTV::Init() |
1926 | 121 | { | 122 | { |
1929 | 122 | launcher_controller.reset(new launcher::Controller()); | 123 | auto xdnd_manager = std::make_shared<XdndManager>(); |
1930 | 123 | dash_controller.reset(new dash::Controller()); | 124 | launcher_controller = std::make_shared<launcher::Controller>(xdnd_manager); |
1931 | 125 | dash_controller = std::make_shared<dash::Controller>(); | ||
1932 | 124 | dash_controller->launcher_width = launcher_controller->launcher().GetAbsoluteWidth() - 1; | 126 | dash_controller->launcher_width = launcher_controller->launcher().GetAbsoluteWidth() - 1; |
1933 | 125 | 127 | ||
1934 | 126 | UBusManager().SendMessage(UBUS_DASH_EXTERNAL_ACTIVATION, nullptr); | 128 | UBusManager().SendMessage(UBUS_DASH_EXTERNAL_ACTIVATION, nullptr); |
Overall I'm up for this new implementation... Few comments though:
603+Controller: :Impl:: Impl(Controller * parent, XdndManager::Ptr xdnd_manager)
const& ? :)
xdnd_manager_ ->dnd_started. connect( [this]( std::string const& data, int monitor)
And other lambdas... Since they're quite long, mabye it's better to put them into methods.
806 +class XdndCollectionW indow : boost::noncopyable {
new line for {
820 +#endif
821 \ No newline at end of file
Add \n ;)
864 + SetGeometry( wm.GetScreenGeo metry() );
Shouldn't you update this value when the screen geometry changes?
971 + void Collect() /*override*/;
972 + void Deactivate() /*override*/;
I think you can re-enable them since now we use gcc-4.7 in jenkins too.
884 + auto display = nux::GetGraphic sDisplay( )->GetX11Displa y();
You can check for this value only if window_id is the target one, isn't it?
900 + std::vector< std::string> data; back(mime) ;
901 + for (auto mime : mimes)
902 + data.push_
Can't be happen that std::list<char>
1082 + if (valid_ dnd_in_ progress_ ) {
Fix indentation
1096 + char target[] = "text/uri-list";
Adding a global const for this?
There's some commented code in TestXdndManager .SignalDndStart ed, do you want to clean it up?