43
BamfLauncherIcon* self;
44
IndicatorDesktopShortcuts* shortcuts;
47
typedef struct _ShortcutData ShortcutData;
48
static void shortcut_data_destroy(ShortcutData* data)
50
g_object_unref(data->shortcuts);
52
g_slice_free(ShortcutData, data);
55
static void shortcut_activated(DbusmenuMenuitem* _sender, guint timestamp, gpointer userdata)
57
ShortcutData* data = (ShortcutData*)userdata;
58
indicator_desktop_shortcuts_nick_exec(data->shortcuts, data->nick);
43
NUX_IMPLEMENT_OBJECT_TYPE(BamfLauncherIcon);
45
BamfLauncherIcon::BamfLauncherIcon(BamfApplication* app)
46
: SimpleLauncherIcon()
47
, _bamf_app(app, glib::AddRef())
50
, _supported_types_filled(false)
51
, _fill_supported_types_id(0)
54
auto bamf_view = glib::object_cast<BamfView>(_bamf_app);
56
glib::String icon(bamf_view_get_icon(bamf_view));
58
tooltip_text = BamfName();
59
icon_name = icon.Str();
60
SetIconType(TYPE_APPLICATION);
63
SetQuirk(QUIRK_VISIBLE, true);
65
SetQuirk(QUIRK_VISIBLE, bamf_view_user_visible(bamf_view));
67
SetQuirk(QUIRK_ACTIVE, bamf_view_is_active(bamf_view));
68
SetQuirk(QUIRK_RUNNING, bamf_view_is_running(bamf_view));
70
glib::SignalBase* sig;
72
sig = new glib::Signal<void, BamfView*, BamfView*>(bamf_view, "child-added",
73
[&] (BamfView*, BamfView*) {
76
UpdateIconGeometries(GetCenters());
80
sig = new glib::Signal<void, BamfView*, BamfView*>(bamf_view, "child-removed",
81
[&] (BamfView*, BamfView*) { EnsureWindowState(); });
84
sig = new glib::Signal<void, BamfView*, gboolean>(bamf_view, "urgent-changed",
85
[&] (BamfView*, gboolean urgent) {
86
SetQuirk(QUIRK_URGENT, urgent);
90
sig = new glib::Signal<void, BamfView*, gboolean>(bamf_view, "active-changed",
91
[&] (BamfView*, gboolean active) {
92
SetQuirk(QUIRK_ACTIVE, active);
96
sig = new glib::Signal<void, BamfView*, gboolean>(bamf_view, "running-changed",
97
[&] (BamfView*, gboolean running) {
98
SetQuirk(QUIRK_RUNNING, running);
102
UpdateIconGeometries(GetCenters());
107
sig = new glib::Signal<void, BamfView*, gboolean>(bamf_view, "user-visible-changed",
108
[&] (BamfView*, gboolean visible) {
110
SetQuirk(QUIRK_VISIBLE, visible);
114
sig = new glib::Signal<void, BamfView*>(bamf_view, "closed",
121
WindowManager::Default()->window_minimized.connect(sigc::mem_fun(this, &BamfLauncherIcon::OnWindowMinimized));
122
WindowManager::Default()->window_moved.connect(sigc::mem_fun(this, &BamfLauncherIcon::OnWindowMoved));
123
WindowManager::Default()->compiz_screen_viewport_switch_ended.connect(sigc::mem_fun(this, &BamfLauncherIcon::EnsureWindowState));
124
WindowManager::Default()->terminate_expo.connect(sigc::mem_fun(this, &BamfLauncherIcon::EnsureWindowState));
133
// Calls when there are no higher priority events pending to the default main loop.
134
_fill_supported_types_id = g_idle_add([] (gpointer data) -> gboolean {
135
static_cast<BamfLauncherIcon*>(data)->FillSupportedTypes();
140
BamfLauncherIcon::~BamfLauncherIcon()
142
g_object_set_qdata(G_OBJECT(_bamf_app.RawPtr()),
143
g_quark_from_static_string("unity-seen"),
146
if (_fill_supported_types_id != 0)
147
g_source_remove(_fill_supported_types_id);
149
if (_window_moved_id != 0)
150
g_source_remove(_window_moved_id);
152
if (_dnd_hover_timer != 0)
153
g_source_remove(_dnd_hover_timer);
156
bool BamfLauncherIcon::IsSticky() const
158
return bamf_view_is_sticky(BAMF_VIEW(_bamf_app.RawPtr()));
161
bool BamfLauncherIcon::IsVisible() const
163
return GetQuirk(QUIRK_VISIBLE);
166
bool BamfLauncherIcon::IsActive() const
168
return GetQuirk(QUIRK_ACTIVE);
171
bool BamfLauncherIcon::IsRunning() const
173
return GetQuirk(QUIRK_RUNNING);
176
bool BamfLauncherIcon::IsUrgent() const
178
return GetQuirk(QUIRK_URGENT);
61
181
void BamfLauncherIcon::ActivateLauncherIcon(ActionArg arg)
165
286
if (arg.source != ActionArg::SWITCHER)
166
ubus_server_send_message(ubus_server_get_default(), UBUS_LAUNCHER_ACTION_DONE, NULL);
169
BamfLauncherIcon::BamfLauncherIcon(Launcher* IconManager, BamfApplication* app)
170
: SimpleLauncherIcon(IconManager)
171
, _supported_types_filled(false)
172
, _fill_supported_types_id(0)
174
_cached_desktop_file = NULL;
178
_dnd_hover_timer = 0;
179
_dnd_hovered = false;
180
_launcher = IconManager;
181
_desktop_file_monitor = NULL;
182
_menu_desktop_shortcuts = NULL;
183
_on_desktop_file_changed_handler_id = 0;
184
_window_moved_id = 0;
185
glib::String icon(bamf_view_get_icon(BAMF_VIEW(m_App)));
187
tooltip_text = BamfName();
188
icon_name = icon.Str();
189
SetIconType(TYPE_APPLICATION);
191
if (bamf_view_is_sticky(BAMF_VIEW(m_App)))
192
SetQuirk(QUIRK_VISIBLE, true);
194
SetQuirk(QUIRK_VISIBLE, bamf_view_user_visible(BAMF_VIEW(m_App)));
196
SetQuirk(QUIRK_ACTIVE, bamf_view_is_active(BAMF_VIEW(m_App)));
197
SetQuirk(QUIRK_RUNNING, bamf_view_is_running(BAMF_VIEW(m_App)));
199
g_signal_connect(app, "child-removed", (GCallback) &BamfLauncherIcon::OnChildRemoved, this);
200
g_signal_connect(app, "child-added", (GCallback) &BamfLauncherIcon::OnChildAdded, this);
201
g_signal_connect(app, "urgent-changed", (GCallback) &BamfLauncherIcon::OnUrgentChanged, this);
202
g_signal_connect(app, "running-changed", (GCallback) &BamfLauncherIcon::OnRunningChanged, this);
203
g_signal_connect(app, "active-changed", (GCallback) &BamfLauncherIcon::OnActiveChanged, this);
204
g_signal_connect(app, "user-visible-changed", (GCallback) &BamfLauncherIcon::OnUserVisibleChanged, this);
205
g_signal_connect(app, "closed", (GCallback) &BamfLauncherIcon::OnClosed, this);
214
WindowManager::Default()->window_minimized.connect(sigc::mem_fun(this, &BamfLauncherIcon::OnWindowMinimized));
215
WindowManager::Default()->window_moved.connect(sigc::mem_fun(this, &BamfLauncherIcon::OnWindowMoved));
216
WindowManager::Default()->compiz_screen_viewport_switch_ended.connect(sigc::mem_fun(this, &BamfLauncherIcon::EnsureWindowState));
217
WindowManager::Default()->terminate_expo.connect(sigc::mem_fun(this, &BamfLauncherIcon::EnsureWindowState));
218
IconManager->hidden_changed.connect(sigc::mem_fun(this, &BamfLauncherIcon::OnLauncherHiddenChanged));
223
// Calls when there are no higher priority events pending to the default main loop.
224
_fill_supported_types_id = g_idle_add((GSourceFunc)FillSupportedTypes, this);
228
BamfLauncherIcon::~BamfLauncherIcon()
230
g_object_set_qdata(G_OBJECT(m_App), g_quark_from_static_string("unity-seen"), GINT_TO_POINTER(0));
232
// We might not have created the menu items yet
233
for (auto it = _menu_clients.begin(); it != _menu_clients.end(); it++)
235
g_object_unref(G_OBJECT(it->second));
238
if (_menu_items.find("Pin") != _menu_items.end())
240
g_signal_handler_disconnect(G_OBJECT(_menu_items["Pin"]),
241
_menu_callbacks["Pin"]);
244
if (_menu_items.find("Quit") != _menu_items.end())
246
g_signal_handler_disconnect(G_OBJECT(_menu_items["Quit"]),
247
_menu_callbacks["Quit"]);
250
for (auto it = _menu_items.begin(); it != _menu_items.end(); it++)
252
g_object_unref(G_OBJECT(it->second));
255
for (auto it = _menu_items_extra.begin(); it != _menu_items_extra.end(); it++)
257
g_object_unref(G_OBJECT(it->second));
260
if (G_IS_OBJECT(_menu_desktop_shortcuts))
261
g_object_unref(G_OBJECT(_menu_desktop_shortcuts));
263
if (_on_desktop_file_changed_handler_id != 0)
264
g_signal_handler_disconnect(G_OBJECT(_desktop_file_monitor),
265
_on_desktop_file_changed_handler_id);
267
if (_fill_supported_types_id != 0)
268
g_source_remove(_fill_supported_types_id);
270
if (_window_moved_id != 0)
271
g_source_remove(_window_moved_id);
273
g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnChildRemoved, this);
274
g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnChildAdded, this);
275
g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnUrgentChanged, this);
276
g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnRunningChanged, this);
277
g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnActiveChanged, this);
278
g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnUserVisibleChanged, this);
279
g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnClosed, this);
281
g_object_unref(m_App);
282
g_object_unref(_desktop_file_monitor);
284
g_free(_cached_desktop_file);
285
g_free(_cached_name);
288
std::vector<Window> BamfLauncherIcon::RelatedXids ()
290
std::vector<Window> results;
293
WindowManager *wm = WindowManager::Default();
295
children = bamf_view_get_children(BAMF_VIEW(m_App));
296
for (l = children; l; l = l->next)
298
view = static_cast <BamfView*> (l->data);
299
if (BAMF_IS_WINDOW(view))
301
guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
303
if (wm->IsWindowMapped(xid))
305
results.push_back (xid);
310
g_list_free(children);
314
std::string BamfLauncherIcon::NameForWindow (Window window)
287
ubus_server_send_message(ubus_server_get_default(), UBUS_LAUNCHER_ACTION_DONE, nullptr);
290
std::vector<Window> BamfLauncherIcon::Windows()
292
std::vector<Window> results;
294
WindowManager *wm = WindowManager::Default();
296
children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr()));
297
for (l = children; l; l = l->next)
299
if (!BAMF_IS_WINDOW(l->data))
302
Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data));
304
if (wm->IsWindowMapped(xid))
306
results.push_back(xid);
310
g_list_free(children);
314
std::vector<Window> BamfLauncherIcon::WindowsForMonitor(int monitor)
316
std::vector<Window> results;
318
WindowManager *wm = WindowManager::Default();
320
children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr()));
321
for (l = children; l; l = l->next)
323
if (!BAMF_IS_WINDOW(l->data))
326
auto window = static_cast<BamfWindow*>(l->data);
327
if (bamf_window_get_monitor(window) == monitor)
329
guint32 xid = bamf_window_get_xid(window);
330
bool user_visible = bamf_view_user_visible(reinterpret_cast<BamfView*>(window));
332
if (user_visible && wm->IsWindowMapped(xid) && wm->IsWindowOnCurrentDesktop(xid))
333
results.push_back(xid);
337
g_list_free(children);
341
std::string BamfLauncherIcon::NameForWindow(Window window)
316
343
std::string result;
317
344
GList* children, *l;
320
children = bamf_view_get_children(BAMF_VIEW(m_App));
346
children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr()));
321
347
for (l = children; l; l = l->next)
323
view = static_cast <BamfView*> (l->data);
324
if (BAMF_IS_WINDOW(view) && (Window) bamf_window_get_xid(BAMF_WINDOW(view)) == window)
349
if (!BAMF_IS_WINDOW(l->data))
352
if (bamf_window_get_xid(static_cast<BamfWindow*>(l->data)) == window)
326
gchar *name = bamf_view_get_name (view);
354
auto view = static_cast<BamfView*>(l->data);
355
result = glib::String(bamf_view_get_name(view)).Str();
351
373
void BamfLauncherIcon::OnWindowMoved(guint32 moved_win)
375
if (!OwnsWindow(moved_win))
353
378
if (_window_moved_id != 0)
354
379
g_source_remove(_window_moved_id);
356
_window_moved_xid = moved_win;
358
381
_window_moved_id = g_timeout_add(250, [] (gpointer data) -> gboolean
360
383
BamfLauncherIcon* self = static_cast<BamfLauncherIcon*>(data);
361
384
self->EnsureWindowState();
385
self->UpdateIconGeometries(self->GetCenters());
362
386
self->_window_moved_id = 0;
367
bool BamfLauncherIcon::IsSticky()
369
return bamf_view_is_sticky(BAMF_VIEW(m_App));
372
391
void BamfLauncherIcon::UpdateDesktopFile()
374
char* filename = NULL;
375
filename = (char*) bamf_application_get_desktop_file(m_App);
393
const char* filename = bamf_application_get_desktop_file(_bamf_app);
377
if (filename != NULL && g_strcmp0(_cached_desktop_file, filename) != 0)
395
if (filename != nullptr && filename[0] != '\0' && _desktop_file != filename)
379
if (_cached_desktop_file != NULL)
380
g_free(_cached_desktop_file);
382
_cached_desktop_file = g_strdup(filename);
397
_desktop_file = filename;
384
399
// add a file watch to the desktop file so that if/when the app is removed
385
400
// we can remove ourself from the launcher and when it's changed
386
401
// we can update the quicklist.
387
402
if (_desktop_file_monitor)
389
if (_on_desktop_file_changed_handler_id != 0)
390
g_signal_handler_disconnect(G_OBJECT(_desktop_file_monitor),
391
_on_desktop_file_changed_handler_id);
392
g_object_unref(_desktop_file_monitor);
403
_gsignals.Disconnect(_desktop_file_monitor, "changed");
395
GFile* desktop_file = g_file_new_for_path(DesktopFile());
405
glib::Object<GFile> desktop_file(g_file_new_for_path(_desktop_file.c_str()));
396
406
_desktop_file_monitor = g_file_monitor_file(desktop_file, G_FILE_MONITOR_NONE,
398
g_file_monitor_set_rate_limit (_desktop_file_monitor, 1000);
399
_on_desktop_file_changed_handler_id = g_signal_connect(_desktop_file_monitor,
401
G_CALLBACK(&BamfLauncherIcon::OnDesktopFileChanged),
408
g_file_monitor_set_rate_limit(_desktop_file_monitor, 1000);
410
auto sig = new glib::Signal<void, GFileMonitor*, GFile*, GFile*, GFileMonitorEvent>(_desktop_file_monitor, "changed",
411
[&] (GFileMonitor*, GFile*, GFile*, GFileMonitorEvent event_type) {
414
case G_FILE_MONITOR_EVENT_DELETED:
417
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
418
UpdateDesktopQuickList();
406
const char* BamfLauncherIcon::DesktopFile()
428
std::string BamfLauncherIcon::DesktopFile()
408
430
UpdateDesktopFile();
409
return _cached_desktop_file;
431
return _desktop_file;
412
const char* BamfLauncherIcon::BamfName()
434
std::string BamfLauncherIcon::BamfName() const
414
gchar* name = bamf_view_get_name(BAMF_VIEW(m_App));
419
if (_cached_name != NULL)
420
g_free(_cached_name);
436
glib::String name(bamf_view_get_name(BAMF_VIEW(_bamf_app.RawPtr())));
427
440
void BamfLauncherIcon::AddProperties(GVariantBuilder* builder)
429
442
LauncherIcon::AddProperties(builder);
431
g_variant_builder_add(builder, "{sv}", "desktop-file", g_variant_new_string(DesktopFile()));
433
444
GList* children, *l;
436
children = bamf_view_get_children(BAMF_VIEW(m_App));
445
children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr()));
437
446
GVariant* xids[(int) g_list_length(children)];
440
449
for (l = children; l; l = l->next)
442
view = static_cast <BamfView*> (l->data);
451
if (!BAMF_IS_WINDOW(l->data))
444
if (BAMF_IS_WINDOW(view))
446
xids[i++] = g_variant_new_uint32(bamf_window_get_xid(BAMF_WINDOW(view)));
454
Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data));
455
xids[i++] = g_variant_new_uint32(xid);
449
457
g_list_free(children);
450
g_variant_builder_add(builder, "{sv}", "xids", g_variant_new_array(G_VARIANT_TYPE_UINT32, xids, i));
459
variant::BuilderWrapper(builder)
460
.add("desktop-file", DesktopFile())
461
.add("xids", g_variant_new_array(G_VARIANT_TYPE_UINT32, xids, i))
462
.add("sticky", IsSticky());
453
bool BamfLauncherIcon::OwnsWindow(Window w)
465
bool BamfLauncherIcon::OwnsWindow(Window xid) const
455
467
GList* children, *l;
457
468
bool owns = false;
461
children = bamf_view_get_children(BAMF_VIEW(m_App));
473
children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr()));
463
475
for (l = children; l; l = l->next)
465
view = static_cast <BamfView*> (l->data);
477
if (!BAMF_IS_WINDOW(l->data))
467
if (BAMF_IS_WINDOW(view))
480
if (bamf_window_get_xid(static_cast<BamfWindow*>(l->data)) == xid)
469
guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
638
633
return WindowManager::Default()->ScaleWindowGroup(windowList, state, force);
641
void BamfLauncherIcon::OnClosed(BamfView* view, gpointer data)
643
BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data);
645
if (!bamf_view_is_sticky(BAMF_VIEW(self->m_App)))
649
void BamfLauncherIcon::OnUserVisibleChanged(BamfView* view, gboolean visible,
652
BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data);
654
if (!bamf_view_is_sticky(BAMF_VIEW(self->m_App)))
655
self->SetQuirk(QUIRK_VISIBLE, visible);
658
void BamfLauncherIcon::OnRunningChanged(BamfView* view, gboolean running,
661
BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data);
662
self->SetQuirk(QUIRK_RUNNING, running);
666
self->EnsureWindowState();
667
self->UpdateIconGeometries(self->GetCenter());
671
void BamfLauncherIcon::OnActiveChanged(BamfView* view, gboolean active, gpointer data)
673
BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data);
674
self->SetQuirk(QUIRK_ACTIVE, active);
677
void BamfLauncherIcon::OnUrgentChanged(BamfView* view, gboolean urgent, gpointer data)
679
BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data);
680
self->SetQuirk(QUIRK_URGENT, urgent);
683
636
void BamfLauncherIcon::EnsureWindowState()
685
638
GList* children, *l;
686
bool has_win_on_current_vp = false;
687
unsigned int user_visible_count = 0;
688
unsigned int children_count = 0;
639
std::vector<bool> monitors;
640
monitors.resize(max_num_monitors);
690
children = bamf_view_get_children(BAMF_VIEW(m_App));
642
children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr()));
691
643
for (l = children; l; l = l->next)
693
645
if (!BAMF_IS_WINDOW(l->data))
696
Window xid = bamf_window_get_xid(BAMF_WINDOW(l->data));
697
if (WindowManager::Default()->IsWindowOnCurrentDesktop(xid))
699
has_win_on_current_vp = true;
701
if (bamf_view_user_visible (BAMF_VIEW (l->data)))
703
user_visible_count++;
710
if (user_visible_count > 0)
712
SetRelatedWindows(user_visible_count);
714
else if (children_count > 0)
716
SetRelatedWindows(1);
719
SetHasWindowOnViewport(has_win_on_current_vp);
648
auto window = static_cast<BamfWindow*>(l->data);
649
Window xid = bamf_window_get_xid(window);
650
int monitor = bamf_window_get_monitor(window);
652
if (monitor >= 0 && WindowManager::Default()->IsWindowOnCurrentDesktop(xid))
653
monitors[monitor] = true;
656
for (int i = 0; i < max_num_monitors; i++)
657
SetWindowVisibleOnMonitor(monitors[i], i);
721
661
g_list_free(children);
724
void BamfLauncherIcon::OnChildAdded(BamfView* view, BamfView* child, gpointer data)
726
BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data);
727
self->EnsureWindowState();
729
self->UpdateIconGeometries(self->GetCenter());
732
void BamfLauncherIcon::OnChildRemoved(BamfView* view, BamfView* child, gpointer data)
734
BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data);
735
self->EnsureWindowState();
738
664
void BamfLauncherIcon::UpdateDesktopQuickList()
740
IndicatorDesktopShortcuts* desktop_shortcuts;
742
GError* error = NULL;
743
const char *desktop_file;
745
desktop_file = DesktopFile();
747
if (!desktop_file || g_strcmp0(desktop_file, "") == 0)
750
// check that we have the X-Ayatana-Desktop-Shortcuts flag
751
// not sure if we should do this or if libindicator should shut up
752
// and not report errors when it can't find the key.
753
// so FIXME when ted is around
754
keyfile = g_key_file_new();
755
g_key_file_load_from_file(keyfile, desktop_file, G_KEY_FILE_NONE, &error);
759
g_warning("Could not load desktop file for: %s", desktop_file);
760
g_key_file_free(keyfile);
765
if (g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP,
766
"X-Ayatana-Desktop-Shortcuts", NULL))
768
DbusmenuMenuitem* root = dbusmenu_menuitem_new();
769
dbusmenu_menuitem_set_root(root, TRUE);
770
desktop_shortcuts = indicator_desktop_shortcuts_new(desktop_file, "Unity");
771
const gchar** nicks = indicator_desktop_shortcuts_get_nicks(desktop_shortcuts);
776
while (((gpointer*) nicks)[index])
779
DbusmenuMenuitem* item;
780
name = indicator_desktop_shortcuts_nick_get_name(desktop_shortcuts,
782
ShortcutData* data = g_slice_new0(ShortcutData);
784
data->shortcuts = INDICATOR_DESKTOP_SHORTCUTS(g_object_ref(desktop_shortcuts));
785
data->nick = g_strdup(nicks[index]);
787
item = dbusmenu_menuitem_new();
788
dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, name);
789
dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
790
dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
791
g_signal_connect_data(item, "item-activated",
792
(GCallback) shortcut_activated, (gpointer) data,
793
(GClosureNotify) shortcut_data_destroy, (GConnectFlags)0);
795
dbusmenu_menuitem_child_append(root, item);
803
if (G_IS_OBJECT(_menu_desktop_shortcuts))
804
g_object_unref(G_OBJECT(_menu_desktop_shortcuts));
806
_menu_desktop_shortcuts = root;
809
g_key_file_free(keyfile);
666
std::string const& desktop_file = DesktopFile();
668
if (desktop_file.empty())
671
for (GList *l = dbusmenu_menuitem_get_children(_menu_desktop_shortcuts); l; l = l->next)
672
_gsignals.Disconnect(l->data, "item-activated");
674
_menu_desktop_shortcuts = dbusmenu_menuitem_new();
675
dbusmenu_menuitem_set_root(_menu_desktop_shortcuts, TRUE);
677
// Build a desktop shortcuts object and tell it that our
678
// environment is Unity to handle the filtering
679
_desktop_shortcuts = indicator_desktop_shortcuts_new(desktop_file.c_str(), "Unity");
680
// This will get us a list of the nicks available, it should
681
// always be at least one entry of NULL if there either aren't
682
// any or they're filtered for the environment we're in
683
const gchar** nicks = indicator_desktop_shortcuts_get_nicks(_desktop_shortcuts);
686
while (nicks[index]) {
688
// Build a dbusmenu item for each nick that is the desktop
689
// file that is built from it's name and includes a callback
690
// to the desktop shortcuts object to execute the nick
691
glib::String name(indicator_desktop_shortcuts_nick_get_name(_desktop_shortcuts,
693
glib::Object<DbusmenuMenuitem> item(dbusmenu_menuitem_new());
694
dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, name);
695
dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
696
dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
697
dbusmenu_menuitem_property_set(item, "shortcut-nick", nicks[index]);
699
auto sig = new glib::Signal<void, DbusmenuMenuitem*, gint>(item, "item-activated",
700
[&] (DbusmenuMenuitem* item, gint) {
702
nick = dbusmenu_menuitem_property_get(item, "shortcut-nick");
703
indicator_desktop_shortcuts_nick_exec(_desktop_shortcuts, nick);
707
dbusmenu_menuitem_child_append(_menu_desktop_shortcuts, item);
812
712
void BamfLauncherIcon::UpdateMenus()
814
714
GList* children, *l;
816
children = bamf_view_get_children(BAMF_VIEW(m_App));
716
children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr()));
817
717
for (l = children; l; l = l->next)
819
719
if (!BAMF_IS_INDICATOR(l->data))
822
BamfIndicator* indicator = BAMF_INDICATOR(l->data);
722
auto indicator = static_cast<BamfIndicator*>(l->data);
823
723
std::string path = bamf_indicator_get_dbus_menu_path(indicator);
825
725
// we already have this
826
726
if (_menu_clients.find(path) != _menu_clients.end())
829
DbusmenuClient* client = dbusmenu_client_new(bamf_indicator_get_remote_address(indicator), path.c_str());
830
_menu_clients[path] = client;
729
std::string address = bamf_indicator_get_remote_address(indicator);
730
DbusmenuClient* client = dbusmenu_client_new(address.c_str(), path.c_str());
731
_menu_clients[path] = glib::Object<DbusmenuClient>(client);
833
734
g_list_free(children);
835
736
// add dynamic quicklist
836
if (_menuclient_dynamic_quicklist != NULL)
838
auto menu_client = DBUSMENU_CLIENT(g_object_ref(_menuclient_dynamic_quicklist));
839
_menu_clients["dynamicquicklist"] = menu_client;
737
if (DBUSMENU_IS_CLIENT(_menuclient_dynamic_quicklist))
739
if (_menu_clients["dynamicquicklist"] != _menuclient_dynamic_quicklist)
741
_menu_clients["dynamicquicklist"] = glib::Object<DbusmenuClient>(_menuclient_dynamic_quicklist);
744
else if (_menu_clients["dynamicquicklist"])
746
_menu_clients.erase("dynamicquicklist");
747
_menuclient_dynamic_quicklist = nullptr;
842
750
// make a client for desktop file actions
843
if (!DBUSMENU_IS_MENUITEM(_menu_desktop_shortcuts))
751
if (!DBUSMENU_IS_MENUITEM(_menu_desktop_shortcuts.RawPtr()))
845
753
UpdateDesktopQuickList();
850
void BamfLauncherIcon::OnQuit(DbusmenuMenuitem* item, int time, BamfLauncherIcon* self)
855
757
void BamfLauncherIcon::Quit()
857
759
GList* children, *l;
860
children = bamf_view_get_children(BAMF_VIEW(m_App));
761
children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr()));
862
763
for (l = children; l; l = l->next)
864
view = static_cast <BamfView*> (l->data);
765
if (!BAMF_IS_WINDOW(l->data))
866
if (BAMF_IS_WINDOW(view))
868
guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
869
WindowManager::Default()->Close(xid);
768
Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data));
769
WindowManager::Default()->Close(xid);
873
772
g_list_free(children);
876
void BamfLauncherIcon::Stick()
775
void BamfLauncherIcon::Stick(bool save)
878
BamfView* view = BAMF_VIEW(m_App);
880
if (bamf_view_is_sticky(view))
883
const gchar* desktop_file = DesktopFile();
884
bamf_view_set_sticky(view, true);
886
if (desktop_file && strlen(desktop_file) > 0)
887
FavoriteStore::GetDefault().AddFavorite(desktop_file, -1);
780
std::string const& desktop_file = DesktopFile();
781
bamf_view_set_sticky(BAMF_VIEW(_bamf_app.RawPtr()), true);
783
if (save && !desktop_file.empty())
784
FavoriteStore::GetDefault().AddFavorite(desktop_file.c_str(), -1);
890
void BamfLauncherIcon::UnStick(void)
787
void BamfLauncherIcon::UnStick()
892
BamfView* view = BAMF_VIEW(this->m_App);
894
if (!bamf_view_is_sticky(view))
897
const gchar* desktop_file = DesktopFile();
792
std::string const& desktop_file = DesktopFile();
793
BamfView* view = BAMF_VIEW(_bamf_app.RawPtr());
898
794
bamf_view_set_sticky(view, false);
900
796
if (bamf_view_is_closed(view) || !bamf_view_user_visible(view))
903
if (desktop_file && desktop_file[0] != '\0')
904
FavoriteStore::GetDefault().RemoveFavorite(desktop_file);
799
if (!desktop_file.empty())
800
FavoriteStore::GetDefault().RemoveFavorite(desktop_file.c_str());
907
void BamfLauncherIcon::OnTogglePin(DbusmenuMenuitem* item, int time, BamfLauncherIcon* self)
803
void BamfLauncherIcon::ToggleSticky()
909
BamfView* view = BAMF_VIEW(self->m_App);
910
bool sticky = bamf_view_is_sticky(view);
911
const gchar* desktop_file = self->DesktopFile();
919
bamf_view_set_sticky(view, true);
921
if (desktop_file && strlen(desktop_file) > 0)
922
FavoriteStore::GetDefault().AddFavorite(desktop_file, -1);
1236
1110
return ValidateUrisForLaunch(dnd_data).empty() ? nux::DNDACTION_NONE : nux::DNDACTION_COPY;
1239
void BamfLauncherIcon::OnAcceptDrop(unity::DndData& dnd_data)
1113
void BamfLauncherIcon::OnAcceptDrop(unity::DndData& dnd_data)
1241
1115
OpenInstanceWithUris(ValidateUrisForLaunch(dnd_data));
1244
void BamfLauncherIcon::OnDesktopFileChanged(GFileMonitor* monitor,
1247
GFileMonitorEvent event_type,
1118
bool BamfLauncherIcon::ShowInSwitcher(bool current)
1250
BamfLauncherIcon* self = static_cast<BamfLauncherIcon*>(data);
1120
bool result = false;
1122
if (IsRunning() && IsVisible())
1253
case G_FILE_MONITOR_EVENT_DELETED:
1256
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
1257
self->UpdateDesktopQuickList();
1124
// If current is true, we only want to show the current workspace.
1131
for (int i = 0; i < max_num_monitors; i++)
1133
if (WindowVisibleOnMonitor(i))
1265
BamfLauncherIcon::ShowInSwitcher()
1267
return GetQuirk(QUIRK_RUNNING) && GetQuirk(QUIRK_VISIBLE);
1271
BamfLauncherIcon::SwitcherPriority()
1145
unsigned long long BamfLauncherIcon::SwitcherPriority()
1273
1147
GList* children, *l;
1275
1148
unsigned long long result = 0;
1277
children = bamf_view_get_children(BAMF_VIEW(m_App));
1150
children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr()));
1279
1152
/* get the list of windows */
1280
1153
for (l = children; l; l = l->next)
1282
view = static_cast <BamfView*> (l->data);
1155
if (!BAMF_IS_WINDOW(l->data))
1284
if (BAMF_IS_WINDOW(view))
1286
guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
1287
result = std::max(result, WindowManager::Default()->GetWindowActiveNumber (xid));
1158
Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data));
1159
result = std::max(result, WindowManager::Default()->GetWindowActiveNumber(xid));
1291
1162
g_list_free(children);
1295
const std::set<std::string>&
1296
BamfLauncherIcon::GetSupportedTypes()
1166
const std::set<std::string>& BamfLauncherIcon::GetSupportedTypes()
1298
1168
if (!_supported_types_filled)
1299
FillSupportedTypes(this);
1169
FillSupportedTypes();
1301
1171
return _supported_types;
1305
BamfLauncherIcon::FillSupportedTypes(gpointer data)
1174
void BamfLauncherIcon::FillSupportedTypes()
1307
BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data);
1309
if (self->_fill_supported_types_id)
1176
if (_fill_supported_types_id)
1311
g_source_remove(self->_fill_supported_types_id);
1312
self->_fill_supported_types_id = 0;
1178
g_source_remove(_fill_supported_types_id);
1179
_fill_supported_types_id = 0;
1315
if (!self->_supported_types_filled)
1182
if (!_supported_types_filled)
1317
self->_supported_types_filled = true;
1319
self->_supported_types.clear();
1321
const char* desktop_file = self->DesktopFile();
1323
if (!desktop_file || strlen(desktop_file) <= 1)
1184
_supported_types_filled = true;
1185
_supported_types.clear();
1187
std::string const& desktop_file = DesktopFile();
1189
if (desktop_file.empty())
1326
1192
GKeyFile* key_file = g_key_file_new();
1327
unity::glib::Error error;
1329
g_key_file_load_from_file(key_file, desktop_file, (GKeyFileFlags) 0, &error);
1195
g_key_file_load_from_file(key_file, desktop_file.c_str(), (GKeyFileFlags) 0, &error);
1333
1199
g_key_file_free(key_file);
1337
char** mimes = g_key_file_get_string_list(key_file, "Desktop Entry", "MimeType", NULL, NULL);
1203
char** mimes = g_key_file_get_string_list(key_file, "Desktop Entry", "MimeType", nullptr, nullptr);
1340
1206
g_key_file_free(key_file);
1344
for (int i=0; mimes[i]; i++)
1210
for (int i = 0; mimes[i]; i++)
1346
1212
unity::glib::String super_type(g_content_type_from_mime_type(mimes[i]));
1347
self->_supported_types.insert(super_type.Str());
1213
_supported_types.insert(super_type.Str());
1350
1216
g_key_file_free(key_file);
1351
1217
g_strfreev(mimes);
1221
std::string BamfLauncherIcon::GetName() const
1223
return "BamfLauncherIcon";
1357
1226
} // namespace launcher