~jamespharaoh/ubuntu/oneiric/unity/fix-for-880672

« back to all changes in this revision

Viewing changes to .pc/debian-changes-4.8.2-0ubuntu3/plugins/unityshell/src/BamfLauncherIcon.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2011-08-19 18:53:28 UTC
  • Revision ID: james.westby@ubuntu.com-20110819185328-qaxk9eepjaghewu9
Tags: 4.8.2-0ubuntu4
Backport another trunk commit to fix an alt-tab segfault

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2
 
/*
3
 
 * Copyright (C) 2010 Canonical Ltd
4
 
 *
5
 
 * This program is free software: you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License version 3 as
7
 
 * published by the Free Software Foundation.
8
 
 *
9
 
 * This program is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 * GNU General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU General Public License
15
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 
 *
17
 
 * Authored by: Jason Smith <jason.smith@canonical.com>
18
 
 */
19
 
 
20
 
#include "Nux/Nux.h"
21
 
#include "Nux/BaseWindow.h"
22
 
 
23
 
#include "BamfLauncherIcon.h"
24
 
#include "Launcher.h"
25
 
#include "PluginAdapter.h"
26
 
#include "FavoriteStore.h"
27
 
 
28
 
#include "ubus-server.h"
29
 
#include "UBusMessages.h"
30
 
 
31
 
#include <glib/gi18n-lib.h>
32
 
#include <gio/gdesktopappinfo.h>
33
 
#include <libindicator/indicator-desktop-shortcuts.h>
34
 
#include <core/core.h>
35
 
#include <core/atoms.h>
36
 
 
37
 
using unity::FavoriteStore;
38
 
 
39
 
struct _ShortcutData
40
 
{
41
 
  BamfLauncherIcon* self;
42
 
  IndicatorDesktopShortcuts* shortcuts;
43
 
  char* nick;
44
 
};
45
 
typedef struct _ShortcutData ShortcutData;
46
 
static void shortcut_data_destroy(ShortcutData* data)
47
 
{
48
 
  g_object_unref(data->shortcuts);
49
 
  g_free(data->nick);
50
 
  g_slice_free(ShortcutData, data);
51
 
}
52
 
 
53
 
static void shortcut_activated(DbusmenuMenuitem* _sender, guint timestamp, gpointer userdata)
54
 
{
55
 
  ShortcutData* data = (ShortcutData*)userdata;
56
 
  indicator_desktop_shortcuts_nick_exec(data->shortcuts, data->nick);
57
 
}
58
 
 
59
 
void BamfLauncherIcon::Activate(ActionArg arg)
60
 
{
61
 
  ActivateLauncherIcon(arg);
62
 
}
63
 
 
64
 
 
65
 
void BamfLauncherIcon::ActivateLauncherIcon(ActionArg arg)
66
 
{
67
 
  bool scaleWasActive = PluginAdapter::Default()->IsScaleActive();
68
 
 
69
 
  bool active, running;
70
 
  active = bamf_view_is_active(BAMF_VIEW(m_App));
71
 
  running = bamf_view_is_running(BAMF_VIEW(m_App));
72
 
 
73
 
  if (arg.target && OwnsWindow (arg.target))
74
 
  {
75
 
    CompWindow* window = m_Screen->findWindow(arg.target);
76
 
    window->activate ();
77
 
    return;
78
 
  }
79
 
 
80
 
  /* Behaviour:
81
 
   * 1) Nothing running -> launch application
82
 
   * 2) Running and active -> spread application
83
 
   * 3) Running and not active -> focus application
84
 
   * 4) Spread is active and different icon pressed -> change spread
85
 
   * 5) Spread is active -> Spread de-activated, and fall through
86
 
   */
87
 
 
88
 
  if (!running) // #1 above
89
 
  {
90
 
    if (GetQuirk(QUIRK_STARTING))
91
 
      return;
92
 
 
93
 
    if (scaleWasActive)
94
 
    {
95
 
      PluginAdapter::Default()->TerminateScale();
96
 
    }
97
 
 
98
 
    SetQuirk(QUIRK_STARTING, true);
99
 
    OpenInstanceLauncherIcon(ActionArg ());
100
 
  }
101
 
  else // app is running
102
 
  {
103
 
    if (active)
104
 
    {
105
 
      if (scaleWasActive) // #5 above
106
 
      {
107
 
        PluginAdapter::Default()->TerminateScale();
108
 
        Focus();
109
 
      }
110
 
      else // #2 above
111
 
      {
112
 
        if (arg.source != ActionArg::SWITCHER)
113
 
          Spread(0, false);
114
 
      }
115
 
    }
116
 
    else
117
 
    {
118
 
      if (scaleWasActive) // #4 above
119
 
      {
120
 
        PluginAdapter::Default()->TerminateScale();
121
 
        Focus();
122
 
        if (arg.source != ActionArg::SWITCHER)
123
 
          Spread(0, false);
124
 
      }
125
 
      else // #3 above
126
 
      {
127
 
        Focus();
128
 
      }
129
 
    }
130
 
  }
131
 
 
132
 
  ubus_server_send_message(ubus_server_get_default(), UBUS_LAUNCHER_ACTION_DONE, NULL);
133
 
}
134
 
 
135
 
BamfLauncherIcon::BamfLauncherIcon(Launcher* IconManager, BamfApplication* app, CompScreen* screen)
136
 
  :   SimpleLauncherIcon(IconManager)
137
 
{
138
 
  _cached_desktop_file = NULL;
139
 
  _cached_name = NULL;
140
 
  m_App = app;
141
 
  m_Screen = screen;
142
 
  _remote_uri = 0;
143
 
  _dnd_hover_timer = 0;
144
 
  _dnd_hovered = false;
145
 
  _launcher = IconManager;
146
 
  _menu_desktop_shortcuts = NULL;
147
 
  char* icon_name = bamf_view_get_icon(BAMF_VIEW(m_App));
148
 
 
149
 
  tooltip_text = BamfName();
150
 
  SetIconName(icon_name);
151
 
  SetIconType(TYPE_APPLICATION);
152
 
 
153
 
  if (bamf_view_is_sticky(BAMF_VIEW(m_App)))
154
 
    SetQuirk(QUIRK_VISIBLE, true);
155
 
  else
156
 
    SetQuirk(QUIRK_VISIBLE, bamf_view_user_visible(BAMF_VIEW(m_App)));
157
 
 
158
 
  SetQuirk(QUIRK_ACTIVE, bamf_view_is_active(BAMF_VIEW(m_App)));
159
 
  SetQuirk(QUIRK_RUNNING, bamf_view_is_running(BAMF_VIEW(m_App)));
160
 
 
161
 
  g_free(icon_name);
162
 
 
163
 
  g_signal_connect(app, "child-removed", (GCallback) &BamfLauncherIcon::OnChildRemoved, this);
164
 
  g_signal_connect(app, "child-added", (GCallback) &BamfLauncherIcon::OnChildAdded, this);
165
 
  g_signal_connect(app, "urgent-changed", (GCallback) &BamfLauncherIcon::OnUrgentChanged, this);
166
 
  g_signal_connect(app, "running-changed", (GCallback) &BamfLauncherIcon::OnRunningChanged, this);
167
 
  g_signal_connect(app, "active-changed", (GCallback) &BamfLauncherIcon::OnActiveChanged, this);
168
 
  g_signal_connect(app, "user-visible-changed", (GCallback) &BamfLauncherIcon::OnUserVisibleChanged, this);
169
 
  g_signal_connect(app, "closed", (GCallback) &BamfLauncherIcon::OnClosed, this);
170
 
 
171
 
  g_object_ref(m_App);
172
 
 
173
 
  EnsureWindowState();
174
 
  UpdateMenus();
175
 
 
176
 
  // add a file watch to the desktop file so that if/when the app is removed we can remove ourself from the launcher.
177
 
  GFile* _desktop_file = g_file_new_for_path(DesktopFile());
178
 
  _desktop_file_monitor = g_file_monitor_file(_desktop_file,
179
 
                                              G_FILE_MONITOR_NONE,
180
 
                                              NULL,
181
 
                                              NULL);
182
 
 
183
 
  _on_desktop_file_changed_handler_id = g_signal_connect(_desktop_file_monitor,
184
 
                                                         "changed",
185
 
                                                         G_CALLBACK(&BamfLauncherIcon::OnDesktopFileChanged),
186
 
                                                         this);
187
 
 
188
 
  PluginAdapter::Default()->window_minimized.connect(sigc::mem_fun(this, &BamfLauncherIcon::OnWindowMinimized));
189
 
  IconManager->hidden_changed.connect(sigc::mem_fun(this, &BamfLauncherIcon::OnLauncherHiddenChanged));
190
 
 
191
 
  /* hack */
192
 
  SetProgress(0.0f);
193
 
 
194
 
}
195
 
 
196
 
BamfLauncherIcon::~BamfLauncherIcon()
197
 
{
198
 
  g_object_set_qdata(G_OBJECT(m_App), g_quark_from_static_string("unity-seen"), GINT_TO_POINTER(0));
199
 
 
200
 
  // We might not have created the menu items yet
201
 
  if (_menu_items.find("Pin") != _menu_items.end())
202
 
  {
203
 
    g_signal_handler_disconnect((gpointer) _menu_items["Pin"],
204
 
                                _menu_callbacks["Pin"]);
205
 
  }
206
 
 
207
 
  if (_menu_items.find("Quit") != _menu_items.end())
208
 
  {
209
 
    g_signal_handler_disconnect((gpointer) _menu_items["Quit"],
210
 
                                _menu_callbacks["Quit"]);
211
 
  }
212
 
 
213
 
  if (_on_desktop_file_changed_handler_id != 0)
214
 
    g_signal_handler_disconnect((gpointer) _desktop_file_monitor,
215
 
                                _on_desktop_file_changed_handler_id);
216
 
 
217
 
  g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnChildRemoved,       this);
218
 
  g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnChildAdded,         this);
219
 
  g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnUrgentChanged,      this);
220
 
  g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnRunningChanged,     this);
221
 
  g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnActiveChanged,      this);
222
 
  g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnUserVisibleChanged, this);
223
 
  g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnClosed,             this);
224
 
 
225
 
  g_object_unref(m_App);
226
 
  g_object_unref(_desktop_file_monitor);
227
 
 
228
 
  g_free(_cached_desktop_file);
229
 
  g_free(_cached_name);
230
 
}
231
 
 
232
 
std::vector<Window> BamfLauncherIcon::RelatedXids ()
233
 
{
234
 
  std::vector<Window> results;
235
 
  GList* children, *l;
236
 
  BamfView* view;
237
 
 
238
 
  children = bamf_view_get_children(BAMF_VIEW(m_App));
239
 
  for (l = children; l; l = l->next)
240
 
  {
241
 
    view = (BamfView*) l->data;
242
 
    if (BAMF_IS_WINDOW(view))
243
 
      results.push_back ((Window) bamf_window_get_xid(BAMF_WINDOW(view)));
244
 
  }
245
 
 
246
 
  g_list_free(children);
247
 
  return results;
248
 
}
249
 
 
250
 
void BamfLauncherIcon::OnLauncherHiddenChanged()
251
 
{
252
 
  UpdateIconGeometries(GetCenter());
253
 
}
254
 
 
255
 
void BamfLauncherIcon::OnWindowMinimized(guint32 xid)
256
 
{
257
 
  if (!OwnsWindow(xid))
258
 
    return;
259
 
 
260
 
  Present(0.5f, 600);
261
 
  UpdateQuirkTimeDelayed(300, QUIRK_SHIMMER);
262
 
}
263
 
 
264
 
bool BamfLauncherIcon::IsSticky()
265
 
{
266
 
  return bamf_view_is_sticky(BAMF_VIEW(m_App));
267
 
}
268
 
 
269
 
const char* BamfLauncherIcon::DesktopFile()
270
 
{
271
 
  char* filename = NULL;
272
 
  filename = (char*) bamf_application_get_desktop_file(m_App);
273
 
 
274
 
  if (filename != NULL)
275
 
  {
276
 
    if (_cached_desktop_file != NULL)
277
 
      g_free(_cached_desktop_file);
278
 
 
279
 
    _cached_desktop_file = g_strdup(filename);
280
 
  }
281
 
 
282
 
  return _cached_desktop_file;
283
 
}
284
 
 
285
 
const char* BamfLauncherIcon::BamfName()
286
 
{
287
 
  const char* name = NULL;
288
 
  name = bamf_view_get_name(BAMF_VIEW(m_App));
289
 
 
290
 
  if (name == NULL)
291
 
    name = "";
292
 
 
293
 
  if (_cached_name != NULL)
294
 
    g_free(_cached_name);
295
 
 
296
 
  _cached_name = g_strdup(name);
297
 
 
298
 
  return _cached_name;
299
 
}
300
 
 
301
 
void BamfLauncherIcon::AddProperties(GVariantBuilder* builder)
302
 
{
303
 
  LauncherIcon::AddProperties(builder);
304
 
 
305
 
  g_variant_builder_add(builder, "{sv}", "desktop-file", g_variant_new_string(bamf_application_get_desktop_file(m_App)));
306
 
 
307
 
  GList* children, *l;
308
 
  BamfView* view;
309
 
 
310
 
  children = bamf_view_get_children(BAMF_VIEW(m_App));
311
 
  GVariant* xids[(int) g_list_length(children)];
312
 
 
313
 
  int i = 0;
314
 
  for (l = children; l; l = l->next)
315
 
  {
316
 
    view = (BamfView*) l->data;
317
 
 
318
 
    if (BAMF_IS_WINDOW(view))
319
 
    {
320
 
      xids[i++] = g_variant_new_uint32(bamf_window_get_xid(BAMF_WINDOW(view)));
321
 
    }
322
 
  }
323
 
  g_list_free(children);
324
 
  g_variant_builder_add(builder, "{sv}", "xids", g_variant_new_array(G_VARIANT_TYPE_UINT32, xids, i));
325
 
}
326
 
 
327
 
bool BamfLauncherIcon::OwnsWindow(Window w)
328
 
{
329
 
  GList* children, *l;
330
 
  BamfView* view;
331
 
  bool owns = false;
332
 
 
333
 
  children = bamf_view_get_children(BAMF_VIEW(m_App));
334
 
 
335
 
  for (l = children; l; l = l->next)
336
 
  {
337
 
    view = (BamfView*) l->data;
338
 
 
339
 
    if (BAMF_IS_WINDOW(view))
340
 
    {
341
 
      guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
342
 
 
343
 
      if (xid == w)
344
 
      {
345
 
        owns = true;
346
 
        break;
347
 
      }
348
 
    }
349
 
  }
350
 
 
351
 
  g_list_free(children);
352
 
  return owns;
353
 
}
354
 
 
355
 
void BamfLauncherIcon::OpenInstanceWithUris(std::list<char*> uris)
356
 
{
357
 
  GDesktopAppInfo* appInfo;
358
 
  GError* error = NULL;
359
 
  std::list<char*>::iterator it;
360
 
 
361
 
  appInfo = g_desktop_app_info_new_from_filename(bamf_application_get_desktop_file(BAMF_APPLICATION(m_App)));
362
 
 
363
 
  if (g_app_info_supports_uris(G_APP_INFO(appInfo)))
364
 
  {
365
 
    GList* list = NULL;
366
 
 
367
 
    for (it = uris.begin(); it != uris.end(); it++)
368
 
      list = g_list_prepend(list, *it);
369
 
 
370
 
    g_app_info_launch_uris(G_APP_INFO(appInfo), list, NULL, &error);
371
 
    g_list_free(list);
372
 
  }
373
 
  else if (g_app_info_supports_files(G_APP_INFO(appInfo)))
374
 
  {
375
 
    GList* list = NULL, *l;
376
 
    for (it = uris.begin(); it != uris.end(); it++)
377
 
    {
378
 
      GFile* file = g_file_new_for_uri(*it);
379
 
      list = g_list_prepend(list, file);
380
 
    }
381
 
    g_app_info_launch(G_APP_INFO(appInfo), list, NULL, &error);
382
 
 
383
 
    for (l = list; l; l = l->next)
384
 
      g_object_unref(G_FILE(list->data));
385
 
 
386
 
    g_list_free(list);
387
 
  }
388
 
  else
389
 
  {
390
 
    g_app_info_launch(G_APP_INFO(appInfo), NULL, NULL, &error);
391
 
  }
392
 
 
393
 
  g_object_unref(appInfo);
394
 
 
395
 
  if (error)
396
 
  {
397
 
    g_warning("%s\n", error->message);
398
 
    g_error_free(error);
399
 
  }
400
 
 
401
 
  UpdateQuirkTime(QUIRK_STARTING);
402
 
}
403
 
 
404
 
void BamfLauncherIcon::OpenInstanceLauncherIcon(ActionArg arg)
405
 
{
406
 
  std::list<char*> empty;
407
 
  OpenInstanceWithUris(empty);
408
 
  ubus_server_send_message(ubus_server_get_default(), UBUS_LAUNCHER_ACTION_DONE, NULL);
409
 
}
410
 
 
411
 
void BamfLauncherIcon::Focus()
412
 
{
413
 
  GList* children, *l;
414
 
  BamfView* view;
415
 
  bool any_urgent = false;
416
 
  bool any_on_current = false;
417
 
  bool any_mapped = false;
418
 
 
419
 
  children = bamf_view_get_children(BAMF_VIEW(m_App));
420
 
 
421
 
  CompWindowList windows;
422
 
 
423
 
  /* get the list of windows */
424
 
  for (l = children; l; l = l->next)
425
 
  {
426
 
    view = (BamfView*) l->data;
427
 
 
428
 
    if (BAMF_IS_WINDOW(view))
429
 
    {
430
 
      guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
431
 
 
432
 
      CompWindow* window = m_Screen->findWindow((Window) xid);
433
 
 
434
 
      if (window)
435
 
      {
436
 
        if (bamf_view_is_urgent(view))
437
 
          any_urgent = true;
438
 
        windows.push_back(window);
439
 
      }
440
 
    }
441
 
  }
442
 
 
443
 
  // not a good sign
444
 
  if (windows.empty())
445
 
  {
446
 
    g_list_free(children);
447
 
    return;
448
 
  }
449
 
 
450
 
  /* sort the list */
451
 
  CompWindowList tmp;
452
 
  for (auto win : m_Screen->clientList())
453
 
  {
454
 
    if (std::find(windows.begin(), windows.end(), win) != windows.end())
455
 
      tmp.push_back(win);
456
 
  }
457
 
  windows = tmp;
458
 
 
459
 
  /* filter based on workspace */
460
 
  for (CompWindow* &win : windows)
461
 
  {
462
 
    if (win->defaultViewport() == m_Screen->vp())
463
 
    {
464
 
      any_on_current = true;
465
 
    }
466
 
 
467
 
    if (!win->minimized())
468
 
    {
469
 
      any_mapped = true;
470
 
    }
471
 
 
472
 
    if (any_on_current && any_mapped)
473
 
      break;
474
 
  }
475
 
 
476
 
  if (any_urgent)
477
 
  {
478
 
    // FIXME we cant use the compiz tracking since it is currently broken
479
 
    /*for (it = windows.begin (); it != windows.end (); it++)
480
 
    {
481
 
      if ((*it)->state () & CompWindowStateDemandsAttentionMask)
482
 
      {
483
 
        (*it)->activate ();
484
 
        break;
485
 
      }
486
 
    }*/
487
 
    for (l = children; l; l = l->next)
488
 
    {
489
 
      view = (BamfView*) l->data;
490
 
 
491
 
      if (BAMF_IS_WINDOW(view))
492
 
      {
493
 
        guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
494
 
 
495
 
        CompWindow* window = m_Screen->findWindow((Window) xid);
496
 
 
497
 
        if (window && bamf_view_is_urgent(view))
498
 
        {
499
 
          window->activate();
500
 
          break;
501
 
        }
502
 
      }
503
 
    }
504
 
  }
505
 
  else if (any_on_current)
506
 
  {
507
 
    // to ensure proper stacking we process windows in reverse order (high to low)
508
 
    // then we active the first window and raise each following window. Due to the
509
 
    // way stack requests work (async), each subsequent raise call will stack below
510
 
    // the previous one.
511
 
    bool first = false;
512
 
    windows.reverse();
513
 
    for (CompWindow* &win : windows)
514
 
    {
515
 
      if (win->defaultViewport() == m_Screen->vp() &&
516
 
          ((any_mapped && !win->minimized()) || !any_mapped))
517
 
      {
518
 
        if (!first)
519
 
        {
520
 
          win->activate();
521
 
          first = true;
522
 
        }
523
 
        else
524
 
        {
525
 
          win->raise();
526
 
        }
527
 
      }
528
 
    }
529
 
 
530
 
  }
531
 
  else
532
 
  {
533
 
    (*(windows.rbegin()))->activate();
534
 
  }
535
 
 
536
 
  g_list_free(children);
537
 
}
538
 
 
539
 
bool BamfLauncherIcon::Spread(int state, bool force)
540
 
{
541
 
  BamfView* view;
542
 
  GList* children, *l;
543
 
  children = bamf_view_get_children(BAMF_VIEW(m_App));
544
 
 
545
 
  std::list<Window> windowList;
546
 
  for (l = children; l; l = l->next)
547
 
  {
548
 
    view = (BamfView*) l->data;
549
 
 
550
 
    if (BAMF_IS_WINDOW(view))
551
 
    {
552
 
      guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
553
 
      CompWindow* window = m_Screen->findWindow((Window) xid);
554
 
 
555
 
      // filter by workspace
556
 
      if (window && window->defaultViewport() == m_Screen->vp())
557
 
      {
558
 
        windowList.push_back((Window) xid);
559
 
      }
560
 
    }
561
 
  }
562
 
 
563
 
  if (windowList.size() > 1 || (windowList.size() > 0 && force))
564
 
  {
565
 
    std::string match = PluginAdapter::Default()->MatchStringForXids(&windowList);
566
 
    PluginAdapter::Default()->InitiateScale(match, state);
567
 
    g_list_free(children);
568
 
    return true;
569
 
  }
570
 
 
571
 
  g_list_free(children);
572
 
 
573
 
  return false;
574
 
}
575
 
 
576
 
void BamfLauncherIcon::OnClosed(BamfView* view, gpointer data)
577
 
{
578
 
  BamfLauncherIcon* self = (BamfLauncherIcon*) data;
579
 
 
580
 
  if (!bamf_view_is_sticky(BAMF_VIEW(self->m_App)))
581
 
    self->Remove();
582
 
}
583
 
 
584
 
void BamfLauncherIcon::OnUserVisibleChanged(BamfView* view, gboolean visible,
585
 
                                            gpointer data)
586
 
{
587
 
  BamfLauncherIcon* self = (BamfLauncherIcon*) data;
588
 
 
589
 
  if (!bamf_view_is_sticky(BAMF_VIEW(self->m_App)))
590
 
    self->SetQuirk(QUIRK_VISIBLE, visible);
591
 
}
592
 
 
593
 
void BamfLauncherIcon::OnRunningChanged(BamfView* view, gboolean running,
594
 
                                        gpointer data)
595
 
{
596
 
  BamfLauncherIcon* self = (BamfLauncherIcon*) data;
597
 
  self->SetQuirk(QUIRK_RUNNING, running);
598
 
 
599
 
  if (running)
600
 
  {
601
 
    self->EnsureWindowState();
602
 
    self->UpdateIconGeometries(self->GetCenter());
603
 
  }
604
 
}
605
 
 
606
 
void BamfLauncherIcon::OnActiveChanged(BamfView* view, gboolean active, gpointer data)
607
 
{
608
 
  BamfLauncherIcon* self = (BamfLauncherIcon*) data;
609
 
  self->SetQuirk(QUIRK_ACTIVE, active);
610
 
}
611
 
 
612
 
void BamfLauncherIcon::OnUrgentChanged(BamfView* view, gboolean urgent, gpointer data)
613
 
{
614
 
  BamfLauncherIcon* self = (BamfLauncherIcon*) data;
615
 
  self->SetQuirk(QUIRK_URGENT, urgent);
616
 
}
617
 
 
618
 
void BamfLauncherIcon::EnsureWindowState()
619
 
{
620
 
  GList* children, *l;
621
 
  int count = 0;
622
 
 
623
 
  bool has_visible = false;
624
 
 
625
 
  children = bamf_view_get_children(BAMF_VIEW(m_App));
626
 
  for (l = children; l; l = l->next)
627
 
  {
628
 
    if (!BAMF_IS_WINDOW(l->data))
629
 
      continue;
630
 
 
631
 
    count++;
632
 
 
633
 
    guint32 xid = bamf_window_get_xid(BAMF_WINDOW(l->data));
634
 
    CompWindow* window = m_Screen->findWindow((Window) xid);
635
 
 
636
 
    if (window && window->defaultViewport() == m_Screen->vp())
637
 
      has_visible = true;
638
 
  }
639
 
 
640
 
  SetRelatedWindows(count);
641
 
  SetHasWindowOnViewport(has_visible);
642
 
 
643
 
  g_list_free(children);
644
 
}
645
 
 
646
 
void BamfLauncherIcon::OnChildAdded(BamfView* view, BamfView* child, gpointer data)
647
 
{
648
 
  BamfLauncherIcon* self = (BamfLauncherIcon*) data;
649
 
  self->EnsureWindowState();
650
 
  self->UpdateMenus();
651
 
  self->UpdateIconGeometries(self->GetCenter());
652
 
}
653
 
 
654
 
void BamfLauncherIcon::OnChildRemoved(BamfView* view, BamfView* child, gpointer data)
655
 
{
656
 
  BamfLauncherIcon* self = (BamfLauncherIcon*) data;
657
 
  self->EnsureWindowState();
658
 
}
659
 
 
660
 
void BamfLauncherIcon::UpdateMenus()
661
 
{
662
 
  GList* children, *l;
663
 
  IndicatorDesktopShortcuts* desktop_shortcuts;
664
 
 
665
 
  children = bamf_view_get_children(BAMF_VIEW(m_App));
666
 
  for (l = children; l; l = l->next)
667
 
  {
668
 
    if (!BAMF_IS_INDICATOR(l->data))
669
 
      continue;
670
 
 
671
 
    BamfIndicator* indicator = BAMF_INDICATOR(l->data);
672
 
    std::string path = bamf_indicator_get_dbus_menu_path(indicator);
673
 
 
674
 
    // we already have this
675
 
    if (_menu_clients.find(path) != _menu_clients.end())
676
 
      continue;
677
 
 
678
 
    DbusmenuClient* client = dbusmenu_client_new(bamf_indicator_get_remote_address(indicator), path.c_str());
679
 
    _menu_clients[path] = client;
680
 
  }
681
 
 
682
 
  g_list_free(children);
683
 
 
684
 
  // add dynamic quicklist
685
 
  if (_menuclient_dynamic_quicklist != NULL)
686
 
    _menu_clients["dynamicquicklist"] = _menuclient_dynamic_quicklist;
687
 
 
688
 
  // make a client for desktop file actions
689
 
  if (!DBUSMENU_IS_MENUITEM(_menu_desktop_shortcuts) &&
690
 
      g_strcmp0(DesktopFile(), """"))
691
 
  {
692
 
    GKeyFile* keyfile;
693
 
    GError* error = NULL;
694
 
 
695
 
    // check that we have the X-Ayatana-Desktop-Shortcuts flag
696
 
    // not sure if we should do this or if libindicator should shut up
697
 
    // and not report errors when it can't find the key.
698
 
    // so FIXME when ted is around
699
 
    keyfile = g_key_file_new();
700
 
    g_key_file_load_from_file(keyfile, DesktopFile(), G_KEY_FILE_NONE, &error);
701
 
 
702
 
    if (error != NULL)
703
 
    {
704
 
      g_warning("Could not load desktop file for: %s" , DesktopFile());
705
 
      g_error_free(error);
706
 
      return;
707
 
    }
708
 
 
709
 
    if (g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP,
710
 
                           "X-Ayatana-Desktop-Shortcuts", NULL))
711
 
    {
712
 
      DbusmenuMenuitem* root = dbusmenu_menuitem_new();
713
 
      dbusmenu_menuitem_set_root(root, TRUE);
714
 
      desktop_shortcuts = indicator_desktop_shortcuts_new(bamf_application_get_desktop_file(m_App),
715
 
                                                          "Unity");
716
 
      const gchar** nicks = indicator_desktop_shortcuts_get_nicks(desktop_shortcuts);
717
 
 
718
 
      int index = 0;
719
 
      if (nicks)
720
 
      {
721
 
        while (((gpointer*) nicks)[index])
722
 
        {
723
 
          gchar* name;
724
 
          DbusmenuMenuitem* item;
725
 
          name = indicator_desktop_shortcuts_nick_get_name(desktop_shortcuts,
726
 
                                                           nicks[index]);
727
 
          ShortcutData* data = g_slice_new0(ShortcutData);
728
 
          data->self = this;
729
 
          data->shortcuts = INDICATOR_DESKTOP_SHORTCUTS(g_object_ref(desktop_shortcuts));
730
 
          data->nick = g_strdup(nicks[index]);
731
 
 
732
 
          item = dbusmenu_menuitem_new();
733
 
          dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, name);
734
 
          dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
735
 
          dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
736
 
          g_signal_connect_data(item, "item-activated",
737
 
                                (GCallback) shortcut_activated, (gpointer) data,
738
 
                                (GClosureNotify) shortcut_data_destroy, (GConnectFlags)0);
739
 
 
740
 
          dbusmenu_menuitem_child_append(root, item);
741
 
 
742
 
          index++;
743
 
 
744
 
          g_free(name);
745
 
        }
746
 
      }
747
 
 
748
 
      _menu_desktop_shortcuts = root;
749
 
      g_key_file_free(keyfile);
750
 
 
751
 
    }
752
 
  }
753
 
 
754
 
}
755
 
 
756
 
void BamfLauncherIcon::OnQuit(DbusmenuMenuitem* item, int time, BamfLauncherIcon* self)
757
 
{
758
 
  GList* children, *l;
759
 
  BamfView* view;
760
 
 
761
 
  children = bamf_view_get_children(BAMF_VIEW(self->m_App));
762
 
 
763
 
  for (l = children; l; l = l->next)
764
 
  {
765
 
    view = (BamfView*) l->data;
766
 
 
767
 
    if (BAMF_IS_WINDOW(view))
768
 
    {
769
 
      guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
770
 
      CompWindow* window = self->m_Screen->findWindow((Window) xid);
771
 
 
772
 
      if (window)
773
 
        window->close(self->m_Screen->getCurrentTime());
774
 
    }
775
 
  }
776
 
 
777
 
  g_list_free(children);
778
 
}
779
 
 
780
 
void BamfLauncherIcon::UnStick(void)
781
 
{
782
 
  BamfView* view = BAMF_VIEW(this->m_App);
783
 
 
784
 
  if (!bamf_view_is_sticky(view))
785
 
    return;
786
 
 
787
 
  const gchar* desktop_file = bamf_application_get_desktop_file(this->m_App);
788
 
  bamf_view_set_sticky(view, false);
789
 
  if (bamf_view_is_closed(view))
790
 
    this->Remove();
791
 
 
792
 
  if (desktop_file && strlen(desktop_file) > 0)
793
 
    FavoriteStore::GetDefault().RemoveFavorite(desktop_file);
794
 
}
795
 
 
796
 
void BamfLauncherIcon::OnTogglePin(DbusmenuMenuitem* item, int time, BamfLauncherIcon* self)
797
 
{
798
 
  BamfView* view = BAMF_VIEW(self->m_App);
799
 
  bool sticky = bamf_view_is_sticky(view);
800
 
  const gchar* desktop_file = bamf_application_get_desktop_file(self->m_App);
801
 
 
802
 
  if (sticky)
803
 
  {
804
 
    self->UnStick();
805
 
  }
806
 
  else
807
 
  {
808
 
    bamf_view_set_sticky(view, true);
809
 
 
810
 
    if (desktop_file && strlen(desktop_file) > 0)
811
 
      FavoriteStore::GetDefault().AddFavorite(desktop_file, -1);
812
 
  }
813
 
}
814
 
 
815
 
void BamfLauncherIcon::EnsureMenuItemsReady()
816
 
{
817
 
  DbusmenuMenuitem* menu_item;
818
 
 
819
 
  /* Pin */
820
 
  if (_menu_items.find("Pin") == _menu_items.end())
821
 
  {
822
 
    menu_item = dbusmenu_menuitem_new();
823
 
    g_object_ref(menu_item);
824
 
 
825
 
    dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_CHECK);
826
 
    dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Keep in launcher"));
827
 
    dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
828
 
    dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
829
 
 
830
 
    _menu_callbacks["Pin"] = g_signal_connect(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnTogglePin, this);
831
 
 
832
 
    _menu_items["Pin"] = menu_item;
833
 
  }
834
 
  int checked = !bamf_view_is_sticky(BAMF_VIEW(m_App)) ?
835
 
                DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED : DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED;
836
 
 
837
 
  dbusmenu_menuitem_property_set_int(_menu_items["Pin"],
838
 
                                     DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
839
 
                                     checked);
840
 
 
841
 
 
842
 
  /* Quit */
843
 
  if (_menu_items.find("Quit") == _menu_items.end())
844
 
  {
845
 
    menu_item = dbusmenu_menuitem_new();
846
 
    g_object_ref(menu_item);
847
 
 
848
 
    dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Quit"));
849
 
    dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
850
 
    dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
851
 
 
852
 
    _menu_callbacks["Quit"] = g_signal_connect(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnQuit, this);
853
 
 
854
 
    _menu_items["Quit"] = menu_item;
855
 
  }
856
 
}
857
 
 
858
 
static void OnAppLabelActivated(DbusmenuMenuitem* sender,
859
 
                                guint             timestamp,
860
 
                                gpointer data)
861
 
{
862
 
  BamfLauncherIcon* self = NULL;
863
 
 
864
 
  if (!data)
865
 
    return;
866
 
 
867
 
  self = (BamfLauncherIcon*) data;
868
 
  self->ActivateLauncherIcon(ActionArg(ActionArg::OTHER, 0));
869
 
}
870
 
 
871
 
std::list<DbusmenuMenuitem*> BamfLauncherIcon::GetMenus()
872
 
{
873
 
  std::map<std::string, DbusmenuClient*>::iterator it;
874
 
  std::list<DbusmenuMenuitem*> result;
875
 
  bool first_separator_needed = false;
876
 
  DbusmenuMenuitem* item = NULL;
877
 
 
878
 
  // FIXME for O: hack around the wrong abstraction
879
 
  UpdateMenus();
880
 
 
881
 
  for (it = _menu_clients.begin(); it != _menu_clients.end(); it++)
882
 
  {
883
 
    GList* child = NULL;
884
 
    DbusmenuClient* client = (*it).second;
885
 
    DbusmenuMenuitem* root = dbusmenu_client_get_root(client);
886
 
 
887
 
    for (child = dbusmenu_menuitem_get_children(root); child != NULL; child = g_list_next(child))
888
 
    {
889
 
      DbusmenuMenuitem* item = (DbusmenuMenuitem*) child->data;
890
 
 
891
 
      if (!item)
892
 
        continue;
893
 
 
894
 
      first_separator_needed = true;
895
 
 
896
 
      result.push_back(item);
897
 
    }
898
 
  }
899
 
 
900
 
  // FIXME: this should totally be added as a _menu_client
901
 
  if (DBUSMENU_IS_MENUITEM(_menu_desktop_shortcuts))
902
 
  {
903
 
    GList* child = NULL;
904
 
    DbusmenuMenuitem* root = _menu_desktop_shortcuts;
905
 
 
906
 
    for (child = dbusmenu_menuitem_get_children(root); child != NULL; child = g_list_next(child))
907
 
    {
908
 
      DbusmenuMenuitem* item = (DbusmenuMenuitem*) child->data;
909
 
 
910
 
      if (!item)
911
 
        continue;
912
 
 
913
 
      first_separator_needed = true;
914
 
 
915
 
      result.push_back(item);
916
 
    }
917
 
  }
918
 
 
919
 
  if (first_separator_needed)
920
 
  {
921
 
    item = dbusmenu_menuitem_new();
922
 
    dbusmenu_menuitem_property_set(item,
923
 
                                   DBUSMENU_MENUITEM_PROP_TYPE,
924
 
                                   DBUSMENU_CLIENT_TYPES_SEPARATOR);
925
 
    result.push_back(item);
926
 
  }
927
 
 
928
 
  gchar* app_name;
929
 
  app_name = g_markup_escape_text(BamfName(), -1);
930
 
 
931
 
  item = dbusmenu_menuitem_new();
932
 
  dbusmenu_menuitem_property_set(item,
933
 
                                 DBUSMENU_MENUITEM_PROP_LABEL,
934
 
                                 app_name);
935
 
  dbusmenu_menuitem_property_set_bool(item,
936
 
                                      DBUSMENU_MENUITEM_PROP_ENABLED,
937
 
                                      true);
938
 
  g_signal_connect(item, "item-activated", (GCallback) OnAppLabelActivated, this);
939
 
  result.push_back(item);
940
 
  g_free(app_name);
941
 
 
942
 
  item = dbusmenu_menuitem_new();
943
 
  dbusmenu_menuitem_property_set(item,
944
 
                                 DBUSMENU_MENUITEM_PROP_TYPE,
945
 
                                 DBUSMENU_CLIENT_TYPES_SEPARATOR);
946
 
  result.push_back(item);
947
 
 
948
 
  EnsureMenuItemsReady();
949
 
 
950
 
  std::map<std::string, DbusmenuMenuitem*>::iterator it_m;
951
 
  std::list<DbusmenuMenuitem*>::iterator it_l;
952
 
  bool exists;
953
 
  for (it_m = _menu_items.begin(); it_m != _menu_items.end(); it_m++)
954
 
  {
955
 
    const char* key = ((*it_m).first).c_str();
956
 
    if (g_strcmp0(key , "Quit") == 0 && !bamf_view_is_running(BAMF_VIEW(m_App)))
957
 
      continue;
958
 
 
959
 
    exists = false;
960
 
    std::string label_default = dbusmenu_menuitem_property_get((*it_m).second, DBUSMENU_MENUITEM_PROP_LABEL);
961
 
    for (it_l = result.begin(); it_l != result.end(); it_l++)
962
 
    {
963
 
      const gchar* type = dbusmenu_menuitem_property_get(*it_l, DBUSMENU_MENUITEM_PROP_TYPE);
964
 
      if (type == NULL)//(g_strcmp0 (type, DBUSMENU_MENUITEM_PROP_LABEL) == 0)
965
 
      {
966
 
        std::string label_menu = dbusmenu_menuitem_property_get(*it_l, DBUSMENU_MENUITEM_PROP_LABEL);
967
 
        if (label_menu.compare(label_default) == 0)
968
 
        {
969
 
          exists = true;
970
 
          break;
971
 
        }
972
 
      }
973
 
    }
974
 
 
975
 
    if (!exists)
976
 
      result.push_back((*it_m).second);
977
 
  }
978
 
 
979
 
  return result;
980
 
}
981
 
 
982
 
 
983
 
void BamfLauncherIcon::UpdateIconGeometries(nux::Point3 center)
984
 
{
985
 
  GList* children, *l;
986
 
  BamfView* view;
987
 
  long data[4];
988
 
 
989
 
  if (_launcher->Hidden() && !_launcher->ShowOnEdge())
990
 
  {
991
 
    data[0] = 0;
992
 
    data[1] = 0;
993
 
  }
994
 
  else
995
 
  {
996
 
    data[0] = center.x - 24;
997
 
    data[1] = center.y - 24;
998
 
  }
999
 
  data[2] = 48;
1000
 
  data[3] = 48;
1001
 
 
1002
 
  children = bamf_view_get_children(BAMF_VIEW(m_App));
1003
 
 
1004
 
  for (l = children; l; l = l->next)
1005
 
  {
1006
 
    view = (BamfView*) l->data;
1007
 
 
1008
 
    if (BAMF_IS_WINDOW(view))
1009
 
    {
1010
 
      guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
1011
 
 
1012
 
      XChangeProperty(m_Screen->dpy(), xid, Atoms::wmIconGeometry,
1013
 
                      XA_CARDINAL, 32, PropModeReplace,
1014
 
                      (unsigned char*) data, 4);
1015
 
    }
1016
 
  }
1017
 
 
1018
 
  g_list_free(children);
1019
 
}
1020
 
 
1021
 
void BamfLauncherIcon::OnCenterStabilized(nux::Point3 center)
1022
 
{
1023
 
  UpdateIconGeometries(center);
1024
 
}
1025
 
 
1026
 
const gchar* BamfLauncherIcon::GetRemoteUri()
1027
 
{
1028
 
  if (!_remote_uri)
1029
 
  {
1030
 
    const gchar* desktop_file = bamf_application_get_desktop_file(BAMF_APPLICATION(m_App));
1031
 
    gchar* basename =  g_path_get_basename(desktop_file);
1032
 
 
1033
 
    _remote_uri = g_strdup_printf("application://%s", basename);
1034
 
 
1035
 
    g_free(basename);
1036
 
  }
1037
 
 
1038
 
  return _remote_uri;
1039
 
}
1040
 
 
1041
 
std::list<char*> BamfLauncherIcon::ValidateUrisForLaunch(std::list<char*> uris)
1042
 
{
1043
 
  GKeyFile* key_file;
1044
 
  const char* desktop_file;
1045
 
  GError* error = NULL;
1046
 
  std::list<char*> results;
1047
 
 
1048
 
  desktop_file = DesktopFile();
1049
 
 
1050
 
  if (!desktop_file || strlen(desktop_file) <= 1)
1051
 
    return results;
1052
 
 
1053
 
  key_file = g_key_file_new();
1054
 
  g_key_file_load_from_file(key_file, desktop_file, (GKeyFileFlags) 0, &error);
1055
 
 
1056
 
  if (error)
1057
 
  {
1058
 
    g_error_free(error);
1059
 
    g_key_file_free(key_file);
1060
 
    return results;
1061
 
  }
1062
 
 
1063
 
  char** mimes = g_key_file_get_string_list(key_file, "Desktop Entry", "MimeType", NULL, NULL);
1064
 
  if (!mimes)
1065
 
  {
1066
 
    g_key_file_free(key_file);
1067
 
    return results;
1068
 
  }
1069
 
 
1070
 
  std::list<char*>::iterator it;
1071
 
  for (it = uris.begin(); it != uris.end(); it++)
1072
 
  {
1073
 
    GFile* file = g_file_new_for_uri(*it);
1074
 
    GFileInfo* info = g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL);
1075
 
    const char* content_type = g_file_info_get_content_type(info);
1076
 
 
1077
 
    int i = 0;
1078
 
    for (; mimes[i]; i++)
1079
 
    {
1080
 
      char* super_type = g_content_type_from_mime_type(mimes[i]);
1081
 
      if (g_content_type_is_a(content_type, super_type))
1082
 
      {
1083
 
        results.push_back(*it);
1084
 
        break;
1085
 
      }
1086
 
      g_free(super_type);
1087
 
    }
1088
 
 
1089
 
 
1090
 
    g_object_unref(file);
1091
 
    g_object_unref(info);
1092
 
  }
1093
 
 
1094
 
  g_strfreev(mimes);
1095
 
  g_key_file_free(key_file);
1096
 
  return results;
1097
 
}
1098
 
 
1099
 
gboolean BamfLauncherIcon::OnDndHoveredTimeout(gpointer data)
1100
 
{
1101
 
  BamfLauncherIcon* self = (BamfLauncherIcon*) data;
1102
 
  if (self->_dnd_hovered && bamf_view_is_running(BAMF_VIEW(self->m_App)))
1103
 
    self->Spread(CompAction::StateInitEdgeDnd, true);
1104
 
 
1105
 
  self->_dnd_hover_timer = 0;
1106
 
  return false;
1107
 
}
1108
 
 
1109
 
void BamfLauncherIcon::OnDndEnter()
1110
 
{
1111
 
  _dnd_hovered = true;
1112
 
  _dnd_hover_timer = g_timeout_add(1000, &BamfLauncherIcon::OnDndHoveredTimeout, this);
1113
 
}
1114
 
 
1115
 
void BamfLauncherIcon::OnDndLeave()
1116
 
{
1117
 
  _dnd_hovered = false;
1118
 
 
1119
 
  if (_dnd_hover_timer)
1120
 
    g_source_remove(_dnd_hover_timer);
1121
 
  _dnd_hover_timer = 0;
1122
 
}
1123
 
 
1124
 
nux::DndAction BamfLauncherIcon::OnQueryAcceptDrop(std::list<char*> uris)
1125
 
{
1126
 
  return ValidateUrisForLaunch(uris).empty() ? nux::DNDACTION_NONE : nux::DNDACTION_COPY;
1127
 
}
1128
 
 
1129
 
void  BamfLauncherIcon::OnAcceptDrop(std::list<char*> uris)
1130
 
{
1131
 
  OpenInstanceWithUris(ValidateUrisForLaunch(uris));
1132
 
}
1133
 
 
1134
 
void BamfLauncherIcon::OnDesktopFileChanged(GFileMonitor*        monitor,
1135
 
                                            GFile*               file,
1136
 
                                            GFile*               other_file,
1137
 
                                            GFileMonitorEvent    event_type,
1138
 
                                            gpointer             data)
1139
 
{
1140
 
  BamfLauncherIcon* self = static_cast<BamfLauncherIcon*>(data);
1141
 
  switch (event_type)
1142
 
  {
1143
 
    case G_FILE_MONITOR_EVENT_DELETED:
1144
 
      self->UnStick();
1145
 
      break;
1146
 
    default:
1147
 
      break;
1148
 
  }
1149
 
}
1150
 
 
1151
 
bool
1152
 
BamfLauncherIcon::ShowInSwitcher()
1153
 
{
1154
 
  return GetQuirk(QUIRK_RUNNING) && GetQuirk(QUIRK_VISIBLE);
1155
 
}
1156
 
 
1157
 
unsigned int
1158
 
BamfLauncherIcon::SwitcherPriority()
1159
 
{
1160
 
  GList* children, *l;
1161
 
  BamfView* view;
1162
 
  unsigned int result = 0;
1163
 
 
1164
 
  children = bamf_view_get_children(BAMF_VIEW(m_App));
1165
 
 
1166
 
  /* get the list of windows */
1167
 
  for (l = children; l; l = l->next)
1168
 
  {
1169
 
    view = (BamfView*) l->data;
1170
 
 
1171
 
    if (BAMF_IS_WINDOW(view))
1172
 
    {
1173
 
      guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
1174
 
      CompWindow* window = m_Screen->findWindow((Window) xid);
1175
 
 
1176
 
      if (window)
1177
 
        result = std::max(result, window->activeNum());
1178
 
    }
1179
 
  }
1180
 
 
1181
 
  g_list_free(children);
1182
 
  return result;
1183
 
}