53
56
nux::logging::Logger logger("unity.launcher");
63
const int super_tap_duration = 250;
64
const int launcher_minimum_show_duration = 1250;
65
const int shortcuts_show_delay = 750;
66
const int ignore_repeat_shortcut_duration = 250;
56
70
class Controller::Impl
59
Impl(Display* display);
73
Impl(Display* display, Controller* parent);
62
76
void UpdateNumWorkspaces(int workspaces);
78
Launcher* CreateLauncher(int monitor);
65
81
void SortAndUpdate();
67
void OnIconAdded(LauncherIcon* icon);
68
void OnIconRemoved(LauncherIcon* icon);
70
void OnLauncherAddRequest(char* path, LauncherIcon* before);
71
void OnLauncherAddRequestSpecial(char* path, LauncherIcon* before, char* aptdaemon_trans_id, char* icon_path);
72
void OnLauncherRemoveRequest(LauncherIcon* icon);
83
nux::ObjectPtr<Launcher> CurrentLauncher();
85
void OnIconAdded(AbstractLauncherIcon::Ptr icon);
86
void OnIconRemoved(AbstractLauncherIcon::Ptr icon);
88
void OnLauncherAddRequest(char* path, AbstractLauncherIcon::Ptr before);
89
void OnLauncherAddRequestSpecial(std::string const& path, AbstractLauncherIcon::Ptr before, std::string const& aptdaemon_trans_id, std::string const& icon_path);
90
void OnLauncherRemoveRequest(AbstractLauncherIcon::Ptr icon);
74
92
void OnLauncherEntryRemoteAdded(LauncherEntryRemote* entry);
75
93
void OnLauncherEntryRemoteRemoved(LauncherEntryRemote* entry);
95
void OnFavoriteStoreFavoriteAdded(std::string const& entry, std::string const& pos, bool before);
96
void OnFavoriteStoreFavoriteRemoved(std::string const& entry);
97
void OnFavoriteStoreReordered();
77
100
void InsertExpoAction();
78
101
void RemoveExpoAction();
80
103
void InsertDesktopIcon();
81
104
void RemoveDesktopIcon();
106
bool TapTimeUnderLimit();
108
void SendHomeActivationRequest();
110
int TimeSinceLauncherKeyPress();
112
int MonitorWithMouse();
83
114
void InsertTrash();
85
void RegisterIcon(LauncherIcon* icon);
87
LauncherIcon* CreateFavorite(const char* file_path);
89
SoftwareCenterLauncherIcon* CreateSCLauncherIcon(const char* file_path, const char* aptdaemon_trans_id, char* icon_path);
116
void RegisterIcon(AbstractLauncherIcon::Ptr icon);
118
AbstractLauncherIcon::Ptr CreateFavorite(const char* file_path);
120
AbstractLauncherIcon::Ptr CreateSCLauncherIcon(std::string const& file_path, std::string const& aptdaemon_trans_id, std::string const& icon_path);
124
void EnsureLaunchers(std::vector<nux::Geometry> const& monitors);
93
126
void OnExpoActivated();
128
void OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors);
130
void OnWindowFocusChanged (guint32 xid);
132
void ReceiveMouseDownOutsideArea(int x, int y, unsigned long button_flags, unsigned long key_flags);
134
void ReceiveLauncherKeyPress(unsigned long eventType,
135
unsigned long keysym,
137
const char* character,
138
unsigned short keyCount);
97
142
static void OnViewOpened(BamfMatcher* matcher, BamfView* view, gpointer data);
99
145
glib::Object<BamfMatcher> matcher_;
100
146
LauncherModel::Ptr model_;
101
nux::ObjectPtr<nux::BaseWindow> launcher_window_;
102
147
nux::ObjectPtr<Launcher> launcher_;
148
nux::ObjectPtr<Launcher> keyboard_launcher_;
103
149
int sort_priority_;
104
150
DeviceLauncherSection* device_section_;
105
151
LauncherEntryRemoteModel remote_model_;
106
SimpleLauncherIcon* expo_icon_;
107
DesktopLauncherIcon* desktop_launcher_icon_;
108
nux::ObjectPtr<AbstractLauncherIcon> desktop_icon_;
152
AbstractLauncherIcon::Ptr expo_icon_;
153
AbstractLauncherIcon::Ptr desktop_launcher_icon_;
154
AbstractLauncherIcon::Ptr desktop_icon_;
109
155
int num_workspaces_;
110
156
bool show_desktop_icon_;
112
guint bamf_timer_handler_id_;
114
guint32 on_view_opened_id_;
159
guint bamf_timer_handler_id_;
160
guint on_view_opened_id_;
161
guint launcher_key_press_handler_id_;
162
guint launcher_label_show_handler_id_;
163
guint launcher_hide_handler_id_;
166
bool launcher_keynav;
167
bool launcher_grabbed;
168
bool reactivate_keynav;
169
int reactivate_index;
170
bool keynav_restore_window_;
174
struct timespec launcher_key_press_time_;
176
LauncherList launchers;
116
178
sigc::connection on_expoicon_activate_connection_;
179
sigc::connection launcher_key_press_connection_;
180
sigc::connection launcher_event_outside_connection_;
120
Controller::Impl::Impl(Display* display)
184
Controller::Impl::Impl(Display* display, Controller* parent)
122
187
, model_(new LauncherModel())
123
188
, sort_priority_(0)
124
189
, show_desktop_icon_(false)
126
// NOTE: should the launcher itself hold the base window?
127
// seems like it probably should...
128
launcher_window_ = new nux::BaseWindow(TEXT("LauncherWindow"));
130
Launcher* raw_launcher = new Launcher(launcher_window_.GetPointer());
131
launcher_ = raw_launcher;
132
launcher_->display = display;
133
launcher_->SetIconSize(54, 48);
134
launcher_->SetBacklightMode(Launcher::BACKLIGHT_ALWAYS_ON);
135
launcher_->SetHideMode(Launcher::LAUNCHER_HIDE_DODGE_WINDOWS);
136
launcher_->SetLaunchAnimation(Launcher::LAUNCH_ANIMATION_PULSE);
137
launcher_->SetUrgentAnimation(Launcher::URGENT_ANIMATION_WIGGLE);
139
nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION);
140
layout->AddView(raw_launcher, 1);
141
layout->SetContentDistribution(nux::eStackLeft);
142
layout->SetVerticalExternalMargin(0);
143
layout->SetHorizontalExternalMargin(0);
145
launcher_window_->SetLayout(layout);
146
launcher_window_->SetBackgroundColor(nux::color::Transparent);
147
launcher_window_->ShowWindow(true);
148
launcher_window_->EnableInputWindow(true, "launcher", false, false);
149
launcher_window_->InputWindowEnableStruts(false);
150
launcher_window_->SetEnterFocusInputArea(raw_launcher);
152
launcher_->SetModel(model_.get());
153
launcher_->launcher_addrequest.connect(sigc::mem_fun(this, &Impl::OnLauncherAddRequest));
154
launcher_->launcher_addrequest_special.connect(sigc::mem_fun(this, &Impl::OnLauncherAddRequestSpecial));
155
launcher_->launcher_removerequest.connect(sigc::mem_fun(this, &Impl::OnLauncherRemoveRequest));
157
device_section_ = new DeviceLauncherSection(raw_launcher);
192
UScreen* uscreen = UScreen::GetDefault();
193
auto monitors = uscreen->GetMonitors();
195
launcher_open = false;
196
launcher_keynav = false;
197
launcher_grabbed = false;
198
reactivate_keynav = false;
199
keynav_restore_window_ = true;
201
EnsureLaunchers(monitors);
203
launcher_ = launchers[0];
205
device_section_ = new DeviceLauncherSection();
158
206
device_section_->IconAdded.connect(sigc::mem_fun(this, &Impl::OnIconAdded));
160
208
num_workspaces_ = WindowManager::Default()->WorkspaceCount();
195
262
delete device_section_;
199
void Controller::Impl::OnLauncherAddRequest(char* path, LauncherIcon* before)
265
void Controller::Impl::EnsureLaunchers(std::vector<nux::Geometry> const& monitors)
267
unsigned int num_monitors;
268
if (parent_->multiple_launchers)
270
num_monitors = monitors.size();
278
for (i = 0; i < num_monitors; i++)
280
if (i >= launchers.size())
281
launchers.push_back(nux::ObjectPtr<Launcher> (CreateLauncher(i)));
283
launchers[i]->Resize();
286
for (; i < launchers.size(); ++i)
288
auto launcher = launchers[i];
289
if (launcher.IsValid())
290
launcher->GetParent()->UnReference();
292
launchers.resize(num_monitors);
295
void Controller::Impl::OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors)
297
EnsureLaunchers(monitors);
300
void Controller::Impl::OnWindowFocusChanged (guint32 xid)
302
static bool keynav_first_focus = false;
304
if (keynav_first_focus)
306
keynav_first_focus = false;
307
keynav_restore_window_ = false;
308
parent_->KeyNavTerminate(false);
310
else if (launcher_keynav)
312
keynav_first_focus = true;
316
Launcher* Controller::Impl::CreateLauncher(int monitor)
318
nux::BaseWindow* launcher_window = new nux::BaseWindow(TEXT("LauncherWindow"));
320
Launcher* launcher = new Launcher(launcher_window);
321
launcher->display = display_;
322
launcher->monitor = monitor;
323
launcher->options = parent_->options();
325
nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION);
326
layout->AddView(launcher, 1);
327
layout->SetContentDistribution(nux::eStackLeft);
328
layout->SetVerticalExternalMargin(0);
329
layout->SetHorizontalExternalMargin(0);
331
launcher_window->SetLayout(layout);
332
launcher_window->SetBackgroundColor(nux::color::Transparent);
333
launcher_window->ShowWindow(true);
334
launcher_window->EnableInputWindow(true, "launcher", false, false);
335
launcher_window->InputWindowEnableStruts(false);
336
launcher_window->SetEnterFocusInputArea(launcher);
338
launcher->SetModel(model_.get());
339
launcher->launcher_addrequest.connect(sigc::mem_fun(this, &Impl::OnLauncherAddRequest));
340
launcher->launcher_removerequest.connect(sigc::mem_fun(this, &Impl::OnLauncherRemoveRequest));
342
parent_->AddChild(launcher);
347
void Controller::Impl::OnLauncherAddRequest(char* path, AbstractLauncherIcon::Ptr before)
201
349
for (auto it : model_->GetSublist<BamfLauncherIcon> ())
203
if (!g_strcmp0(path, it->DesktopFile()))
351
if (path && path == it->DesktopFile())
206
354
model_->ReorderBefore(it, before, false);
225
373
unity::FavoriteList desktop_paths;
227
375
// Updates gsettings favorites.
228
std::list<BamfLauncherIcon*> launchers = model_->GetSublist<BamfLauncherIcon> ();
376
auto launchers = model_->GetSublist<BamfLauncherIcon> ();
229
377
for (auto icon : launchers)
231
379
if (!icon->IsSticky())
234
const char* desktop_file = icon->DesktopFile();
382
std::string const& desktop_file = icon->DesktopFile();
236
if (desktop_file && strlen(desktop_file) > 0)
237
desktop_paths.push_back(desktop_file);
384
if (!desktop_file.empty())
385
desktop_paths.push_back(desktop_file.c_str());
240
388
unity::FavoriteStore::GetDefault().SetFavorites(desktop_paths);
244
Controller::Impl::OnLauncherAddRequestSpecial(char* path, LauncherIcon* before, char* aptdaemon_trans_id, char* icon_path)
392
Controller::Impl::OnLauncherAddRequestSpecial(std::string const& path,
393
AbstractLauncherIcon::Ptr before,
394
std::string const& aptdaemon_trans_id,
395
std::string const& icon_path)
246
std::list<BamfLauncherIcon*> launchers;
247
std::list<BamfLauncherIcon*>::iterator it;
249
launchers = model_->GetSublist<BamfLauncherIcon> ();
250
for (it = launchers.begin(); it != launchers.end(); it++)
397
auto launchers = model_->GetSublist<BamfLauncherIcon>();
398
for (auto icon : launchers)
252
if (g_strcmp0(path, (*it)->DesktopFile()) == 0)
400
if (icon->DesktopFile() == path)
256
SoftwareCenterLauncherIcon* result = CreateSCLauncherIcon(path, aptdaemon_trans_id, icon_path);
404
AbstractLauncherIcon::Ptr result = CreateSCLauncherIcon(path, aptdaemon_trans_id, icon_path);
259
407
RegisterIcon(result);
499
void Controller::Impl::OnFavoriteStoreFavoriteAdded(std::string const& entry, std::string const& pos, bool before)
501
auto bamf_list = model_->GetSublist<BamfLauncherIcon>();
502
AbstractLauncherIcon::Ptr other;
503
if (bamf_list.size() > 0)
504
other = *(bamf_list.begin());
508
for (auto it : bamf_list)
510
if (it->GetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE) && pos == it->DesktopFile())
515
for (auto it : bamf_list)
517
if (entry == it->DesktopFile())
521
model_->ReorderAfter(it, other);
523
model_->ReorderBefore(it, other, false);
528
AbstractLauncherIcon::Ptr result = CreateFavorite(entry.c_str());
531
RegisterIcon(result);
533
model_->ReorderAfter(result, other);
535
model_->ReorderBefore(result, other, false);
539
void Controller::Impl::OnFavoriteStoreFavoriteRemoved(std::string const& entry)
541
for (auto it : model_->GetSublist<BamfLauncherIcon> ())
543
if (it->DesktopFile() == entry)
545
OnLauncherRemoveRequest(it);
551
void Controller::Impl::OnFavoriteStoreReordered()
553
FavoriteList const& favs = FavoriteStore::GetDefault().GetFavorites();
554
auto bamf_list = model_->GetSublist<BamfLauncherIcon>();
559
auto icon = std::find_if(bamf_list.begin(), bamf_list.end(),
560
[&it](AbstractLauncherIcon::Ptr x) { return (x->DesktopFile() == it); });
562
if (icon != bamf_list.end())
564
(*icon)->SetSortPriority(i++);
568
for (auto it : bamf_list)
571
it->SetSortPriority(i++);
352
577
void Controller::Impl::OnExpoActivated()
354
579
WindowManager::Default()->InitiateExpo();
449
BamfLauncherIcon* icon = new BamfLauncherIcon(self->launcher_.GetPointer(), app);
450
icon->SetIconType(LauncherIcon::TYPE_APPLICATION);
667
AbstractLauncherIcon::Ptr icon (new BamfLauncherIcon(app));
451
668
icon->SetSortPriority(self->sort_priority_++);
453
670
self->RegisterIcon(icon);
456
LauncherIcon* Controller::Impl::CreateFavorite(const char* file_path)
673
AbstractLauncherIcon::Ptr Controller::Impl::CreateFavorite(const char* file_path)
458
675
BamfApplication* app;
459
BamfLauncherIcon* icon;
676
AbstractLauncherIcon::Ptr result;
461
678
app = bamf_matcher_get_application_for_desktop_file(matcher_, file_path, true);
465
682
if (g_object_get_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen")))
467
684
bamf_view_set_sticky(BAMF_VIEW(app), true);
471
688
g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GINT_TO_POINTER(1));
473
690
bamf_view_set_sticky(BAMF_VIEW(app), true);
474
icon = new BamfLauncherIcon(launcher_.GetPointer(), app);
475
icon->SetIconType(LauncherIcon::TYPE_APPLICATION);
691
AbstractLauncherIcon::Ptr icon (new BamfLauncherIcon(app));
476
692
icon->SetSortPriority(sort_priority_++);
481
SoftwareCenterLauncherIcon*
482
Controller::Impl::CreateSCLauncherIcon(const char* file_path, const char* aptdaemon_trans_id, char* icon_path)
698
AbstractLauncherIcon::Ptr
699
Controller::Impl::CreateSCLauncherIcon(std::string const& file_path,
700
std::string const& aptdaemon_trans_id,
701
std::string const& icon_path)
484
703
BamfApplication* app;
485
SoftwareCenterLauncherIcon* icon;
704
AbstractLauncherIcon::Ptr result;
487
app = bamf_matcher_get_application_for_desktop_file(matcher_, file_path, true);
706
app = bamf_matcher_get_application_for_desktop_file(matcher_, file_path.c_str(), true);
488
707
if (!BAMF_IS_APPLICATION(app))
491
710
if (g_object_get_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen")))
493
712
bamf_view_set_sticky(BAMF_VIEW(app), true);
497
716
g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GINT_TO_POINTER(1));
499
718
bamf_view_set_sticky(BAMF_VIEW(app), true);
500
icon = new SoftwareCenterLauncherIcon(launcher_.GetPointer(), app, (char*)aptdaemon_trans_id, icon_path);
501
icon->SetIconType(LauncherIcon::TYPE_APPLICATION);
719
AbstractLauncherIcon::Ptr icon(new SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path));
502
720
icon->SetSortPriority(sort_priority_++);
507
726
void Controller::Impl::SetupBamf()
510
729
BamfApplication* app;
511
BamfLauncherIcon* icon;
513
731
// Sufficiently large number such that we ensure proper sorting
514
732
// (avoids case where first item gets tacked onto end rather than start)
588
836
return shortcuts;
591
std::vector<AbstractLauncherIcon*> Controller::GetAltTabIcons()
839
std::vector<AbstractLauncherIcon::Ptr> Controller::GetAltTabIcons(bool current) const
593
std::vector<AbstractLauncherIcon*> results;
841
std::vector<AbstractLauncherIcon::Ptr> results;
595
results.push_back(pimpl->desktop_icon_.GetPointer());
843
results.push_back(pimpl->desktop_icon_);
597
845
for (auto icon : *(pimpl->model_))
598
if (icon->ShowInSwitcher())
846
if (icon->ShowInSwitcher(current))
599
847
results.push_back(icon);
604
void Controller::PrimaryMonitorGeometryChanged(nux::Geometry const& rect)
852
Window Controller::LauncherWindowId(int launcher) const
606
const int panel_height = 24;
608
int launcher_width = pimpl->launcher_window_->GetGeometry().width;
610
nux::Geometry new_geometry(rect.x,
611
rect.y + panel_height,
613
rect.height - panel_height);
615
LOG_DEBUG(logger) << "Setting to launcher rect:"
616
<< " x=" << new_geometry.x
617
<< " y=" << new_geometry.y
618
<< " w=" << new_geometry.width
619
<< " h=" << new_geometry.height;
621
pimpl->launcher_->SetMaximumHeight(new_geometry.height);
623
pimpl->launcher_window_->SetGeometry(new_geometry);
624
pimpl->launcher_->SetGeometry(new_geometry);
854
if (launcher >= (int)pimpl->launchers.size())
856
return pimpl->launchers[launcher]->GetParent()->GetInputWindowId();
627
Window Controller::launcher_input_window_id()
859
Window Controller::KeyNavLauncherInputWindowId() const
629
return pimpl->launcher_window_->GetInputWindowId();
861
if (KeyNavIsActive())
862
return pimpl->keyboard_launcher_->GetParent()->GetInputWindowId();
632
866
void Controller::PushToFront()
634
pimpl->launcher_window_->PushToFront();
868
pimpl->launcher_->GetParent()->PushToFront();
637
871
void Controller::SetShowDesktopIcon(bool show_desktop_icon)
647
881
pimpl->RemoveDesktopIcon();
884
int Controller::Impl::MonitorWithMouse()
886
UScreen* uscreen = UScreen::GetDefault();
887
return uscreen->GetMonitorWithMouse();
890
nux::ObjectPtr<Launcher> Controller::Impl::CurrentLauncher()
892
nux::ObjectPtr<Launcher> result;
893
int best = std::max<int> (launchers.size() - 1, MonitorWithMouse());
895
result = launchers[best];
899
void Controller::HandleLauncherKeyPress()
901
unity::TimeUtil::SetTimeStruct(&pimpl->launcher_key_press_time_);
903
auto show_launcher = [](gpointer user_data) -> gboolean
905
Impl* self = static_cast<Impl*>(user_data);
906
if (self->keyboard_launcher_.IsNull())
907
self->keyboard_launcher_ = self->CurrentLauncher();
909
if (self->launcher_hide_handler_id_ > 0)
911
g_source_remove(self->launcher_hide_handler_id_);
912
self->launcher_hide_handler_id_ = 0;
915
self->keyboard_launcher_->ForceReveal(true);
916
self->launcher_open = true;
917
self->launcher_key_press_handler_id_ = 0;
920
pimpl->launcher_key_press_handler_id_ = g_timeout_add(local::super_tap_duration, show_launcher, pimpl);
922
auto show_shortcuts = [](gpointer user_data) -> gboolean
924
Impl* self = static_cast<Impl*>(user_data);
925
if (!self->launcher_keynav)
927
if (self->keyboard_launcher_.IsNull())
928
self->keyboard_launcher_ = self->CurrentLauncher();
930
self->keyboard_launcher_->ShowShortcuts(true);
931
self->launcher_open = true;
932
self->launcher_label_show_handler_id_ = 0;
936
pimpl->launcher_label_show_handler_id_ = g_timeout_add(local::shortcuts_show_delay, show_shortcuts, pimpl);
939
void Controller::HandleLauncherKeyRelease(bool was_tap)
941
if (pimpl->TapTimeUnderLimit() && was_tap)
943
pimpl->SendHomeActivationRequest();
946
if (pimpl->launcher_label_show_handler_id_)
948
g_source_remove(pimpl->launcher_label_show_handler_id_);
949
pimpl->launcher_label_show_handler_id_ = 0;
952
if (pimpl->launcher_key_press_handler_id_)
954
g_source_remove(pimpl->launcher_key_press_handler_id_);
955
pimpl->launcher_key_press_handler_id_ = 0;
958
if (pimpl->keyboard_launcher_.IsValid())
960
pimpl->keyboard_launcher_->ShowShortcuts(false);
962
int ms_since_show = pimpl->TimeSinceLauncherKeyPress();
963
if (ms_since_show > local::launcher_minimum_show_duration)
965
pimpl->keyboard_launcher_->ForceReveal(false);
966
pimpl->launcher_open = false;
968
if (!pimpl->launcher_keynav)
969
pimpl->keyboard_launcher_.Release();
973
int time_left = local::launcher_minimum_show_duration - ms_since_show;
974
auto hide_launcher = [](gpointer user_data) -> gboolean
976
Impl *self = static_cast<Impl*>(user_data);
977
if (self->keyboard_launcher_.IsValid())
979
self->keyboard_launcher_->ForceReveal(false);
980
self->launcher_open = false;
982
if (!self->launcher_keynav)
983
self->keyboard_launcher_.Release();
986
self->launcher_hide_handler_id_ = 0;
990
pimpl->launcher_hide_handler_id_ = g_timeout_add(time_left, hide_launcher, pimpl);
995
bool Controller::HandleLauncherKeyEvent(Display *display, unsigned int key_sym, unsigned long key_code, unsigned long key_state, char* key_string)
997
LauncherModel::iterator it;
999
// Shortcut to start launcher icons. Only relies on Keycode, ignore modifier
1000
for (it = pimpl->model_->begin(); it != pimpl->model_->end(); it++)
1002
if ((XKeysymToKeycode(display, (*it)->GetShortcut()) == key_code) ||
1003
((gchar)((*it)->GetShortcut()) == key_string[0]))
1005
struct timespec last_action_time = (*it)->GetQuirkTime(AbstractLauncherIcon::QUIRK_LAST_ACTION);
1006
struct timespec current;
1007
TimeUtil::SetTimeStruct(¤t);
1008
if (TimeUtil::TimeDelta(¤t, &last_action_time) > local::ignore_repeat_shortcut_duration)
1010
if (g_ascii_isdigit((gchar)(*it)->GetShortcut()) && (key_state & ShiftMask))
1011
(*it)->OpenInstance(ActionArg(ActionArg::LAUNCHER, 0));
1013
(*it)->Activate(ActionArg(ActionArg::LAUNCHER, 0));
1016
// disable the "tap on super" check
1017
pimpl->launcher_key_press_time_ = { 0, 0 };
1025
void Controller::Impl::ReceiveMouseDownOutsideArea(int x, int y, unsigned long button_flags, unsigned long key_flags)
1027
if (launcher_grabbed)
1028
parent_->KeyNavTerminate(false);
1031
void Controller::KeyNavGrab()
1033
pimpl->ubus.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
1035
pimpl->keyboard_launcher_->GrabKeyboard();
1036
pimpl->launcher_grabbed = true;
1038
pimpl->launcher_key_press_connection_ =
1039
pimpl->keyboard_launcher_->key_down.connect(sigc::mem_fun(pimpl, &Controller::Impl::ReceiveLauncherKeyPress));
1040
pimpl->launcher_event_outside_connection_ =
1041
pimpl->keyboard_launcher_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(pimpl, &Controller::Impl::ReceiveMouseDownOutsideArea));
1044
void Controller::KeyNavActivate()
1046
if (pimpl->launcher_keynav)
1049
pimpl->reactivate_keynav = false;
1050
pimpl->launcher_keynav = true;
1051
pimpl->keynav_restore_window_ = true;
1052
pimpl->keyboard_launcher_ = pimpl->CurrentLauncher();
1054
pimpl->keyboard_launcher_->EnterKeyNavMode();
1055
pimpl->model_->SetSelection(0);
1057
pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_SWTICHER, g_variant_new_boolean(true));
1058
pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_NAV, NULL);
1061
void Controller::KeyNavNext()
1063
pimpl->model_->SelectNext();
1066
void Controller::KeyNavPrevious()
1068
pimpl->model_->SelectPrevious();
1071
void Controller::KeyNavTerminate(bool activate)
1073
if (!pimpl->launcher_keynav)
1076
pimpl->keyboard_launcher_->ExitKeyNavMode();
1077
if (pimpl->launcher_grabbed)
1079
pimpl->keyboard_launcher_->UnGrabKeyboard();
1080
pimpl->launcher_key_press_connection_.disconnect();
1081
pimpl->launcher_event_outside_connection_.disconnect();
1082
pimpl->launcher_grabbed = false;
1086
pimpl->model_->Selection()->Activate(ActionArg(ActionArg::LAUNCHER, 0));
1088
pimpl->launcher_keynav = false;
1089
if (!pimpl->launcher_open)
1090
pimpl->keyboard_launcher_.Release();
1092
pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_SWTICHER, g_variant_new_boolean(true));
1093
pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_NAV, g_variant_new_boolean(pimpl->keynav_restore_window_));
1096
bool Controller::KeyNavIsActive() const
1098
return pimpl->launcher_keynav;
1102
Controller::GetName() const
1104
return "LauncherController";
1108
Controller::AddProperties(GVariantBuilder* builder)
1111
clock_gettime(CLOCK_MONOTONIC, ¤t);
1113
unity::variant::BuilderWrapper(builder)
1114
.add("key_nav_is_active", KeyNavIsActive())
1115
.add("key_nav_launcher_monitor", pimpl->keyboard_launcher_.IsValid() ? pimpl->keyboard_launcher_->monitor : -1)
1116
.add("key_nav_selection", pimpl->model_->SelectionIndex())
1117
.add("key_nav_is_grabbed", pimpl->launcher_grabbed)
1118
.add("keyboard_launcher", pimpl->CurrentLauncher()->monitor);
1121
void Controller::Impl::ReceiveLauncherKeyPress(unsigned long eventType,
1122
unsigned long keysym,
1123
unsigned long state,
1124
const char* character,
1125
unsigned short keyCount)
1128
* all key events below are related to keynavigation. Make an additional
1129
* check that we are in a keynav mode when we inadvertadly receive the focus
1131
if (!launcher_grabbed)
1136
// up (move selection up or go to global-menu if at top-most icon)
1139
parent_->KeyNavPrevious();
1142
// down (move selection down and unfold launcher if needed)
1145
parent_->KeyNavNext();
1148
// super/control/alt/esc/left (close quicklist or exit laucher key-focus)
1151
case NUX_VK_CONTROL:
1157
parent_->KeyNavTerminate(false);
1160
// right/shift-f10 (open quicklist of currently selected icon)
1162
if (!(state & nux::NUX_STATE_SHIFT))
1167
if (model_->Selection()->OpenQuicklist(true, keyboard_launcher_->monitor()))
1169
reactivate_keynav = true;
1170
reactivate_index = model_->SelectionIndex();
1171
parent_->KeyNavTerminate(false);
1175
// <SPACE> (open a new instance)
1177
model_->Selection()->OpenInstance(ActionArg(ActionArg::LAUNCHER, 0));
1178
parent_->KeyNavTerminate(false);
1181
// <RETURN> (start/activate currently selected icon)
1184
model_->Selection()->Activate(ActionArg(ActionArg::LAUNCHER, 0));
1185
parent_->KeyNavTerminate(false);
651
1194
} // namespace launcher
652
1195
} // namespace unity