2
* Copyright (C) 2011 Canonical Ltd
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License version 3 as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authored by: Jason Smith <jason.smith@canonical.com>
22
#include <Nux/HLayout.h>
24
#include "UBusMessages.h"
25
#include "ubus-server.h"
27
#include "SwitcherController.h"
34
SwitcherController::SwitcherController()
42
detail_on_timeout = false;
43
detail_timeout_length = 1500;
45
UBusServer *ubus = ubus_server_get_default();
46
ubus_server_register_interest(ubus, UBUS_BACKGROUND_COLOR_CHANGED,
47
(UBusCallback)&SwitcherController::OnBackgroundUpdate,
51
SwitcherController::~SwitcherController()
55
void SwitcherController::OnBackgroundUpdate (GVariant *data, SwitcherController *self)
57
gdouble red, green, blue, alpha;
58
g_variant_get(data, "(dddd)", &red, &green, &blue, &alpha);
59
self->bg_color_ = nux::Color (red, green, blue, alpha);
62
self->view_->background_color = self->bg_color_;
65
void SwitcherController::Show(SwitcherController::ShowMode show, SwitcherController::SortMode sort, bool reverse, std::vector<AbstractLauncherIcon*> results)
67
if (sort == FOCUS_ORDER)
68
std::sort(results.begin(), results.end(), CompareSwitcherItemsPriority);
70
model_ = SwitcherModel::Ptr(new SwitcherModel(results));
71
model_->selection_changed.connect (sigc::mem_fun(this, &SwitcherController::OnModelSelectionChanged));
77
if (timeout_length > 0)
79
show_timer_ = g_timeout_add(timeout_length, &SwitcherController::OnShowTimer, this);
86
if (detail_on_timeout)
88
detail_timer_ = g_timeout_add(detail_timeout_length, &SwitcherController::OnDetailTimer, this);
92
gboolean SwitcherController::OnShowTimer(gpointer data)
94
SwitcherController* self = static_cast<SwitcherController*>(data);
97
self->ConstructView();
99
self->show_timer_ = 0;
103
gboolean SwitcherController::OnDetailTimer(gpointer data)
105
SwitcherController* self = static_cast<SwitcherController*>(data);
107
if (!self->visible_ || self->model_->detail_selection)
110
self->SetDetail(true);
111
self->detail_mode_ = TAB_NEXT_WINDOW;
112
self->detail_timer_ = 0;
116
void SwitcherController::OnModelSelectionChanged(AbstractLauncherIcon *icon)
118
if (detail_on_timeout)
121
g_source_remove(detail_timer_);
123
detail_timer_ = g_timeout_add(detail_timeout_length, &SwitcherController::OnDetailTimer, this);
127
void SwitcherController::ConstructView()
129
nux::HLayout* layout;
131
layout = new nux::HLayout();
133
view_ = new SwitcherView();
134
view_->SetModel(model_);
135
view_->background_color = bg_color_;
137
layout->AddView(view_, 1);
138
layout->SetVerticalExternalMargin(0);
139
layout->SetHorizontalExternalMargin(0);
141
view_window_ = new nux::BaseWindow("Switcher");
142
view_window_->SinkReference();
143
view_window_->SetLayout(layout);
144
view_window_->SetBackgroundColor(nux::Color(0x00000000));
145
view_window_->SetGeometry(workarea_);
147
view_window_->ShowWindow(true);
150
void SwitcherController::SetWorkspace(nux::Geometry geo)
155
void SwitcherController::Hide(bool accept_state)
162
AbstractLauncherIcon* selection = model_->Selection();
165
if (model_->detail_selection)
167
selection->Activate(ActionArg(ActionArg::SWITCHER, 0, model_->DetailSelectionWindow ()));
171
if (selection->GetQuirk (AbstractLauncherIcon::QUIRK_ACTIVE))
173
selection->Activate(ActionArg (ActionArg::SWITCHER, 0, model_->DetailXids()[0]));
177
selection->Activate(ActionArg(ActionArg::SWITCHER, 0));
188
view_window_->ShowWindow(false);
189
view_window_->UnReference();
194
g_source_remove(show_timer_);
200
bool SwitcherController::Visible()
205
int SwitcherController::WindowsRelatedToSelection()
207
if (model_->Selection())
208
return model_->Selection()->RelatedWindows ();
212
void SwitcherController::Next()
217
if (model_->detail_selection)
219
switch (detail_mode_)
221
case TAB_NEXT_WINDOW:
222
if (model_->detail_selection_index < WindowsRelatedToSelection() - 1)
223
model_->NextDetail();
230
case TAB_NEXT_WINDOW_LOOP:
231
model_->NextDetail(); //looping automatic
241
void SwitcherController::Prev()
246
if (model_->detail_selection)
248
switch (detail_mode_)
250
case TAB_NEXT_WINDOW:
251
if (model_->detail_selection_index > 0)
252
model_->PrevDetail();
259
case TAB_NEXT_WINDOW_LOOP:
260
model_->PrevDetail(); //looping automatic
270
SwitcherView * SwitcherController::GetView()
275
void SwitcherController::SetDetail(bool value)
277
if (value && model_->Selection()->RelatedWindows() > 0)
279
model_->detail_selection = true;
280
detail_mode_ = TAB_NEXT_WINDOW_LOOP;
284
model_->detail_selection = false;
288
void SwitcherController::NextDetail()
290
if (!model_->detail_selection)
293
detail_mode_ = TAB_NEXT_TILE;
297
model_->NextDetail();
301
void SwitcherController::PrevDetail()
303
model_->PrevDetail();
306
LayoutWindowList SwitcherController::ExternalRenderTargets ()
310
LayoutWindowList result;
313
return view_->ExternalTargets ();
316
bool SwitcherController::CompareSwitcherItemsPriority(AbstractLauncherIcon* first, AbstractLauncherIcon* second)
318
if (first->Type() == second->Type())
319
return first->SwitcherPriority() > second->SwitcherPriority();
320
return first->Type() < second->Type();
323
void SwitcherController::SelectFirstItem()
328
AbstractLauncherIcon *first = model_->at (1);
329
AbstractLauncherIcon *second = model_->at (2);
342
unsigned int first_highest = 0;
343
unsigned int first_second = 0; // first icons second highest active
344
unsigned int second_first = 0; // second icons first highest active
346
for (guint32 xid : first->RelatedXids ())
348
unsigned int num = WindowManager::Default ()->GetWindowActiveNumber (xid);
350
if (num > first_highest)
352
first_second = first_highest;
355
else if (num > first_second)
361
for (guint32 xid : second->RelatedXids ())
363
second_first = MAX (WindowManager::Default ()->GetWindowActiveNumber (xid), second_first);
366
if (first_second > second_first)
367
model_->Select (first);
369
model_->Select (second);