Merge lp:~brandontschaefer/unity/alt+tab-mouse into lp:unity

Proposed by Brandon Schaefer
Status: Merged
Approved by: Brandon Schaefer
Approved revision: no longer in the source branch.
Merged at revision: 3462
Proposed branch: lp:~brandontschaefer/unity/alt+tab-mouse
Merge into: lp:unity
Diff against target: 1214 lines (+599/-73)
16 files modified
launcher/StandaloneSwitcher.cpp (+0/-1)
launcher/SwitcherController.cpp (+59/-23)
launcher/SwitcherController.h (+1/-2)
launcher/SwitcherControllerImpl.h (+2/-1)
launcher/SwitcherModel.cpp (+6/-0)
launcher/SwitcherModel.h (+1/-0)
launcher/SwitcherView.cpp (+241/-6)
launcher/SwitcherView.h (+35/-3)
plugins/unityshell/src/unityshell.cpp (+73/-35)
plugins/unityshell/src/unityshell.h (+3/-0)
tests/autopilot/unity/emulators/switcher.py (+14/-0)
tests/autopilot/unity/tests/test_switcher.py (+99/-0)
tests/test_switcher_controller.cpp (+28/-0)
unity-shared/AbstractIconRenderer.h (+15/-1)
unity-shared/LayoutSystem.cpp (+14/-0)
unity-shared/LayoutSystem.h (+8/-1)
To merge this branch: bzr merge lp:~brandontschaefer/unity/alt+tab-mouse
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
PS Jenkins bot (community) continuous-integration Approve
Christopher Townsend Approve
Review via email: mp+174898@code.launchpad.net

Commit message

Adds the ability to use the mouse in the switcher.

Description of the change

We use compiz to grab the screen, and from there send all the grabbed events down to nux, which then nux emits them back up to the SwitcherView.

From there we have to figure out where the mouse is located x/y, if its over an icon change selection, same with detail mode. As the SwitcherView takes up most of the screen.

Right clicking toggles detail mode.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

I like a lot the change and the cleanup in event handling for the switcher we had. Even more that we can reuse some code we wrote to get things work easily.
Some comments.

It would be nice if you could abastract a little these signal names:

right_clicked_icon (detail request?)
mouse_moving_over_icon (mouse_move?)

131 + introspection_results_.clear();

Do we really need to keep them around? Why not just a local var?

Anyway:
135 + for (auto target : render_targets_)

322 + int half_size = icon_size.Get() / 2 + 10;

10? Magic number? :)

use auto const& please.

Also there are other behaviors to fix:
* The logic of the scroll wheel, as now here it's inverted to the one we had before.
* The click activation, as it should make sure that you activate an icon only if the mouse-up happened where mouse down happened before.
* The detail selection doesn't work on secondary monitors.
* It would be nice to remove the spread offset (or at least to define it in the controller, just once)

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Christopher Townsend (townsend) wrote :

Jenkins failures are due to an undefined member:

/tmp/buildd/unity-7.0.2+13.10.20130705.1bzr3437pkg0saucy156/launcher/StandaloneSwitcher.cpp: In function 'void ThreadWidgetInit(nux::NThread*, void*)':
/tmp/buildd/unity-7.0.2+13.10.20130705.1bzr3437pkg0saucy156/launcher/StandaloneSwitcher.cpp:134:15: error: 'class unity::switcher::Controller' has no member named 'SetWorkspace'
   controller->SetWorkspace(nux::Geometry(0, 0, 900, 600), 0);
               ^

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Good... Some comments:

124 + monitor_geo.x += XY_OFFSET;
125 + monitor_geo.y += XY_OFFSET;
126 + monitor_geo.width -= WH_OFFSET;
127 + monitor_geo.height -= WH_OFFSET;

What about monitor_geo.OffsetSize() and monitor_geo.OffsetPosition() ?

139 + view_->hide_request.connect ([this] (bool activate) { Hide(activate); });

Since both have a bool as parameter, you can just use sigc::mem_fun or std::bind there...

994
  LayoutWindow::Ptr layout_window(0);

No need to set it to 0, however you can also just return inside the loop and return nullptr otherwise, g++ will be smart enough to convert.

UnityScreen::get (screen)

Get rid of the spaces

825 + LayoutWindow::Ptr const &layout_window = UnityScreen::get(screen)->
826 + GetSwitcherDetailLayoutWindow(window->id());

One line please (in case use auto const&).

Some code in lines 659-673 and 681-696 (middle click mouse handling in UnityWindow) is duplicated, what about adding a function to check if the position hits a window thumbnail (that basically checks the case of the switcher and of the scale).

I've also incurred into a regression: if I select the top-left window in detail mode (or the only one existent in case we have just one), then the switcher selects the window but it doesn't hide.

Finally, this not happen always, but when I do click -> move the mouse outside the clicked area -> release, the switcher closes

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Christopher Townsend (townsend) wrote :

I'm running all of the unity.tests.test_switcher.* AP tests and getting a Compiz crash in (I think) the test_switcher_scroll_next (show_desktop_icon_true) test.

The stack trace shows the crash manifests itself in unity/launcher/SwitcherModel.cpp on line 154 which is new to this MP.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Christopher Townsend (townsend) wrote :

The unity.tests.test_switcher.SwitcherWindowsManagementTests.test_switcher_rises_other_application AP test fails with this MP. It does not fail with trunk.

review: Needs Fixing
Revision history for this message
Christopher Townsend (townsend) wrote :

Well, I think the failing AP test is caused by something on my machine. It failed twice in a row, then after that, has passed at least 5 times with no issue.

Since Marco has weighed in and all of his concerns are addressed and now all AP tests pass, I'm going to approve this thing.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Cool, I see all the changes I requested are in the merged version, nice! :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'launcher/StandaloneSwitcher.cpp'
--- launcher/StandaloneSwitcher.cpp 2013-02-06 17:27:24 +0000
+++ launcher/StandaloneSwitcher.cpp 2013-08-09 17:51:48 +0000
@@ -131,7 +131,6 @@
131 nux::VLayout* layout = new nux::VLayout(TEXT(""), NUX_TRACKER_LOCATION);131 nux::VLayout* layout = new nux::VLayout(TEXT(""), NUX_TRACKER_LOCATION);
132132
133 controller = std::make_shared<Controller>();133 controller = std::make_shared<Controller>();
134 controller->SetWorkspace(nux::Geometry(0, 0, 900, 600), 0);
135134
136 layout->SetContentDistribution(nux::MAJOR_POSITION_CENTER);135 layout->SetContentDistribution(nux::MAJOR_POSITION_CENTER);
137 layout->SetHorizontalExternalMargin (10);136 layout->SetHorizontalExternalMargin (10);
138137
=== modified file 'launcher/SwitcherController.cpp'
--- launcher/SwitcherController.cpp 2013-06-18 19:04:55 +0000
+++ launcher/SwitcherController.cpp 2013-08-09 17:51:48 +0000
@@ -23,6 +23,7 @@
2323
24#include "unity-shared/UBusMessages.h"24#include "unity-shared/UBusMessages.h"
25#include "unity-shared/WindowManager.h"25#include "unity-shared/WindowManager.h"
26#include "unity-shared/UScreen.h"
2627
27#include "SwitcherController.h"28#include "SwitcherController.h"
28#include "SwitcherControllerImpl.h"29#include "SwitcherControllerImpl.h"
@@ -41,6 +42,8 @@
41const std::string DETAIL_TIMEOUT = "detail-timeout";42const std::string DETAIL_TIMEOUT = "detail-timeout";
42const std::string VIEW_CONSTRUCT_IDLE = "view-construct-idle";43const std::string VIEW_CONSTRUCT_IDLE = "view-construct-idle";
43const unsigned FADE_DURATION = 80;44const unsigned FADE_DURATION = 80;
45const int XY_OFFSET = 100;
46const int WH_OFFSET = -200;
4447
45/**48/**
46 * Helper comparison functor for sorting application icons.49 * Helper comparison functor for sorting application icons.
@@ -78,7 +81,6 @@
78 , impl_(new Controller::Impl(this, 20, create_window))81 , impl_(new Controller::Impl(this, 20, create_window))
79{}82{}
8083
81
82Controller::~Controller()84Controller::~Controller()
83{}85{}
8486
@@ -93,6 +95,9 @@
93 SortMode sort,95 SortMode sort,
94 std::vector<AbstractLauncherIcon::Ptr> results)96 std::vector<AbstractLauncherIcon::Ptr> results)
95{97{
98 auto uscreen = UScreen::GetDefault();
99 monitor_ = uscreen->GetMonitorWithMouse();
100
96 impl_->Show(show, sort, results);101 impl_->Show(show, sort, results);
97}102}
98103
@@ -102,15 +107,6 @@
102 impl_->model_->Select(index);107 impl_->model_->Select(index);
103}108}
104109
105void Controller::SetWorkspace(nux::Geometry geo, int monitor)
106{
107 monitor_ = monitor;
108 impl_->workarea_ = geo;
109
110 if (impl_->view_)
111 impl_->view_->monitor = monitor_;
112}
113
114void Controller::Hide(bool accept_state)110void Controller::Hide(bool accept_state)
115{111{
116 if (Visible())112 if (Visible())
@@ -124,6 +120,14 @@
124 return visible_;120 return visible_;
125}121}
126122
123nux::Geometry Controller::GetInputWindowGeometry() const
124{
125 if (impl_->view_window_)
126 return impl_->view_window_->GetGeometry();
127
128 return {0, 0, 0, 0};
129}
130
127bool Controller::StartDetailMode()131bool Controller::StartDetailMode()
128{132{
129 if (visible_)133 if (visible_)
@@ -333,6 +337,7 @@
333 obj_->AddChild(model_.get());337 obj_->AddChild(model_.get());
334 model_->selection_changed.connect(sigc::mem_fun(this, &Controller::Impl::OnModelSelectionChanged));338 model_->selection_changed.connect(sigc::mem_fun(this, &Controller::Impl::OnModelSelectionChanged));
335 model_->detail_selection.changed.connect([this] (bool) { sources_.Remove(DETAIL_TIMEOUT); });339 model_->detail_selection.changed.connect([this] (bool) { sources_.Remove(DETAIL_TIMEOUT); });
340 model_->request_detail_hide.connect(sigc::mem_fun(this, &Controller::Impl::DetailHide));
336 model_->only_detail_on_viewport = (show == ShowMode::CURRENT_VIEWPORT);341 model_->only_detail_on_viewport = (show == ShowMode::CURRENT_VIEWPORT);
337342
338 SelectFirstItem();343 SelectFirstItem();
@@ -350,17 +355,21 @@
350 ShowView();355 ShowView();
351 }356 }
352357
353 if (obj_->detail_on_timeout)358 ResetDetailTimer(obj_->initial_detail_timeout_length);
354 {
355 auto cb_func = sigc::mem_fun(this, &Controller::Impl::OnDetailTimer);
356 sources_.AddTimeout(obj_->initial_detail_timeout_length, cb_func, DETAIL_TIMEOUT);
357 }
358359
359 ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);360 ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
360 ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN,361 ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN,
361 g_variant_new("(bi)", true, obj_->monitor_));362 g_variant_new("(bi)", true, obj_->monitor_));
362}363}
363364
365void Controller::Impl::ResetDetailTimer(int timeout_length)
366{
367 if (obj_->detail_on_timeout)
368 {
369 auto cb_func = sigc::mem_fun(this, &Controller::Impl::OnDetailTimer);
370 sources_.AddTimeout(timeout_length, cb_func, DETAIL_TIMEOUT);
371 }
372}
364373
365bool Controller::Impl::OnDetailTimer()374bool Controller::Impl::OnDetailTimer()
366{375{
@@ -375,11 +384,7 @@
375384
376void Controller::Impl::OnModelSelectionChanged(AbstractLauncherIcon::Ptr const& icon)385void Controller::Impl::OnModelSelectionChanged(AbstractLauncherIcon::Ptr const& icon)
377{386{
378 if (obj_->detail_on_timeout)387 ResetDetailTimer(obj_->detail_timeout_length);
379 {
380 auto cb_func = sigc::mem_fun(this, &Controller::Impl::OnDetailTimer);
381 sources_.AddTimeout(obj_->detail_timeout_length, cb_func, DETAIL_TIMEOUT);
382 }
383388
384 if (icon)389 if (icon)
385 {390 {
@@ -434,10 +439,21 @@
434 view_window_->SetOpacity(0.0f);439 view_window_->SetOpacity(0.0f);
435 view_window_->SetLayout(main_layout_);440 view_window_->SetLayout(main_layout_);
436 view_window_->SetBackgroundColor(nux::color::Transparent);441 view_window_->SetBackgroundColor(nux::color::Transparent);
437 view_window_->SetGeometry(workarea_);
438 }442 }
439}443}
440444
445nux::Geometry GetSwitcherViewsGeometry()
446{
447 auto uscreen = UScreen::GetDefault();
448 int monitor = uscreen->GetMonitorWithMouse();
449 auto monitor_geo = uscreen->GetMonitorGeometry(monitor);
450
451 monitor_geo.OffsetPosition(XY_OFFSET, XY_OFFSET);
452 monitor_geo.OffsetSize(WH_OFFSET, WH_OFFSET);
453
454 return monitor_geo;
455}
456
441void Controller::Impl::ConstructView()457void Controller::Impl::ConstructView()
442{458{
443 if (view_ || !model_)459 if (view_ || !model_)
@@ -451,10 +467,22 @@
451 view_->background_color = bg_color_;467 view_->background_color = bg_color_;
452 view_->monitor = obj_->monitor_;468 view_->monitor = obj_->monitor_;
453469
470 view_->hide_request.connect(sigc::mem_fun(this, &Controller::Impl::Hide));
471
472 view_->switcher_mouse_up.connect([this] (int icon_index, int button) {
473 if (button == 3)
474 InitiateDetail(true);
475 });
476
477 view_->switcher_mouse_move.connect([this] (int icon_index) {
478 if (icon_index >= 0)
479 ResetDetailTimer(obj_->detail_timeout_length);
480 });
481
454 ConstructWindow();482 ConstructWindow();
455 main_layout_->AddView(view_.GetPointer(), 1);483 main_layout_->AddView(view_.GetPointer(), 1);
456 view_window_->SetEnterFocusInputArea(view_.GetPointer());484 view_window_->SetEnterFocusInputArea(view_.GetPointer());
457 view_window_->SetGeometry(workarea_);485 view_window_->SetGeometry(GetSwitcherViewsGeometry());
458486
459 view_built.emit();487 view_built.emit();
460}488}
@@ -491,6 +519,14 @@
491 }519 }
492}520}
493521
522void Controller::Impl::DetailHide()
523{
524 // FIXME We need to refactor SwitcherModel so we can add/remove icons without causing
525 // a crash. If you remove the last application in the list it crashes.
526 model_->detail_selection = false;
527 Hide(false);
528}
529
494void Controller::Impl::HideWindow()530void Controller::Impl::HideWindow()
495{531{
496 main_layout_->RemoveChildObject(view_.GetPointer());532 main_layout_->RemoveChildObject(view_.GetPointer());
@@ -579,7 +615,7 @@
579 obj_->detail_mode_ = DetailMode::TAB_NEXT_WINDOW;615 obj_->detail_mode_ = DetailMode::TAB_NEXT_WINDOW;
580 }616 }
581 else617 else
582 { 618 {
583 model_->detail_selection = false;619 model_->detail_selection = false;
584 }620 }
585}621}
586622
=== modified file 'launcher/SwitcherController.h'
--- launcher/SwitcherController.h 2013-06-18 18:48:31 +0000
+++ launcher/SwitcherController.h 2013-08-09 17:51:48 +0000
@@ -88,6 +88,7 @@
88 bool CanShowSwitcher(const std::vector<launcher::AbstractLauncherIcon::Ptr>& resutls) const;88 bool CanShowSwitcher(const std::vector<launcher::AbstractLauncherIcon::Ptr>& resutls) const;
8989
90 bool Visible();90 bool Visible();
91 nux::Geometry GetInputWindowGeometry() const;
9192
92 bool StartDetailMode();93 bool StartDetailMode();
93 bool StopDetailMode();94 bool StopDetailMode();
@@ -107,8 +108,6 @@
107108
108 void SelectFirstItem();109 void SelectFirstItem();
109110
110 void SetWorkspace(nux::Geometry geo, int monitor);
111
112 nux::ObjectPtr<SwitcherView> GetView() const;111 nux::ObjectPtr<SwitcherView> GetView() const;
113112
114 ui::LayoutWindow::Vector ExternalRenderTargets();113 ui::LayoutWindow::Vector ExternalRenderTargets();
115114
=== modified file 'launcher/SwitcherControllerImpl.h'
--- launcher/SwitcherControllerImpl.h 2013-06-14 00:23:34 +0000
+++ launcher/SwitcherControllerImpl.h 2013-08-09 17:51:48 +0000
@@ -48,6 +48,7 @@
4848
49 void Show(ShowMode show, SortMode sort, std::vector<launcher::AbstractLauncherIcon::Ptr> results);49 void Show(ShowMode show, SortMode sort, std::vector<launcher::AbstractLauncherIcon::Ptr> results);
50 void Hide(bool accept_state);50 void Hide(bool accept_state);
51 void DetailHide();
5152
52 void Next();53 void Next();
53 void Prev();54 void Prev();
@@ -82,6 +83,7 @@
82 void ShowView();83 void ShowView();
83 void HideWindow();84 void HideWindow();
8485
86 void ResetDetailTimer(int timeout_length);
85 bool OnDetailTimer();87 bool OnDetailTimer();
86 void OnModelSelectionChanged(launcher::AbstractLauncherIcon::Ptr const& icon);88 void OnModelSelectionChanged(launcher::AbstractLauncherIcon::Ptr const& icon);
87 void OnBackgroundUpdate(GVariant* data);89 void OnBackgroundUpdate(GVariant* data);
@@ -94,7 +96,6 @@
94 SwitcherView::Ptr view_;96 SwitcherView::Ptr view_;
9597
96 // @todo move these view data into the SwitcherView class98 // @todo move these view data into the SwitcherView class
97 nux::Geometry workarea_;
98 Controller::WindowCreator create_window_;99 Controller::WindowCreator create_window_;
99 MockableBaseWindow::Ptr view_window_;100 MockableBaseWindow::Ptr view_window_;
100 nux::HLayout* main_layout_;101 nux::HLayout* main_layout_;
101102
=== modified file 'launcher/SwitcherModel.cpp'
--- launcher/SwitcherModel.cpp 2013-06-20 20:46:40 +0000
+++ launcher/SwitcherModel.cpp 2013-08-09 17:51:48 +0000
@@ -149,6 +149,12 @@
149 results.push_back(xid);149 results.push_back(xid);
150 }150 }
151151
152 if (results.empty() && detail_selection)
153 {
154 request_detail_hide.emit();
155 return results;
156 }
157
152 std::sort(results.begin(), results.end(), [&wm](Window first, Window second) {158 std::sort(results.begin(), results.end(), [&wm](Window first, Window second) {
153 return wm.GetWindowActiveNumber(first) > wm.GetWindowActiveNumber(second);159 return wm.GetWindowActiveNumber(first) > wm.GetWindowActiveNumber(second);
154 });160 });
155161
=== modified file 'launcher/SwitcherModel.h'
--- launcher/SwitcherModel.h 2013-06-17 23:56:23 +0000
+++ launcher/SwitcherModel.h 2013-08-09 17:51:48 +0000
@@ -101,6 +101,7 @@
101 void Select(unsigned int index);101 void Select(unsigned int index);
102102
103 sigc::signal<void, launcher::AbstractLauncherIcon::Ptr const&> selection_changed;103 sigc::signal<void, launcher::AbstractLauncherIcon::Ptr const&> selection_changed;
104 sigc::signal<void> request_detail_hide;
104105
105protected:106protected:
106 // Introspectable methods107 // Introspectable methods
107108
=== modified file 'launcher/SwitcherView.cpp'
--- launcher/SwitcherView.cpp 2013-07-29 17:17:43 +0000
+++ launcher/SwitcherView.cpp 2013-08-09 17:51:48 +0000
@@ -21,6 +21,7 @@
21#include "SwitcherView.h"21#include "SwitcherView.h"
22#include "unity-shared/IconRenderer.h"22#include "unity-shared/IconRenderer.h"
23#include "unity-shared/TimeUtil.h"23#include "unity-shared/TimeUtil.h"
24#include "unity-shared/UScreen.h"
2425
25#include <Nux/Nux.h>26#include <Nux/Nux.h>
26#include <UnityCore/Variant.h>27#include <UnityCore/Variant.h>
@@ -36,6 +37,8 @@
36namespace37namespace
37{38{
38 const unsigned int VERTICAL_PADDING = 45;39 const unsigned int VERTICAL_PADDING = 45;
40 const unsigned int SPREAD_OFFSET = 100;
41 const unsigned int EXTRA_ICON_SPACE = 10;
39}42}
4043
41NUX_IMPLEMENT_OBJECT_TYPE(SwitcherView);44NUX_IMPLEMENT_OBJECT_TYPE(SwitcherView);
@@ -55,6 +58,8 @@
55 , spread_size(3.5f)58 , spread_size(3.5f)
56 , icon_renderer_(std::make_shared<IconRenderer>())59 , icon_renderer_(std::make_shared<IconRenderer>())
57 , text_view_(new StaticCairoText(""))60 , text_view_(new StaticCairoText(""))
61 , last_icon_selected_(-1)
62 , last_detail_icon_selected_(-1)
58 , target_sizes_set_(false)63 , target_sizes_set_(false)
59{64{
60 icon_renderer_->pip_style = OVER_TILE;65 icon_renderer_->pip_style = OVER_TILE;
@@ -68,7 +73,13 @@
68 icon_size.changed.connect (sigc::mem_fun (this, &SwitcherView::OnIconSizeChanged));73 icon_size.changed.connect (sigc::mem_fun (this, &SwitcherView::OnIconSizeChanged));
69 tile_size.changed.connect (sigc::mem_fun (this, &SwitcherView::OnTileSizeChanged));74 tile_size.changed.connect (sigc::mem_fun (this, &SwitcherView::OnTileSizeChanged));
7075
76 mouse_move.connect (sigc::mem_fun(this, &SwitcherView::RecvMouseMove));
77 mouse_down.connect (sigc::mem_fun(this, &SwitcherView::RecvMouseDown));
78 mouse_up.connect (sigc::mem_fun(this, &SwitcherView::RecvMouseUp));
79 mouse_wheel.connect(sigc::mem_fun(this, &SwitcherView::RecvMouseWheel));
80
71 CaptureMouseDownAnyWhereElse(true);81 CaptureMouseDownAnyWhereElse(true);
82 SetAcceptMouseWheelEvent(true);
72 ResetTimer();83 ResetTimer();
7384
74 animate.changed.connect([this] (bool enabled) {85 animate.changed.connect([this] (bool enabled) {
@@ -103,9 +114,32 @@
103 .add("animation-length", animation_length)114 .add("animation-length", animation_length)
104 .add("spread-size", (float)spread_size)115 .add("spread-size", (float)spread_size)
105 .add("label", text_view_->GetText())116 .add("label", text_view_->GetText())
117 .add("spread_offset", SPREAD_OFFSET)
106 .add("label_visible", text_view_->IsVisible());118 .add("label_visible", text_view_->IsVisible());
107}119}
108120
121debug::Introspectable::IntrospectableList SwitcherView::GetIntrospectableChildren()
122{
123 std::list<unity::debug::Introspectable*> introspection_results;
124
125 if (model_->detail_selection)
126 {
127 for (auto const& target : render_targets_)
128 {
129 introspection_results.push_back(target.get());
130 }
131 }
132 else if (!last_args_.empty())
133 {
134 for (auto& args : last_args_)
135 {
136 introspection_results.push_back(&args);
137 }
138 }
139
140 return introspection_results;
141}
142
109LayoutWindow::Vector SwitcherView::ExternalTargets ()143LayoutWindow::Vector SwitcherView::ExternalTargets ()
110{144{
111 return render_targets_;145 return render_targets_;
@@ -118,6 +152,8 @@
118 model->detail_selection.changed.connect (sigc::mem_fun (this, &SwitcherView::OnDetailSelectionChanged));152 model->detail_selection.changed.connect (sigc::mem_fun (this, &SwitcherView::OnDetailSelectionChanged));
119 model->detail_selection_index.changed.connect (sigc::mem_fun (this, &SwitcherView::OnDetailSelectionIndexChanged));153 model->detail_selection_index.changed.connect (sigc::mem_fun (this, &SwitcherView::OnDetailSelectionIndexChanged));
120154
155 last_icon_selected_ = -1;
156
121 if (!model->Selection())157 if (!model->Selection())
122 return;158 return;
123159
@@ -129,12 +165,12 @@
129165
130void SwitcherView::OnIconSizeChanged (int size)166void SwitcherView::OnIconSizeChanged (int size)
131{167{
132 icon_renderer_->SetTargetSize(tile_size, icon_size, 10);168 icon_renderer_->SetTargetSize(tile_size, icon_size, minimum_spacing);
133}169}
134170
135void SwitcherView::OnTileSizeChanged (int size)171void SwitcherView::OnTileSizeChanged (int size)
136{172{
137 icon_renderer_->SetTargetSize(tile_size, icon_size, 10);173 icon_renderer_->SetTargetSize(tile_size, icon_size, minimum_spacing);
138 vertical_size = tile_size + VERTICAL_PADDING * 2;174 vertical_size = tile_size + VERTICAL_PADDING * 2;
139}175}
140176
@@ -167,6 +203,8 @@
167{203{
168 text_view_->SetVisible(!detail);204 text_view_->SetVisible(!detail);
169205
206 last_detail_icon_selected_ = -1;
207
170 if (!detail)208 if (!detail)
171 {209 {
172 text_view_->SetText(model_->Selection()->tooltip_text());210 text_view_->SetText(model_->Selection()->tooltip_text());
@@ -186,6 +224,181 @@
186 QueueDraw();224 QueueDraw();
187}225}
188226
227nux::Point CalculateMouseMonitorOffset(int x, int y)
228{
229 int monitor = unity::UScreen::GetDefault()->GetMonitorWithMouse();
230 nux::Geometry const& geo = unity::UScreen::GetDefault()->GetMonitorGeometry(monitor);
231
232 return {geo.x + x, geo.y + y};
233}
234
235void SwitcherView::RecvMouseMove(int x, int y, int /*dx*/, int /*dy*/, unsigned long /*button_flags*/, unsigned long /*key_flags*/)
236{
237 if (model_->detail_selection)
238 {
239 HandleDetailMouseMove(x, y);
240 }
241 else
242 {
243 HandleMouseMove(x, y);
244 }
245}
246
247void SwitcherView::HandleDetailMouseMove(int x, int y)
248{
249 nux::Point const& mouse_pos = CalculateMouseMonitorOffset(x, y);
250 int detail_icon_index = DetailIconIdexAt(mouse_pos.x, mouse_pos.y);
251
252 if (detail_icon_index >= 0 && detail_icon_index != last_detail_icon_selected_)
253 {
254 model_->detail_selection_index = detail_icon_index;
255 last_detail_icon_selected_ = detail_icon_index;
256 }
257}
258
259void SwitcherView::HandleMouseMove(int x, int y)
260{
261 int icon_index = IconIndexAt(x, y);
262
263 if (icon_index >= 0)
264 {
265 if (icon_index != last_icon_selected_)
266 {
267 if (icon_index != model_->SelectionIndex())
268 {
269 model_->Select(icon_index);
270 }
271
272 last_icon_selected_ = icon_index;
273 }
274
275 switcher_mouse_move.emit(icon_index);
276 }
277}
278
279void SwitcherView::RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long /*key_flags*/)
280{
281 int button = nux::GetEventButton(button_flags);
282
283 if (!CheckMouseInsideBackground(x, y))
284 hide_request.emit(false);
285
286 if (model_->detail_selection)
287 {
288 HandleDetailMouseDown(x, y, button);
289 }
290 else
291 {
292 HandleMouseDown(x, y, button);
293 }
294}
295
296void SwitcherView::HandleDetailMouseDown(int x, int y, int button)
297{
298 nux::Point const& mouse_pos = CalculateMouseMonitorOffset(x, y);
299 int detail_icon_index = DetailIconIdexAt(mouse_pos.x, mouse_pos.y);
300
301 last_detail_icon_selected_ = detail_icon_index;
302
303 switcher_mouse_down.emit(detail_icon_index, button);
304}
305
306void SwitcherView::HandleMouseDown(int x, int y, int button)
307{
308 int icon_index = IconIndexAt(x,y);
309
310 last_icon_selected_ = icon_index;
311
312 switcher_mouse_down.emit(icon_index, button);
313}
314
315void SwitcherView::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long /*key_flags*/)
316{
317 int button = nux::GetEventButton(button_flags);
318
319 if (model_->detail_selection)
320 {
321 HandleDetailMouseUp(x, y, button);
322 }
323 else
324 {
325 HandleMouseUp(x, y, button);
326 }
327}
328
329void SwitcherView::HandleDetailMouseUp(int x, int y, int button)
330{
331 nux::Point const& mouse_pos = CalculateMouseMonitorOffset(x, y);
332 int detail_icon_index = DetailIconIdexAt(mouse_pos.x, mouse_pos.y);
333
334 switcher_mouse_up.emit(detail_icon_index, button);
335
336 if (button == 1)
337 {
338 if (detail_icon_index >= 0 && detail_icon_index == last_detail_icon_selected_)
339 {
340 model_->detail_selection_index = detail_icon_index;
341 hide_request.emit(true);
342 }
343 }
344 else if (button == 3)
345 {
346 model_->detail_selection = false;
347 }
348}
349
350void SwitcherView::HandleMouseUp(int x, int y, int button)
351{
352 int icon_index = IconIndexAt(x,y);
353
354 switcher_mouse_up.emit(icon_index, button);
355
356 if (button == 1)
357 {
358 if (icon_index >= 0 && icon_index == last_icon_selected_)
359 {
360 model_->Select(icon_index);
361 hide_request.emit(true);
362 }
363 }
364}
365
366void SwitcherView::RecvMouseWheel(int /*x*/, int /*y*/, int wheel_delta, unsigned long /*button_flags*/, unsigned long /*key_flags*/)
367{
368 if (model_->detail_selection)
369 {
370 HandleDetailMouseWheel(wheel_delta);
371 }
372 else
373 {
374 HandleMouseWheel(wheel_delta);
375 }
376}
377
378void SwitcherView::HandleDetailMouseWheel(int wheel_delta)
379{
380 if (wheel_delta > 0)
381 {
382 model_->NextDetail();
383 }
384 else
385 {
386 model_->PrevDetail();
387 }
388}
389
390void SwitcherView::HandleMouseWheel(int wheel_delta)
391{
392 if (wheel_delta > 0)
393 {
394 model_->Next();
395 }
396 else
397 {
398 model_->Prev();
399 }
400}
401
189SwitcherModel::Ptr SwitcherView::GetModel()402SwitcherModel::Ptr SwitcherView::GetModel()
190{403{
191 return model_;404 return model_;
@@ -420,7 +633,7 @@
420 nux::Geometry const& spread_bounds = UpdateRenderTargets(progress);633 nux::Geometry const& spread_bounds = UpdateRenderTargets(progress);
421 ResizeRenderTargets(spread_bounds, progress);634 ResizeRenderTargets(spread_bounds, progress);
422 // remove extra space consumed by spread635 // remove extra space consumed by spread
423 spread_padded_width = spread_bounds.width + 100;636 spread_padded_width = spread_bounds.width + SPREAD_OFFSET;
424 max_width -= spread_padded_width - tile_size;637 max_width -= spread_padded_width - tile_size;
425638
426 int expansion = std::max(0, spread_bounds.height - icon_size);639 int expansion = std::max(0, spread_bounds.height - icon_size);
@@ -551,7 +764,7 @@
551764
552 if (!target_sizes_set_)765 if (!target_sizes_set_)
553 {766 {
554 icon_renderer_->SetTargetSize(tile_size, icon_size, 10);767 icon_renderer_->SetTargetSize(tile_size, icon_size, minimum_spacing);
555 target_sizes_set_ = true;768 target_sizes_set_ = true;
556 }769 }
557770
@@ -640,9 +853,9 @@
640 }853 }
641}854}
642855
643int SwitcherView::IconIndexAt(int x, int y)856int SwitcherView::IconIndexAt(int x, int y) const
644{857{
645 int half_size = icon_size.Get() / 2;858 int half_size = icon_size.Get() / 2 + EXTRA_ICON_SPACE;
646 int icon_index = -1;859 int icon_index = -1;
647860
648 // Taking icon rotation into consideration will make selection more861 // Taking icon rotation into consideration will make selection more
@@ -673,5 +886,27 @@
673 return icon_index;886 return icon_index;
674}887}
675888
889int SwitcherView::DetailIconIdexAt(int x, int y) const
890{
891 int index = -1;
892
893 for (unsigned int i = 0; i < render_targets_.size(); ++i)
894 {
895 if (render_targets_[i]->result.IsPointInside(x + SPREAD_OFFSET, y + SPREAD_OFFSET))
896 return i;
897 }
898
899 return index;
900}
901
902bool SwitcherView::CheckMouseInsideBackground(int x, int y) const
903{
904 nux::Point p(x,y);
905 if (last_background_.IsInside(p))
906 return true;
907
908 return false;
909}
910
676}911}
677}912}
678913
=== modified file 'launcher/SwitcherView.h'
--- launcher/SwitcherView.h 2013-02-13 01:45:00 +0000
+++ launcher/SwitcherView.h 2013-08-09 17:51:48 +0000
@@ -25,6 +25,7 @@
25#include "unity-shared/StaticCairoText.h"25#include "unity-shared/StaticCairoText.h"
26#include "unity-shared/LayoutSystem.h"26#include "unity-shared/LayoutSystem.h"
27#include "unity-shared/BackgroundEffectHelper.h"27#include "unity-shared/BackgroundEffectHelper.h"
28#include "unity-shared/Introspectable.h"
28#include "unity-shared/UnityWindowView.h"29#include "unity-shared/UnityWindowView.h"
2930
30#include <Nux/View.h>31#include <Nux/View.h>
@@ -70,13 +71,24 @@
7071
71 // Returns the index of the icon at the given position, in window coordinates.72 // Returns the index of the icon at the given position, in window coordinates.
72 // If there's no icon there, -1 is returned.73 // If there's no icon there, -1 is returned.
73 int IconIndexAt(int x, int y);74 int IconIndexAt(int x, int y) const;
7475 int DetailIconIdexAt(int x, int y) const;
76
77 /* void; int icon_index, int button*/
78 sigc::signal<void, int, int> switcher_mouse_down;
79 sigc::signal<void, int, int> switcher_mouse_up;
80
81 /* void; int icon_index */
82 sigc::signal<void, int> switcher_mouse_move;
83
84 /* void; bool visible */
85 sigc::signal<void, bool> hide_request;
7586
76protected:87protected:
77 // Introspectable methods88 // Introspectable methods
78 std::string GetName() const;89 std::string GetName() const;
79 void AddProperties(GVariantBuilder* builder);90 void AddProperties(GVariantBuilder* builder);
91 IntrospectableList GetIntrospectableChildren();
8092
81 void PreDraw(nux::GraphicsEngine& GfxContext, bool force_draw);93 void PreDraw(nux::GraphicsEngine& GfxContext, bool force_draw);
82 void DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry const& clip);94 void DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry const& clip);
@@ -88,7 +100,24 @@
88 std::list<ui::RenderArg> RenderArgsFlat(nux::Geometry& background_geo, int selection, float progress);100 std::list<ui::RenderArg> RenderArgsFlat(nux::Geometry& background_geo, int selection, float progress);
89101
90 ui::RenderArg CreateBaseArgForIcon(launcher::AbstractLauncherIcon::Ptr const& icon);102 ui::RenderArg CreateBaseArgForIcon(launcher::AbstractLauncherIcon::Ptr const& icon);
103
91private:104private:
105 void RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
106 void HandleDetailMouseMove(int x, int y);
107 void HandleMouseMove(int x, int y);
108
109 void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
110 void HandleDetailMouseDown(int x, int y, int button);
111 void HandleMouseDown(int x, int y, int button);
112
113 void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags);
114 void HandleDetailMouseUp(int x, int y, int button);
115 void HandleMouseUp(int x, int y, int button);
116
117 void RecvMouseWheel(int x, int y, int wheel_delta, unsigned long button_flags, unsigned long key_flags);
118 void HandleDetailMouseWheel(int wheel_delta);
119 void HandleMouseWheel(int wheel_delta);
120
92 void OnSelectionChanged(launcher::AbstractLauncherIcon::Ptr const& selection);121 void OnSelectionChanged(launcher::AbstractLauncherIcon::Ptr const& selection);
93 void OnDetailSelectionChanged (bool detail);122 void OnDetailSelectionChanged (bool detail);
94 void OnDetailSelectionIndexChanged (unsigned int index);123 void OnDetailSelectionIndexChanged (unsigned int index);
@@ -111,14 +140,17 @@
111 void ResetTimer();140 void ResetTimer();
112 void SaveLast();141 void SaveLast();
113142
143 bool CheckMouseInsideBackground(int x, int y) const;
144
114 SwitcherModel::Ptr model_;145 SwitcherModel::Ptr model_;
115 ui::LayoutSystem layout_system_;146 ui::LayoutSystem layout_system_;
116 ui::AbstractIconRenderer::Ptr icon_renderer_;147 ui::AbstractIconRenderer::Ptr icon_renderer_;
117 nux::ObjectPtr<StaticCairoText> text_view_;148 nux::ObjectPtr<StaticCairoText> text_view_;
118149
150 int last_icon_selected_;
151 int last_detail_icon_selected_;
119 bool target_sizes_set_;152 bool target_sizes_set_;
120153
121
122 std::list<ui::RenderArg> last_args_;154 std::list<ui::RenderArg> last_args_;
123 std::list<ui::RenderArg> saved_args_;155 std::list<ui::RenderArg> saved_args_;
124156
125157
=== modified file 'plugins/unityshell/src/unityshell.cpp'
--- plugins/unityshell/src/unityshell.cpp 2013-08-07 13:27:56 +0000
+++ plugins/unityshell/src/unityshell.cpp 2013-08-09 17:51:48 +0000
@@ -971,6 +971,19 @@
971 return false;971 return false;
972}972}
973973
974LayoutWindow::Ptr UnityScreen::GetSwitcherDetailLayoutWindow(Window window) const
975{
976 LayoutWindow::Vector const& targets = switcher_controller_->ExternalRenderTargets();
977
978 for (LayoutWindow::Ptr const& target : targets)
979 {
980 if (target->xid == window)
981 return target;
982 }
983
984 return nullptr;
985}
986
974void UnityWindow::enterShowDesktop ()987void UnityWindow::enterShowDesktop ()
975{988{
976 if (!mShowdesktopHandler)989 if (!mShowdesktopHandler)
@@ -1169,7 +1182,8 @@
1169 handled = true;1182 handled = true;
1170 }1183 }
1171 else if (event->xbutton.button == Button2 &&1184 else if (event->xbutton.button == Button2 &&
1172 GetScaledGeometry().IsPointInside(event->xbutton.x_root, event->xbutton.y_root))1185 (GetScaledGeometry().IsPointInside(event->xbutton.x_root, event->xbutton.y_root) ||
1186 GetLayoutWindowGeometry().IsPointInside(event->xbutton.x_root, event->xbutton.y_root)))
1173 {1187 {
1174 middle_clicked_ = true;1188 middle_clicked_ = true;
1175 handled = true;1189 handled = true;
@@ -1190,7 +1204,9 @@
1190 if (was_pressed)1204 if (was_pressed)
1191 {1205 {
1192 if (close_button_geo_.IsPointInside(event->xbutton.x_root, event->xbutton.y_root))1206 if (close_button_geo_.IsPointInside(event->xbutton.x_root, event->xbutton.y_root))
1207 {
1193 window->close(0);1208 window->close(0);
1209 }
11941210
1195 handled = true;1211 handled = true;
1196 }1212 }
@@ -1198,7 +1214,8 @@
1198 if (middle_clicked_)1214 if (middle_clicked_)
1199 {1215 {
1200 if (event->xbutton.button == Button2 &&1216 if (event->xbutton.button == Button2 &&
1201 GetScaledGeometry().IsPointInside(event->xbutton.x_root, event->xbutton.y_root))1217 (GetScaledGeometry().IsPointInside(event->xbutton.x_root, event->xbutton.y_root) ||
1218 GetLayoutWindowGeometry().IsPointInside(event->xbutton.x_root, event->xbutton.y_root)))
1202 {1219 {
1203 window->close(0);1220 window->close(0);
1204 }1221 }
@@ -1492,6 +1509,14 @@
1492 if (CompWindow *w = screen->findWindow(ss->getSelectedWindow()))1509 if (CompWindow *w = screen->findWindow(ss->getSelectedWindow()))
1493 skip_other_plugins = UnityWindow::get(w)->handleEvent(event);1510 skip_other_plugins = UnityWindow::get(w)->handleEvent(event);
1494 }1511 }
1512 else if (switcher_controller_->IsDetailViewShown())
1513 {
1514 Window win = switcher_controller_->GetCurrentSelection().window_;
1515 CompWindow* w = screen->findWindow(win);
1516
1517 if (w)
1518 skip_other_plugins = UnityWindow::get(w)->handleEvent(event);
1519 }
1495 break;1520 break;
1496 case ButtonPress:1521 case ButtonPress:
1497 if (super_keypressed_)1522 if (super_keypressed_)
@@ -1505,6 +1530,14 @@
1505 if (CompWindow *w = screen->findWindow(ss->getSelectedWindow()))1530 if (CompWindow *w = screen->findWindow(ss->getSelectedWindow()))
1506 skip_other_plugins = UnityWindow::get(w)->handleEvent(event);1531 skip_other_plugins = UnityWindow::get(w)->handleEvent(event);
1507 }1532 }
1533 else if (switcher_controller_->IsDetailViewShown())
1534 {
1535 Window win = switcher_controller_->GetCurrentSelection().window_;
1536 CompWindow* w = screen->findWindow(win);
1537
1538 if (w)
1539 skip_other_plugins = UnityWindow::get(w)->handleEvent(event);
1540 }
15081541
1509 if (dash_controller_->IsVisible())1542 if (dash_controller_->IsVisible())
1510 {1543 {
@@ -1532,8 +1565,7 @@
1532 }1565 }
1533 }1566 }
1534 }1567 }
15351568 else if (hud_controller_->IsVisible())
1536 if (hud_controller_->IsVisible())
1537 {1569 {
1538 nux::Point pt(event->xbutton.x_root, event->xbutton.y_root);1570 nux::Point pt(event->xbutton.x_root, event->xbutton.y_root);
1539 nux::Geometry const& hud_geo = hud_controller_->GetInputWindowGeometry();1571 nux::Geometry const& hud_geo = hud_controller_->GetInputWindowGeometry();
@@ -1547,24 +1579,26 @@
1547 hud_controller_->HideHud(false);1579 hud_controller_->HideHud(false);
1548 }1580 }
1549 }1581 }
1582 else if (switcher_controller_->Visible())
1583 {
1584 nux::Point pt(event->xbutton.x_root, event->xbutton.y_root);
1585 nux::Geometry const& switcher_geo = switcher_controller_->GetInputWindowGeometry();
1586
1587 if (!switcher_geo.IsInside(pt))
1588 {
1589 switcher_controller_->Hide(false);
1590 }
1591 }
1550 break;1592 break;
1551 case ButtonRelease:1593 case ButtonRelease:
1552 if (switcher_controller_ && switcher_controller_->Visible())1594
1595 if (switcher_controller_->IsDetailViewShown())
1553 {1596 {
1554 XButtonEvent *bev = reinterpret_cast<XButtonEvent*>(event);1597 Window win = switcher_controller_->GetCurrentSelection().window_;
1555 if (bev->time - last_scroll_event_ > 150)1598 CompWindow* w = screen->findWindow(win);
1556 {1599
1557 if (bev->button == Button4 || bev->button == local::SCROLL_UP_BUTTON)1600 if (w)
1558 {1601 skip_other_plugins = UnityWindow::get(w)->handleEvent(event);
1559 switcher_controller_->Prev();
1560 last_scroll_event_ = bev->time;
1561 }
1562 else if (bev->button == Button5 || bev->button == local::SCROLL_DOWN_BUTTON)
1563 {
1564 switcher_controller_->Next();
1565 last_scroll_event_ = bev->time;
1566 }
1567 }
1568 }1602 }
1569 else if (wm.IsScaleActive())1603 else if (wm.IsScaleActive())
1570 {1604 {
@@ -1686,7 +1720,7 @@
1686 }1720 }
16871721
1688 if (!skip_other_plugins &&1722 if (!skip_other_plugins &&
1689 screen->otherGrabExist("deco", "move", "switcher", "resize", "unity-switcher", nullptr))1723 screen->otherGrabExist("deco", "move", "switcher", "resize", nullptr))
1690 {1724 {
1691 wt->ProcessForeignEvent(event, nullptr);1725 wt->ProcessForeignEvent(event, nullptr);
1692 }1726 }
@@ -1890,7 +1924,7 @@
1890bool UnityScreen::altTabInitiateCommon(CompAction* action, switcher::ShowMode show_mode)1924bool UnityScreen::altTabInitiateCommon(CompAction* action, switcher::ShowMode show_mode)
1891{1925{
1892 if (!grab_index_)1926 if (!grab_index_)
1893 grab_index_ = screen->pushGrab (screen->invisibleCursor(), "unity-switcher");1927 grab_index_ = screen->pushGrab (screen->normalCursor(), "unity-switcher");
18941928
1895 screen->addAction(&optionGetAltTabRight());1929 screen->addAction(&optionGetAltTabRight());
1896 screen->addAction(&optionGetAltTabDetailStart());1930 screen->addAction(&optionGetAltTabDetailStart());
@@ -1921,18 +1955,6 @@
19211955
1922void UnityScreen::SetUpAndShowSwitcher(switcher::ShowMode show_mode)1956void UnityScreen::SetUpAndShowSwitcher(switcher::ShowMode show_mode)
1923{1957{
1924 // maybe check launcher position/hide state?
1925
1926 auto uscreen = UScreen::GetDefault();
1927 int monitor = uscreen->GetMonitorWithMouse();
1928 auto monitor_geo = uscreen->GetMonitorGeometry(monitor);
1929
1930 monitor_geo.x += 100;
1931 monitor_geo.y += 100;
1932 monitor_geo.width -= 200;
1933 monitor_geo.height -= 200;
1934 switcher_controller_->SetWorkspace(monitor_geo, monitor);
1935
1936 RaiseInputWindows();1958 RaiseInputWindows();
19371959
1938 auto results = launcher_controller_->GetAltTabIcons(show_mode == switcher::ShowMode::CURRENT_VIEWPORT,1960 auto results = launcher_controller_->GetAltTabIcons(show_mode == switcher::ShowMode::CURRENT_VIEWPORT,
@@ -3819,15 +3841,31 @@
3819 if (state != ScaleScreen::Wait && state != ScaleScreen::Out)3841 if (state != ScaleScreen::Wait && state != ScaleScreen::Out)
3820 return;3842 return;
38213843
3822 auto const& scaled_geo = GetScaledGeometry();3844 nux::Geometry const& scale_geo = GetScaledGeometry();
3845
3823 auto const& pos = scale_win->getCurrentPosition();3846 auto const& pos = scale_win->getCurrentPosition();
38243847
3825 bool highlighted = (ss->getSelectedWindow() == window->id());3848 bool highlighted = (ss->getSelectedWindow() == window->id());
3826 paintFakeDecoration(scaled_geo, attrib, transform, mask, highlighted, pos.scale);3849 paintFakeDecoration(scale_geo, attrib, transform, mask, highlighted, pos.scale);
3850}
3851
3852nux::Geometry UnityWindow::GetLayoutWindowGeometry()
3853{
3854 auto const& layout_window = UnityScreen::get(screen)->GetSwitcherDetailLayoutWindow(window->id());
3855
3856 if (layout_window)
3857 return layout_window->result;
3858
3859 return nux::Geometry();
3827}3860}
38283861
3829nux::Geometry UnityWindow::GetScaledGeometry()3862nux::Geometry UnityWindow::GetScaledGeometry()
3830{3863{
3864 WindowManager& wm = WindowManager::Default();
3865
3866 if (!wm.IsScaleActive())
3867 return nux::Geometry();
3868
3831 ScaleWindow* scale_win = ScaleWindow::get(window);3869 ScaleWindow* scale_win = ScaleWindow::get(window);
38323870
3833 ScalePosition const& pos = scale_win->getCurrentPosition();3871 ScalePosition const& pos = scale_win->getCurrentPosition();
38343872
=== modified file 'plugins/unityshell/src/unityshell.h'
--- plugins/unityshell/src/unityshell.h 2013-08-07 13:27:56 +0000
+++ plugins/unityshell/src/unityshell.h 2013-08-09 17:51:48 +0000
@@ -193,6 +193,8 @@
193193
194 bool DoesPointIntersectUnityGeos(nux::Point const& pt);194 bool DoesPointIntersectUnityGeos(nux::Point const& pt);
195195
196 ui::LayoutWindow::Ptr GetSwitcherDetailLayoutWindow(Window window) const;
197
196protected:198protected:
197 std::string GetName() const;199 std::string GetName() const;
198 void AddProperties(GVariantBuilder* builder);200 void AddProperties(GVariantBuilder* builder);
@@ -392,6 +394,7 @@
392 bool place(CompPoint& pos);394 bool place(CompPoint& pos);
393 CompPoint tryNotIntersectUI(CompPoint& pos);395 CompPoint tryNotIntersectUI(CompPoint& pos);
394 nux::Geometry GetScaledGeometry();396 nux::Geometry GetScaledGeometry();
397 nux::Geometry GetLayoutWindowGeometry();
395398
396 void paintThumbnail(nux::Geometry const& bounding, float parent_alpha, float alpha, float scale_ratio, unsigned deco_height, bool selected);399 void paintThumbnail(nux::Geometry const& bounding, float parent_alpha, float alpha, float scale_ratio, unsigned deco_height, bool selected);
397400
398401
=== modified file 'tests/autopilot/unity/emulators/switcher.py'
--- tests/autopilot/unity/emulators/switcher.py 2013-05-10 05:16:07 +0000
+++ tests/autopilot/unity/emulators/switcher.py 2013-08-09 17:51:48 +0000
@@ -234,6 +234,20 @@
234class SwitcherView(UnityIntrospectionObject):234class SwitcherView(UnityIntrospectionObject):
235 """An emulator class for interacting with with SwitcherView."""235 """An emulator class for interacting with with SwitcherView."""
236236
237 @property
238 def icon_args(self):
239 return self.get_children_by_type(RenderArgs);
240
241 @property
242 def detail_icons(self):
243 return self.get_children_by_type(LayoutWindow);
244
245
246class RenderArgs(UnityIntrospectionObject):
247 """An emulator class for interacting with the RenderArgs class."""
248
249class LayoutWindow(UnityIntrospectionObject):
250 """An emulator class for interacting with the LayoutWindows class."""
237251
238class SwitcherModel(UnityIntrospectionObject):252class SwitcherModel(UnityIntrospectionObject):
239 """An emulator class for interacting with the SwitcherModel."""253 """An emulator class for interacting with the SwitcherModel."""
240254
=== modified file 'tests/autopilot/unity/tests/test_switcher.py'
--- tests/autopilot/unity/tests/test_switcher.py 2013-06-15 02:24:01 +0000
+++ tests/autopilot/unity/tests/test_switcher.py 2013-08-09 17:51:48 +0000
@@ -512,3 +512,102 @@
512 self.addCleanup(self.unity.switcher.terminate)512 self.addCleanup(self.unity.switcher.terminate)
513513
514 self.assertThat(self.unity.switcher.visible, Eventually(Equals(False)))514 self.assertThat(self.unity.switcher.visible, Eventually(Equals(False)))
515
516class SwitcherDetailsMouseTests(SwitcherTestCase):
517 """ Test the interactions with the mouse and the switcher. """
518
519 def setUp(self):
520 super(SwitcherDetailsMouseTests, self).setUp()
521 self.set_timeout_setting(False)
522
523 def test_mouse_highlights_switcher_icons(self):
524 """ Tests that the mouse can hightlight all the switcher icons. """
525
526 self.process_manager.start_app("Character Map")
527
528 self.unity.switcher.initiate()
529 self.addCleanup(self.unity.switcher.terminate)
530
531 icon_args = self.unity.switcher.view.icon_args
532 offset = self.unity.switcher.view.spread_offset
533 icon_cords = []
534
535 # Must collect the cords before moving mouse
536 for args in icon_args:
537 x = args.logical_center_x + offset
538 y = args.logical_center_y + offset
539 icon_cords.append((x,y))
540
541 index = 0;
542 for cords in icon_cords:
543 self.mouse.move(cords[0], cords[1])
544 self.assertThat(index, Equals(self.unity.switcher.selection_index))
545 index += 1
546
547 def test_mouse_clicks_activate_icon(self):
548 """
549 Opens 2 different applications, CharMap being opened before TextEditor.
550 Then we get the index of the CharMap, and click on it, asserting CharMap is focused.
551 """
552
553 char_win1, char_win2 = self.start_applications("Character Map", "Text Editor")
554 self.assertVisibleWindowStack([char_win2, char_win1])
555 self.assertProperty(char_win1, is_focused=False)
556
557 self.unity.switcher.initiate()
558 self.addCleanup(self.unity.switcher.terminate)
559
560 index = self.unity.switcher.selection_index
561 offset = self.unity.switcher.view.spread_offset
562
563 icon_arg = self.unity.switcher.view.icon_args[index]
564 x = icon_arg.logical_center_x + offset
565 y = icon_arg.logical_center_y + offset
566 self.mouse.move(x, y)
567 self.mouse.click()
568
569 self.assertProperty(char_win1, is_focused=True)
570
571 def test_mouse_highlights_switcher_deatil_icons_motion(self):
572 """
573 Gather the cords of all the detail icons, move the mouse through each
574 asserting the index of each icon we move through.
575 """
576
577 self.start_applications("Character Map", "Character Map", "Character Map")
578
579 self.unity.switcher.initiate(SwitcherMode.DETAIL)
580 self.addCleanup(self.unity.switcher.terminate)
581
582 offset = self.unity.switcher.view.spread_offset
583 cords = []
584
585 for icon in self.unity.switcher.view.detail_icons:
586 cords.append((icon.x + offset, icon.y + offset))
587
588 index = 0;
589 for cord in cords:
590 self.mouse.move(cord[0], cord[1])
591 self.assertThat(index, Equals(self.unity.switcher.detail_selection_index))
592 index += 1
593
594 def test_mouse_click_will_activate_detail_icon(self):
595 """
596 Start 2 application of the same type, then click on index 0 in detail mode. This
597 will cause the focus from char_win2 to move to char_win1, showing clicking wokrs.
598 """
599
600 char_win1, char_win2 = self.start_applications("Character Map", "Character Map")
601 self.assertVisibleWindowStack([char_win2, char_win1])
602
603 self.unity.switcher.initiate(SwitcherMode.DETAIL)
604 self.addCleanup(self.unity.switcher.terminate)
605
606 offset = self.unity.switcher.view.spread_offset
607 x = self.unity.switcher.view.detail_icons[0].x + offset
608 y = self.unity.switcher.view.detail_icons[0].y + offset
609
610 self.mouse.move(x,y)
611 self.mouse.click()
612
613 self.assertProperty(char_win1, is_focused=True)
515614
=== modified file 'tests/test_switcher_controller.cpp'
--- tests/test_switcher_controller.cpp 2013-06-21 18:58:17 +0000
+++ tests/test_switcher_controller.cpp 2013-08-09 17:51:48 +0000
@@ -272,3 +272,31 @@
272 EXPECT_EQ(mock_window_->GetOpacity(), 0.0f);272 EXPECT_EQ(mock_window_->GetOpacity(), 0.0f);
273 Mock::VerifyAndClearExpectations(mock_window_.GetPointer());273 Mock::VerifyAndClearExpectations(mock_window_.GetPointer());
274}274}
275
276TEST_F(TestSwitcherController, TestRightClickedReceived)
277{
278 controller_->Show(ShowMode::ALL, SortMode::LAUNCHER_ORDER, icons_);
279
280 auto const& view = controller_->GetView();
281 auto const& model = view->GetModel();
282
283 ASSERT_FALSE(model->detail_selection());
284
285 view->switcher_mouse_up.emit(-1, 3);
286 view->switcher_mouse_down.emit(-1, 3);
287
288 ASSERT_TRUE(model->detail_selection());
289}
290
291TEST_F(TestSwitcherController, TestHideRequest)
292{
293 controller_->Show(ShowMode::ALL, SortMode::LAUNCHER_ORDER, icons_);
294
295 auto const& view = controller_->GetView();
296
297 ASSERT_TRUE(controller_->Visible());
298
299 view->hide_request.emit(false);
300
301 ASSERT_FALSE(controller_->Visible());
302}
275303
=== modified file 'unity-shared/AbstractIconRenderer.h'
--- unity-shared/AbstractIconRenderer.h 2013-04-12 23:33:52 +0000
+++ unity-shared/AbstractIconRenderer.h 2013-08-09 17:51:48 +0000
@@ -22,8 +22,11 @@
2222
23#include <Nux/Nux.h>23#include <Nux/Nux.h>
2424
25#include "Introspectable.h"
25#include "IconTextureSource.h"26#include "IconTextureSource.h"
2627
28#include <UnityCore/Variant.h>
29
27namespace unity30namespace unity
28{31{
29namespace ui32namespace ui
@@ -35,7 +38,7 @@
35 OVER_TILE,38 OVER_TILE,
36};39};
3740
38class RenderArg41class RenderArg : public debug::Introspectable
39{42{
40public:43public:
41 RenderArg()44 RenderArg()
@@ -91,6 +94,17 @@
91 bool colorify_background;94 bool colorify_background;
92 int window_indicators;95 int window_indicators;
93 char shortcut_label;96 char shortcut_label;
97
98protected:
99 // Introspectable methods
100 std::string GetName() const { return "RenderArgs"; }
101 void AddProperties(GVariantBuilder* builder)
102 {
103 unity::variant::BuilderWrapper(builder)
104 .add("logical_center_x", logical_center.x)
105 .add("logical_center_y", logical_center.y)
106 .add("logical_center_z", logical_center.z);
107 }
94};108};
95109
96class AbstractIconRenderer110class AbstractIconRenderer
97111
=== modified file 'unity-shared/LayoutSystem.cpp'
--- unity-shared/LayoutSystem.cpp 2013-06-17 23:56:23 +0000
+++ unity-shared/LayoutSystem.cpp 2013-08-09 17:51:48 +0000
@@ -19,6 +19,8 @@
1919
20#include "LayoutSystem.h"20#include "LayoutSystem.h"
2121
22#include <UnityCore/Variant.h>
23
22namespace unity {24namespace unity {
23namespace ui {25namespace ui {
2426
@@ -290,5 +292,17 @@
290 }292 }
291}293}
292294
295// Introspectable methods
296std::string LayoutWindow::GetName() const
297{
298 return "LayoutWindow";
299}
300
301void LayoutWindow::AddProperties(GVariantBuilder* builder)
302{
303 unity::variant::BuilderWrapper(builder)
304 .add(result);
305}
306
293}307}
294}308}
295309
=== modified file 'unity-shared/LayoutSystem.h'
--- unity-shared/LayoutSystem.h 2013-06-14 00:23:34 +0000
+++ unity-shared/LayoutSystem.h 2013-08-09 17:51:48 +0000
@@ -24,13 +24,15 @@
24#include <sigc++/sigc++.h>24#include <sigc++/sigc++.h>
25#include <Nux/Nux.h>25#include <Nux/Nux.h>
2626
27#include "unity-shared/Introspectable.h"
27#include "unity-shared/WindowManager.h"28#include "unity-shared/WindowManager.h"
2829
29namespace unity {30namespace unity {
30namespace ui {31namespace ui {
3132
32struct LayoutWindow33class LayoutWindow : public debug::Introspectable
33{34{
35public:
34 typedef std::shared_ptr<LayoutWindow> Ptr;36 typedef std::shared_ptr<LayoutWindow> Ptr;
35 typedef std::vector<LayoutWindow::Ptr> Vector;37 typedef std::vector<LayoutWindow::Ptr> Vector;
3638
@@ -45,6 +47,11 @@
45 bool selected;47 bool selected;
46 float aspect_ratio;48 float aspect_ratio;
47 float alpha;49 float alpha;
50
51protected:
52 // Introspectable methods
53 std::string GetName() const;
54 void AddProperties(GVariantBuilder* builder);
48};55};
4956
50class LayoutSystem57class LayoutSystem