Merge lp:~nick-dedekind/unity/lp857422.dash-mouse-steal into lp:unity
- lp857422.dash-mouse-steal
- Merge into trunk
Proposed by
Nick Dedekind
Status: | Merged |
---|---|
Approved by: | Brandon Schaefer |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2715 |
Proposed branch: | lp:~nick-dedekind/unity/lp857422.dash-mouse-steal |
Merge into: | lp:unity |
Diff against target: |
948 lines (+329/-111) 17 files modified
dash/DashController.cpp (+30/-13) dash/DashController.h (+4/-5) dash/DashView.cpp (+5/-0) dash/DashView.h (+2/-0) hud/HudAbstractView.h (+3/-1) hud/HudController.cpp (+42/-11) hud/HudController.h (+7/-3) hud/HudView.cpp (+60/-65) hud/HudView.h (+4/-5) hud/StandaloneHud.cpp (+1/-4) plugins/unityshell/src/unityshell.cpp (+45/-3) plugins/unityshell/src/unityshell.h (+2/-0) tests/autopilot/unity/emulators/dash.py (+4/-0) tests/autopilot/unity/tests/test_dash.py (+33/-0) tests/autopilot/unity/tests/test_hud.py (+32/-0) tests/test_hud_controller.cpp (+2/-1) unity-shared/ResizingBaseWindow.h (+53/-0) |
To merge this branch: | bzr merge lp:~nick-dedekind/unity/lp857422.dash-mouse-steal |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brandon Schaefer (community) | Approve | ||
Review via email: mp+124221@code.launchpad.net |
Commit message
Dash/Hud no longer steal mouse events outside their content area. Better draw handling of hud animation.
Description of the change
Resize input window relative to the size of the dash/hud. Now only encompasses the required content area.
Added some draw performance fixes for the hud. (only redraw when needed)
To post a comment you must log in.
Revision history for this message
Nick Dedekind (nick-dedekind) wrote : | # |
Revision history for this message
Omer Akram (om26er) wrote : | # |
Has conflicts?
Revision history for this message
Nick Dedekind (nick-dedekind) wrote : | # |
Fixed conflicts.
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote : | # |
I checked with trunk and the launcher looks the same as trunk so we are good there :).
Other then that everything looks awesome :). The tests worked for me, and it works manually for me as well. The launcher works, the Window buttons works...
soo this branch looks good to me :)
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'dash/DashController.cpp' |
2 | --- dash/DashController.cpp 2012-09-17 10:00:38 +0000 |
3 | +++ dash/DashController.cpp 2012-09-18 17:41:27 +0000 |
4 | @@ -66,13 +66,13 @@ |
5 | , timeline_animator_(90) |
6 | , dbus_connect_cancellable_(g_cancellable_new()) |
7 | { |
8 | - SetupRelayoutCallbacks(); |
9 | RegisterUBusInterests(); |
10 | |
11 | ensure_timeout_.Run([&]() { EnsureDash(); return false; }); |
12 | timeline_animator_.animation_updated.connect(sigc::mem_fun(this, &Controller::OnViewShowHideFrame)); |
13 | |
14 | SetupWindow(); |
15 | + UScreen::GetDefault()->changed.connect([&] (int, std::vector<nux::Geometry>&) { Relayout(true); }); |
16 | |
17 | Settings::Instance().changed.connect([&]() |
18 | { |
19 | @@ -97,7 +97,12 @@ |
20 | |
21 | void Controller::SetupWindow() |
22 | { |
23 | - window_ = new nux::BaseWindow(dash::window_title); |
24 | + window_ = new ResizingBaseWindow(dash::window_title, [this](nux::Geometry const& geo) |
25 | + { |
26 | + if (view_) |
27 | + return GetInputWindowGeometry(); |
28 | + return geo; |
29 | + }); |
30 | window_->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f)); |
31 | window_->SetConfigureNotifyCallback(&Controller::OnWindowConfigure, this); |
32 | window_->ShowWindow(false); |
33 | @@ -122,19 +127,13 @@ |
34 | layout->SetContentDistribution(nux::eStackLeft); |
35 | layout->SetVerticalExternalMargin(0); |
36 | layout->SetHorizontalExternalMargin(0); |
37 | - |
38 | window_->SetLayout(layout); |
39 | + |
40 | + window_->UpdateInputWindowGeometry(); |
41 | + |
42 | ubus_manager_.UnregisterInterest(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST); |
43 | } |
44 | |
45 | -void Controller::SetupRelayoutCallbacks() |
46 | -{ |
47 | - GdkScreen* screen = gdk_screen_get_default(); |
48 | - auto relayout_cb = sigc::mem_fun(this, &Controller::Relayout); |
49 | - sig_manager_.Add<void, GdkScreen*>(screen, "monitors-changed", relayout_cb); |
50 | - sig_manager_.Add<void, GdkScreen*>(screen, "size-changed", relayout_cb); |
51 | -} |
52 | - |
53 | void Controller::RegisterUBusInterests() |
54 | { |
55 | ubus_manager_.RegisterInterest(UBUS_DASH_EXTERNAL_ACTIVATION, |
56 | @@ -218,13 +217,19 @@ |
57 | monitor_geo.height - panel_style.panel_height); |
58 | } |
59 | |
60 | -void Controller::Relayout(GdkScreen*screen) |
61 | +void Controller::Relayout(bool check_monitor) |
62 | { |
63 | EnsureDash(); |
64 | |
65 | + if (check_monitor) |
66 | + { |
67 | + monitor_ = CLAMP(GetIdealMonitor(), 0, static_cast<int>(UScreen::GetDefault()->GetMonitors().size()-1)); |
68 | + printf("relayout on monitor:%d, monitor count:%d\n", monitor_, static_cast<int>(UScreen::GetDefault()->GetMonitors().size())); |
69 | + } |
70 | + |
71 | nux::Geometry geo = GetIdealWindowGeometry(); |
72 | + view_->Relayout(); |
73 | window_->SetGeometry(geo); |
74 | - view_->Relayout(); |
75 | panel::Style &panel_style = panel::Style::Instance(); |
76 | view_->SetMonitorOffset(launcher_width, panel_style.panel_height); |
77 | } |
78 | @@ -291,7 +296,11 @@ |
79 | window_->ShowWindow(true); |
80 | window_->PushToFront(); |
81 | if (!Settings::Instance().is_standalone) // in standalone mode, we do not need an input window. we are one. |
82 | + { |
83 | window_->EnableInputWindow(true, dash::window_title, true, false); |
84 | + // update the input window geometry. This causes the input window to match the actual size of the dash. |
85 | + window_->UpdateInputWindowGeometry(); |
86 | + } |
87 | window_->SetInputFocus(); |
88 | window_->CaptureMouseDownAnyWhereElse(true); |
89 | window_->QueueDraw(); |
90 | @@ -445,6 +454,14 @@ |
91 | } |
92 | } |
93 | |
94 | +nux::Geometry Controller::GetInputWindowGeometry() |
95 | +{ |
96 | + EnsureDash(); |
97 | + nux::Geometry const& window_geo(window_->GetGeometry()); |
98 | + nux::Geometry const& view_content_geo(view_->GetContentGeometry()); |
99 | + return nux::Geometry(window_geo.x, window_geo.y, view_content_geo.width, view_content_geo.height); |
100 | +} |
101 | + |
102 | |
103 | } |
104 | } |
105 | |
106 | === modified file 'dash/DashController.h' |
107 | --- dash/DashController.h 2012-09-13 10:56:42 +0000 |
108 | +++ dash/DashController.h 2012-09-18 17:41:27 +0000 |
109 | @@ -27,12 +27,12 @@ |
110 | #include <NuxCore/Property.h> |
111 | #include <NuxGraphics/GraphicsEngine.h> |
112 | #include <Nux/Nux.h> |
113 | -#include <Nux/BaseWindow.h> |
114 | |
115 | #include "DashView.h" |
116 | #include "unity-shared/Animator.h" |
117 | #include "unity-shared/Introspectable.h" |
118 | #include "unity-shared/UBusWrapper.h" |
119 | +#include "unity-shared/ResizingBaseWindow.h" |
120 | |
121 | namespace unity |
122 | { |
123 | @@ -60,6 +60,7 @@ |
124 | void HideDash(bool restore_focus = true); |
125 | |
126 | bool IsVisible() const; |
127 | + nux::Geometry GetInputWindowGeometry(); |
128 | |
129 | protected: |
130 | std::string GetName() const; |
131 | @@ -69,12 +70,11 @@ |
132 | void EnsureDash(); |
133 | void SetupWindow(); |
134 | void SetupDashView(); |
135 | - void SetupRelayoutCallbacks(); |
136 | void RegisterUBusInterests(); |
137 | |
138 | nux::Geometry GetIdealWindowGeometry(); |
139 | int GetIdealMonitor(); |
140 | - void Relayout(GdkScreen*screen=NULL); |
141 | + void Relayout(bool check_monitor =false); |
142 | |
143 | void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags); |
144 | void OnScreenUngrabbed(); |
145 | @@ -96,7 +96,7 @@ |
146 | static void OnWindowConfigure(int width, int height, nux::Geometry& geo, void* data); |
147 | |
148 | private: |
149 | - nux::ObjectPtr<nux::BaseWindow> window_; |
150 | + nux::ObjectPtr<ResizingBaseWindow> window_; |
151 | int monitor_; |
152 | |
153 | bool visible_; |
154 | @@ -104,7 +104,6 @@ |
155 | DashView* view_; |
156 | |
157 | sigc::connection screen_ungrabbed_slot_; |
158 | - glib::SignalManager sig_manager_; |
159 | glib::TimeoutSeconds ensure_timeout_; |
160 | Animator timeline_animator_; |
161 | UBusManager ubus_manager_; |
162 | |
163 | === modified file 'dash/DashView.cpp' |
164 | --- dash/DashView.cpp 2012-09-18 13:29:09 +0000 |
165 | +++ dash/DashView.cpp 2012-09-18 17:41:27 +0000 |
166 | @@ -1078,5 +1078,10 @@ |
167 | return (view == nullptr) ? this : view; |
168 | } |
169 | |
170 | +nux::Geometry const& DashView::GetContentGeometry() const |
171 | +{ |
172 | + return content_geo_; |
173 | +} |
174 | + |
175 | } |
176 | } |
177 | |
178 | === modified file 'dash/DashView.h' |
179 | --- dash/DashView.h 2012-08-17 07:28:10 +0000 |
180 | +++ dash/DashView.h 2012-09-18 17:41:27 +0000 |
181 | @@ -69,6 +69,8 @@ |
182 | |
183 | nux::View* default_focus() const; |
184 | |
185 | + nux::Geometry const& GetContentGeometry() const; |
186 | + |
187 | protected: |
188 | void ProcessDndEnter(); |
189 | |
190 | |
191 | === modified file 'hud/HudAbstractView.h' |
192 | --- hud/HudAbstractView.h 2012-06-09 08:42:53 +0000 |
193 | +++ hud/HudAbstractView.h 2012-09-18 17:41:27 +0000 |
194 | @@ -48,8 +48,9 @@ |
195 | virtual void SearchFinished() = 0; |
196 | virtual void SetIcon(std::string const& icon_name, unsigned int tile_size, unsigned int size, unsigned int padding) = 0; |
197 | virtual void SetQueries(Hud::Queries queries) = 0; |
198 | - virtual void SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo) = 0; |
199 | + virtual void SetMonitorOffset(int x, int y) = 0; |
200 | virtual void ShowEmbeddedIcon(bool show) = 0; |
201 | + virtual nux::Geometry GetContentGeometry() = 0; |
202 | |
203 | virtual nux::View* default_focus() const = 0; |
204 | |
205 | @@ -58,6 +59,7 @@ |
206 | sigc::signal<void, std::string> search_activated; |
207 | sigc::signal<void, Query::Ptr> query_activated; |
208 | sigc::signal<void, Query::Ptr> query_selected; |
209 | + sigc::signal<void> layout_changed; |
210 | }; |
211 | |
212 | } // namespace hud |
213 | |
214 | === modified file 'hud/HudController.cpp' |
215 | --- hud/HudController.cpp 2012-09-17 10:00:38 +0000 |
216 | +++ hud/HudController.cpp 2012-09-18 17:41:27 +0000 |
217 | @@ -54,7 +54,7 @@ |
218 | { |
219 | LOG_DEBUG(logger) << "hud startup"; |
220 | SetupWindow(); |
221 | - UScreen::GetDefault()->changed.connect([&] (int, std::vector<nux::Geometry>&) { Relayout(); }); |
222 | + UScreen::GetDefault()->changed.connect([&] (int, std::vector<nux::Geometry>&) { Relayout(true); }); |
223 | |
224 | ubus.RegisterInterest(UBUS_HUD_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud)); |
225 | |
226 | @@ -90,7 +90,12 @@ |
227 | // Since BaseWindow is a View it is initially unowned. This means that the first |
228 | // reference that is taken grabs ownership of the pointer. Since the smart pointer |
229 | // references it, it becomes the owner, so no need to adopt the pointer here. |
230 | - window_ = new nux::BaseWindow("Hud"); |
231 | + window_ = new ResizingBaseWindow("Hud", [this](nux::Geometry const& geo) |
232 | + { |
233 | + if (view_) |
234 | + return GetInputWindowGeometry(); |
235 | + return geo; |
236 | + }); |
237 | window_->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f)); |
238 | window_->SetConfigureNotifyCallback(&Controller::OnWindowConfigure, this); |
239 | window_->ShowWindow(false); |
240 | @@ -117,6 +122,8 @@ |
241 | layout_->AddView(view_, 1, nux::MINOR_POSITION_TOP); |
242 | window_->SetLayout(layout_); |
243 | |
244 | + window_->UpdateInputWindowGeometry(); |
245 | + |
246 | view_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &Controller::OnMouseDownOutsideWindow)); |
247 | |
248 | LOG_DEBUG(logger) << "connecting to signals"; |
249 | @@ -124,6 +131,7 @@ |
250 | view_->search_activated.connect(sigc::mem_fun(this, &Controller::OnSearchActivated)); |
251 | view_->query_activated.connect(sigc::mem_fun(this, &Controller::OnQueryActivated)); |
252 | view_->query_selected.connect(sigc::mem_fun(this, &Controller::OnQuerySelected)); |
253 | + view_->layout_changed.connect(sigc::bind(sigc::mem_fun(this, &Controller::Relayout), nullptr)); |
254 | // Add to the debug introspection. |
255 | AddChild(view_); |
256 | } |
257 | @@ -155,13 +163,15 @@ |
258 | |
259 | void Controller::EnsureHud() |
260 | { |
261 | - LOG_DEBUG(logger) << "Initializing Hud"; |
262 | - |
263 | if (!window_) |
264 | + { |
265 | + LOG_DEBUG(logger) << "Initializing Hud Window"; |
266 | SetupWindow(); |
267 | + } |
268 | |
269 | if (!view_) |
270 | { |
271 | + LOG_DEBUG(logger) << "Initializing Hud View"; |
272 | SetupHudView(); |
273 | Relayout(); |
274 | } |
275 | @@ -212,16 +222,20 @@ |
276 | return geo; |
277 | } |
278 | |
279 | -void Controller::Relayout() |
280 | +void Controller::Relayout(bool check_monitor) |
281 | { |
282 | EnsureHud(); |
283 | - nux::Geometry const& content_geo = view_->GetGeometry(); |
284 | + |
285 | + if (check_monitor) |
286 | + { |
287 | + monitor_index_ = CLAMP(GetIdealMonitor(), 0, static_cast<int>(UScreen::GetDefault()->GetMonitors().size()-1)); |
288 | + } |
289 | nux::Geometry const& geo = GetIdealWindowGeometry(); |
290 | |
291 | + view_->Relayout(); |
292 | window_->SetGeometry(geo); |
293 | - layout_->SetMinMaxSize(content_geo.width, content_geo.height); |
294 | - view_->SetWindowGeometry(window_->GetAbsoluteGeometry(), window_->GetGeometry()); |
295 | - view_->Relayout(); |
296 | + panel::Style &panel_style = panel::Style::Instance(); |
297 | + view_->SetMonitorOffset(launcher_width, panel_style.panel_height); |
298 | } |
299 | |
300 | void Controller::OnMouseDownOutsideWindow(int x, int y, |
301 | @@ -255,7 +269,15 @@ |
302 | { |
303 | LOG_DEBUG(logger) << "External Hiding the hud"; |
304 | EnsureHud(); |
305 | - HideHud(); |
306 | + |
307 | + if (variant) |
308 | + { |
309 | + HideHud(g_variant_get_boolean(variant)); |
310 | + } |
311 | + else |
312 | + { |
313 | + HideHud(); |
314 | + } |
315 | } |
316 | |
317 | void Controller::ShowHideHud() |
318 | @@ -353,6 +375,7 @@ |
319 | window_->ShowWindow(true); |
320 | window_->PushToFront(); |
321 | window_->EnableInputWindow(true, "Hud", true, false); |
322 | + window_->UpdateInputWindowGeometry(); |
323 | window_->SetInputFocus(); |
324 | window_->CaptureMouseDownAnyWhereElse(true); |
325 | view_->CaptureMouseDownAnyWhereElse(true); |
326 | @@ -363,7 +386,6 @@ |
327 | visible_ = true; |
328 | |
329 | StartShowHideTimeline(); |
330 | - view_->SetWindowGeometry(window_->GetAbsoluteGeometry(), window_->GetGeometry()); |
331 | |
332 | // hide the launcher |
333 | GVariant* message_data = g_variant_new("(b)", TRUE); |
334 | @@ -504,6 +526,15 @@ |
335 | .add("locked_to_launcher", IsLockedToLauncher(monitor_index_)); |
336 | } |
337 | |
338 | +nux::Geometry Controller::GetInputWindowGeometry() |
339 | +{ |
340 | + EnsureHud(); |
341 | + nux::Geometry const& window_geo(window_->GetGeometry()); |
342 | + nux::Geometry const& view_content_geo(view_->GetContentGeometry()); |
343 | + return nux::Geometry(window_geo.x, window_geo.y, view_content_geo.width, view_content_geo.height); |
344 | +} |
345 | + |
346 | + |
347 | |
348 | } |
349 | } |
350 | |
351 | === modified file 'hud/HudController.h' |
352 | --- hud/HudController.h 2012-09-13 10:56:42 +0000 |
353 | +++ hud/HudController.h 2012-09-18 17:41:27 +0000 |
354 | @@ -24,14 +24,15 @@ |
355 | |
356 | #include <gdk/gdk.h> |
357 | #include <UnityCore/Hud.h> |
358 | +#include <UnityCore/GLibSignal.h> |
359 | |
360 | #include <NuxCore/Property.h> |
361 | #include <NuxGraphics/GraphicsEngine.h> |
362 | #include <Nux/Nux.h> |
363 | -#include <Nux/BaseWindow.h> |
364 | |
365 | #include "unity-shared/Animator.h" |
366 | #include "unity-shared/UBusWrapper.h" |
367 | +#include "unity-shared/ResizingBaseWindow.h" |
368 | #include "HudView.h" |
369 | |
370 | namespace unity |
371 | @@ -59,6 +60,8 @@ |
372 | void HideHud(bool restore_focus = true); |
373 | bool IsVisible(); |
374 | |
375 | + nux::Geometry GetInputWindowGeometry(); |
376 | + |
377 | protected: |
378 | // Introspectable |
379 | std::string GetName() const; |
380 | @@ -75,7 +78,7 @@ |
381 | bool IsLockedToLauncher(int monitor); |
382 | |
383 | nux::Geometry GetIdealWindowGeometry(); |
384 | - void Relayout(); |
385 | + void Relayout(bool check_monitor =false); |
386 | |
387 | void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags); |
388 | void OnScreenUngrabbed(); |
389 | @@ -96,8 +99,9 @@ |
390 | void OnQueriesFinished(Hud::Queries queries); |
391 | |
392 | private: |
393 | - nux::ObjectPtr<nux::BaseWindow> window_; |
394 | + nux::ObjectPtr<ResizingBaseWindow> window_; |
395 | UBusManager ubus; |
396 | + glib::SignalManager sig_manager_; |
397 | Hud hud_service_; |
398 | bool visible_; |
399 | bool need_show_; |
400 | |
401 | === modified file 'hud/HudView.cpp' |
402 | --- hud/HudView.cpp 2012-09-13 10:56:42 +0000 |
403 | +++ hud/HudView.cpp 2012-09-18 17:41:27 +0000 |
404 | @@ -61,10 +61,10 @@ |
405 | : AbstractView() |
406 | , button_views_(nullptr) |
407 | , visible_(false) |
408 | + , timeline_animating_(false) |
409 | , start_time_(0) |
410 | , last_known_height_(0) |
411 | , current_height_(0) |
412 | - , timeline_need_more_draw_(false) |
413 | , selected_button_(0) |
414 | , show_embedded_icon_(true) |
415 | , keyboard_stole_focus_(false) |
416 | @@ -122,6 +122,12 @@ |
417 | { |
418 | } |
419 | |
420 | +void View::SetMonitorOffset(int x, int y) |
421 | +{ |
422 | + renderer_.x_offset = x; |
423 | + renderer_.y_offset = y; |
424 | +} |
425 | + |
426 | void View::ProcessGrowShrink() |
427 | { |
428 | float diff = g_get_monotonic_time() - start_time_; |
429 | @@ -129,24 +135,25 @@ |
430 | // only animate if we are after our defined pause time |
431 | if (diff > pause_before_grow_length) |
432 | { |
433 | - float progress = (diff - pause_before_grow_length) / grow_anim_length; |
434 | - int last_height = last_known_height_; |
435 | - int new_height = 0; |
436 | - |
437 | - if (last_height < target_height) |
438 | - { |
439 | - // grow |
440 | - new_height = last_height + ((target_height - last_height) * progress); |
441 | - } |
442 | - else |
443 | - { |
444 | - //shrink |
445 | - new_height = last_height - ((last_height - target_height) * progress); |
446 | - } |
447 | - |
448 | - LOG_DEBUG(logger) << "resizing to " << target_height << " (" << new_height << ")" |
449 | + float progress = (diff - pause_before_grow_length) / grow_anim_length; |
450 | + int last_height = last_known_height_; |
451 | + int new_height = 0; |
452 | + |
453 | + if (last_height < target_height) |
454 | + { |
455 | + // grow |
456 | + new_height = last_height + ((target_height - last_height) * progress); |
457 | + } |
458 | + else |
459 | + { |
460 | + //shrink |
461 | + new_height = last_height - ((last_height - target_height) * progress); |
462 | + } |
463 | + |
464 | + |
465 | + LOG_DEBUG(logger) << "resizing to " << target_height << " (" << new_height << ")" |
466 | << "View height: " << GetGeometry().height; |
467 | - current_height_ = new_height; |
468 | + current_height_ = new_height; |
469 | } |
470 | |
471 | for (auto button : buttons_) |
472 | @@ -154,14 +161,23 @@ |
473 | button->SetSkipDraw((button->GetAbsoluteY() + button->GetBaseHeight()) > (GetAbsoluteY() + current_height_)); |
474 | } |
475 | |
476 | - QueueDraw(); |
477 | - |
478 | if (diff > grow_anim_length + pause_before_grow_length) |
479 | { |
480 | // ensure we are at our final location and update last known height |
481 | current_height_ = target_height; |
482 | last_known_height_ = target_height; |
483 | - timeline_need_more_draw_ = false; |
484 | + |
485 | + layout_changed.emit(); |
486 | + timeline_idle_.reset(); |
487 | + timeline_animating_ = false; |
488 | + } |
489 | + else |
490 | + { |
491 | + timeline_idle_.reset(new glib::Timeout(0, [this] |
492 | + { |
493 | + QueueDraw(); |
494 | + return false; |
495 | + })); |
496 | } |
497 | } |
498 | |
499 | @@ -187,27 +203,6 @@ |
500 | QueueDraw(); |
501 | } |
502 | |
503 | -long View::PostLayoutManagement(long LayoutResult) |
504 | -{ |
505 | - Relayout(); |
506 | - if (GetGeometry().height != last_known_height_) |
507 | - { |
508 | - // Start the timeline of drawing the dash resize |
509 | - if (timeline_need_more_draw_) |
510 | - { |
511 | - // already started, just reset the last known height |
512 | - last_known_height_ = current_height_; |
513 | - } |
514 | - |
515 | - timeline_need_more_draw_ = true; |
516 | - start_time_ = g_get_monotonic_time(); |
517 | - QueueDraw(); |
518 | - } |
519 | - |
520 | - return LayoutResult; |
521 | -} |
522 | - |
523 | - |
524 | nux::View* View::default_focus() const |
525 | { |
526 | return search_bar_->text_entry(); |
527 | @@ -361,14 +356,6 @@ |
528 | renderer_.AboutToHide(); |
529 | } |
530 | |
531 | -void View::SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo) |
532 | -{ |
533 | - window_geometry_ = geo; |
534 | - window_geometry_.x = 0; |
535 | - window_geometry_.y = 0; |
536 | - absolute_window_geometry_ = absolute_geo; |
537 | -} |
538 | - |
539 | void View::SetupViews() |
540 | { |
541 | dash::Style& style = dash::Style::Instance(); |
542 | @@ -405,6 +392,17 @@ |
543 | content_layout_->AddLayout(button_views_.GetPointer(), 1, nux::MINOR_POSITION_LEFT); |
544 | } |
545 | |
546 | + content_layout_->OnGeometryChanged.connect([&](nux::Area*, nux::Geometry& geo) |
547 | + { |
548 | + if (!timeline_animating_) |
549 | + { |
550 | + timeline_animating_ = true; |
551 | + start_time_ = g_get_monotonic_time(); |
552 | + QueueDraw(); |
553 | + } |
554 | + }); |
555 | + |
556 | + |
557 | layout_->AddLayout(content_layout_.GetPointer(), 1, nux::MINOR_POSITION_TOP); |
558 | } |
559 | |
560 | @@ -450,14 +448,12 @@ |
561 | |
562 | void View::Draw(nux::GraphicsEngine& gfx_context, bool force_draw) |
563 | { |
564 | - if (timeline_need_more_draw_) |
565 | - { |
566 | + if (timeline_animating_) |
567 | ProcessGrowShrink(); |
568 | - } |
569 | |
570 | nux::Geometry draw_content_geo(layout_->GetGeometry()); |
571 | draw_content_geo.height = current_height_; |
572 | - renderer_.DrawFull(gfx_context, draw_content_geo, absolute_window_geometry_, window_geometry_, true); |
573 | + renderer_.DrawFull(gfx_context, draw_content_geo, GetAbsoluteGeometry(), GetGeometry(), true); |
574 | } |
575 | |
576 | void View::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw) |
577 | @@ -465,7 +461,7 @@ |
578 | nux::Geometry draw_content_geo(layout_->GetGeometry()); |
579 | draw_content_geo.height = current_height_; |
580 | |
581 | - renderer_.DrawInner(gfx_context, draw_content_geo, absolute_window_geometry_, window_geometry_); |
582 | + renderer_.DrawInner(gfx_context, draw_content_geo, GetAbsoluteGeometry(), GetGeometry()); |
583 | |
584 | gfx_context.PushClippingRectangle(draw_content_geo); |
585 | |
586 | @@ -492,16 +488,7 @@ |
587 | } |
588 | gfx_context.PopClippingRectangle(); |
589 | |
590 | - renderer_.DrawInnerCleanup(gfx_context, draw_content_geo, absolute_window_geometry_, window_geometry_); |
591 | - |
592 | - if (timeline_need_more_draw_ && !timeline_idle_) |
593 | - { |
594 | - timeline_idle_.reset(new glib::Idle([&] () { |
595 | - QueueDraw(); |
596 | - timeline_idle_.reset(); |
597 | - return false; |
598 | - })); |
599 | - } |
600 | + renderer_.DrawInnerCleanup(gfx_context, draw_content_geo, GetAbsoluteGeometry(), GetGeometry()); |
601 | } |
602 | |
603 | void View::MouseStealsHudButtonFocus() |
604 | @@ -769,6 +756,14 @@ |
605 | return search_bar_->text_entry(); |
606 | } |
607 | |
608 | +nux::Geometry View::GetContentGeometry() |
609 | +{ |
610 | + nux::Geometry geo(content_geo_); |
611 | + geo.height = current_height_; |
612 | + return geo; |
613 | +} |
614 | + |
615 | + |
616 | } |
617 | } |
618 | |
619 | |
620 | === modified file 'hud/HudView.h' |
621 | --- hud/HudView.h 2012-09-04 18:15:34 +0000 |
622 | +++ hud/HudView.h 2012-09-18 17:41:27 +0000 |
623 | @@ -60,7 +60,9 @@ |
624 | void AboutToShow(); |
625 | void AboutToHide(); |
626 | |
627 | - void SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo); |
628 | + void SetMonitorOffset(int x, int y); |
629 | + |
630 | + nux::Geometry GetContentGeometry(); |
631 | |
632 | protected: |
633 | virtual Area* FindKeyFocusArea(unsigned int event_type, |
634 | @@ -69,7 +71,6 @@ |
635 | |
636 | void SetupViews(); |
637 | void OnSearchChanged(std::string const& search_string); |
638 | - virtual long PostLayoutManagement(long LayoutResult); |
639 | |
640 | private: |
641 | void OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key); |
642 | @@ -110,14 +111,12 @@ |
643 | Hud::Queries queries_; |
644 | nux::Geometry content_geo_; |
645 | OverlayRenderer renderer_; |
646 | - nux::Geometry window_geometry_; |
647 | - nux::Geometry absolute_window_geometry_; |
648 | glib::Source::UniquePtr timeline_idle_; |
649 | + bool timeline_animating_; |
650 | |
651 | guint64 start_time_; |
652 | int last_known_height_; |
653 | int current_height_; |
654 | - bool timeline_need_more_draw_; |
655 | int selected_button_; |
656 | bool show_embedded_icon_; |
657 | bool activated_signal_sent_; |
658 | |
659 | === modified file 'hud/StandaloneHud.cpp' |
660 | --- hud/StandaloneHud.cpp 2012-06-01 15:24:14 +0000 |
661 | +++ hud/StandaloneHud.cpp 2012-09-18 17:41:27 +0000 |
662 | @@ -69,7 +69,7 @@ |
663 | |
664 | hud_view_ = new unity::hud::View(); |
665 | |
666 | - layout->AddView (hud_view_, 0, nux::MINOR_POSITION_TOP); |
667 | + layout->AddView (hud_view_, 1, nux::MINOR_POSITION_TOP); |
668 | nux::GetWindowCompositor().SetKeyFocusArea(hud_view_->default_focus()); |
669 | |
670 | nux::GetWindowThread()->SetLayout (layout); |
671 | @@ -109,9 +109,6 @@ |
672 | }); |
673 | |
674 | hud_service_.RequestQuery(""); |
675 | - |
676 | - hud_view_->SetWindowGeometry(layout->GetAbsoluteGeometry(), layout->GetGeometry()); |
677 | - |
678 | } |
679 | |
680 | void TestRunner::InitWindowThread(nux::NThread* thread, void* InitData) |
681 | |
682 | === modified file 'plugins/unityshell/src/unityshell.cpp' |
683 | --- plugins/unityshell/src/unityshell.cpp 2012-09-18 01:41:46 +0000 |
684 | +++ plugins/unityshell/src/unityshell.cpp 2012-09-18 17:41:27 +0000 |
685 | @@ -913,6 +913,33 @@ |
686 | } |
687 | } |
688 | |
689 | +bool UnityScreen::DoesPointIntersectUnityGeos(nux::Point const& pt) |
690 | +{ |
691 | + auto launchers = launcher_controller_->launchers(); |
692 | + for (auto launcher : launchers) |
693 | + { |
694 | + nux::Geometry hud_geo = launcher->GetAbsoluteGeometry(); |
695 | + |
696 | + if (launcher->Hidden()) |
697 | + continue; |
698 | + |
699 | + if (hud_geo.IsInside(pt)) |
700 | + { |
701 | + return true; |
702 | + } |
703 | + } |
704 | + |
705 | + for (nux::Geometry &panel_geo : panel_controller_->GetGeometries ()) |
706 | + { |
707 | + if (panel_geo.IsInside(pt)) |
708 | + { |
709 | + return true; |
710 | + } |
711 | + } |
712 | + |
713 | + return false; |
714 | +} |
715 | + |
716 | void UnityWindow::enterShowDesktop () |
717 | { |
718 | if (!mShowdesktopHandler) |
719 | @@ -1435,12 +1462,26 @@ |
720 | if (CompWindow *w = screen->findWindow(ss->getSelectedWindow())) |
721 | skip_other_plugins = UnityWindow::get(w)->handleEvent(event); |
722 | } |
723 | - if (launcher_controller_->IsOverlayOpen()) |
724 | + |
725 | + |
726 | + if (dash_controller_->IsVisible()) |
727 | { |
728 | - int monitor_with_mouse = UScreen::GetDefault()->GetMonitorWithMouse(); |
729 | - if (overlay_monitor_ != monitor_with_mouse) |
730 | + nux::Point pt(event->xbutton.x_root, event->xbutton.y_root); |
731 | + nux::Geometry dash_geo = dash_controller_->GetInputWindowGeometry(); |
732 | + |
733 | + if (!dash_geo.IsInside(pt) && !DoesPointIntersectUnityGeos(pt)) |
734 | { |
735 | dash_controller_->HideDash(false); |
736 | + } |
737 | + } |
738 | + |
739 | + if (hud_controller_->IsVisible()) |
740 | + { |
741 | + nux::Point pt(event->xbutton.x_root, event->xbutton.y_root); |
742 | + nux::Geometry hud_geo = hud_controller_->GetInputWindowGeometry(); |
743 | + |
744 | + if (!hud_geo.IsInside(pt) && !DoesPointIntersectUnityGeos(pt)) |
745 | + { |
746 | hud_controller_->HideHud(false); |
747 | } |
748 | } |
749 | @@ -2683,6 +2724,7 @@ |
750 | return pos; |
751 | } |
752 | |
753 | + |
754 | bool UnityWindow::place(CompPoint& pos) |
755 | { |
756 | bool was_maximized = PluginAdapter::Default ()->MaximizeIfBigEnough(window); |
757 | |
758 | === modified file 'plugins/unityshell/src/unityshell.h' |
759 | --- plugins/unityshell/src/unityshell.h 2012-09-18 01:41:46 +0000 |
760 | +++ plugins/unityshell/src/unityshell.h 2012-09-18 17:41:27 +0000 |
761 | @@ -190,6 +190,8 @@ |
762 | switcher::Controller::Ptr switcher_controller(); |
763 | launcher::Controller::Ptr launcher_controller(); |
764 | |
765 | + bool DoesPointIntersectUnityGeos(nux::Point const& pt); |
766 | + |
767 | protected: |
768 | std::string GetName() const; |
769 | void AddProperties(GVariantBuilder* builder); |
770 | |
771 | === modified file 'tests/autopilot/unity/emulators/dash.py' |
772 | --- tests/autopilot/unity/emulators/dash.py 2012-09-13 10:56:42 +0000 |
773 | +++ tests/autopilot/unity/emulators/dash.py 2012-09-18 17:41:27 +0000 |
774 | @@ -155,6 +155,10 @@ |
775 | active_lens_name = self.view.get_lensbar().active_lens |
776 | return self.view.get_lensview_by_name(active_lens_name) |
777 | |
778 | + @property |
779 | + def geometry(self): |
780 | + return (self.view.x, self.view.y, self.view.width, self.view.height) |
781 | + |
782 | |
783 | class DashController(UnityIntrospectionObject): |
784 | """The main dash controller object.""" |
785 | |
786 | === modified file 'tests/autopilot/unity/tests/test_dash.py' |
787 | --- tests/autopilot/unity/tests/test_dash.py 2012-09-18 01:41:46 +0000 |
788 | +++ tests/autopilot/unity/tests/test_dash.py 2012-09-18 17:41:27 +0000 |
789 | @@ -107,6 +107,39 @@ |
790 | self.dash.reveal_application_lens() |
791 | self.assertThat(self.dash.active_lens, Eventually(Equals('applications.lens'))) |
792 | |
793 | + def test_closes_mouse_down_outside(self): |
794 | + """Test that a mouse down outside of the dash closes the dash.""" |
795 | + |
796 | + self.dash.ensure_visible() |
797 | + current_monitor = self.dash.monitor |
798 | + |
799 | + (x,y,w,h) = self.dash.geometry |
800 | + (screen_x,screen_y,screen_w,screen_h) = self.screen_geo.get_monitor_geometry(current_monitor) |
801 | + |
802 | + self.mouse.move(x + w + (screen_w-((screen_x-x)+w))/2, y + h + (screen_h-((screen_y-y)+h))/2) |
803 | + self.mouse.click() |
804 | + |
805 | + self.assertThat(self.dash.visible, Eventually(Equals(False))) |
806 | + |
807 | + def test_closes_then_focuses_window_on_mouse_down(self): |
808 | + """If 2 windows are open with 1 maximized and the non-maxmized |
809 | + focused. Then from the Dash clicking on the maximized window |
810 | + must focus that window and close the dash. |
811 | + """ |
812 | + char_win = self.start_app("Character Map") |
813 | + self.keybinding("window/maximize") |
814 | + self.start_app("Calculator") |
815 | + |
816 | + self.dash.ensure_visible() |
817 | + |
818 | + #Click bottom right of the screen |
819 | + w = self.screen_geo.get_screen_width() |
820 | + h = self.screen_geo.get_screen_height() |
821 | + self.mouse.move(w,h) |
822 | + self.mouse.click() |
823 | + |
824 | + self.assertProperty(char_win, is_active=True) |
825 | + |
826 | |
827 | class DashSearchInputTests(DashTestCase): |
828 | """Test features involving input to the dash search""" |
829 | |
830 | === modified file 'tests/autopilot/unity/tests/test_hud.py' |
831 | --- tests/autopilot/unity/tests/test_hud.py 2012-09-18 01:41:46 +0000 |
832 | +++ tests/autopilot/unity/tests/test_hud.py 2012-09-18 17:41:27 +0000 |
833 | @@ -409,6 +409,38 @@ |
834 | self.keyboard.type("HasFocus") |
835 | self.assertThat(self.hud.search_string, Eventually(Equals("HasFocus"))) |
836 | |
837 | + def test_closes_mouse_down_outside(self): |
838 | + """Test that a mouse down outside of the hud closes the hud.""" |
839 | + |
840 | + self.hud.ensure_visible() |
841 | + current_monitor = self.hud.monitor |
842 | + |
843 | + (x,y,w,h) = self.hud.geometry |
844 | + (screen_x,screen_y,screen_w,screen_h) = self.screen_geo.get_monitor_geometry(current_monitor) |
845 | + |
846 | + self.mouse.move(x + w + (screen_w-((screen_x-x)+w))/2, y + h + (screen_h-((screen_y-y)+h))/2) |
847 | + self.mouse.click() |
848 | + |
849 | + self.assertThat(self.hud.visible, Eventually(Equals(False))) |
850 | + |
851 | + def test_closes_then_focuses_window_on_mouse_down(self): |
852 | + """If 2 windows are open with 1 maximized and the non-maxmized |
853 | + focused. Then from the Hud clicking on the maximized window |
854 | + must focus that window and close the hud. |
855 | + """ |
856 | + char_win = self.start_app("Character Map") |
857 | + self.keybinding("window/maximize") |
858 | + self.start_app("Calculator") |
859 | + |
860 | + self.hud.ensure_visible() |
861 | + |
862 | + #Click bottom right of the screen |
863 | + w = self.screen_geo.get_screen_width() |
864 | + h = self.screen_geo.get_screen_height() |
865 | + self.mouse.move(w,h) |
866 | + self.mouse.click() |
867 | + |
868 | + self.assertProperty(char_win, is_active=True) |
869 | |
870 | class HudLauncherInteractionsTests(HudTestsBase): |
871 | |
872 | |
873 | === modified file 'tests/test_hud_controller.cpp' |
874 | --- tests/test_hud_controller.cpp 2012-07-04 02:37:23 +0000 |
875 | +++ tests/test_hud_controller.cpp 2012-09-18 17:41:27 +0000 |
876 | @@ -44,12 +44,13 @@ |
877 | MOCK_METHOD0(SearchFinished, void()); |
878 | MOCK_METHOD4(SetIcon, void(std::string const&, unsigned int tile_size, unsigned int size, unsigned int padding)); |
879 | MOCK_METHOD1(SetQueries, void(hud::Hud::Queries queries)); |
880 | - MOCK_METHOD2(SetWindowGeometry, void(nux::Geometry const& absolute_geo, nux::Geometry const& geo)); |
881 | + MOCK_METHOD2(SetMonitorOffset, void(int x, int y)); |
882 | MOCK_METHOD1(ShowEmbeddedIcon, void(bool show)); |
883 | MOCK_CONST_METHOD0(default_focus, nux::View*()); |
884 | MOCK_CONST_METHOD0(GetName, std::string()); |
885 | MOCK_METHOD1(AddProperties, void(GVariantBuilder*)); |
886 | MOCK_METHOD2(Draw, void(nux::GraphicsEngine&, bool)); |
887 | + MOCK_METHOD0(GetContentGeometry, nux::Geometry()); |
888 | |
889 | }; |
890 | |
891 | |
892 | === added file 'unity-shared/ResizingBaseWindow.h' |
893 | --- unity-shared/ResizingBaseWindow.h 1970-01-01 00:00:00 +0000 |
894 | +++ unity-shared/ResizingBaseWindow.h 2012-09-18 17:41:27 +0000 |
895 | @@ -0,0 +1,53 @@ |
896 | +/* |
897 | + * Copyright (C) 2012 Canonical Ltd |
898 | + * |
899 | + * This program is free software: you can redistribute it and/or modify |
900 | + * it under the terms of the GNU General Public License version 3 as |
901 | + * published by the Free Software Foundation. |
902 | + * |
903 | + * This program is distributed in the hope that it will be useful, |
904 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
905 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
906 | + * GNU General Public License for more details. |
907 | + * |
908 | + * You should have received a copy of the GNU General Public License |
909 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
910 | + * |
911 | + * Authored by: Nick Dedekind <nick.dedekind@canonical.com> |
912 | + */ |
913 | + |
914 | +#ifndef RESIZEDINPUTWINDOW_BASEWINDOW_H |
915 | +#define RESIZEDINPUTWINDOW_BASEWINDOW_H |
916 | + |
917 | +#include <Nux/BaseWindow.h> |
918 | + |
919 | +namespace unity |
920 | +{ |
921 | + |
922 | +class ResizingBaseWindow : public nux::BaseWindow |
923 | +{ |
924 | +public: |
925 | + ResizingBaseWindow(const char *WindowName, std::function<nux::Geometry (nux::Geometry const&)> geo_func) |
926 | + : BaseWindow(WindowName, NUX_TRACKER_LOCATION) |
927 | + { |
928 | + geo_func_ = geo_func; |
929 | + } |
930 | + |
931 | + void UpdateInputWindowGeometry() |
932 | + { |
933 | + if (m_input_window && m_input_window_enabled) |
934 | + m_input_window->SetGeometry(geo_func_(GetGeometry())); |
935 | + } |
936 | + |
937 | + virtual void SetGeometry(const nux::Geometry &geo) |
938 | + { |
939 | + Area::SetGeometry(geo); |
940 | + UpdateInputWindowGeometry(); |
941 | + } |
942 | + |
943 | +private: |
944 | + std::function<nux::Geometry (nux::Geometry const&)> geo_func_; |
945 | +}; |
946 | + |
947 | +} |
948 | +#endif // RESIZEDINPUTWINDOW_BASEWINDOW_H |
This is a bit of a cheeky fix.
The problem causing the events to be stolen is that the base window of the dash/hud takes the monitor geometry as it's own. The XInputWindow which is responsible for receiving the XEvents has the same geometry.
This branch side-steps this issue by resizing the XInputWindow to match the actual size of the dash/hud, so if a user clicks outside the dash, it doesnt receive the click.