~ubuntu-branches/debian/sid/avant-window-navigator/sid

« back to all changes in this revision

Viewing changes to src/awn-task.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien Lavergne
  • Date: 2010-06-07 22:49:37 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20100607224937-3xojks0yo8r6xmkh
Tags: 0.4.0-1
* New upstream release.
 - Fix icons placed outside the panel. Closes: #471661
 - Add an option to go under the panel. Closes: #474228
 - Fix autohide behavior. LP: #130235
 - Allow only 1 instance of Awn. LP: #258675
 - Ensure the autostart exist before trying to delete it. LP: #334454
 - Fix position with multiple screen. LP: #248769
 - Fix crash when event is NULL. LP: #550541
 - Fix crash in awn-setting when adding applet. LP: #557778
* debian/patches:
 - 10_correct_exception.patch: Dropped, problem fixed in the new version.
 - 00-wm-behavior.patch and 01-tasks-have-arrow.patch: Merged upstream.
 - 02-ftbfs-python-2.6.patch: Refresh.
 - 03-python-import.patch: Refresh.
 - 01-bad-pointer-init.patch: From upstream, bad unitialized pointer.
* Bump libawn SONAME
* debian/control:
 - Add minimum requirement for libwnck-dev libgtk2.0-dev libglib2.0-dev and
   valac.
 - Drop build-depends on libgnome2-dev, libgnome-desktop-dev, libglade2-dev.
 - Bump build-depends for debhelper to (>= 7.0.50~) for overrides.
 - Build-depends on libgtop2-dev.
 - Replace build-depends on python-gnome2-dev by python-gtk2-dev (>= 2.12).
 - Build-depends on gconf2, libdesktop-agnostic-dev, libdesktop-agnostic-bin,
   python-desktop-agnostic, vala-desktop-agnostic for desktop-agnostic
   support.
 - Demote the composite manager to Recommends, Awn works without it.
 - Depends on libdesktop-agnostic-* and dbus.
 - Bump libawn SONAME.
 - Rename awn-manager to awn-settings.
 - libawn-dev : drop libgnome*-dev and add libdesktop-agnostic-dev depends.
 - Demote depends on awn-manager by a recommends on awn-settings for
   avant-window-navigator.
 - Add depends on avant-window-navigator, python-desktop-agnostic, bzr and
   python-dbus for awn-settings.
 - Remove depends on python-galde2 for awn-settings.
 - Replace vala depends by vala-desktop-agnostic for vala-awn.
 - Add Conflicts/Replaces to replace separator applets which is in core now.
 - Add mutter as another composite manager.
 - Use space instead of tabulation.
 - Add Conflicts/Replaces on awn-manager for awn-settings.
   (LP: #507822, #512411)
 - Add depends on python-desktop-agnostic for python-awn.
 - Add mention of Awn in the description.
* debian/rules:
 - Rewrite with overrides.
 - Remove awn.wrapper.
 - Bump libawn SONAME.
 - Use dh_install --fail-missing.
 - Remove .la, .a, .pyo and pyc before installing.
* debian/avant-window-navigator{,-data}.install:
 - Update installed files in core.
 - Install core applets
* debian/awn.wrapper & debian/avant-window-navigator.links:
 - Dropped, previous configuration is incompatible.
* debian/awn-manager.install
 - Rename to awn-settings.install.
 - Update installed files.
* debian/awn-applet*.1 && debian/avant-window-navigator.manpages
 - Update manpages.
* debian/awn-manager.*
 - Rename awn-manager to awn-settings and update the content.
 - Remove unused manpages.
* debian/python-awn:
 - Update to the new location.
* debian/README.Debian:
 - Mention that real transparency is not needed.
 - Add mutter in the list of composite managers.
* debian/copyright:
 - Update copyright and licenses.
* debian/libawn1.symbols: 
 - Add missing symbol.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  Copyright (C) 2007 Neil Jagdish Patel <njpatel@gmail.com>
3
 
 *
4
 
 *  This program is free software; you can redistribute it and/or modify
5
 
 *  it under the terms of the GNU General Public License as published by
6
 
 *  the Free Software Foundation; either version 2 of the License, or
7
 
 *  (at your option) any later version.
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, write to the Free Software
16
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
17
 
 *
18
 
 *  Author : Neil Jagdish Patel <njpatel@gmail.com>
19
 
*/
20
 
 
21
 
#ifdef HAVE_CONFIG_H
22
 
#include "config.h"
23
 
#endif
24
 
 
25
 
#include <gtk/gtk.h>
26
 
#include <string.h>
27
 
#include <math.h>
28
 
#ifdef LIBAWN_USE_GNOME
29
 
#include <libgnome/libgnome.h>
30
 
#else
31
 
#include <glib/gi18n.h>
32
 
#endif
33
 
 
34
 
#if !GTK_CHECK_VERSION(2,14,0)
35
 
#define g_timeout_add_seconds(seconds, callback, user_data) g_timeout_add(seconds * 1000, callback, user_data)
36
 
#endif
37
 
 
38
 
#include <libawn/awn-config-client.h>
39
 
#include <libawn/awn-effects.h>
40
 
#include <libawn/awn-vfs.h>
41
 
 
42
 
#include "awn-task.h"
43
 
#include "awn-x.h"
44
 
 
45
 
#include "awn-utils.h"
46
 
#include "awn-marshallers.h"
47
 
 
48
 
#define AWN_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), AWN_TYPE_TASK, AwnTaskPrivate))
49
 
 
50
 
G_DEFINE_TYPE(AwnTask, awn_task, GTK_TYPE_DRAWING_AREA);
51
 
 
52
 
#define  M_PI      3.14159265358979323846
53
 
#define  AWN_CLICK_IDLE_TIME   450
54
 
#define PIXBUF_SAVE_PATH ".config/awn/custom-icons"
55
 
 
56
 
/* FORWARD DECLERATIONS */
57
 
 
58
 
static gboolean awn_task_expose(GtkWidget *task, GdkEventExpose *event);
59
 
static gboolean awn_task_button_press(GtkWidget *task, GdkEventButton *event);
60
 
static gboolean awn_task_scroll_event(GtkWidget *task, GdkEventScroll *event);  //Ceceppa
61
 
static gboolean awn_task_drag_motion(GtkWidget *task,
62
 
                                     GdkDragContext *context, gint x, gint y, guint t);
63
 
static void
64
 
awn_task_drag_leave(GtkWidget *widget, GdkDragContext *drag_context,
65
 
                    guint time);
66
 
static void awn_task_create_menu(AwnTask *task, GtkMenu *menu);
67
 
 
68
 
static const gchar* awn_task_get_title(GtkWidget *);
69
 
static void _task_refresh(GtkWidget *obj);
70
 
 
71
 
 
72
 
/* STRUCTS & ENUMS */
73
 
 
74
 
typedef enum
75
 
{
76
 
  AWN_TASK_MENU_TYPE_NORMAL,
77
 
  AWN_TASK_MENU_TYPE_CHECK
78
 
} AwnTaskMenuType;
79
 
 
80
 
typedef struct
81
 
{
82
 
  AwnTaskMenuType  type;
83
 
  GtkWidget  *item;
84
 
  gint    id;
85
 
  gboolean  active;
86
 
 
87
 
 
88
 
} AwnTaskMenuItem;
89
 
 
90
 
typedef struct _AwnTaskPrivate AwnTaskPrivate;
91
 
 
92
 
struct _AwnTaskPrivate
93
 
{
94
 
  AwnTaskManager   *task_manager;
95
 
  AwnSettings   *settings;
96
 
 
97
 
  AwnDesktopItem *item;
98
 
  gint pid;
99
 
 
100
 
  gchar *application;
101
 
 
102
 
  gboolean is_launcher;
103
 
  AwnSmartLauncher launcher;
104
 
  gboolean is_starter;
105
 
 
106
 
  WnckWindow *window;
107
 
  AwnTitle *title;
108
 
 
109
 
  gboolean is_active;
110
 
  gboolean drag_hover;
111
 
 
112
 
  GdkPixbuf *icon;
113
 
  GdkPixbuf *reflect;
114
 
 
115
 
  gint progress;
116
 
 
117
 
  gboolean info;
118
 
  gchar *info_text;
119
 
 
120
 
  /* EFFECT VARIABLE */
121
 
  AwnEffects * effects;
122
 
 
123
 
  /* MenuItems */
124
 
  AwnTaskMenuItem *menu_items[5];
125
 
 
126
 
  /* random */
127
 
  guint timestamp;
128
 
  /* signal handler ID's, for clean close */
129
 
  gulong icon_changed;
130
 
  gulong state_changed;
131
 
  gulong name_changed;
132
 
  gulong geometry_changed;
133
 
 
134
 
  /* Ceceppa: old window position */
135
 
  gint old_x;
136
 
  gint old_y;
137
 
  int timer_count;
138
 
 
139
 
  gboolean dispose_has_run;
140
 
};
141
 
 
142
 
enum
143
 
{
144
 
  MENU_ITEM_CLICKED,
145
 
  CHECK_ITEM_CLICKED,
146
 
  LAST_SIGNAL
147
 
};
148
 
 
149
 
static guint awn_task_signals[LAST_SIGNAL] = { 0 };
150
 
 
151
 
/* GLOBALS */
152
 
 
153
 
static gpointer global_awn_task_parent_class = NULL;
154
 
static gint menu_item_id = 100;
155
 
static WnckWindow *last_active_window = NULL;       //Ceceppa
156
 
 
157
 
static const GtkTargetEntry drop_types[] =
158
 
{
159
 
  { "STRING", 0, 0 },
160
 
  { "text/plain", 0, 0},
161
 
  { "text/uri-list", 0, 0}
162
 
};
163
 
static const gint n_drop_types = G_N_ELEMENTS(drop_types);
164
 
 
165
 
static void
166
 
awn_task_dispose(GObject *obj)
167
 
{
168
 
  AwnTaskPrivate *priv = AWN_TASK_GET_PRIVATE(AWN_TASK(obj));
169
 
 
170
 
  if (priv->dispose_has_run) return;
171
 
 
172
 
  priv->dispose_has_run = TRUE;
173
 
 
174
 
  awn_effects_finalize(priv->effects);
175
 
 
176
 
  if (priv->window) {
177
 
    if (priv->icon_changed) {
178
 
      g_signal_handler_disconnect((gpointer)priv->window,
179
 
                                  priv->icon_changed);
180
 
      priv->icon_changed = 0;
181
 
    }
182
 
    if (priv->state_changed) {
183
 
      g_signal_handler_disconnect((gpointer)priv->window,
184
 
                                  priv->state_changed);
185
 
      priv->state_changed = 0;
186
 
    }
187
 
    if (priv->name_changed) {
188
 
      g_signal_handler_disconnect((gpointer)priv->window,
189
 
                                  priv->name_changed);
190
 
      priv->name_changed = 0;
191
 
    }
192
 
    if (priv->geometry_changed) {
193
 
      g_signal_handler_disconnect((gpointer)priv->window,
194
 
                                  priv->geometry_changed);
195
 
      priv->geometry_changed = 0;
196
 
    }
197
 
  }
198
 
 
199
 
  G_OBJECT_CLASS(global_awn_task_parent_class)->dispose(obj);
200
 
}
201
 
 
202
 
static void
203
 
awn_task_finalize(GObject *obj)
204
 
{
205
 
  AwnTaskPrivate *priv = AWN_TASK_GET_PRIVATE(AWN_TASK(obj));
206
 
 
207
 
  awn_effects_free(priv->effects);
208
 
 
209
 
  G_OBJECT_CLASS(global_awn_task_parent_class)->finalize(obj);
210
 
}
211
 
 
212
 
static void
213
 
awn_task_class_init(AwnTaskClass *class)
214
 
{
215
 
  GObjectClass *obj_class;
216
 
  GtkWidgetClass *widget_class;
217
 
 
218
 
  obj_class = G_OBJECT_CLASS(class);
219
 
  widget_class = GTK_WIDGET_CLASS(class);
220
 
 
221
 
  obj_class->dispose = awn_task_dispose;
222
 
  obj_class->finalize = awn_task_finalize;
223
 
 
224
 
  global_awn_task_parent_class = g_type_class_peek_parent(class);
225
 
 
226
 
  /* GtkWidget signals */
227
 
  widget_class->expose_event = awn_task_expose;
228
 
  widget_class->button_press_event = awn_task_button_press;
229
 
  widget_class->scroll_event = awn_task_scroll_event;         //Ceceppa: mouse wheel
230
 
  widget_class->drag_motion = awn_task_drag_motion;
231
 
  widget_class->drag_leave = awn_task_drag_leave;
232
 
 
233
 
  g_type_class_add_private(obj_class, sizeof(AwnTaskPrivate));
234
 
 
235
 
  awn_task_signals[MENU_ITEM_CLICKED] =
236
 
    g_signal_new("menu_item_clicked",
237
 
                 G_OBJECT_CLASS_TYPE(obj_class),
238
 
                 G_SIGNAL_RUN_LAST,
239
 
                 G_STRUCT_OFFSET(AwnTaskClass, menu_item_clicked),
240
 
                 NULL, NULL,
241
 
                 g_cclosure_marshal_VOID__UINT,
242
 
                 G_TYPE_NONE,
243
 
                 1,
244
 
                 G_TYPE_UINT);
245
 
 
246
 
  awn_task_signals[CHECK_ITEM_CLICKED] =
247
 
    g_signal_new("check_item_clicked",
248
 
                 G_OBJECT_CLASS_TYPE(obj_class),
249
 
                 G_SIGNAL_RUN_LAST,
250
 
                 G_STRUCT_OFFSET(AwnTaskClass, check_item_clicked),
251
 
                 NULL, NULL,
252
 
                 _awn_marshal_VOID__UINT_BOOLEAN,
253
 
                 G_TYPE_NONE,
254
 
                 2,
255
 
                 G_TYPE_UINT, G_TYPE_BOOLEAN);
256
 
}
257
 
 
258
 
static void
259
 
awn_task_init(AwnTask *task)
260
 
{
261
 
  gtk_widget_add_events(GTK_WIDGET(task), GDK_ALL_EVENTS_MASK);
262
 
 
263
 
  gtk_drag_dest_set(GTK_WIDGET(task),
264
 
                    GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
265
 
                    drop_types, n_drop_types,
266
 
                    GDK_ACTION_MOVE | GDK_ACTION_COPY);
267
 
 
268
 
 
269
 
#if !GTK_CHECK_VERSION(2,9,0)
270
 
  /* TODO: equivalent of following function: */
271
 
#else
272
 
  //gtk_drag_dest_set_track_motion  (GTK_WIDGET (task),TRUE);
273
 
#endif
274
 
  gtk_drag_dest_add_uri_targets(GTK_WIDGET(task));
275
 
  /* set all priv variables */
276
 
  AwnTaskPrivate *priv;
277
 
  priv = AWN_TASK_GET_PRIVATE(task);
278
 
 
279
 
  priv->item = NULL;
280
 
  priv->pid = -1;
281
 
  priv->application = NULL;
282
 
  priv->is_launcher = FALSE;
283
 
  priv->is_starter = FALSE;
284
 
  priv->window = NULL;
285
 
  priv->title = NULL;
286
 
  priv->icon = NULL;
287
 
  priv->reflect = NULL;
288
 
  priv->progress = 100;
289
 
  priv->info = FALSE;
290
 
  priv->info_text = NULL;
291
 
  priv->is_active = FALSE;
292
 
  priv->drag_hover = FALSE;
293
 
  priv->menu_items[0] = NULL;
294
 
  priv->menu_items[1] = NULL;
295
 
  priv->menu_items[2] = NULL;
296
 
  priv->menu_items[3] = NULL;
297
 
  priv->menu_items[4] = NULL;
298
 
  priv->timer_count = 0;
299
 
 
300
 
  /* Ceceppa */
301
 
  priv->old_x = -1;
302
 
  priv->old_y = -1;
303
 
 
304
 
  priv->dispose_has_run = FALSE;
305
 
 
306
 
  priv->effects = awn_effects_new_for_widget(GTK_WIDGET(task));
307
 
  awn_effects_register(priv->effects, GTK_WIDGET(task));
308
 
}
309
 
 
310
 
static const gchar* awn_task_get_title(GtkWidget *obj)
311
 
{
312
 
  return awn_task_get_name(AWN_TASK(obj));
313
 
}
314
 
 
315
 
/************* EFFECTS *****************/
316
 
 
317
 
static void
318
 
_task_refresh(GtkWidget *obj)
319
 
{
320
 
  AwnTask *task = AWN_TASK(obj);
321
 
  AwnTaskPrivate *priv;
322
 
  priv = AWN_TASK_GET_PRIVATE(task);
323
 
  gtk_widget_set_size_request(GTK_WIDGET(obj),
324
 
                              (priv->settings->task_width),
325
 
                              (priv->settings->bar_height + 2) * 2);
326
 
 
327
 
  /*
328
 
   Note: Timeout will only happen once.  awn_task_manager_refresh_box() always 
329
 
   returns FALSE.
330
 
   */
331
 
  g_timeout_add(50, (GSourceFunc)awn_task_manager_refresh_box,
332
 
                priv->task_manager);
333
 
}
334
 
 
335
 
static void
336
 
launch_launched_effect(AwnTask *task)
337
 
{
338
 
  AwnTaskPrivate *priv;
339
 
  priv = AWN_TASK_GET_PRIVATE(task);
340
 
  awn_effects_start_ex(priv->effects, AWN_EFFECT_LAUNCHING, NULL, NULL, 10);
341
 
}
342
 
 
343
 
static gboolean
344
 
_shrink_widget(AwnTask *task)
345
 
{
346
 
  AwnTaskPrivate *priv;
347
 
 
348
 
  g_return_val_if_fail(AWN_IS_TASK(task), FALSE);
349
 
  priv = AWN_TASK_GET_PRIVATE(task);
350
 
 
351
 
  if (priv->timer_count)
352
 
  {
353
 
    return TRUE;
354
 
  }
355
 
 
356
 
  if (priv->is_launcher)
357
 
    awn_task_manager_remove_launcher(priv->task_manager, task);
358
 
  else
359
 
    awn_task_manager_remove_task(priv->task_manager, task);
360
 
 
361
 
  priv->title = NULL;
362
 
 
363
 
  g_free(priv->application);
364
 
 
365
 
  gtk_widget_hide(GTK_WIDGET(task));
366
 
 
367
 
  if (priv->icon)
368
 
  {
369
 
    gdk_pixbuf_unref(priv->icon);
370
 
  }
371
 
 
372
 
  if (priv->reflect)
373
 
  {
374
 
    gdk_pixbuf_unref(priv->reflect);
375
 
  }
376
 
 
377
 
  g_timeout_add_seconds(1, (GSourceFunc)awn_task_manager_refresh_box,
378
 
 
379
 
                priv->task_manager);
380
 
 
381
 
  gtk_object_destroy(GTK_OBJECT(task));
382
 
  task = NULL;
383
 
 
384
 
  return FALSE;
385
 
}
386
 
 
387
 
static void
388
 
_task_destroy(GtkWidget *obj)
389
 
{
390
 
  g_timeout_add(40, (GSourceFunc)_shrink_widget, obj);
391
 
}
392
 
 
393
 
/**********************  CALLBACKS  **********************/
394
 
 
395
 
 
396
 
static void
397
 
_rounded_rectangle(cairo_t *cr, double w, double h, double x, double y)
398
 
{
399
 
  const float RADIUS_CORNERS = 1.5;
400
 
 
401
 
  cairo_move_to(cr, x + RADIUS_CORNERS, y);
402
 
  cairo_line_to(cr, x + w - RADIUS_CORNERS, y);
403
 
  cairo_move_to(cr, w + x, y + RADIUS_CORNERS);
404
 
  cairo_line_to(cr, w + x, h + y - RADIUS_CORNERS);
405
 
  cairo_move_to(cr, w + x - RADIUS_CORNERS, h + y);
406
 
  cairo_line_to(cr, x + RADIUS_CORNERS, h + y);
407
 
  cairo_move_to(cr, x, h + y - RADIUS_CORNERS);
408
 
  cairo_line_to(cr, x, y + RADIUS_CORNERS);
409
 
 
410
 
 
411
 
}
412
 
 
413
 
static void
414
 
_rounded_corners(cairo_t *cr, double w, double h, double x, double y)
415
 
{
416
 
  double radius = 1.5;
417
 
  cairo_move_to(cr, x + radius, y);
418
 
  cairo_arc(cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 2);
419
 
  cairo_arc(cr, x + w - radius, y + h - radius, radius, 0, M_PI * 0.5);
420
 
  cairo_arc(cr, x + radius,   y + h - radius, radius, M_PI * 0.5, M_PI);
421
 
  cairo_arc(cr, x + radius,   y + radius,   radius, M_PI, M_PI * 1.5);
422
 
 
423
 
}
424
 
 
425
 
static void
426
 
_rounded_rect(cairo_t *cr, gint x, gint y, gint w, gint h)
427
 
{
428
 
  double radius, RADIUS_CORNERS;
429
 
  radius = RADIUS_CORNERS = 6;
430
 
 
431
 
  cairo_move_to(cr, x + radius, y);
432
 
  cairo_arc(cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 2);
433
 
  cairo_arc(cr, x + w - radius, y + h - radius, radius, 0, M_PI * 0.5);
434
 
  cairo_arc(cr, x + radius,   y + h - radius, radius, M_PI * 0.5, M_PI);
435
 
  cairo_arc(cr, x + radius,   y + radius,   radius, M_PI, M_PI * 1.5);
436
 
  cairo_move_to(cr, x + RADIUS_CORNERS, y);
437
 
  cairo_line_to(cr, x + w - RADIUS_CORNERS, y);
438
 
  cairo_move_to(cr, w + x, y + RADIUS_CORNERS);
439
 
  cairo_line_to(cr, w + x, h + y - RADIUS_CORNERS);
440
 
  cairo_move_to(cr, w + x - RADIUS_CORNERS, h + y);
441
 
  cairo_line_to(cr, x + RADIUS_CORNERS, h + y);
442
 
  cairo_move_to(cr, x, h + y - RADIUS_CORNERS);
443
 
  cairo_line_to(cr, x, y + RADIUS_CORNERS);
444
 
 
445
 
}
446
 
 
447
 
static void
448
 
draw(GtkWidget *task, cairo_t *cr)
449
 
{
450
 
  AwnTaskPrivate *priv;
451
 
  AwnSettings *settings;
452
 
  double width, height;
453
 
 
454
 
  priv = AWN_TASK_GET_PRIVATE(task);
455
 
  settings = priv->settings;
456
 
 
457
 
  width = task->allocation.width;
458
 
  height = task->allocation.height;
459
 
 
460
 
  awn_effects_draw_set_window_size(priv->effects, width, height);
461
 
 
462
 
  gint resize_offset = settings->bar_height + 12 - settings->task_width;
463
 
 
464
 
  /* task back */
465
 
  cairo_set_source_rgba(cr, 1, 0, 0, 0.0);
466
 
  cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
467
 
  cairo_rectangle(cr, -1, -1, width + 1, height + 1);
468
 
  cairo_fill(cr);
469
 
 
470
 
  cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
471
 
 
472
 
  /* active */
473
 
 
474
 
  if (priv->window && wnck_window_is_active(priv->window))
475
 
  {
476
 
    cairo_set_source_rgba(cr, settings->border_color.red,
477
 
                          settings->border_color.green,
478
 
                          settings->border_color.blue,
479
 
                          0.2);
480
 
 
481
 
    if (settings->bar_angle < 0)
482
 
    {
483
 
      _rounded_rect(cr, 0 , settings->bar_height + resize_offset - priv->effects->curve_offset,
484
 
                    width, settings->bar_height - resize_offset);
485
 
 
486
 
      cairo_fill(cr);
487
 
    }
488
 
    else
489
 
    {
490
 
      _rounded_rect(cr, 0 , settings->bar_height + resize_offset,
491
 
                    width, settings->bar_height - resize_offset);
492
 
 
493
 
      cairo_fill(cr);
494
 
 
495
 
      cairo_set_source_rgba(cr, settings->border_color.red,
496
 
                            settings->border_color.green,
497
 
                            settings->border_color.blue,
498
 
                            0.2 / 3);
499
 
      _rounded_rect(cr, 0 , settings->bar_height*2,
500
 
                    width, settings->icon_offset);
501
 
      cairo_fill(cr);
502
 
    }
503
 
  }
504
 
 
505
 
  /* use libawn to draw */
506
 
  awn_effects_draw_background(priv->effects, cr);
507
 
 
508
 
  awn_effects_draw_icons(priv->effects, cr, priv->icon, priv->reflect);
509
 
 
510
 
  awn_effects_draw_foreground(priv->effects, cr);
511
 
 
512
 
  /* arrows */
513
 
  double x1;
514
 
 
515
 
  double arrow_top;
516
 
 
517
 
  x1 = width / 2.0;
518
 
 
519
 
  if (settings->bar_angle >= 0)
520
 
  {
521
 
    arrow_top = (settings->bar_height * 2) + settings->arrow_offset;
522
 
    cairo_set_source_rgba(cr, settings->arrow_color.red,
523
 
                          settings->arrow_color.green,
524
 
                          settings->arrow_color.blue,
525
 
                          settings->arrow_color.alpha);
526
 
    cairo_move_to(cr, x1 - 5, arrow_top);
527
 
    cairo_line_to(cr, x1, arrow_top - 5);
528
 
    cairo_line_to(cr, x1 + 5, arrow_top);
529
 
    cairo_close_path(cr);
530
 
  }
531
 
  else
532
 
  {
533
 
    cairo_set_source_rgba(cr, settings->arrow_color.red,
534
 
                          settings->arrow_color.green,
535
 
                          settings->arrow_color.blue,
536
 
                          settings->arrow_color.alpha);
537
 
    cairo_arc(cr, width / 2., (settings->bar_height * 2) - 5, 3., 0., 2 * M_PI);
538
 
  }
539
 
 
540
 
  if (settings->tasks_have_arrows)
541
 
  {
542
 
    if (priv->window != NULL)
543
 
      cairo_fill(cr);
544
 
 
545
 
  }
546
 
  else if (priv->is_launcher && (priv->window == NULL))
547
 
    cairo_fill(cr);
548
 
  else
549
 
  {
550
 
    ;
551
 
  }
552
 
 
553
 
  /* progress meter */
554
 
  cairo_new_path(cr);
555
 
 
556
 
  if (priv->progress != 100)
557
 
  {
558
 
    cairo_move_to(cr, width / 2.0, settings->bar_height *1.5);
559
 
    cairo_set_source_rgba(cr, settings->background.red,
560
 
                          settings->background.green,
561
 
                          settings->background.blue,
562
 
                          settings->background.alpha);
563
 
 
564
 
    cairo_arc(cr, width / 2.0, settings->bar_height *1.5, 15, 0, 360.0 * (M_PI / 180.0));
565
 
    cairo_fill(cr);
566
 
 
567
 
    cairo_move_to(cr, width / 2.0, settings->bar_height *1.5);
568
 
    cairo_set_source_rgba(cr, settings->text_color.red,
569
 
                          settings->text_color.green,
570
 
                          settings->text_color.blue,
571
 
                          0.8);
572
 
    cairo_arc(cr, width / 2.0,
573
 
              settings->bar_height * 1.5,
574
 
              12, 270.0 * (M_PI / 180.0),
575
 
              (270.0 + ((double)(priv->progress / 100.0) * 360.0))  * (M_PI / 180.0));
576
 
    cairo_fill(cr);
577
 
  }
578
 
 
579
 
  if ((priv->progress == 100) && priv->info)
580
 
  {
581
 
 
582
 
    cairo_text_extents_t extents;
583
 
    cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
584
 
                           CAIRO_FONT_WEIGHT_BOLD);
585
 
    gint len = strlen(priv->info_text);
586
 
 
587
 
    if (len > 8)
588
 
      cairo_set_font_size(cr, 8);
589
 
    else if (len > 4)
590
 
      cairo_set_font_size(cr, 10);
591
 
    else
592
 
      cairo_set_font_size(cr, 12);
593
 
 
594
 
    cairo_text_extents(cr, priv->info_text, &extents);
595
 
 
596
 
    cairo_move_to(cr, width / 2.0, settings->bar_height *1.5);
597
 
 
598
 
    cairo_set_source_rgba(cr, settings->background.red,
599
 
                          settings->background.green,
600
 
                          settings->background.blue,
601
 
                          settings->background.alpha);
602
 
 
603
 
    _rounded_rectangle(cr, (double) extents.width + 8.0,
604
 
                       (double) extents.height + 84.0,
605
 
                       (width / 2.0) - 4.0 - ((extents.width + extents.x_bearing) / 2.0),
606
 
                       (settings->bar_height *1.5) - (extents.height / 2.0) - 4.0);
607
 
 
608
 
    _rounded_corners(cr, (double) extents.width + 8.0,
609
 
                     (double) extents.height + 8.0,
610
 
                     (width / 2.0) - 4.0 - ((extents.width + extents.x_bearing) / 2.0),
611
 
                     (settings->bar_height *1.5) - (extents.height / 2.0) - 4.0);
612
 
 
613
 
    cairo_fill(cr);
614
 
 
615
 
 
616
 
    cairo_set_source_rgba(cr, settings->text_color.red,
617
 
                          settings->text_color.green,
618
 
                          settings->text_color.blue,
619
 
                          0.8);
620
 
 
621
 
    cairo_move_to(cr, (width / 2.0) - ((extents.width + extents.x_bearing) / 2.0) - 1, (settings->bar_height *1.5) + (extents.height / 2.0));
622
 
 
623
 
    cairo_show_text(cr, priv->info_text);
624
 
  }
625
 
}
626
 
 
627
 
static gboolean
628
 
awn_task_expose(GtkWidget *task, GdkEventExpose *event)
629
 
{
630
 
  AwnTaskPrivate *priv;
631
 
  cairo_t *cr;
632
 
  priv = AWN_TASK_GET_PRIVATE(task);
633
 
 
634
 
  /* get a cairo_t */
635
 
  cr = gdk_cairo_create(task->window);
636
 
 
637
 
  draw(task, cr);
638
 
 
639
 
  cairo_destroy(cr);
640
 
 
641
 
  return FALSE;
642
 
}
643
 
 
644
 
static void
645
 
awn_task_launch_unique(AwnTask *task, const char *arg_str)
646
 
{
647
 
  AwnTaskPrivate *priv;
648
 
  priv = AWN_TASK_GET_PRIVATE(task);;
649
 
 
650
 
  GError *err = NULL;
651
 
  int pid = awn_desktop_item_launch(priv->item, NULL, &err);
652
 
 
653
 
  if (err)
654
 
  {
655
 
    g_print("Error: %s", err->message);
656
 
    g_error_free(err);
657
 
  }
658
 
  else
659
 
    g_print("Launched application : %d\n", pid);
660
 
 
661
 
}
662
 
 
663
 
static void
664
 
awn_task_launch(AwnTask *task, const char *arg_str)
665
 
{
666
 
  AwnTaskPrivate *priv;
667
 
  priv = AWN_TASK_GET_PRIVATE(task);;
668
 
 
669
 
  GError *err = NULL;
670
 
  priv->pid = awn_desktop_item_launch(priv->item, NULL, &err);
671
 
 
672
 
  if (err)
673
 
  {
674
 
    g_print("Error: %s", err->message);
675
 
    g_error_free(err);
676
 
  }
677
 
  else
678
 
    g_print("Launched application : %d\n", priv->pid);
679
 
 
680
 
}
681
 
 
682
 
/*Callback to start awn-manager. */
683
 
static gboolean
684
 
awn_start_awn_manager(GtkMenuItem *menuitem, gpointer null)
685
 
{
686
 
  GError *err = NULL;
687
 
  g_spawn_command_line_async("awn-manager", &err);
688
 
 
689
 
  if (err)
690
 
  {
691
 
    g_warning("Failed to start awn-manager: %s\n", err->message);
692
 
    g_error_free(err);
693
 
  }
694
 
 
695
 
  return TRUE;
696
 
}
697
 
 
698
 
static void
699
 
awn_task_activate_transient (AwnTask *task, guint32 time)
700
 
{
701
 
  AwnTaskPrivate *priv = AWN_TASK_GET_PRIVATE(task);
702
 
  WnckScreen *screen;
703
 
  WnckWorkspace *active_workspace, *window_workspace;
704
 
 
705
 
  if (!priv->window) return;
706
 
 
707
 
  gint activate_behavior =
708
 
    awn_task_manager_get_activate_behavior (priv->task_manager);
709
 
 
710
 
  switch (activate_behavior)
711
 
  {
712
 
    case AWN_ACTIVATE_MOVE_TO_TASK_VIEWPORT:
713
 
      screen = wnck_window_get_screen(priv->window);
714
 
      active_workspace = wnck_screen_get_active_workspace (screen);
715
 
      window_workspace = wnck_window_get_workspace (priv->window);
716
 
 
717
 
      if (active_workspace && window_workspace &&
718
 
            !wnck_window_is_on_workspace(priv->window, active_workspace))
719
 
        wnck_workspace_activate(window_workspace, time);
720
 
 
721
 
      break;
722
 
 
723
 
    case AWN_ACTIVATE_MOVE_TASK_TO_ACTIVE_VIEWPORT:
724
 
      screen = wnck_window_get_screen(priv->window);
725
 
      active_workspace = wnck_screen_get_active_workspace (screen);
726
 
 
727
 
      if (active_workspace &&
728
 
            !wnck_window_is_on_workspace(priv->window, active_workspace))
729
 
        wnck_window_move_to_workspace(priv->window, active_workspace);
730
 
 
731
 
      break;
732
 
 
733
 
    case AWN_ACTIVATE_DEFAULT:
734
 
    default:
735
 
      break;
736
 
  }
737
 
  // last step is always activating the window
738
 
  wnck_window_activate_transient (priv->window, time);
739
 
}
740
 
 
741
 
static gboolean
742
 
awn_task_button_press(GtkWidget *task, GdkEventButton *event)
743
 
{
744
 
  static guint32 past_time; // 3v1n0 double-click (or more) prevention
745
 
  AwnTaskPrivate *priv;
746
 
  GtkWidget *menu = NULL;
747
 
 
748
 
  priv = AWN_TASK_GET_PRIVATE(task);
749
 
 
750
 
 
751
 
  if (priv->window)
752
 
  {
753
 
 
754
 
    switch (event->button)
755
 
    {
756
 
 
757
 
      case 1:
758
 
 
759
 
        if (event->time - past_time > AWN_CLICK_IDLE_TIME)
760
 
        {
761
 
          past_time = event->time;
762
 
 
763
 
          if (wnck_window_is_active(priv->window))
764
 
          {
765
 
            wnck_window_minimize(priv->window);
766
 
            return TRUE;
767
 
          }
768
 
 
769
 
          awn_task_activate_transient (AWN_TASK (task), event->time);
770
 
        }
771
 
 
772
 
        break;
773
 
 
774
 
      case 2:
775
 
 
776
 
        if (priv->is_launcher)
777
 
          awn_task_launch_unique(AWN_TASK(task), NULL);
778
 
 
779
 
        break;
780
 
 
781
 
      case 3:
782
 
        menu = wnck_create_window_action_menu(priv->window);
783
 
 
784
 
        awn_task_create_menu(AWN_TASK(task), GTK_MENU(menu));
785
 
 
786
 
        gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL,
787
 
                       NULL, 3, event->time);
788
 
 
789
 
        break;
790
 
 
791
 
      default:
792
 
        return FALSE;
793
 
    }
794
 
  }
795
 
  else if (priv->is_launcher)
796
 
  {
797
 
    switch (event->button)
798
 
    {
799
 
 
800
 
      case 1:
801
 
 
802
 
        if (event->time - past_time > AWN_CLICK_IDLE_TIME)
803
 
        {
804
 
          past_time = event->time;
805
 
          awn_task_launch(AWN_TASK(task), NULL);
806
 
          launch_launched_effect(AWN_TASK(task));
807
 
        }
808
 
 
809
 
        break;
810
 
 
811
 
//    case 2:
812
 
//      // Manage middle click on launchers
813
 
//      g_print("Middle click pressed for launcher\n");
814
 
//      break;
815
 
 
816
 
      case 3:
817
 
        menu = gtk_menu_new();
818
 
        awn_task_create_menu(AWN_TASK(task), GTK_MENU(menu));
819
 
 
820
 
        gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL,
821
 
                       NULL, 3, event->time);
822
 
        break;
823
 
 
824
 
      default:
825
 
        return FALSE;
826
 
    }
827
 
  }
828
 
  else
829
 
  {
830
 
    ;
831
 
  }
832
 
 
833
 
 
834
 
  return TRUE;
835
 
}
836
 
 
837
 
//Ceceppa
838
 
static gboolean
839
 
awn_task_scroll_event(GtkWidget *task, GdkEventScroll *event)
840
 
{
841
 
  AwnTaskPrivate *priv;
842
 
  gboolean in_viewport;
843
 
  int x, y;
844
 
  int w, h;
845
 
  WnckWindow *focus = NULL;
846
 
  WnckScreen *screen;
847
 
  WnckWorkspace *space;
848
 
 
849
 
  priv = AWN_TASK_GET_PRIVATE(task);
850
 
 
851
 
  if (priv->is_launcher)
852
 
    return TRUE;
853
 
 
854
 
  screen = wnck_screen_get_default();
855
 
 
856
 
  space  = wnck_screen_get_active_workspace(screen);
857
 
 
858
 
  if (event->direction == GDK_SCROLL_UP)
859
 
  {
860
 
    if (wnck_window_is_active(priv->window))
861
 
      return TRUE;
862
 
 
863
 
    //Save current position
864
 
    wnck_window_get_geometry(priv->window,
865
 
                             &x,
866
 
                             &y,
867
 
                             &w,
868
 
                             &h);
869
 
 
870
 
    if (priv->old_x == -1 && priv->old_y == -1)
871
 
    {
872
 
      priv->old_x = x;
873
 
      priv->old_y = y;
874
 
    }
875
 
 
876
 
    //Window is in current viewport? If no, center window
877
 
    in_viewport = wnck_window_is_in_viewport(priv->window, space);
878
 
 
879
 
    x = in_viewport ? x : (wnck_screen_get_width(screen) - w) / 2;
880
 
 
881
 
    y = in_viewport ? y : (wnck_screen_get_height(screen) - h) / 2;
882
 
 
883
 
    //Save last active window
884
 
    last_active_window = wnck_screen_get_active_window(wnck_screen_get_default());
885
 
 
886
 
    focus = priv->window;
887
 
  }
888
 
  else if (event->direction == GDK_SCROLL_DOWN)
889
 
  {
890
 
    if (priv->old_x == -1 && priv->old_y == -1)
891
 
      return TRUE;
892
 
 
893
 
    x = priv->old_x;
894
 
 
895
 
    y = priv->old_y;
896
 
 
897
 
    focus = wnck_window_is_active(priv->window) ?
898
 
            last_active_window :
899
 
            wnck_screen_get_active_window(screen);
900
 
 
901
 
    priv->old_x = -1;
902
 
 
903
 
    priv->old_y = -1;
904
 
 
905
 
    last_active_window = NULL;
906
 
  }
907
 
 
908
 
  wnck_window_set_geometry(priv->window,
909
 
 
910
 
                           WNCK_WINDOW_GRAVITY_CURRENT,
911
 
                           WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y,
912
 
                           x, y,
913
 
                           w, h);
914
 
 
915
 
  if (focus != NULL)
916
 
    wnck_window_activate_transient(focus, event->time);
917
 
 
918
 
  return TRUE;
919
 
}
920
 
 
921
 
 
922
 
static void
923
 
_task_drag_data_recieved(GtkWidget *widget, GdkDragContext *context,
924
 
                         gint x, gint y, GtkSelectionData *selection_data,
925
 
                         guint target_type, guint time,
926
 
                         AwnTask *task)
927
 
{
928
 
 
929
 
  GSList      *list;
930
 
 
931
 
  gboolean delete_selection_data = FALSE;
932
 
 
933
 
  AwnTaskPrivate *priv;
934
 
  priv = AWN_TASK_GET_PRIVATE(task);
935
 
  gtk_drag_finish(context, TRUE, FALSE, time);
936
 
 
937
 
  if (!priv->is_launcher)
938
 
  {
939
 
    gtk_drag_finish(context, FALSE, delete_selection_data, time);
940
 
    return;
941
 
  }
942
 
 
943
 
  char *res = NULL;
944
 
 
945
 
  res = strstr((char *)selection_data->data, ".desktop");
946
 
 
947
 
  if (res)
948
 
    return;
949
 
 
950
 
  GError *err = NULL;
951
 
 
952
 
  list = awn_vfs_get_pathlist_from_string((gchar *)selection_data->data, &err);
953
 
 
954
 
  priv->pid = awn_desktop_item_launch(priv->item, list, &err);
955
 
 
956
 
  if (err)
957
 
  {
958
 
    g_print("Error: %s", err->message);
959
 
    g_error_free(err);
960
 
  }
961
 
  else
962
 
    g_print("Launched application : %d\n", priv->pid);
963
 
 
964
 
  g_slist_foreach(list, (GFunc)g_free, NULL);
965
 
 
966
 
  g_slist_free(list);
967
 
 
968
 
  return;
969
 
}
970
 
 
971
 
 
972
 
static gboolean
973
 
activate_window(AwnTask *task)
974
 
{
975
 
  AwnTaskPrivate *priv;
976
 
  priv = AWN_TASK_GET_PRIVATE(task);
977
 
 
978
 
  if (priv->drag_hover && !wnck_window_is_active(priv->window))
979
 
    awn_task_activate_transient(task, priv->timestamp);
980
 
 
981
 
  return FALSE;
982
 
}
983
 
 
984
 
static gboolean
985
 
awn_task_drag_motion(GtkWidget *task,
986
 
                     GdkDragContext *context, gint x, gint y, guint t)
987
 
{
988
 
  AwnTaskPrivate *priv;
989
 
  priv = AWN_TASK_GET_PRIVATE(task);
990
 
 
991
 
  if (priv->settings->auto_hide && priv->settings->hidden)
992
 
  {
993
 
    awn_show(priv->settings);
994
 
  }
995
 
 
996
 
  if (priv->window)
997
 
  {
998
 
    if (!wnck_window_is_active(priv->window))
999
 
    {
1000
 
      priv->drag_hover = TRUE;
1001
 
      priv->timestamp = gtk_get_current_event_time();
1002
 
      g_timeout_add_seconds(1, (GSourceFunc)activate_window, (gpointer)task);
1003
 
    }
1004
 
 
1005
 
    awn_effects_start_ex(priv->effects, AWN_EFFECT_LAUNCHING, NULL, NULL, 1);
1006
 
  }
1007
 
 
1008
 
  return FALSE;
1009
 
}
1010
 
 
1011
 
static void
1012
 
awn_task_drag_leave(GtkWidget *task, GdkDragContext *drag_context,
1013
 
                    guint time)
1014
 
{
1015
 
  AwnTaskPrivate *priv;
1016
 
  priv = AWN_TASK_GET_PRIVATE(task);
1017
 
  priv->drag_hover = FALSE;
1018
 
 
1019
 
  if (priv->settings->auto_hide && !priv->settings->hidden)
1020
 
  {
1021
 
    awn_hide(priv->settings);
1022
 
  }
1023
 
}
1024
 
 
1025
 
static void
1026
 
_task_wnck_icon_changed(WnckWindow *window, AwnTask *task)
1027
 
{
1028
 
  AwnTaskPrivate *priv;
1029
 
  priv = AWN_TASK_GET_PRIVATE(task);
1030
 
 
1031
 
  if (priv->is_launcher)
1032
 
    return;
1033
 
 
1034
 
  GdkPixbuf *old = NULL;
1035
 
 
1036
 
  GdkPixbuf *old_reflect = NULL;
1037
 
 
1038
 
  old = priv->icon;
1039
 
 
1040
 
  old_reflect = priv->reflect;
1041
 
 
1042
 
  int height = priv->settings->bar_height;
1043
 
 
1044
 
  if ((priv->settings->task_width - 12) < height)
1045
 
  {
1046
 
    height = priv->settings->task_width - 12;
1047
 
  }
1048
 
 
1049
 
  priv->icon = awn_x_get_icon_for_window(priv->window,
1050
 
 
1051
 
                                         height, height);
1052
 
  priv->reflect = gdk_pixbuf_flip(priv->icon, FALSE);
1053
 
 
1054
 
  awn_effects_draw_set_icon_size(priv->effects, gdk_pixbuf_get_width(priv->icon), gdk_pixbuf_get_height(priv->icon));
1055
 
 
1056
 
  gdk_pixbuf_unref(old);
1057
 
  gdk_pixbuf_unref(old_reflect);
1058
 
  gtk_widget_queue_draw(GTK_WIDGET(task));
1059
 
}
1060
 
 
1061
 
static gboolean
1062
 
_task_wnck_name_hide(AwnTask *task)
1063
 
{
1064
 
  AwnTaskPrivate *priv;
1065
 
  priv = AWN_TASK_GET_PRIVATE(task);
1066
 
  awn_title_hide(AWN_TITLE(priv->title), GTK_WIDGET(task));
1067
 
  awn_effects_stop(priv->effects, AWN_EFFECT_ATTENTION);
1068
 
  /* If wanted, this could be done in a GDestroyNotify callback if
1069
 
     we added the timer using g_timeout_add_full () */
1070
 
  priv->timer_count--;
1071
 
  return FALSE;
1072
 
}
1073
 
 
1074
 
static void
1075
 
_task_wnck_name_changed(WnckWindow *window, AwnTask *task)
1076
 
{
1077
 
  g_return_if_fail(AWN_IS_TASK(task));
1078
 
 
1079
 
  AwnTaskPrivate *priv;
1080
 
  priv = AWN_TASK_GET_PRIVATE(task);
1081
 
 
1082
 
  if (!priv->window || !priv->settings->name_change_notify)
1083
 
  {
1084
 
    return;
1085
 
  }
1086
 
 
1087
 
  /*
1088
 
  g_print("Name changed on window '%s'\n",
1089
 
   wnck_window_get_name (priv->window));
1090
 
         */
1091
 
 
1092
 
  if (!wnck_window_is_active(priv->window))
1093
 
  {
1094
 
    gint x, y;
1095
 
    gdk_window_get_origin(GTK_WIDGET(task)->window, &x, &y);
1096
 
 
1097
 
    awn_effects_start_ex(priv->effects, AWN_EFFECT_ATTENTION, NULL, NULL, 10);
1098
 
 
1099
 
    awn_title_show(AWN_TITLE(priv->title),
1100
 
                   GTK_WIDGET(task),
1101
 
                   awn_task_get_name(AWN_TASK(task)));
1102
 
 
1103
 
    priv->timer_count++;
1104
 
    g_timeout_add(2500, (GSourceFunc)_task_wnck_name_hide, (gpointer)task);
1105
 
 
1106
 
  }
1107
 
}
1108
 
 
1109
 
static void
1110
 
_task_wnck_state_changed(WnckWindow *window, WnckWindowState  old,
1111
 
                         WnckWindowState  new, AwnTask *task)
1112
 
{
1113
 
  AwnTaskPrivate *priv;
1114
 
  priv = AWN_TASK_GET_PRIVATE(task);
1115
 
 
1116
 
  if (priv->window == NULL)
1117
 
    return;
1118
 
 
1119
 
  if (wnck_window_is_skip_tasklist(priv->window))
1120
 
    gtk_widget_hide(GTK_WIDGET(task));
1121
 
  else
1122
 
    gtk_widget_show(GTK_WIDGET(task));
1123
 
 
1124
 
  if (wnck_window_needs_attention(priv->window))
1125
 
  {
1126
 
    awn_effects_start(priv->effects, AWN_EFFECT_ATTENTION);
1127
 
  }
1128
 
  else
1129
 
  {
1130
 
    awn_effects_stop(priv->effects, AWN_EFFECT_ATTENTION);
1131
 
  }
1132
 
}
1133
 
 
1134
 
gboolean updating = FALSE;
1135
 
static gboolean
1136
 
_viewport_changed_so_update(AwnTaskManager *task_manager)
1137
 
{
1138
 
  updating = FALSE;
1139
 
  awn_task_manager_refresh_box(task_manager);
1140
 
  return FALSE;
1141
 
}
1142
 
 
1143
 
static void
1144
 
_task_wnck_geometry_changed(WnckWindow *window, AwnTask *task)
1145
 
{
1146
 
  AwnTaskPrivate *priv;
1147
 
  WnckScreen* screen;
1148
 
  int x,y,width,height;
1149
 
 
1150
 
  g_return_if_fail(AWN_IS_TASK(task));
1151
 
 
1152
 
  priv = AWN_TASK_GET_PRIVATE(task);
1153
 
 
1154
 
  if (priv->window == NULL)
1155
 
    return;
1156
 
 
1157
 
  screen = wnck_window_get_screen(priv->window);  
1158
 
  wnck_window_get_geometry(priv->window,
1159
 
                           &x,
1160
 
                           &y,
1161
 
                           &width,
1162
 
                           &height);
1163
 
 
1164
 
  if( x <= -width || x >= wnck_screen_get_width(screen) )
1165
 
  {
1166
 
    /* Window is moved off viewport, so update the list of tasks */
1167
 
    if( !updating )
1168
 
    {
1169
 
      updating = TRUE;
1170
 
      g_timeout_add(50, (GSourceFunc)_viewport_changed_so_update, priv->task_manager);
1171
 
    }
1172
 
  }
1173
 
}
1174
 
 
1175
 
/**********************Gets & Sets **********************/
1176
 
 
1177
 
gboolean
1178
 
awn_task_get_is_launcher(AwnTask *task)
1179
 
{
1180
 
  AwnTaskPrivate *priv;
1181
 
  priv = AWN_TASK_GET_PRIVATE(task);
1182
 
  return priv->is_launcher;
1183
 
}
1184
 
 
1185
 
gboolean
1186
 
awn_task_set_window(AwnTask *task, WnckWindow *window)
1187
 
{
1188
 
  g_return_val_if_fail(WNCK_IS_WINDOW(window), 0);
1189
 
 
1190
 
  AwnTaskPrivate *priv;
1191
 
  priv = AWN_TASK_GET_PRIVATE(task);
1192
 
 
1193
 
  if (priv->window != NULL)
1194
 
    return FALSE;
1195
 
 
1196
 
  gboolean connect_geom_signal = 
1197
 
        awn_task_manager_screen_has_viewports (priv->task_manager);
1198
 
 
1199
 
  priv->window = window;
1200
 
 
1201
 
  if (!priv->is_launcher)
1202
 
  {
1203
 
    gint size = priv->settings->task_width - 12;
1204
 
    if (size <= 0) size = 1;
1205
 
    priv->icon = awn_x_get_icon_for_window(priv->window,
1206
 
                                           size, size);
1207
 
    if (GDK_IS_PIXBUF (priv->icon))
1208
 
      priv->reflect = gdk_pixbuf_flip(priv->icon, FALSE);
1209
 
    else
1210
 
      priv->reflect = NULL;
1211
 
 
1212
 
    awn_effects_draw_set_icon_size(priv->effects, gdk_pixbuf_get_width(priv->icon), gdk_pixbuf_get_height(priv->icon));
1213
 
 
1214
 
  }
1215
 
 
1216
 
  priv->icon_changed = g_signal_connect(G_OBJECT(priv->window), "icon_changed",
1217
 
 
1218
 
                                        G_CALLBACK(_task_wnck_icon_changed), (gpointer)task);
1219
 
 
1220
 
  priv->state_changed = g_signal_connect(G_OBJECT(priv->window), "state_changed",
1221
 
                                         G_CALLBACK(_task_wnck_state_changed), (gpointer)task);
1222
 
 
1223
 
  priv->name_changed = g_signal_connect(G_OBJECT(priv->window), "name_changed",
1224
 
                                        G_CALLBACK(_task_wnck_name_changed), (gpointer)task);
1225
 
 
1226
 
  if (connect_geom_signal)
1227
 
  {
1228
 
    priv->geometry_changed = g_signal_connect(G_OBJECT(priv->window), "geometry_changed",
1229
 
                                              G_CALLBACK(_task_wnck_geometry_changed), (gpointer)task);
1230
 
  }
1231
 
 
1232
 
  /* if launcher, set a launch_sequence
1233
 
  else if starter, stop the launch_sequence, disable starter flag*/
1234
 
 
1235
 
  //awn_task_refresh_icon_geometry(task);
1236
 
 
1237
 
  if (wnck_window_is_skip_tasklist(window))
1238
 
    return TRUE;
1239
 
 
1240
 
  if (priv->is_launcher)
1241
 
  {
1242
 
    awn_effects_stop(priv->effects, AWN_EFFECT_LAUNCHING);
1243
 
    return TRUE;
1244
 
  }
1245
 
 
1246
 
  awn_effects_start_ex(priv->effects, AWN_EFFECT_OPENING, NULL, _task_refresh, 1);
1247
 
 
1248
 
  return TRUE;
1249
 
}
1250
 
 
1251
 
gboolean
1252
 
awn_task_set_launcher(AwnTask *task, AwnDesktopItem *item)
1253
 
{
1254
 
  AwnTaskPrivate *priv;
1255
 
  gchar *icon_name = NULL;
1256
 
 
1257
 
  priv = AWN_TASK_GET_PRIVATE(task);
1258
 
 
1259
 
  priv->is_launcher = item != NULL;
1260
 
  if (item == NULL) return FALSE;
1261
 
 
1262
 
  gboolean was_null = priv->item == NULL;
1263
 
 
1264
 
  icon_name = awn_desktop_item_get_icon(item, priv->settings->icon_theme);
1265
 
  if (!icon_name)
1266
 
    return FALSE;
1267
 
 
1268
 
  g_free(icon_name);
1269
 
 
1270
 
  priv->item = item;
1271
 
 
1272
 
  priv->icon = awn_x_get_icon_for_launcher(item,
1273
 
               priv->settings->task_width - 12,
1274
 
               priv->settings->task_width - 12);
1275
 
 
1276
 
  if (!priv->icon)
1277
 
  {
1278
 
    return FALSE;
1279
 
  }
1280
 
 
1281
 
  priv->reflect = gdk_pixbuf_flip(priv->icon, FALSE);
1282
 
 
1283
 
  awn_effects_draw_set_icon_size(priv->effects, gdk_pixbuf_get_width(priv->icon), gdk_pixbuf_get_height(priv->icon));
1284
 
 
1285
 
  if (was_null)
1286
 
  {
1287
 
    awn_effects_start_ex(priv->effects, AWN_EFFECT_OPENING, 
1288
 
                         NULL, _task_refresh, 1);
1289
 
  }
1290
 
 
1291
 
  return TRUE;
1292
 
}
1293
 
 
1294
 
gboolean
1295
 
awn_task_is_launcher(AwnTask *task)
1296
 
{
1297
 
  AwnTaskPrivate *priv;
1298
 
  priv = AWN_TASK_GET_PRIVATE(task);
1299
 
  return priv->is_launcher;
1300
 
}
1301
 
 
1302
 
WnckWindow *
1303
 
awn_task_get_window(AwnTask *task)
1304
 
{
1305
 
  AwnTaskPrivate *priv;
1306
 
  priv = AWN_TASK_GET_PRIVATE(task);
1307
 
  return priv->window;
1308
 
}
1309
 
 
1310
 
gulong
1311
 
awn_task_get_xid(AwnTask *task)
1312
 
{
1313
 
  AwnTaskPrivate *priv;
1314
 
  priv = AWN_TASK_GET_PRIVATE(task);
1315
 
 
1316
 
  if (priv->window == NULL)
1317
 
    return 0;
1318
 
 
1319
 
  g_return_val_if_fail(WNCK_IS_WINDOW(priv->window), 0);
1320
 
 
1321
 
  return wnck_window_get_xid(priv->window);
1322
 
}
1323
 
 
1324
 
gint
1325
 
awn_task_get_pid(AwnTask *task)
1326
 
{
1327
 
  AwnTaskPrivate *priv;
1328
 
  priv = AWN_TASK_GET_PRIVATE(task);
1329
 
 
1330
 
  if (priv->window != NULL)
1331
 
    return wnck_window_get_pid(priv->window);
1332
 
 
1333
 
  return priv->pid;
1334
 
}
1335
 
 
1336
 
void
1337
 
awn_task_set_is_active(AwnTask *task, gboolean is_active)
1338
 
{
1339
 
  AwnTaskPrivate *priv;
1340
 
  priv = AWN_TASK_GET_PRIVATE(task);
1341
 
 
1342
 
  if (priv->window == NULL)
1343
 
    return;
1344
 
 
1345
 
  priv->is_active = wnck_window_is_active(priv->window);
1346
 
 
1347
 
  gtk_widget_queue_draw(GTK_WIDGET(task));
1348
 
}
1349
 
 
1350
 
void
1351
 
awn_task_set_needs_attention(AwnTask *task, gboolean needs_attention)
1352
 
{
1353
 
  // wow, it's never called
1354
 
  AwnTaskPrivate *priv;
1355
 
  priv = AWN_TASK_GET_PRIVATE(task);
1356
 
 
1357
 
  if (needs_attention)
1358
 
    awn_effects_start(priv->effects, AWN_EFFECT_ATTENTION);
1359
 
  else
1360
 
    awn_effects_stop(priv->effects, AWN_EFFECT_ATTENTION);
1361
 
}
1362
 
 
1363
 
const char*
1364
 
awn_task_get_name(AwnTask *task)
1365
 
{
1366
 
  AwnTaskPrivate *priv;
1367
 
  priv = AWN_TASK_GET_PRIVATE(task);
1368
 
 
1369
 
  const char *name = NULL;
1370
 
 
1371
 
 
1372
 
  if (priv->window)
1373
 
    name =  wnck_window_get_name(priv->window);
1374
 
 
1375
 
  else if (priv->is_launcher)
1376
 
    name = awn_desktop_item_get_name(priv->item);
1377
 
  else
1378
 
    name =  "No name";
1379
 
 
1380
 
  return name;
1381
 
}
1382
 
 
1383
 
const char*
1384
 
awn_task_get_application(AwnTask *task)
1385
 
{
1386
 
  AwnTaskPrivate *priv;
1387
 
  WnckApplication *wnck_app;
1388
 
  char *app;
1389
 
  GString *str;
1390
 
 
1391
 
  priv = AWN_TASK_GET_PRIVATE(task);
1392
 
  app = NULL;
1393
 
 
1394
 
  if (priv->application)
1395
 
    return priv->application;
1396
 
 
1397
 
  if (priv->is_launcher)
1398
 
  {
1399
 
 
1400
 
    str = g_string_new(awn_desktop_item_get_exec(priv->item));
1401
 
    int i = 0;
1402
 
 
1403
 
    for (i = 0; i < str->len; i++)
1404
 
    {
1405
 
      if (str->str[i] == ' ')
1406
 
        break;
1407
 
    }
1408
 
 
1409
 
    if (i)
1410
 
      str = g_string_truncate(str, i);
1411
 
 
1412
 
    priv->application = g_strdup(str->str);
1413
 
 
1414
 
    app = g_string_free(str, TRUE);
1415
 
 
1416
 
  }
1417
 
  else if (priv->window)
1418
 
  {
1419
 
    wnck_app = wnck_window_get_application(priv->window);
1420
 
 
1421
 
    if (WNCK_IS_APPLICATION(wnck_app))
1422
 
    {
1423
 
      str = g_string_new(wnck_application_get_name(wnck_app));
1424
 
    }
1425
 
    else
1426
 
    {
1427
 
      str = g_string_new(NULL);
1428
 
    }
1429
 
 
1430
 
    str = g_string_ascii_down(str);
1431
 
 
1432
 
    priv->application = g_strdup(str->str);
1433
 
    app = g_string_free(str, TRUE);
1434
 
 
1435
 
  }
1436
 
  else
1437
 
    priv->application = NULL;
1438
 
 
1439
 
  return priv->application;
1440
 
}
1441
 
 
1442
 
void
1443
 
awn_task_set_title(AwnTask *task, AwnTitle *title)
1444
 
{
1445
 
  AwnTaskPrivate *priv;
1446
 
  priv = AWN_TASK_GET_PRIVATE(task);
1447
 
 
1448
 
  priv->title = title;
1449
 
  awn_effects_set_title(priv->effects, title, awn_task_get_title);
1450
 
}
1451
 
 
1452
 
AwnSettings*
1453
 
awn_task_get_settings(AwnTask *task)
1454
 
{
1455
 
  AwnTaskPrivate *priv;
1456
 
  priv = AWN_TASK_GET_PRIVATE(task);
1457
 
  return priv->settings;
1458
 
}
1459
 
 
1460
 
void
1461
 
awn_task_refresh_icon_geometry(AwnTask *task)
1462
 
{
1463
 
  AwnTaskPrivate *priv;
1464
 
  static gint old_x = 0;
1465
 
  static gint old_y = 0;
1466
 
  gint x, y;
1467
 
  gint width, height;
1468
 
 
1469
 
  priv = AWN_TASK_GET_PRIVATE(task);
1470
 
 
1471
 
  if (priv->window == NULL)
1472
 
    return;
1473
 
 
1474
 
  gdk_window_get_origin(GTK_WIDGET(task)->window, &x, &y);
1475
 
 
1476
 
  gdk_drawable_get_size(GDK_DRAWABLE(GTK_WIDGET(task)->window),
1477
 
                        &width, &height);
1478
 
 
1479
 
  //width = priv->icon_width;
1480
 
  //height = priv->icon_height;
1481
 
 
1482
 
  //printf("width: %d, height: %d\n", width, height);
1483
 
 
1484
 
  if ((x != old_x) || (y != old_y))
1485
 
  {
1486
 
    gint res = 0;
1487
 
 
1488
 
    if (x > old_x)
1489
 
      res = x - old_x;
1490
 
    else
1491
 
      res = old_x - x;
1492
 
 
1493
 
    if (res > 10)
1494
 
    {
1495
 
      wnck_window_set_icon_geometry(priv->window, x, y, width, height);
1496
 
    }
1497
 
 
1498
 
    old_x = x;
1499
 
 
1500
 
    old_y = y;
1501
 
  }
1502
 
 
1503
 
}
1504
 
 
1505
 
void
1506
 
awn_task_update_icon(AwnTask *task)
1507
 
{
1508
 
  AwnTaskPrivate *priv;
1509
 
  GdkPixbuf *old = NULL;
1510
 
  GdkPixbuf *old_reflect = NULL;
1511
 
  priv = AWN_TASK_GET_PRIVATE(task);
1512
 
 
1513
 
  old = priv->icon;
1514
 
  old_reflect = priv->reflect;
1515
 
 
1516
 
  int height = priv->settings->bar_height;
1517
 
 
1518
 
  if ((priv->settings->task_width - 12) < height)
1519
 
  {
1520
 
    height = priv->settings->task_width - 12;
1521
 
  }
1522
 
 
1523
 
  priv->icon = awn_x_get_icon_for_launcher(priv->item,
1524
 
 
1525
 
               height, height);
1526
 
 
1527
 
  if (!priv->icon)
1528
 
  {
1529
 
    priv->icon = old;
1530
 
    return;
1531
 
  }
1532
 
 
1533
 
  priv->reflect = gdk_pixbuf_flip(priv->icon, FALSE);
1534
 
 
1535
 
  awn_effects_draw_set_icon_size(priv->effects,
1536
 
                         gdk_pixbuf_get_width(priv->icon),
1537
 
                         gdk_pixbuf_get_height(priv->icon));
1538
 
 
1539
 
  gdk_pixbuf_unref(old);
1540
 
  gdk_pixbuf_unref(old_reflect);
1541
 
}
1542
 
 
1543
 
void
1544
 
awn_task_set_width(AwnTask *task, gint width)
1545
 
{
1546
 
  AwnTaskPrivate *priv;
1547
 
  GdkPixbuf *old = NULL;
1548
 
  GdkPixbuf *old_reflect = NULL;
1549
 
 
1550
 
  if (!AWN_IS_TASK(task))
1551
 
    return;
1552
 
 
1553
 
  g_return_if_fail(AWN_IS_TASK(task));
1554
 
 
1555
 
  priv = AWN_TASK_GET_PRIVATE(task);
1556
 
 
1557
 
  //if (priv->effects.is_closing.state) {
1558
 
  // return;
1559
 
  //}
1560
 
 
1561
 
  old = priv->icon;
1562
 
 
1563
 
  old_reflect = priv->reflect;
1564
 
 
1565
 
  if (priv->is_launcher)
1566
 
  {
1567
 
    char * icon_name = awn_desktop_item_get_icon(priv->item, priv->settings->icon_theme);
1568
 
 
1569
 
    if (!icon_name)
1570
 
    {
1571
 
      priv->icon = awn_x_get_icon_for_window(priv->window, width - 12, width - 12);
1572
 
    }
1573
 
    else
1574
 
    {
1575
 
      priv->icon = awn_x_get_icon_for_launcher(priv->item, width - 12, width - 12);
1576
 
    }
1577
 
 
1578
 
    g_free(icon_name);
1579
 
  }
1580
 
  else
1581
 
  {
1582
 
    if (WNCK_IS_WINDOW(priv->window))
1583
 
    {
1584
 
      priv->icon = awn_x_get_icon_for_window(priv->window, width - 12, width - 12);
1585
 
    }
1586
 
  }
1587
 
 
1588
 
  if (G_IS_OBJECT(priv->icon))
1589
 
  {
1590
 
    priv->reflect = gdk_pixbuf_flip(priv->icon, FALSE);
1591
 
    awn_effects_draw_set_icon_size(priv->effects, gdk_pixbuf_get_width(priv->icon), gdk_pixbuf_get_height(priv->icon));
1592
 
  }
1593
 
 
1594
 
  if (G_IS_OBJECT(old) && (priv->is_launcher || WNCK_IS_WINDOW(priv->window)))
1595
 
    gdk_pixbuf_unref(old);
1596
 
 
1597
 
  if (G_IS_OBJECT(old_reflect))
1598
 
    gdk_pixbuf_unref(old_reflect);
1599
 
 
1600
 
  gtk_widget_set_size_request(GTK_WIDGET(task),
1601
 
                              width,
1602
 
                              (priv->settings->bar_height + 2) * 2);
1603
 
 
1604
 
}
1605
 
 
1606
 
 
1607
 
AwnDesktopItem*
1608
 
awn_task_get_item(AwnTask *task)
1609
 
{
1610
 
  AwnTaskPrivate *priv;
1611
 
  g_return_val_if_fail(AWN_IS_TASK(task), NULL);
1612
 
  priv = AWN_TASK_GET_PRIVATE(task);
1613
 
 
1614
 
  return priv->item;
1615
 
}
1616
 
 
1617
 
/********************* DBUS FUNCTIONS *******************/
1618
 
 
1619
 
void
1620
 
awn_task_set_custom_icon(AwnTask *task, GdkPixbuf *icon)
1621
 
{
1622
 
  AwnTaskPrivate *priv;
1623
 
  GdkPixbuf *old_icon;
1624
 
  GdkPixbuf *old_reflect;
1625
 
 
1626
 
  g_return_if_fail(AWN_IS_TASK(task));
1627
 
 
1628
 
  priv = AWN_TASK_GET_PRIVATE(task);
1629
 
  old_icon = priv->icon;
1630
 
  old_reflect = priv->reflect;
1631
 
 
1632
 
  priv->icon = icon;
1633
 
  priv->reflect = gdk_pixbuf_flip(priv->icon, FALSE);
1634
 
 
1635
 
  awn_effects_draw_set_icon_size(priv->effects, gdk_pixbuf_get_width(priv->icon), gdk_pixbuf_get_height(priv->icon));
1636
 
 
1637
 
  g_object_unref(G_OBJECT(old_icon));
1638
 
  g_object_unref(G_OBJECT(old_reflect));
1639
 
 
1640
 
  gtk_widget_queue_draw(GTK_WIDGET(task));
1641
 
}
1642
 
 
1643
 
void
1644
 
awn_task_unset_custom_icon(AwnTask *task)
1645
 
{
1646
 
  AwnTaskPrivate *priv;
1647
 
  GdkPixbuf *old_icon;
1648
 
  GdkPixbuf *old_reflect;
1649
 
  char *icon_name = NULL;
1650
 
 
1651
 
  g_return_if_fail(AWN_IS_TASK(task));
1652
 
 
1653
 
  priv = AWN_TASK_GET_PRIVATE(task);
1654
 
  old_icon = priv->icon;
1655
 
  old_reflect = priv->reflect;
1656
 
 
1657
 
  if (priv->is_launcher)
1658
 
  {
1659
 
    icon_name = awn_desktop_item_get_icon(priv->item, priv->settings->icon_theme);
1660
 
 
1661
 
    if (!icon_name)
1662
 
    {
1663
 
      priv->icon = awn_x_get_icon_for_window(priv->window, priv->settings->task_width - 12, priv->settings->task_width - 12);
1664
 
    }
1665
 
    else
1666
 
    {
1667
 
      priv->icon = awn_x_get_icon_for_launcher(priv->item, priv->settings->task_width - 12, priv->settings->task_width - 12);
1668
 
    }
1669
 
 
1670
 
    g_free(icon_name);
1671
 
  }
1672
 
  else
1673
 
  {
1674
 
    priv->icon = awn_x_get_icon_for_window(priv->window, priv->settings->bar_height, priv->settings->bar_height);
1675
 
  }
1676
 
 
1677
 
  priv->reflect = gdk_pixbuf_flip(priv->icon, FALSE);
1678
 
 
1679
 
  awn_effects_draw_set_icon_size(priv->effects, gdk_pixbuf_get_width(priv->icon), gdk_pixbuf_get_height(priv->icon));
1680
 
 
1681
 
  g_object_unref(G_OBJECT(old_icon));
1682
 
  g_object_unref(G_OBJECT(old_reflect));
1683
 
 
1684
 
  gtk_widget_queue_draw(GTK_WIDGET(task));
1685
 
}
1686
 
 
1687
 
void
1688
 
awn_task_set_progress(AwnTask *task, gint progress)
1689
 
{
1690
 
  AwnTaskPrivate *priv;
1691
 
 
1692
 
  g_return_if_fail(AWN_IS_TASK(task));
1693
 
 
1694
 
  priv = AWN_TASK_GET_PRIVATE(task);
1695
 
 
1696
 
  if ((progress < 101) && (progress >= 0))
1697
 
    priv->progress = progress;
1698
 
  else
1699
 
    priv->progress = 100;
1700
 
 
1701
 
  gtk_widget_queue_draw(GTK_WIDGET(task));
1702
 
}
1703
 
 
1704
 
void
1705
 
awn_task_set_info(AwnTask *task, const gchar *info)
1706
 
{
1707
 
  AwnTaskPrivate *priv;
1708
 
 
1709
 
  g_return_if_fail(AWN_IS_TASK(task));
1710
 
 
1711
 
  priv = AWN_TASK_GET_PRIVATE(task);
1712
 
 
1713
 
  if (priv->info_text)
1714
 
  {
1715
 
    g_free(priv->info_text);
1716
 
    priv->info_text = NULL;
1717
 
  }
1718
 
 
1719
 
  priv->info = TRUE;
1720
 
 
1721
 
  priv->info_text = g_strdup(info);
1722
 
 
1723
 
  gtk_widget_queue_draw(GTK_WIDGET(task));
1724
 
}
1725
 
 
1726
 
void
1727
 
awn_task_unset_info(AwnTask *task)
1728
 
{
1729
 
  AwnTaskPrivate *priv;
1730
 
 
1731
 
  g_return_if_fail(AWN_IS_TASK(task));
1732
 
 
1733
 
  priv = AWN_TASK_GET_PRIVATE(task);
1734
 
 
1735
 
  priv->info = FALSE;
1736
 
 
1737
 
  if (priv->info_text)
1738
 
  {
1739
 
    g_free(priv->info_text);
1740
 
    priv->info_text = NULL;
1741
 
  }
1742
 
 
1743
 
  gtk_widget_queue_draw(GTK_WIDGET(task));
1744
 
}
1745
 
 
1746
 
gint
1747
 
awn_task_add_menu_item(AwnTask *task, GtkMenuItem *item)
1748
 
{
1749
 
  AwnTaskPrivate *priv;
1750
 
  AwnTaskMenuItem *menu_item;
1751
 
 
1752
 
  g_return_val_if_fail(AWN_IS_TASK(task), 0);
1753
 
 
1754
 
  priv = AWN_TASK_GET_PRIVATE(task);
1755
 
 
1756
 
  int i;
1757
 
 
1758
 
  for (i = 0; i < 5; i++)
1759
 
  {
1760
 
    if (priv->menu_items[i] == NULL)
1761
 
    {
1762
 
      g_object_ref(G_OBJECT(item));
1763
 
      menu_item = g_new0(AwnTaskMenuItem, 1);
1764
 
      menu_item->type = AWN_TASK_MENU_TYPE_NORMAL;
1765
 
      menu_item->item = GTK_WIDGET(item);
1766
 
      menu_item->active = FALSE;
1767
 
      priv->menu_items[i] = menu_item;
1768
 
      menu_item->id =  menu_item_id++;
1769
 
      return menu_item->id;
1770
 
    }
1771
 
  }
1772
 
 
1773
 
  return 0;
1774
 
}
1775
 
 
1776
 
gint
1777
 
awn_task_add_check_item(AwnTask *task, GtkMenuItem *item)
1778
 
{
1779
 
  AwnTaskPrivate *priv;
1780
 
  AwnTaskMenuItem *menu_item;
1781
 
 
1782
 
  g_return_val_if_fail(AWN_IS_TASK(task), 0);
1783
 
 
1784
 
  priv = AWN_TASK_GET_PRIVATE(task);
1785
 
 
1786
 
  int i;
1787
 
 
1788
 
  for (i = 0; i < 5; i++)
1789
 
  {
1790
 
    if (priv->menu_items[i] == NULL)
1791
 
    {
1792
 
      g_object_ref(G_OBJECT(item));
1793
 
      menu_item = g_new0(AwnTaskMenuItem, 1);
1794
 
      menu_item->type = AWN_TASK_MENU_TYPE_CHECK;
1795
 
      menu_item->item = GTK_WIDGET(item);
1796
 
      menu_item->active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item));
1797
 
      priv->menu_items[i] = menu_item;
1798
 
      menu_item->id =  menu_item_id++;
1799
 
      return menu_item->id;
1800
 
    }
1801
 
  }
1802
 
 
1803
 
  return 0;
1804
 
}
1805
 
 
1806
 
void
1807
 
awn_task_set_check_item(AwnTask *task, gint id, gboolean active)
1808
 
{
1809
 
  AwnTaskPrivate *priv;
1810
 
  AwnTaskMenuItem *menu_item;
1811
 
 
1812
 
  g_return_if_fail(AWN_IS_TASK(task));
1813
 
 
1814
 
  priv = AWN_TASK_GET_PRIVATE(task);
1815
 
  int i;
1816
 
 
1817
 
  for (i = 0; i < 5; i++)
1818
 
  {
1819
 
    menu_item = priv->menu_items[i];
1820
 
 
1821
 
    if (menu_item != NULL)
1822
 
    {
1823
 
      if (menu_item->id == id)
1824
 
      {
1825
 
        menu_item->active = active;
1826
 
      }
1827
 
    }
1828
 
  }
1829
 
}
1830
 
 
1831
 
/********************* MISC FUNCTIONS *******************/
1832
 
 
1833
 
typedef struct _FileChooserAndTask FileChooserAndTask;
1834
 
 
1835
 
struct _FileChooserAndTask
1836
 
{
1837
 
  GtkWidget *filechooser;
1838
 
  AwnTask *task;
1839
 
};
1840
 
 
1841
 
 
1842
 
static void _task_choose_custom_icon_performed(GtkWidget *dialog, gint res, FileChooserAndTask *fct)
1843
 
{
1844
 
 
1845
 
  AwnTaskPrivate *priv;
1846
 
  GdkPixbuf *pixbuf = NULL;
1847
 
  GError *err = NULL;
1848
 
  gchar *filename = NULL;
1849
 
  gchar *save = NULL;
1850
 
  gchar *name = NULL;
1851
 
  AwnTask *task = fct->task;
1852
 
  int i;
1853
 
 
1854
 
  g_return_if_fail(AWN_IS_TASK(task));
1855
 
  priv = AWN_TASK_GET_PRIVATE(task);
1856
 
 
1857
 
  filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fct->filechooser));
1858
 
  g_free(fct);
1859
 
  gtk_widget_hide(dialog);
1860
 
  gtk_widget_destroy(dialog);
1861
 
 
1862
 
  /* If not accept, clean up and return */
1863
 
 
1864
 
  if (res != GTK_RESPONSE_ACCEPT)
1865
 
  {
1866
 
    return;
1867
 
  }
1868
 
 
1869
 
  /* Okay, the user has chosen a new icon, so lets load it up */
1870
 
 
1871
 
  pixbuf = gdk_pixbuf_new_from_file_at_size(filename, priv->settings->bar_height, priv->settings->bar_height, &err);
1872
 
 
1873
 
  g_free(filename);
1874
 
 
1875
 
  /* Check if is actually a pixbuf */
1876
 
  if (pixbuf == NULL)
1877
 
  {
1878
 
    g_warning("Failed to load pixbuf (%s)\n", err->message);
1879
 
    g_error_free(err);
1880
 
    return;
1881
 
  }
1882
 
 
1883
 
  /* So we have a nice new pixbuf, we now want to save it's location
1884
 
     for the future */
1885
 
  if (priv->is_launcher)
1886
 
  {
1887
 
    name = g_strdup(awn_desktop_item_get_exec(priv->item));
1888
 
  }
1889
 
  else
1890
 
  {
1891
 
    WnckApplication *app = NULL;
1892
 
    app = wnck_window_get_application(priv->window);
1893
 
 
1894
 
    if (app == NULL)
1895
 
    {
1896
 
      name = NULL;
1897
 
    }
1898
 
    else
1899
 
    {
1900
 
      GString *gname = awn_x_get_application_name(priv->window, app);
1901
 
      name = g_strdup(gname->str);
1902
 
      g_string_free(gname, TRUE);
1903
 
    }
1904
 
  }
1905
 
 
1906
 
  if (name == NULL)
1907
 
  {
1908
 
    /* Somethings gone very wrong */
1909
 
    return;
1910
 
  }
1911
 
 
1912
 
  /* Replace spaces with dashs */
1913
 
  for (i = 0; i < strlen(name); i++)
1914
 
  {
1915
 
    if (name[i] == ' ' || name[i] == '/')
1916
 
      name[i] = '-';
1917
 
  }
1918
 
 
1919
 
  /* Now lets build the save-filename and save it */
1920
 
  save = g_build_filename(g_get_home_dir(),
1921
 
                          PIXBUF_SAVE_PATH,
1922
 
                          name,
1923
 
                          NULL);
1924
 
 
1925
 
  gdk_pixbuf_save(pixbuf, save, "png", &err, NULL);
1926
 
 
1927
 
  g_free(save);
1928
 
 
1929
 
  if (err)
1930
 
  {
1931
 
    g_print("%s\n", err->message);
1932
 
    g_error_free(err);
1933
 
    return;
1934
 
  }
1935
 
 
1936
 
  /* Now we have saved the new pixbuf, lets actually set it as the main
1937
 
     pixbuf and refresh the view */
1938
 
  g_object_unref(G_OBJECT(priv->icon));
1939
 
 
1940
 
  g_object_unref(G_OBJECT(priv->reflect));
1941
 
 
1942
 
  priv->icon = pixbuf;
1943
 
 
1944
 
  priv->reflect = gdk_pixbuf_flip(priv->icon, FALSE);
1945
 
 
1946
 
  awn_effects_draw_set_icon_size(priv->effects, gdk_pixbuf_get_width(priv->icon), gdk_pixbuf_get_height(priv->icon));
1947
 
 
1948
 
  gtk_widget_queue_draw(GTK_WIDGET(task));
1949
 
 
1950
 
  g_free(name);
1951
 
}
1952
 
 
1953
 
static void
1954
 
_task_choose_custom_icon(AwnTask *task)
1955
 
{
1956
 
#define PIXBUF_SAVE_PATH ".config/awn/custom-icons"
1957
 
 
1958
 
  AwnTaskPrivate *priv;
1959
 
  GtkWidget *file;
1960
 
 
1961
 
  g_return_if_fail(AWN_IS_TASK(task));
1962
 
  priv = AWN_TASK_GET_PRIVATE(task);
1963
 
 
1964
 
  /* Create the dialog */
1965
 
  file = gtk_file_chooser_dialog_new(_("Choose New Image..."),
1966
 
                                     GTK_WINDOW(priv->settings->window),
1967
 
                                     GTK_FILE_CHOOSER_ACTION_OPEN,
1968
 
                                     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1969
 
                                     GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
1970
 
                                     NULL);
1971
 
 
1972
 
  FileChooserAndTask *fct = g_new(FileChooserAndTask, 1);
1973
 
  fct->filechooser = file;
1974
 
  fct->task = task;
1975
 
 
1976
 
  g_signal_connect(file, "response", G_CALLBACK(_task_choose_custom_icon_performed), (gpointer)fct);
1977
 
 
1978
 
  /* Run it */
1979
 
  gtk_widget_show_all(file);
1980
 
}
1981
 
 
1982
 
static void
1983
 
_task_menu_item_clicked(GtkMenuItem *item, AwnTask *task)
1984
 
{
1985
 
  AwnTaskPrivate *priv;
1986
 
  AwnTaskMenuItem *menu_item;
1987
 
  int i;
1988
 
 
1989
 
  priv = AWN_TASK_GET_PRIVATE(task);
1990
 
 
1991
 
  for (i = 0; i < 5; i++)
1992
 
  {
1993
 
    menu_item = priv->menu_items[i];
1994
 
 
1995
 
    if (menu_item != NULL)
1996
 
    {
1997
 
      if (GTK_MENU_ITEM(menu_item->item) == item)
1998
 
      {
1999
 
        g_signal_emit(G_OBJECT(task), awn_task_signals[MENU_ITEM_CLICKED], 0,
2000
 
                      (guint) menu_item->id);
2001
 
      }
2002
 
    }
2003
 
  }
2004
 
 
2005
 
}
2006
 
 
2007
 
 
2008
 
static void
2009
 
_task_check_item_clicked(GtkMenuItem *item, AwnTask *task)
2010
 
{
2011
 
  AwnTaskPrivate *priv;
2012
 
  AwnTaskMenuItem *menu_item;
2013
 
  gboolean active;
2014
 
  int i;
2015
 
 
2016
 
  priv = AWN_TASK_GET_PRIVATE(task);
2017
 
 
2018
 
  active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item));
2019
 
 
2020
 
  for (i = 0; i < 5; i++)
2021
 
  {
2022
 
    menu_item = priv->menu_items[i];
2023
 
 
2024
 
    if (menu_item != NULL)
2025
 
    {
2026
 
      if (GTK_MENU_ITEM(menu_item->item) == item)
2027
 
      {
2028
 
        g_signal_emit(G_OBJECT(task), awn_task_signals[CHECK_ITEM_CLICKED], 0,
2029
 
                      (guint) menu_item->id, active);
2030
 
        menu_item->active  = active;
2031
 
      }
2032
 
    }
2033
 
  }
2034
 
 
2035
 
}
2036
 
 
2037
 
static void
2038
 
on_change_icon_clicked(GtkButton *button, AwnTask *task)
2039
 
{
2040
 
  _task_choose_custom_icon(task);
2041
 
}
2042
 
 
2043
 
static void
2044
 
_task_show_prefs(GtkMenuItem *item, AwnTask *task)
2045
 
{
2046
 
  _task_choose_custom_icon(task);
2047
 
  return;
2048
 
 
2049
 
  AwnTaskPrivate *priv;
2050
 
  priv = AWN_TASK_GET_PRIVATE(task);
2051
 
 
2052
 
  GtkWidget *dialog;
2053
 
  GtkWidget *hbox;
2054
 
  GtkWidget *image;
2055
 
  GtkWidget *button, *label;
2056
 
 
2057
 
  dialog = gtk_dialog_new_with_buttons(_("Preferences"),
2058
 
                                       GTK_WINDOW(priv->settings->window),
2059
 
                                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
2060
 
                                       _("Change Icon..."),
2061
 
                                       3,
2062
 
                                       GTK_STOCK_CANCEL,
2063
 
                                       GTK_RESPONSE_REJECT,
2064
 
                                       GTK_STOCK_OK,
2065
 
                                       GTK_RESPONSE_ACCEPT,
2066
 
                                       NULL);
2067
 
  hbox = gtk_hbox_new(FALSE, 10);
2068
 
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0);
2069
 
 
2070
 
  image = gtk_image_new_from_pixbuf(priv->icon);
2071
 
 
2072
 
  button = gtk_button_new_with_label(_("Change Image..."));
2073
 
  gtk_button_set_image(GTK_BUTTON(button), image);
2074
 
  gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 0);
2075
 
 
2076
 
  g_signal_connect(G_OBJECT(button), "clicked",
2077
 
                   G_CALLBACK(on_change_icon_clicked), task);
2078
 
 
2079
 
  label = gtk_label_new(" ");
2080
 
  char *app_name = (char*)awn_task_get_application(task);
2081
 
 
2082
 
  if (app_name)
2083
 
  {
2084
 
    gchar *markup = g_strdup_printf("<span size='larger' weight='bold'>%s</span>", app_name);
2085
 
    gtk_label_set_markup(GTK_LABEL(label), markup);
2086
 
    g_free(markup);
2087
 
  }
2088
 
 
2089
 
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
2090
 
 
2091
 
  gtk_widget_show_all(hbox);
2092
 
 
2093
 
  gint res = gtk_dialog_run(GTK_DIALOG(dialog));
2094
 
 
2095
 
  switch (res)
2096
 
  {
2097
 
 
2098
 
    case 3:
2099
 
      _task_choose_custom_icon(task);
2100
 
      break;
2101
 
 
2102
 
    default:
2103
 
      break;
2104
 
  }
2105
 
 
2106
 
  gtk_widget_destroy(dialog);
2107
 
}
2108
 
 
2109
 
 
2110
 
 
2111
 
typedef struct
2112
 
{
2113
 
  const char *uri;
2114
 
  AwnSettings *settings;
2115
 
 
2116
 
} AwnListTerm;
2117
 
 
2118
 
static void
2119
 
_slist_foreach(char *uri, AwnListTerm *term)
2120
 
{
2121
 
  AwnSettings *settings = term->settings;
2122
 
 
2123
 
  if (strcmp(uri, term->uri) == 0)
2124
 
  {
2125
 
    //g_print ("URI : %s\n", uri);
2126
 
    settings->launchers = g_slist_remove(settings->launchers, uri);
2127
 
    //g_slist_foreach(settings->launchers, (GFunc)_slist_print, (gpointer)term);
2128
 
  }
2129
 
}
2130
 
 
2131
 
void awn_task_remove(AwnTask *task)
2132
 
{
2133
 
  AwnTaskPrivate *priv = AWN_TASK_GET_PRIVATE(task);
2134
 
 
2135
 
  priv->window = NULL;
2136
 
  /* start closing effect */
2137
 
  awn_effects_start_ex(priv->effects, 
2138
 
                       AWN_EFFECT_CLOSING, NULL, _task_destroy, 1);
2139
 
}
2140
 
 
2141
 
static void
2142
 
_task_remove_launcher(GtkMenuItem *item, AwnTask *task)
2143
 
{
2144
 
  AwnTaskPrivate *priv;
2145
 
  AwnSettings *settings;
2146
 
  AwnListTerm term;
2147
 
  gchar *uri;
2148
 
 
2149
 
  priv = AWN_TASK_GET_PRIVATE(task);
2150
 
  settings = priv->settings;
2151
 
 
2152
 
  uri = awn_desktop_item_get_filename(priv->item);
2153
 
 
2154
 
  g_print("Remove : %s\n", uri);
2155
 
  term.uri = uri;
2156
 
  term.settings = settings;
2157
 
  g_slist_foreach(settings->launchers, (GFunc)_slist_foreach, (gpointer)&term);
2158
 
 
2159
 
  AwnConfigClient *client = awn_config_client_new();
2160
 
  awn_config_client_set_list(client, "window_manager", "launchers",
2161
 
                             AWN_CONFIG_CLIENT_LIST_TYPE_STRING, settings->launchers, NULL);
2162
 
 
2163
 
  awn_task_remove (task);
2164
 
}
2165
 
 
2166
 
static void
2167
 
_shell_done(GtkMenuShell *shell, AwnTask *task)
2168
 
{
2169
 
  AwnTaskPrivate *priv;
2170
 
  priv = AWN_TASK_GET_PRIVATE(task);
2171
 
 
2172
 
  if (priv->settings->auto_hide == FALSE)
2173
 
  {
2174
 
    if (priv->settings->hidden == TRUE)
2175
 
    {
2176
 
      awn_show(priv->settings);
2177
 
    }
2178
 
 
2179
 
    return;
2180
 
  }
2181
 
 
2182
 
  awn_hide(priv->settings);
2183
 
}
2184
 
 
2185
 
static void
2186
 
awn_task_create_menu(AwnTask *task, GtkMenu *menu)
2187
 
{
2188
 
  AwnTaskPrivate *priv;
2189
 
  GtkWidget *item;
2190
 
 
2191
 
  priv = AWN_TASK_GET_PRIVATE(task);
2192
 
  item = NULL;
2193
 
 
2194
 
  g_signal_connect(GTK_MENU_SHELL(menu), "selection-done",
2195
 
                   G_CALLBACK(_shell_done), (gpointer)task);
2196
 
 
2197
 
  if (priv->is_launcher && priv->window == NULL)
2198
 
  {
2199
 
 
2200
 
 
2201
 
    item = gtk_image_menu_item_new_from_stock("gtk-remove",
2202
 
           NULL);
2203
 
    gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
2204
 
    gtk_widget_show(item);
2205
 
    g_signal_connect(G_OBJECT(item), "activate",
2206
 
                     G_CALLBACK(_task_remove_launcher), (gpointer)task);
2207
 
  }
2208
 
 
2209
 
  item = gtk_separator_menu_item_new();
2210
 
 
2211
 
  gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
2212
 
  gtk_widget_show(item);
2213
 
 
2214
 
  item = gtk_menu_item_new_with_label(_("Change Icon"));
2215
 
  gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
2216
 
  gtk_widget_show(item);
2217
 
  g_signal_connect(G_OBJECT(item), "activate",
2218
 
                   G_CALLBACK(_task_show_prefs), (gpointer)task);
2219
 
 
2220
 
  AwnTaskMenuItem *menu_item;
2221
 
  int i = 0;
2222
 
 
2223
 
  for (i = 0; i < 5; i++)
2224
 
  {
2225
 
    menu_item = priv->menu_items[i];
2226
 
 
2227
 
    if (menu_item != NULL)
2228
 
    {
2229
 
 
2230
 
      if (i == 0)
2231
 
      {
2232
 
        item = gtk_separator_menu_item_new();
2233
 
        gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
2234
 
        gtk_widget_show(item);
2235
 
      }
2236
 
 
2237
 
 
2238
 
      g_signal_handlers_disconnect_by_func(G_OBJECT(menu_item->item),
2239
 
 
2240
 
                                           _task_menu_item_clicked, (gpointer)task);
2241
 
      g_signal_handlers_disconnect_by_func(G_OBJECT(menu_item->item),
2242
 
                                           _task_check_item_clicked, (gpointer)task);
2243
 
      gtk_widget_unparent(menu_item->item);
2244
 
      gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), menu_item->item);
2245
 
 
2246
 
      if (menu_item->type == AWN_TASK_MENU_TYPE_CHECK)
2247
 
      {
2248
 
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item->item),
2249
 
                                       menu_item->active);
2250
 
        g_signal_connect(G_OBJECT(menu_item->item), "activate",
2251
 
                         G_CALLBACK(_task_check_item_clicked), (gpointer)task);
2252
 
      }
2253
 
      else
2254
 
      {
2255
 
        g_signal_connect(G_OBJECT(menu_item->item), "activate",
2256
 
                         G_CALLBACK(_task_menu_item_clicked), (gpointer) task);
2257
 
      }
2258
 
 
2259
 
      gtk_widget_show(menu_item->item);
2260
 
 
2261
 
    }
2262
 
  }
2263
 
 
2264
 
  item = gtk_image_menu_item_new_with_label(_("Dock Preferences"));
2265
 
 
2266
 
  gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
2267
 
                                gtk_image_new_from_stock(GTK_STOCK_PREFERENCES,
2268
 
                                                         GTK_ICON_SIZE_MENU));
2269
 
 
2270
 
  gtk_widget_show_all(item);
2271
 
  gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
2272
 
  g_signal_connect(G_OBJECT(item), "activate",
2273
 
                   G_CALLBACK(awn_start_awn_manager), NULL);
2274
 
 
2275
 
 
2276
 
}
2277
 
 
2278
 
/********************* awn_task_new * *******************/
2279
 
 
2280
 
GtkWidget *
2281
 
awn_task_new(AwnTaskManager *task_manager, AwnSettings *settings)
2282
 
{
2283
 
  GtkWidget *task;
2284
 
  AwnTaskPrivate *priv;
2285
 
  task = g_object_new(AWN_TYPE_TASK, NULL);
2286
 
  priv = AWN_TASK_GET_PRIVATE(task);
2287
 
 
2288
 
  priv->task_manager = task_manager;
2289
 
  priv->settings = settings;
2290
 
 
2291
 
  /* This is code which I will add later for better hover effects over
2292
 
  the bar */
2293
 
  g_signal_connect(G_OBJECT(task), "drag-data-received",
2294
 
                   G_CALLBACK(_task_drag_data_recieved), (gpointer)task);
2295
 
  g_signal_connect(G_OBJECT(task), "drag-end",
2296
 
                   G_CALLBACK(_task_drag_data_recieved), (gpointer)task);
2297
 
 
2298
 
  _task_refresh(GTK_WIDGET(task));
2299
 
 
2300
 
  return task;
2301
 
}
2302
 
 
2303
 
void
2304
 
awn_task_close(AwnTask *task)
2305
 
{
2306
 
  AwnTaskPrivate *priv;
2307
 
  priv = AWN_TASK_GET_PRIVATE(task);
2308
 
 
2309
 
  if (priv->icon_changed) {
2310
 
    g_signal_handler_disconnect((gpointer)priv->window,
2311
 
                              priv->icon_changed);
2312
 
    priv->icon_changed = 0;
2313
 
  }
2314
 
  if (priv->state_changed) {
2315
 
    g_signal_handler_disconnect((gpointer)priv->window,
2316
 
                              priv->state_changed);
2317
 
    priv->state_changed = 0;
2318
 
  }
2319
 
  if (priv->name_changed) {
2320
 
    g_signal_handler_disconnect((gpointer)priv->window,
2321
 
                              priv->name_changed);
2322
 
    priv->name_changed = 0;
2323
 
  }
2324
 
  if (priv->geometry_changed) {
2325
 
    g_signal_handler_disconnect((gpointer)priv->window,
2326
 
                              priv->geometry_changed);
2327
 
    priv->geometry_changed = 0;
2328
 
  }
2329
 
 
2330
 
  priv->window = NULL;
2331
 
 
2332
 
  AwnTaskMenuItem *item;
2333
 
  int i;
2334
 
 
2335
 
  for (i = 0; i < 5; i++)
2336
 
  {
2337
 
    item = priv->menu_items[i];
2338
 
 
2339
 
    if (item != NULL)
2340
 
    {
2341
 
      if (GTK_IS_WIDGET(item->item))
2342
 
        gtk_widget_destroy(item->item);
2343
 
 
2344
 
      if (item)
2345
 
        g_free(item);
2346
 
 
2347
 
      item = priv->menu_items[i] = NULL;
2348
 
    }
2349
 
 
2350
 
  }
2351
 
 
2352
 
 
2353
 
  if (priv->is_launcher)
2354
 
  {
2355
 
    gtk_widget_queue_draw(GTK_WIDGET(task));
2356
 
    return;
2357
 
  }
2358
 
 
2359
 
  /* start closing effect */
2360
 
  awn_effects_start_ex(priv->effects, AWN_EFFECT_CLOSING,
2361
 
                      NULL, _task_destroy, 1);
2362
 
}
2363
 
 
2364
 
 
2365
 
 
2366
 
 
2367
 
 
2368