~canonical-dx-team/unity/unity.fix-ql-losing-focus

702.3.1 by Michael Terry
add modelines and fix up some inconsistent tabbings
1
// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
572.5.2 by Jay Taoko
* Adding license to files
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
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
20
#include "Nux/Nux.h"
21
#include "Nux/BaseWindow.h"
22
23
#include "BamfLauncherIcon.h"
24
#include "Launcher.h"
25
#include "PluginAdapter.h"
639.2.4 by Jason Smith
Implement pinning
26
#include "FavoriteStore.h"
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
27
821.5.1 by Didier Roche
hide the launcher after an action without triggering another action. (LP: #709178)
28
#include "ubus-server.h"
29
#include "UBusMessages.h"
30
785.2.1 by Didier Roche
make unity able to speak sane languages… like French (LP: #697166)
31
#include <glib/gi18n-lib.h>
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
32
#include <gio/gdesktopappinfo.h>
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
33
#include <libindicator/indicator-desktop-shortcuts.h>
621.2.4 by Jason Smith
ensure we minimize to the right place
34
#include <core/core.h>
35
#include <core/atoms.h>
36
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
37
struct _ShortcutData
38
{
39
  BamfLauncherIcon *self;
40
  IndicatorDesktopShortcuts *shortcuts;
41
  char *nick;
42
};
43
typedef struct _ShortcutData ShortcutData;
44
static void shortcut_data_destroy (ShortcutData *data)
45
{
46
  g_object_unref (data->shortcuts);
47
  g_free (data->nick);
48
  g_slice_free (ShortcutData, data);
49
}
50
51
static void shortcut_activated (DbusmenuMenuitem* _sender, guint timestamp, gpointer userdata)
52
{
53
  ShortcutData *data = (ShortcutData *)userdata;
54
  indicator_desktop_shortcuts_nick_exec (data->shortcuts, data->nick);
55
}
56
803.1.1 by Mirco Müller
modified:
57
void
851.1.3 by Didier Roche
don't mess with public virtual method
58
BamfLauncherIcon::ActivateLauncherIcon ()
803.1.1 by Mirco Müller
modified:
59
{
803.1.9 by Mirco Müller
Use better separation for methods Activate() and OnMouseClick()
60
  bool scaleWasActive = PluginAdapter::Default ()->IsScaleActive ();
61
62
  bool active, running;
63
  active = bamf_view_is_active (BAMF_VIEW (m_App));
64
  running = bamf_view_is_running (BAMF_VIEW (m_App));
65
66
  /* Behaviour:
67
   * Nothing running -> launch application
68
   * Running and active -> spread application
69
   * Spread is active and different icon pressed -> change spread
70
   * Spread is active -> Spread de-activated, and fall through
71
   */
72
73
  if (!running)
74
  {
75
    if (GetQuirk (QUIRK_STARTING))
76
      return;
77
    SetQuirk (QUIRK_STARTING, true);
851.1.3 by Didier Roche
don't mess with public virtual method
78
    OpenInstanceLauncherIcon ();
803.1.9 by Mirco Müller
Use better separation for methods Activate() and OnMouseClick()
79
    return;
80
  }
81
  else if (scaleWasActive)
82
  {
848.1.1 by Jason Smith
implement DND hover to trigger scale
83
    if (!Spread (0, false))
803.1.9 by Mirco Müller
Use better separation for methods Activate() and OnMouseClick()
84
    {
85
      PluginAdapter::Default ()->TerminateScale ();
86
      Focus ();
87
      _launcher->SetLastSpreadIcon (NULL);
88
    }
89
  }
90
  else if (!active)
91
  {
92
    Focus ();
93
  }
94
  else if (active && !scaleWasActive)
95
  {
848.1.1 by Jason Smith
implement DND hover to trigger scale
96
    Spread (0, false);
803.1.9 by Mirco Müller
Use better separation for methods Activate() and OnMouseClick()
97
  }
851.1.2 by Didier Roche
- space in keynav mode triggers a new instance (LP: #717213)
98
99
  ubus_server_send_message (ubus_server_get_default (), UBUS_LAUNCHER_ACTION_DONE, NULL);
803.1.1 by Mirco Müller
modified:
100
}
101
624.1.1 by Jason Smith
Implement trash can
102
BamfLauncherIcon::BamfLauncherIcon (Launcher* IconManager, BamfApplication *app, CompScreen *screen)
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
103
:   SimpleLauncherIcon(IconManager)
104
{
639.2.1 by Jason Smith
Start work on default quicklist work
105
  m_App = app;
106
  m_Screen = screen;
811.1.6 by Jason Smith
hook up libunity to launcher
107
  _remote_uri = 0;
848.1.1 by Jason Smith
implement DND hover to trigger scale
108
  _dnd_hover_timer = 0;
109
  _dnd_hovered = false;
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
110
  _menu_desktop_shortcuts = NULL;
639.2.1 by Jason Smith
Start work on default quicklist work
111
  char *icon_name = bamf_view_get_icon (BAMF_VIEW (m_App));
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
112
639.2.1 by Jason Smith
Start work on default quicklist work
113
  SetTooltipText (bamf_view_get_name (BAMF_VIEW (app)));
114
  SetIconName (icon_name);
726.3.8 by Jason Smith
Use C++ style scoping for enums rather than C style enums
115
  SetIconType (TYPE_APPLICATION);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
116
639.2.1 by Jason Smith
Start work on default quicklist work
117
  if (bamf_view_is_sticky (BAMF_VIEW (m_App)))
726.3.8 by Jason Smith
Use C++ style scoping for enums rather than C style enums
118
    SetQuirk (QUIRK_VISIBLE, true);
639.2.1 by Jason Smith
Start work on default quicklist work
119
  else
726.3.8 by Jason Smith
Use C++ style scoping for enums rather than C style enums
120
    SetQuirk (QUIRK_VISIBLE, bamf_view_user_visible (BAMF_VIEW (m_App)));
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
121
726.3.8 by Jason Smith
Use C++ style scoping for enums rather than C style enums
122
  SetQuirk (QUIRK_ACTIVE, bamf_view_is_active (BAMF_VIEW (m_App)));
123
  SetQuirk (QUIRK_RUNNING, bamf_view_is_running (BAMF_VIEW (m_App)));
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
124
639.2.1 by Jason Smith
Start work on default quicklist work
125
  g_free (icon_name);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
126
639.2.1 by Jason Smith
Start work on default quicklist work
127
  g_signal_connect (app, "child-removed", (GCallback) &BamfLauncherIcon::OnChildRemoved, this);
128
  g_signal_connect (app, "child-added", (GCallback) &BamfLauncherIcon::OnChildAdded, this);
129
  g_signal_connect (app, "urgent-changed", (GCallback) &BamfLauncherIcon::OnUrgentChanged, this);
130
  g_signal_connect (app, "running-changed", (GCallback) &BamfLauncherIcon::OnRunningChanged, this);
131
  g_signal_connect (app, "active-changed", (GCallback) &BamfLauncherIcon::OnActiveChanged, this);
132
  g_signal_connect (app, "user-visible-changed", (GCallback) &BamfLauncherIcon::OnUserVisibleChanged, this);
133
  g_signal_connect (app, "closed", (GCallback) &BamfLauncherIcon::OnClosed, this);
713.1.1 by Gord Allott
removes libindicator debug messages
134
639.2.1 by Jason Smith
Start work on default quicklist work
135
  g_object_ref (m_App);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
136
639.2.1 by Jason Smith
Start work on default quicklist work
137
  EnsureWindowState ();
138
  UpdateMenus ();
713.1.1 by Gord Allott
removes libindicator debug messages
139
711.1.1 by Jason Smith
Random autohide fixes
140
  PluginAdapter::Default ()->window_minimized.connect (sigc::mem_fun (this, &BamfLauncherIcon::OnWindowMinimized));
713.1.1 by Gord Allott
removes libindicator debug messages
141
711.1.3 by Jason Smith
implement progress bars
142
  /* hack */
811.1.7 by Jason Smith
a little tiny fix
143
  SetProgress (0.0f);
848.1.1 by Jason Smith
implement DND hover to trigger scale
144
  
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
145
}
146
147
BamfLauncherIcon::~BamfLauncherIcon()
148
{
639.2.4 by Jason Smith
Implement pinning
149
  g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnChildRemoved,       this);
150
  g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnChildAdded,         this);
151
  g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnUrgentChanged,      this);
152
  g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnRunningChanged,     this);
153
  g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnActiveChanged,      this);
154
  g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnUserVisibleChanged, this);
155
  g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnClosed,             this);
156
639.2.1 by Jason Smith
Start work on default quicklist work
157
  g_object_unref (m_App);
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
158
}
159
711.1.1 by Jason Smith
Random autohide fixes
160
void
729.5.3 by Sam Spilsbury
-> Added maximized window snapoff functionality
161
BamfLauncherIcon::OnWindowMinimized (guint32 xid)
711.1.1 by Jason Smith
Random autohide fixes
162
{
729.5.3 by Sam Spilsbury
-> Added maximized window snapoff functionality
163
  if (!OwnsWindow (xid))
711.1.1 by Jason Smith
Random autohide fixes
164
    return;
713.1.1 by Gord Allott
removes libindicator debug messages
165
711.1.1 by Jason Smith
Random autohide fixes
166
  Present (0.5f, 600);
726.3.8 by Jason Smith
Use C++ style scoping for enums rather than C style enums
167
  UpdateQuirkTimeDelayed (300, QUIRK_SHIMMER);
711.1.1 by Jason Smith
Random autohide fixes
168
}
169
713.1.1 by Gord Allott
removes libindicator debug messages
170
bool
679.5.10 by Jason Smith
save our re-ordering
171
BamfLauncherIcon::IsSticky ()
172
{
173
  return bamf_view_is_sticky (BAMF_VIEW (m_App));
174
}
175
713.1.1 by Gord Allott
removes libindicator debug messages
176
const char*
679.5.10 by Jason Smith
save our re-ordering
177
BamfLauncherIcon::DesktopFile ()
178
{
179
  return bamf_application_get_desktop_file (m_App);
180
}
181
655 by Jason Smith
Fix merge issues
182
void
183
BamfLauncherIcon::AddProperties (GVariantBuilder *builder)
184
{
185
  LauncherIcon::AddProperties (builder);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
186
655 by Jason Smith
Fix merge issues
187
  g_variant_builder_add (builder, "{sv}", "desktop-file", g_variant_new_string (bamf_application_get_desktop_file (m_App)));
713.1.1 by Gord Allott
removes libindicator debug messages
188
679.3.1 by Alex Launi
Add xids to list of BamfLauncherIcon introspection properties and fix a small leak
189
  GList *children, *l;
190
  BamfView *view;
713.1.1 by Gord Allott
removes libindicator debug messages
191
679.3.1 by Alex Launi
Add xids to list of BamfLauncherIcon introspection properties and fix a small leak
192
  children = bamf_view_get_children (BAMF_VIEW (m_App));
193
  GVariant* xids[(int) g_list_length (children)];
713.1.1 by Gord Allott
removes libindicator debug messages
194
679.3.1 by Alex Launi
Add xids to list of BamfLauncherIcon introspection properties and fix a small leak
195
  int i = 0;
196
  for (l = children; l; l = l->next)
197
  {
198
    view = (BamfView *) l->data;
713.1.1 by Gord Allott
removes libindicator debug messages
199
679.3.1 by Alex Launi
Add xids to list of BamfLauncherIcon introspection properties and fix a small leak
200
    if (BAMF_IS_WINDOW (view))
201
    {
202
      xids[i++] = g_variant_new_uint32 (bamf_window_get_xid (BAMF_WINDOW (view)));
702.1.1 by Jason Smith
implement DND animation
203
    }
679.3.1 by Alex Launi
Add xids to list of BamfLauncherIcon introspection properties and fix a small leak
204
  }
205
  g_list_free (children);
206
  g_variant_builder_add (builder, "{sv}", "xids", g_variant_new_array (G_VARIANT_TYPE_UINT32, xids, i));
655 by Jason Smith
Fix merge issues
207
}
208
625.1.1 by Jason Smith
Implement:
209
bool
711.1.1 by Jason Smith
Random autohide fixes
210
BamfLauncherIcon::OwnsWindow (Window w)
625.1.1 by Jason Smith
Implement:
211
{
212
  GList *children, *l;
213
  BamfView *view;
679.3.1 by Alex Launi
Add xids to list of BamfLauncherIcon introspection properties and fix a small leak
214
  bool owns = false;
625.1.1 by Jason Smith
Implement:
215
216
  children = bamf_view_get_children (BAMF_VIEW (m_App));
217
218
  for (l = children; l; l = l->next)
219
  {
220
    view = (BamfView *) l->data;
221
222
    if (BAMF_IS_WINDOW (view))
223
    {
224
      guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view));
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
225
625.1.1 by Jason Smith
Implement:
226
      if (xid == w)
690 by Alex Launi
Add xids to list of BamfLauncherIcon introspection properties and fix a small leak
227
      {
679.3.1 by Alex Launi
Add xids to list of BamfLauncherIcon introspection properties and fix a small leak
228
        owns = true;
679.5.10 by Jason Smith
save our re-ordering
229
        break;
690 by Alex Launi
Add xids to list of BamfLauncherIcon introspection properties and fix a small leak
230
      }
625.1.1 by Jason Smith
Implement:
231
    }
232
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
233
679.3.1 by Alex Launi
Add xids to list of BamfLauncherIcon introspection properties and fix a small leak
234
  g_list_free (children);
235
  return owns;
625.1.1 by Jason Smith
Implement:
236
}
237
831.3.1 by Jason Smith
implement drag to open
238
void 
239
BamfLauncherIcon::OpenInstanceWithUris (std::list<char *> uris)
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
240
{
241
  GDesktopAppInfo *appInfo;
653 by Jason Smith
Merge jason.fixes branch
242
  GError *error = NULL;
831.3.1 by Jason Smith
implement drag to open
243
  std::list<char *>::iterator it;
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
244
245
  appInfo = g_desktop_app_info_new_from_filename (bamf_application_get_desktop_file (BAMF_APPLICATION (m_App)));
831.3.1 by Jason Smith
implement drag to open
246
  
247
  if (g_app_info_supports_uris (G_APP_INFO (appInfo)))
248
  {
249
    GList *list = NULL;
250
    
251
    for (it = uris.begin (); it != uris.end (); it++)
252
      list = g_list_prepend (list, *it);
253
    
254
    g_app_info_launch_uris (G_APP_INFO (appInfo), list, NULL, &error);
255
    g_list_free (list);
256
  }
257
  else if (g_app_info_supports_files (G_APP_INFO (appInfo)))
258
  {
259
    GList *list = NULL, *l;
260
    for (it = uris.begin (); it != uris.end (); it++)
261
      list = g_list_prepend (list, g_filename_from_uri (*it, NULL, NULL));
262
    
263
    g_app_info_launch (G_APP_INFO (appInfo), list, NULL, &error);
264
    
265
    for (l = list; l; l = l->next)
266
      g_free (l->data);
267
    g_list_free (list);
268
  }
269
  else
270
  {
271
    g_app_info_launch (G_APP_INFO (appInfo), NULL, NULL, &error);
272
  }
273
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
274
  g_object_unref (appInfo);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
275
653 by Jason Smith
Merge jason.fixes branch
276
  if (error)
277
  {
278
    g_warning ("%s\n", error->message);
279
    g_error_free (error);
280
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
281
726.3.8 by Jason Smith
Use C++ style scoping for enums rather than C style enums
282
  UpdateQuirkTime (QUIRK_STARTING);
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
283
}
284
285
void
851.1.3 by Didier Roche
don't mess with public virtual method
286
BamfLauncherIcon::OpenInstanceLauncherIcon ()
831.3.1 by Jason Smith
implement drag to open
287
{
288
  std::list<char *> empty;
289
  OpenInstanceWithUris (empty);
851.1.2 by Didier Roche
- space in keynav mode triggers a new instance (LP: #717213)
290
  ubus_server_send_message (ubus_server_get_default (), UBUS_LAUNCHER_ACTION_DONE, NULL);
831.3.1 by Jason Smith
implement drag to open
291
}
292
293
void
663.1.6 by Jason Smith
dramatically improve window management
294
BamfLauncherIcon::Focus ()
295
{
296
  GList *children, *l;
297
  BamfView *view;
704 by Jason Smith
Ensure we give priority focusing to urgent windows
298
  bool any_urgent = false;
299
  bool any_on_current = false;
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
300
663.1.6 by Jason Smith
dramatically improve window management
301
  children = bamf_view_get_children (BAMF_VIEW (m_App));
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
302
663.1.6 by Jason Smith
dramatically improve window management
303
  CompWindowList windows;
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
304
663.1.6 by Jason Smith
dramatically improve window management
305
  /* get the list of windows */
306
  for (l = children; l; l = l->next)
307
  {
308
    view = (BamfView *) l->data;
309
310
    if (BAMF_IS_WINDOW (view))
311
    {
312
      guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view));
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
313
663.1.6 by Jason Smith
dramatically improve window management
314
      CompWindow *window = m_Screen->findWindow ((Window) xid);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
315
663.1.6 by Jason Smith
dramatically improve window management
316
      if (window)
704 by Jason Smith
Ensure we give priority focusing to urgent windows
317
      {
711.1.4 by Jason Smith
one more focus bug down
318
        if (bamf_view_is_urgent (view))
704 by Jason Smith
Ensure we give priority focusing to urgent windows
319
          any_urgent = true;
663.1.6 by Jason Smith
dramatically improve window management
320
        windows.push_back (window);
704 by Jason Smith
Ensure we give priority focusing to urgent windows
321
      }
663.1.6 by Jason Smith
dramatically improve window management
322
    }
323
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
324
704 by Jason Smith
Ensure we give priority focusing to urgent windows
325
  // not a good sign
663.1.6 by Jason Smith
dramatically improve window management
326
  if (windows.empty ())
704 by Jason Smith
Ensure we give priority focusing to urgent windows
327
  {
328
    g_list_free (children);
663.1.6 by Jason Smith
dramatically improve window management
329
    return;
704 by Jason Smith
Ensure we give priority focusing to urgent windows
330
  }
713.1.1 by Gord Allott
removes libindicator debug messages
331
663.1.6 by Jason Smith
dramatically improve window management
332
  /* sort the list */
333
  CompWindowList tmp;
334
  CompWindowList::iterator it;
335
  for (it = m_Screen->windows ().begin (); it != m_Screen->windows ().end (); it++)
336
  {
337
    if (std::find (windows.begin (), windows.end (), *it) != windows.end ())
338
      tmp.push_back (*it);
339
  }
340
  windows = tmp;
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
341
663.1.6 by Jason Smith
dramatically improve window management
342
  /* filter based on workspace */
343
  for (it = windows.begin (); it != windows.end (); it++)
344
  {
345
    if ((*it)->defaultViewport () == m_Screen->vp ())
346
    {
347
      any_on_current = true;
348
      break;
349
    }
350
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
351
704 by Jason Smith
Ensure we give priority focusing to urgent windows
352
  if (any_urgent)
353
  {
711.1.4 by Jason Smith
one more focus bug down
354
    // we cant use the compiz tracking since it is currently broken
355
    /*for (it = windows.begin (); it != windows.end (); it++)
704 by Jason Smith
Ensure we give priority focusing to urgent windows
356
    {
357
      if ((*it)->state () & CompWindowStateDemandsAttentionMask)
358
      {
359
        (*it)->activate ();
360
        break;
361
      }
711.1.4 by Jason Smith
one more focus bug down
362
    }*/
363
    for (l = children; l; l = l->next)
364
    {
365
      view = (BamfView *) l->data;
366
367
      if (BAMF_IS_WINDOW (view))
368
      {
369
        guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view));
370
371
        CompWindow *window = m_Screen->findWindow ((Window) xid);
372
373
        if (window && bamf_view_is_urgent (view))
374
        {
375
          window->activate ();
376
          break;
377
        }
378
      }
704 by Jason Smith
Ensure we give priority focusing to urgent windows
379
    }
380
  }
381
  else if (any_on_current)
663.1.6 by Jason Smith
dramatically improve window management
382
  {
383
    for (it = windows.begin (); it != windows.end (); it++)
384
    {
385
      if ((*it)->defaultViewport () == m_Screen->vp ())
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
386
      {
663.1.6 by Jason Smith
dramatically improve window management
387
        (*it)->activate ();
388
      }
389
    }
390
  }
391
  else
392
  {
393
    (*(windows.rbegin ()))->activate ();
394
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
395
663.1.6 by Jason Smith
dramatically improve window management
396
  g_list_free (children);
397
}
398
729.5.1 by Sam Spilsbury
Improve spread handling:
399
bool
848.1.1 by Jason Smith
implement DND hover to trigger scale
400
BamfLauncherIcon::Spread (int state, bool force)
663.1.6 by Jason Smith
dramatically improve window management
401
{
402
  BamfView *view;
403
  GList *children, *l;
404
  children = bamf_view_get_children (BAMF_VIEW (m_App));
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
405
663.1.6 by Jason Smith
dramatically improve window management
406
  std::list<Window> windowList;
407
  for (l = children; l; l = l->next)
408
  {
409
    view = (BamfView *) l->data;
410
411
    if (BAMF_IS_WINDOW (view))
412
    {
413
      guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view));
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
414
663.1.6 by Jason Smith
dramatically improve window management
415
      windowList.push_back ((Window) xid);
416
    }
417
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
418
848.1.1 by Jason Smith
implement DND hover to trigger scale
419
  if (windowList.size () > 1 || (windowList.size () > 0 && force))
663.1.6 by Jason Smith
dramatically improve window management
420
  {
421
    std::string *match = PluginAdapter::Default ()->MatchStringForXids (&windowList);
729.5.2 by Sam Spilsbury
Fix bugs in implementation, have some better logic too
422
    _launcher->SetLastSpreadIcon ((LauncherIcon *) this);
848.1.1 by Jason Smith
implement DND hover to trigger scale
423
    PluginAdapter::Default ()->InitiateScale (match, state);
663.1.6 by Jason Smith
dramatically improve window management
424
    delete match;
729.5.1 by Sam Spilsbury
Improve spread handling:
425
    g_list_free (children);
426
    return true;
663.1.6 by Jason Smith
dramatically improve window management
427
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
428
729.5.5 by Sam Spilsbury
Don't leak list
429
  g_list_free (children);
430
729.5.1 by Sam Spilsbury
Improve spread handling:
431
  return false;  
663.1.6 by Jason Smith
dramatically improve window management
432
}
433
434
void
572.1.51 by Jason Smith
restore click behavior
435
BamfLauncherIcon::OnMouseClick (int button)
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
436
{
821.4.1 by Didier Roche
Middle click to open a new instance (LP: #709707)
437
  if (button == 1)
851.1.3 by Didier Roche
don't mess with public virtual method
438
    ActivateLauncherIcon ();
821.4.1 by Didier Roche
Middle click to open a new instance (LP: #709707)
439
  else if (button == 2)
851.1.3 by Didier Roche
don't mess with public virtual method
440
    OpenInstanceLauncherIcon ();
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
441
}
442
443
void
444
BamfLauncherIcon::OnClosed (BamfView *view, gpointer data)
445
{
639.2.1 by Jason Smith
Start work on default quicklist work
446
  BamfLauncherIcon *self = (BamfLauncherIcon *) data;
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
447
639.2.1 by Jason Smith
Start work on default quicklist work
448
  if (!bamf_view_is_sticky (BAMF_VIEW (self->m_App)))
449
    self->Remove ();
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
450
}
451
452
void
453
BamfLauncherIcon::OnUserVisibleChanged (BamfView *view, gboolean visible, gpointer data)
454
{
639.2.1 by Jason Smith
Start work on default quicklist work
455
  BamfLauncherIcon *self = (BamfLauncherIcon *) data;
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
456
639.2.1 by Jason Smith
Start work on default quicklist work
457
  if (!bamf_view_is_sticky (BAMF_VIEW (self->m_App)))
726.3.8 by Jason Smith
Use C++ style scoping for enums rather than C style enums
458
    self->SetQuirk (QUIRK_VISIBLE, visible);
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
459
}
460
461
void
462
BamfLauncherIcon::OnRunningChanged (BamfView *view, gboolean running, gpointer data)
463
{
639.2.1 by Jason Smith
Start work on default quicklist work
464
  BamfLauncherIcon *self = (BamfLauncherIcon *) data;
726.3.8 by Jason Smith
Use C++ style scoping for enums rather than C style enums
465
  self->SetQuirk (QUIRK_RUNNING, running);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
466
639.2.1 by Jason Smith
Start work on default quicklist work
467
  if (running)
468
  {
469
    self->EnsureWindowState ();
470
    self->UpdateIconGeometries (self->GetCenter ());
471
  }
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
472
}
473
474
void
475
BamfLauncherIcon::OnActiveChanged (BamfView *view, gboolean active, gpointer data)
476
{
639.2.1 by Jason Smith
Start work on default quicklist work
477
  BamfLauncherIcon *self = (BamfLauncherIcon *) data;
726.3.8 by Jason Smith
Use C++ style scoping for enums rather than C style enums
478
  self->SetQuirk (QUIRK_ACTIVE, active);
572.1.11 by Neil Jagdish Patel
Import the work done so far with Compiz
479
}
572.1.33 by jassmith at gmail
Initial introduction of urgent animation
480
481
void
482
BamfLauncherIcon::OnUrgentChanged (BamfView *view, gboolean urgent, gpointer data)
483
{
639.2.1 by Jason Smith
Start work on default quicklist work
484
  BamfLauncherIcon *self = (BamfLauncherIcon *) data;
726.3.8 by Jason Smith
Use C++ style scoping for enums rather than C style enums
485
  self->SetQuirk (QUIRK_URGENT, urgent);
572.1.33 by jassmith at gmail
Initial introduction of urgent animation
486
}
572.1.38 by jassmith at gmail
indicate number of running windows
487
488
void
489
BamfLauncherIcon::EnsureWindowState ()
490
{
639.2.1 by Jason Smith
Start work on default quicklist work
491
  GList *children, *l;
492
  int count = 0;
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
493
756.1.1 by Jason Smith
More work on launcher design conformance
494
  bool has_visible = false;
495
  
639.2.1 by Jason Smith
Start work on default quicklist work
496
  children = bamf_view_get_children (BAMF_VIEW (m_App));
497
  for (l = children; l; l = l->next)
498
  {
756.1.1 by Jason Smith
More work on launcher design conformance
499
    if (!BAMF_IS_WINDOW (l->data))
500
      continue;
501
      
502
    count++;
503
    
504
    guint32 xid = bamf_window_get_xid (BAMF_WINDOW (l->data));
505
    CompWindow *window = m_Screen->findWindow ((Window) xid);
506
    
507
    if (window && window->defaultViewport () == m_Screen->vp ())
508
      has_visible = true;
639.2.1 by Jason Smith
Start work on default quicklist work
509
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
510
639.2.1 by Jason Smith
Start work on default quicklist work
511
  SetRelatedWindows (count);
756.1.1 by Jason Smith
More work on launcher design conformance
512
  SetHasVisibleWindow (has_visible);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
513
663.1.7 by Jason Smith
fix memory leak
514
  g_list_free (children);
572.1.38 by jassmith at gmail
indicate number of running windows
515
}
516
517
void
518
BamfLauncherIcon::OnChildAdded (BamfView *view, BamfView *child, gpointer data)
519
{
639.2.1 by Jason Smith
Start work on default quicklist work
520
  BamfLauncherIcon *self = (BamfLauncherIcon*) data;
521
  self->EnsureWindowState ();
522
  self->UpdateMenus ();
523
  self->UpdateIconGeometries (self->GetCenter ());
572.1.38 by jassmith at gmail
indicate number of running windows
524
}
525
526
void
527
BamfLauncherIcon::OnChildRemoved (BamfView *view, BamfView *child, gpointer data)
528
{
639.2.1 by Jason Smith
Start work on default quicklist work
529
  BamfLauncherIcon *self = (BamfLauncherIcon*) data;
530
  self->EnsureWindowState ();
531
}
532
533
void
534
BamfLauncherIcon::UpdateMenus ()
535
{
536
  GList *children, *l;
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
537
  IndicatorDesktopShortcuts *desktop_shortcuts;
538
639.2.1 by Jason Smith
Start work on default quicklist work
539
  children = bamf_view_get_children (BAMF_VIEW (m_App));
540
  for (l = children; l; l = l->next)
541
  {
542
    if (!BAMF_IS_INDICATOR (l->data))
543
      continue;
544
545
    BamfIndicator *indicator = BAMF_INDICATOR (l->data);
546
    std::string path = bamf_indicator_get_dbus_menu_path (indicator);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
547
639.2.1 by Jason Smith
Start work on default quicklist work
548
    // we already have this
549
    if (_menu_clients.find (path) != _menu_clients.end ())
550
      continue;
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
551
639.2.1 by Jason Smith
Start work on default quicklist work
552
    DbusmenuClient *client = dbusmenu_client_new (bamf_indicator_get_remote_address (indicator), path.c_str ());
553
    _menu_clients[path] = client;
554
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
555
663.1.7 by Jason Smith
fix memory leak
556
  g_list_free (children);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
557
558
  // make a client for desktop file actions
559
  if (!DBUSMENU_IS_MENUITEM (_menu_desktop_shortcuts) &&
713.1.1 by Gord Allott
removes libindicator debug messages
560
      g_strcmp0 (DesktopFile (), """"))
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
561
  {
713.1.1 by Gord Allott
removes libindicator debug messages
562
    GKeyFile *keyfile;
563
    GError *error = NULL;
564
565
    // check that we have the X-Ayatana-Desktop-Shortcuts flag
566
    // not sure if we should do this or if libindicator should shut up
567
    // and not report errors when it can't find the key.
568
    // so FIXME when ted is around
569
    keyfile = g_key_file_new ();
570
    g_key_file_load_from_file (keyfile, DesktopFile (), G_KEY_FILE_NONE, &error);
571
572
    if (error != NULL)
573
    {
574
      g_warning ("Could not load desktop file for: %s" , DesktopFile ());
575
      g_error_free (error);
576
      return;
577
    }
578
579
    if (g_key_file_has_key (keyfile, G_KEY_FILE_DESKTOP_GROUP,
580
                            "X-Ayatana-Desktop-Shortcuts", NULL))
581
    {
582
      DbusmenuMenuitem *root = dbusmenu_menuitem_new ();
583
      dbusmenu_menuitem_set_root (root, TRUE);
584
      desktop_shortcuts = indicator_desktop_shortcuts_new (bamf_application_get_desktop_file (m_App),
585
                                                           "Unity");
586
      const gchar **nicks = indicator_desktop_shortcuts_get_nicks (desktop_shortcuts);
587
588
      int index = 0;
589
      if (nicks)
590
      {
591
        while (((gpointer*) nicks)[index])
592
        {
593
          const char* name;
594
          DbusmenuMenuitem *item;
595
          name = g_strdup (indicator_desktop_shortcuts_nick_get_name (desktop_shortcuts,
596
                                                                      nicks[index]));
597
          ShortcutData *data = g_slice_new0 (ShortcutData);
598
          data->self = this;
599
          data->shortcuts = INDICATOR_DESKTOP_SHORTCUTS (g_object_ref (desktop_shortcuts));
600
          data->nick = g_strdup (nicks[index]);
601
602
          item = dbusmenu_menuitem_new ();
603
          dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_LABEL, name);
604
          dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
605
          dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
606
          g_signal_connect_data (item, "item-activated",
607
                                (GCallback) shortcut_activated, (gpointer) data,
608
                                (GClosureNotify) shortcut_data_destroy, (GConnectFlags)0);
609
610
          dbusmenu_menuitem_child_append (root, item);
611
612
          index++;
613
614
          g_free ((void *)name);
615
        }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
616
      }
713.1.1 by Gord Allott
removes libindicator debug messages
617
618
      _menu_desktop_shortcuts = root;
713.1.2 by Gord Allott
free the keyfile
619
      g_key_file_free (keyfile);
713.1.1 by Gord Allott
removes libindicator debug messages
620
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
621
    }
622
  }
623
639.2.1 by Jason Smith
Start work on default quicklist work
624
}
625
639.2.3 by Jason Smith
make quit button work
626
void
627
BamfLauncherIcon::OnQuit (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self)
628
{
629
  GList *children, *l;
630
  BamfView *view;
631
632
  children = bamf_view_get_children (BAMF_VIEW (self->m_App));
633
634
  for (l = children; l; l = l->next)
635
  {
636
    view = (BamfView *) l->data;
637
638
    if (BAMF_IS_WINDOW (view))
639
    {
640
      guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view));
641
      CompWindow *window = self->m_Screen->findWindow ((Window) xid);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
642
659 by Jason Smith
minor crash fix
643
      if (window)
644
        window->close (self->m_Screen->getCurrentTime ());
639.2.3 by Jason Smith
make quit button work
645
    }
646
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
647
663.1.7 by Jason Smith
fix memory leak
648
  g_list_free (children);
639.2.3 by Jason Smith
make quit button work
649
}
650
651
void
652
BamfLauncherIcon::OnTogglePin (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self)
653
{
639.2.4 by Jason Smith
Implement pinning
654
  BamfView *view = BAMF_VIEW (self->m_App);
655
  bool sticky = bamf_view_is_sticky (view);
656
  const gchar *desktop_file = bamf_application_get_desktop_file (self->m_App);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
657
639.2.4 by Jason Smith
Implement pinning
658
  if (sticky)
659
  {
660
    bamf_view_set_sticky (view, false);
661
    if (bamf_view_is_closed (view))
662
      self->Remove ();
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
663
639.2.4 by Jason Smith
Implement pinning
664
    if (desktop_file && strlen (desktop_file) > 0)
665
      FavoriteStore::GetDefault ()->RemoveFavorite (desktop_file);
666
  }
667
  else
668
  {
669
    bamf_view_set_sticky (view, true);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
670
639.2.4 by Jason Smith
Implement pinning
671
    if (desktop_file && strlen (desktop_file) > 0)
639.2.5 by Jason Smith
almost finish implementation. Fixes in favorites store required.
672
      FavoriteStore::GetDefault ()->AddFavorite (desktop_file, -1); //self->SortPriority ());
639.2.4 by Jason Smith
Implement pinning
673
  }
639.2.3 by Jason Smith
make quit button work
674
}
675
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
676
void
677
BamfLauncherIcon::EnsureMenuItemsReady ()
678
{
679
  DbusmenuMenuitem *menu_item;
680
681
  /* Pin */
682
  if (_menu_items.find ("Pin") == _menu_items.end ())
683
  {
684
    menu_item = dbusmenu_menuitem_new ();
685
    g_object_ref (menu_item);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
686
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
687
    dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_CHECK);
785.2.1 by Didier Roche
make unity able to speak sane languages… like French (LP: #697166)
688
    dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Keep In Launcher"));
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
689
    dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
690
    dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
691
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
692
    g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnTogglePin, this);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
693
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
694
    _menu_items["Pin"] = menu_item;
695
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
696
  int checked = !bamf_view_is_sticky (BAMF_VIEW (m_App)) ?
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
697
                 DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED : DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED;
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
698
699
  dbusmenu_menuitem_property_set_int (_menu_items["Pin"],
700
                                      DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
701
                                      checked);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
702
703
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
704
  /* Quit */
705
  if (_menu_items.find ("Quit") == _menu_items.end ())
706
  {
707
    menu_item = dbusmenu_menuitem_new ();
708
    g_object_ref (menu_item);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
709
785.2.1 by Didier Roche
make unity able to speak sane languages… like French (LP: #697166)
710
    dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Quit"));
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
711
    dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
712
    dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
713
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
714
    g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnQuit, this);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
715
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
716
    _menu_items["Quit"] = menu_item;
717
  }
718
}
719
639.2.1 by Jason Smith
Start work on default quicklist work
720
std::list<DbusmenuMenuitem *>
572.1.52 by Jason Smith
enable dbus menu work
721
BamfLauncherIcon::GetMenus ()
722
{
639.2.1 by Jason Smith
Start work on default quicklist work
723
  std::map<std::string, DbusmenuClient *>::iterator it;
724
  std::list<DbusmenuMenuitem *> result;
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
725
639.2.1 by Jason Smith
Start work on default quicklist work
726
  for (it = _menu_clients.begin (); it != _menu_clients.end (); it++)
727
  {
728
    GList * child = NULL;
729
    DbusmenuClient *client = (*it).second;
730
    DbusmenuMenuitem *root = dbusmenu_client_get_root (client);
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
731
732
    for (child = dbusmenu_menuitem_get_children(root); child != NULL; child = g_list_next(child))
733
    {
734
      DbusmenuMenuitem *item = (DbusmenuMenuitem *) child->data;
735
736
      if (!item)
737
        continue;
738
739
      result.push_back (item);
740
    }
741
  }
742
743
  if (DBUSMENU_IS_MENUITEM (_menu_desktop_shortcuts))
744
  {
745
    GList * child = NULL;
746
    DbusmenuMenuitem *root = _menu_desktop_shortcuts;
747
748
    for (child = dbusmenu_menuitem_get_children(root); child != NULL; child = g_list_next(child))
749
    {
750
      DbusmenuMenuitem *item = (DbusmenuMenuitem *) child->data;
751
752
      if (!item)
753
        continue;
754
755
      result.push_back (item);
756
    }
757
758
  }
759
648.2.1 by Jason Smith
Some more menu work and a minor crash fix
760
  EnsureMenuItemsReady ();
761
709.1.1 by Stefano Candori
Fixed #683466
762
  std::map<std::string, DbusmenuMenuitem *>::iterator it_m;
763
  std::list<DbusmenuMenuitem *>::iterator it_l;
764
  bool exists;
765
  for (it_m = _menu_items.begin (); it_m != _menu_items.end (); it_m++)
766
  {
711 by Jason Smith
Merge work from Stefano Candori to fix duplicate quit items from quicklists
767
    const char* key = ((*it_m).first).c_str();
768
    if (g_strcmp0 (key , "Quit") == 0 && !bamf_view_is_running (BAMF_VIEW (m_App)))
769
      continue;
770
709.1.1 by Stefano Candori
Fixed #683466
771
    exists = false;
772
    std::string label_default = dbusmenu_menuitem_property_get ((*it_m).second, DBUSMENU_MENUITEM_PROP_LABEL);
773
    for(it_l = result.begin(); it_l != result.end(); it_l++)
774
    {
775
      const gchar* type = dbusmenu_menuitem_property_get (*it_l, DBUSMENU_MENUITEM_PROP_TYPE);
776
      if (type == NULL)//(g_strcmp0 (type, DBUSMENU_MENUITEM_PROP_LABEL) == 0)
777
      {
778
        std::string label_menu = dbusmenu_menuitem_property_get (*it_l, DBUSMENU_MENUITEM_PROP_LABEL);
711 by Jason Smith
Merge work from Stefano Candori to fix duplicate quit items from quicklists
779
        if (label_menu.compare(label_default) == 0)
713.1.1 by Gord Allott
removes libindicator debug messages
780
        {
781
          exists = true;
711 by Jason Smith
Merge work from Stefano Candori to fix duplicate quit items from quicklists
782
          break;
783
        }
709.1.1 by Stefano Candori
Fixed #683466
784
      }
785
    }
713.1.1 by Gord Allott
removes libindicator debug messages
786
709.1.1 by Stefano Candori
Fixed #683466
787
    if (!exists)
788
      result.push_back((*it_m).second);
789
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
790
639.2.1 by Jason Smith
Start work on default quicklist work
791
  return result;
572.1.52 by Jason Smith
enable dbus menu work
792
}
621.2.4 by Jason Smith
ensure we minimize to the right place
793
625.1.4 by Jason Smith
ensure we minimize to the icon
794
795
void
796
BamfLauncherIcon::UpdateIconGeometries (nux::Point3 center)
621.2.4 by Jason Smith
ensure we minimize to the right place
797
{
639.2.1 by Jason Smith
Start work on default quicklist work
798
  GList *children, *l;
799
  BamfView *view;
800
  long data[4];
801
802
  data[0] = center.x - 24;
803
  data[1] = center.y - 24;
804
  data[2] = 48;
805
  data[3] = 48;
806
807
  children = bamf_view_get_children (BAMF_VIEW (m_App));
808
809
  for (l = children; l; l = l->next)
810
  {
811
    view = (BamfView *) l->data;
812
813
    if (BAMF_IS_WINDOW (view))
621.2.4 by Jason Smith
ensure we minimize to the right place
814
    {
639.2.1 by Jason Smith
Start work on default quicklist work
815
      guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view));
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
816
639.2.1 by Jason Smith
Start work on default quicklist work
817
      XChangeProperty (m_Screen->dpy (), xid, Atoms::wmIconGeometry,
818
                       XA_CARDINAL, 32, PropModeReplace,
819
                       (unsigned char *) data, 4);
621.2.4 by Jason Smith
ensure we minimize to the right place
820
    }
639.2.1 by Jason Smith
Start work on default quicklist work
821
  }
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
822
663.1.7 by Jason Smith
fix memory leak
823
  g_list_free (children);
621.2.4 by Jason Smith
ensure we minimize to the right place
824
}
625.1.4 by Jason Smith
ensure we minimize to the icon
825
679.1.1 by Gord Allott
adds Indicator Desktop Shortcut support to quicklists
826
void
625.1.4 by Jason Smith
ensure we minimize to the icon
827
BamfLauncherIcon::OnCenterStabilized (nux::Point3 center)
828
{
829
  UpdateIconGeometries (center);
830
}
811.1.6 by Jason Smith
hook up libunity to launcher
831
832
const gchar *
833
BamfLauncherIcon::GetRemoteUri ()
834
{
835
  if (!_remote_uri)
836
  {
837
    const gchar * desktop_file = bamf_application_get_desktop_file (BAMF_APPLICATION (m_App));
838
    _remote_uri = g_strdup_printf ("application://%s", g_path_get_basename (desktop_file));
839
  }
840
  
841
  return _remote_uri;
842
}
831.3.1 by Jason Smith
implement drag to open
843
844
std::list<char *>
845
BamfLauncherIcon::ValidateUrisForLaunch (std::list<char *> uris)
846
{
847
  GKeyFile *key_file;
848
  const char *desktop_file;
849
  GError *error = NULL;
850
  std::list<char *> results;
851
  
852
  desktop_file = DesktopFile ();
853
  
854
  if (!desktop_file || strlen (desktop_file) <= 1)
855
    return results;
856
  
857
  key_file = g_key_file_new ();
858
  g_key_file_load_from_file (key_file, desktop_file, (GKeyFileFlags) 0, &error);
859
  
860
  if (error)
861
  {
862
    g_error_free (error);
863
    g_key_file_free (key_file);
864
    return results;
865
  }
866
867
  char **mimes = g_key_file_get_string_list (key_file, "Desktop Entry", "MimeType", NULL, NULL);
868
  if (!mimes)
869
  {
870
    g_key_file_free (key_file);
871
    return results;
872
  }
873
  
874
  std::list<char *>::iterator it;
875
  for (it = uris.begin (); it != uris.end (); it++)
876
  {
877
    GFile *file = g_file_new_for_uri (*it);
878
    GFileInfo *info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL);
879
    const char *content_type = g_file_info_get_content_type (info);
880
881
    int i = 0;
882
    for (; mimes[i]; i++)
883
    {
884
      char *super_type = g_content_type_from_mime_type (mimes[i]);
885
      if (g_content_type_is_a (content_type, super_type))
886
      {
887
        results.push_back (*it);
888
        break;
889
      }
890
      g_free (super_type);
891
    }
892
    
893
    
894
    g_object_unref (file);
895
    g_object_unref (info);
896
  }
897
  
898
  g_strfreev (mimes);
899
  g_key_file_free (key_file);
900
  return results;
901
}
902
848.1.1 by Jason Smith
implement DND hover to trigger scale
903
gboolean
904
BamfLauncherIcon::OnDndHoveredTimeout (gpointer data)
905
{
906
  BamfLauncherIcon *self = (BamfLauncherIcon*) data;
907
  if (self->_dnd_hovered && bamf_view_is_running (BAMF_VIEW (self->m_App)))
908
    self->Spread (CompAction::StateInitEdgeDnd, true);
909
  
910
  return false;
911
}
912
913
void
914
BamfLauncherIcon::OnDndEnter ()
915
{
916
  _dnd_hovered = true;
917
  _dnd_hover_timer = g_timeout_add (1000, &BamfLauncherIcon::OnDndHoveredTimeout, this);
918
}
919
920
void
921
BamfLauncherIcon::OnDndLeave ()
922
{
923
  _dnd_hovered = false;
924
  
925
  if (_dnd_hover_timer)
926
    g_source_remove (_dnd_hover_timer);
927
  _dnd_hover_timer = 0;
928
}
929
831.3.4 by Jason Smith
allow icons to specify the action they wish to perform
930
nux::DndAction 
831.3.6 by Jason Smith
implement hinting of drop targets
931
BamfLauncherIcon::OnQueryAcceptDrop (std::list<char *> uris)
831.3.1 by Jason Smith
implement drag to open
932
{
831.3.4 by Jason Smith
allow icons to specify the action they wish to perform
933
  return ValidateUrisForLaunch (uris).empty () ? nux::DNDACTION_NONE : nux::DNDACTION_COPY;
831.3.1 by Jason Smith
implement drag to open
934
}
935
936
void 
937
BamfLauncherIcon::OnAcceptDrop (std::list<char *> uris)
938
{
939
  OpenInstanceWithUris (ValidateUrisForLaunch (uris));
940
}