~ubuntu-branches/ubuntu/maverick/awn-extras-applets/maverick

« back to all changes in this revision

Viewing changes to applets/maintained/indicator-applet/applet.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien Lavergne
  • Date: 2010-08-29 14:29:52 UTC
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: james.westby@ubuntu.com-20100829142952-rhvuetyms9bv5uu7
Tags: upstream-0.4.0+bzr1372
ImportĀ upstreamĀ versionĀ 0.4.0+bzr1372

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2010 Sharkbaitbobby <sharkbaitbobby+awn@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
*/
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include <config.h>
 
22
#endif
 
23
 
 
24
#include <gtk/gtk.h>
 
25
#include <glib/gi18n-lib.h>
 
26
#include <libawn/libawn.h>
 
27
#include <libindicator/indicator-object.h>
 
28
 
 
29
typedef struct _IndicatorApplet IndicatorApplet;
 
30
struct _IndicatorApplet {
 
31
  AwnApplet *applet;
 
32
  GtkWidget *da;
 
33
  GtkWidget *icon_box;
 
34
  GtkWidget *awn_menu;
 
35
  GtkDialog *dialog;
 
36
 
 
37
  IndicatorObject *io;
 
38
 
 
39
  DesktopAgnosticConfigClient *config;
 
40
  gint config_rows_cols;
 
41
  gboolean config_ind_app;
 
42
  gboolean config_ind_app_ses;
 
43
  gboolean config_me;
 
44
  gboolean config_messaging;
 
45
  gboolean config_network;
 
46
  gboolean config_sound;
 
47
  gboolean config_other_menus;
 
48
  gboolean applet_mode;
 
49
 
 
50
  GList *images;
 
51
  GList *menus;
 
52
  GList *shown_images;
 
53
  GList *shown_menus;
 
54
  GList *awnicons;
 
55
 
 
56
  gint num;
 
57
  gint popup_num;
 
58
  gint last_num;
 
59
  gint dx;
 
60
  gint dy;
 
61
};
 
62
 
 
63
static gboolean icon_button_press(AwnIcon *icon, GdkEventButton *event, IndicatorApplet *iapplet);
 
64
static gboolean icon_right_click(AwnIcon *icon, GdkEventButton *event, IndicatorApplet *iapplet);
 
65
static gboolean icon_scroll(AwnIcon *icon, GdkEventScroll *event, IndicatorApplet *iapplet);
 
66
static void get_shown_entries(IndicatorApplet *iapplet);
 
67
static void resize_da(IndicatorApplet *iapplet);
 
68
static void update_config(IndicatorApplet *iapplet);
 
69
static void update_icon_mode(IndicatorApplet *iapplet);
 
70
 
 
71
void
 
72
show_about(GtkMenuItem *item, gpointer user_data)
 
73
{
 
74
  const gchar *license = "This program is free software; you can redistribute \
 
75
it and/or modify it under the terms of the GNU General Public License as \
 
76
published by the Free Software Foundation; either version 2 of the License, \
 
77
or (at your option) any later version.\n\nThis program is distributed in the \
 
78
hope that it will be useful, but WITHOUT ANY WARRANTY; without even the \
 
79
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. \
 
80
See the GNU General Public License for more details.\n\nYou should have \
 
81
received a copy of the GNU General Public License along with this program; \
 
82
if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth \
 
83
Floor, Boston, MA 02110-1301  USA.";
 
84
  const gchar *authors[] = {"Sharkbaitbobby <sharkbaitbobby+awn@gmail.com>",
 
85
                            NULL};
 
86
 
 
87
  GtkWidget *about = gtk_about_dialog_new();
 
88
 
 
89
  gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about), "Indicator Applet");
 
90
  gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about), VERSION);
 
91
  gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about),
 
92
                                _("An applet to hold all of the system indicators"));
 
93
  gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about),
 
94
                                 "Copyright \xc2\xa9 2010 Sharkbaitbobby");
 
95
  gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(about), "indicator-applet");
 
96
  gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about), license);
 
97
  gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(about), TRUE);
 
98
  gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about), authors);
 
99
  gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),
 
100
                               "http://wiki.awn-project.org/Indicator_Applet");
 
101
  gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(about),
 
102
                                     "wiki.awn-project.org");
 
103
 
 
104
  gtk_window_set_icon_name(GTK_WINDOW(about), "indicator-applet");
 
105
 
 
106
  gtk_dialog_run(GTK_DIALOG(about));
 
107
  gtk_widget_destroy(about);
 
108
}
 
109
 
 
110
/* Preferences dialog ... */
 
111
static gboolean
 
112
check_toggled(GtkToggleButton *button, IndicatorApplet *iapplet)
 
113
{
 
114
  desktop_agnostic_config_client_set_bool(iapplet->config,
 
115
                                          DESKTOP_AGNOSTIC_CONFIG_GROUP_DEFAULT,
 
116
                                          (gchar*)g_object_get_data(G_OBJECT(button), "ldakey"),
 
117
                                          gtk_toggle_button_get_active(button), NULL);
 
118
  update_config(iapplet);
 
119
  get_shown_entries(iapplet);
 
120
 
 
121
  update_icon_mode(iapplet);
 
122
 
 
123
  return FALSE;
 
124
}
 
125
 
 
126
static gboolean
 
127
applet_mode_check_toggled(GtkToggleButton *button, IndicatorApplet *iapplet)
 
128
{
 
129
  desktop_agnostic_config_client_set_bool(iapplet->config,
 
130
                                          DESKTOP_AGNOSTIC_CONFIG_GROUP_DEFAULT,
 
131
                                          "applet_icon_mode", gtk_toggle_button_get_active(button),
 
132
                                          NULL);
 
133
 
 
134
  update_config(iapplet);
 
135
  update_icon_mode(iapplet);
 
136
}
 
137
 
 
138
static GtkWidget*
 
139
make_check_button(IndicatorApplet *iapplet,
 
140
                  gchar *label,
 
141
                  gchar *key,
 
142
                  gboolean enabled,
 
143
                  GtkWidget *box)
 
144
{
 
145
  GtkWidget *check = gtk_check_button_new_with_label(label);
 
146
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), enabled);
 
147
  g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(check_toggled), (gpointer)iapplet);
 
148
  g_object_set_data(G_OBJECT(check), "ldakey", key);
 
149
  gtk_box_pack_start(GTK_BOX(box), check, FALSE, FALSE, 0);
 
150
}
 
151
 
 
152
static gboolean
 
153
spin_changed(GtkSpinButton *spin, IndicatorApplet *iapplet)
 
154
{
 
155
  desktop_agnostic_config_client_set_int(iapplet->config,
 
156
                                         DESKTOP_AGNOSTIC_CONFIG_GROUP_DEFAULT,
 
157
                                         "rows_cols", (gint)gtk_spin_button_get_value(spin),
 
158
                                         NULL);
 
159
  update_config(iapplet);
 
160
 
 
161
  if (!iapplet->applet_mode)
 
162
  {
 
163
    resize_da(iapplet);
 
164
  }
 
165
}
 
166
 
 
167
static void
 
168
show_prefs(GtkMenuItem *item, IndicatorApplet *iapplet)
 
169
{
 
170
  GtkDialog *win = GTK_DIALOG(gtk_dialog_new_with_buttons(_("Indicator Applet Preferences"),
 
171
                              NULL, GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
 
172
                              NULL));
 
173
 
 
174
  iapplet->dialog = win;
 
175
 
 
176
  GtkWidget *label = gtk_label_new(NULL);
 
177
  gtk_label_set_markup(GTK_LABEL(label), g_strdup_printf("<b>%s</b>", _("Enabled Entries")));
 
178
  gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
 
179
  gtk_box_pack_start(GTK_BOX(win->vbox), label, FALSE, FALSE, 0);
 
180
 
 
181
  GtkWidget *vbox = gtk_vbox_new(FALSE, 3);
 
182
  make_check_button(iapplet, _("Indicator Applet"),
 
183
                    "indicator_applet", iapplet->config_ind_app, vbox);
 
184
  make_check_button(iapplet, _("Indicator Applet Session (Quit)"),
 
185
                    "indicator_applet_session", iapplet->config_ind_app_ses, vbox);
 
186
  make_check_button(iapplet, _("Me Menu"),
 
187
                    "me_menu", iapplet->config_me, vbox);
 
188
  make_check_button(iapplet, _("Messaging Menu"),
 
189
                    "messaging_menu", iapplet->config_messaging, vbox);
 
190
  make_check_button(iapplet, _("Network Menu"),
 
191
                    "network_menu", iapplet->config_network, vbox);
 
192
  make_check_button(iapplet, _("Sound Control Menu"),
 
193
                    "sound_menu", iapplet->config_sound, vbox);
 
194
  make_check_button(iapplet, _("Other Menus"),
 
195
                    "other_menus", iapplet->config_other_menus, vbox);
 
196
 
 
197
  GtkWidget *align = gtk_alignment_new(0.0, 0.5, 1.0, 0.0);
 
198
  gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, 12, 0);
 
199
  gtk_container_add(GTK_CONTAINER(align), vbox);
 
200
 
 
201
  gtk_box_pack_start(GTK_BOX(win->vbox), align, FALSE, FALSE, 0);
 
202
 
 
203
  label = gtk_label_new(NULL);
 
204
  gtk_label_set_markup(GTK_LABEL(label), g_strdup_printf("<b>%s</b>", _("Options")));
 
205
  gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
 
206
  gtk_box_pack_start(GTK_BOX(win->vbox), label, FALSE, FALSE, 0);
 
207
 
 
208
  vbox = gtk_vbox_new(FALSE, 3);
 
209
  GtkPositionType pos = awn_applet_get_pos_type(iapplet->applet);
 
210
  if (pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM)
 
211
  {
 
212
    label = gtk_label_new(_("Number of rows:"));
 
213
  }
 
214
  else
 
215
  {
 
216
    label = gtk_label_new(_("Number of columns:"));
 
217
  }
 
218
  GtkWidget *spin = gtk_spin_button_new_with_range(1.0, 3.0, 1.0);
 
219
  gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 0);
 
220
  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), (gdouble)iapplet->config_rows_cols);
 
221
  g_signal_connect(G_OBJECT(spin), "value-changed", G_CALLBACK(spin_changed), (gpointer)iapplet);
 
222
 
 
223
  GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
 
224
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
225
  gtk_box_pack_end(GTK_BOX(hbox), spin, FALSE, FALSE, 0);
 
226
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
227
 
 
228
  GtkWidget *check = gtk_check_button_new_with_label(_("Enable Applet Icon mode"));
 
229
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), iapplet->applet_mode);
 
230
  g_signal_connect(G_OBJECT(check), "toggled",
 
231
                   G_CALLBACK(applet_mode_check_toggled), (gpointer)iapplet);
 
232
  gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
 
233
 
 
234
  align = gtk_alignment_new(0.0, 0.5, 1.0, 0.0);
 
235
  gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, 12, 0);
 
236
  gtk_container_add(GTK_CONTAINER(align), vbox);
 
237
  gtk_box_pack_start(GTK_BOX(win->vbox), align, FALSE, FALSE, 0);
 
238
 
 
239
  gtk_container_set_border_width(GTK_CONTAINER(win), 12);
 
240
  gtk_window_set_icon_name(GTK_WINDOW(win), "indicator-applet");
 
241
  gtk_widget_show_all(GTK_WIDGET(win));
 
242
  gtk_dialog_run(win);
 
243
  gtk_widget_destroy(GTK_WIDGET(win));
 
244
}
 
245
 
 
246
static gboolean
 
247
get_bool(IndicatorApplet *iapplet, gchar *key)
 
248
{
 
249
  return desktop_agnostic_config_client_get_bool(iapplet->config,
 
250
                                                 DESKTOP_AGNOSTIC_CONFIG_GROUP_DEFAULT,
 
251
                                                 key, NULL);
 
252
}
 
253
 
 
254
static void
 
255
update_config(IndicatorApplet *iapplet)
 
256
{
 
257
  iapplet->config_rows_cols = desktop_agnostic_config_client_get_int(iapplet->config,
 
258
                                                              DESKTOP_AGNOSTIC_CONFIG_GROUP_DEFAULT,
 
259
                                                                     "rows_cols", NULL);
 
260
  if (iapplet->config_rows_cols < 1)
 
261
  {
 
262
    iapplet->config_rows_cols = 2;
 
263
  }
 
264
  iapplet->config_ind_app = get_bool(iapplet, "indicator_applet");
 
265
  iapplet->config_ind_app_ses = get_bool(iapplet, "indicator_applet_session");
 
266
  iapplet->config_me = get_bool(iapplet, "me_menu");
 
267
  iapplet->config_messaging = get_bool(iapplet, "messaging_menu");
 
268
  iapplet->config_network = get_bool(iapplet, "network_menu");
 
269
  iapplet->config_sound = get_bool(iapplet, "sound_menu");
 
270
  iapplet->config_other_menus = get_bool(iapplet, "other_menus");
 
271
  iapplet->applet_mode = get_bool(iapplet, "applet_icon_mode");
 
272
}
 
273
 
 
274
/* Dealing with libindicator ... */
 
275
static void
 
276
get_shown_entries(IndicatorApplet *iapplet)
 
277
{
 
278
  // Causes segfaults for various reasons... (none fully known)
 
279
  /*if (iapplet->shown_images != NULL)
 
280
  {
 
281
    g_list_free(iapplet->shown_images);
 
282
  }
 
283
  if (iapplet->shown_menus != NULL)
 
284
  {
 
285
    g_list_free(iapplet->shown_menus);
 
286
  }*/
 
287
 
 
288
  iapplet->shown_images = NULL;
 
289
  iapplet->shown_menus = NULL;
 
290
 
 
291
  gchar *name;
 
292
  gboolean add;
 
293
 
 
294
  gint i = 0;
 
295
  GList *l;
 
296
  for (l = iapplet->images; l; l = l->next)
 
297
  {
 
298
    add = FALSE;
 
299
 
 
300
    IndicatorObject *io = INDICATOR_OBJECT(g_object_get_data(G_OBJECT(l->data), "indicator"));
 
301
    if (INDICATOR_IS_OBJECT(io))
 
302
    {
 
303
      name = (gchar*)g_object_get_data(G_OBJECT(io), "filename");
 
304
 
 
305
      if (!g_strcmp0(name, "libapplication.so"))
 
306
      {
 
307
        if (iapplet->config_ind_app)
 
308
        {
 
309
          add = TRUE;
 
310
        }
 
311
      }
 
312
 
 
313
      else if (!g_strcmp0(name, "libme.so"))
 
314
      {
 
315
        if (iapplet->config_me)
 
316
        {
 
317
          add = TRUE;
 
318
        }
 
319
      }
 
320
 
 
321
      else if (!g_strcmp0(name, "libmessaging.so"))
 
322
      {
 
323
        if (iapplet->config_messaging)
 
324
        {
 
325
          add = TRUE;
 
326
        }
 
327
      }
 
328
 
 
329
      else if (!g_strcmp0(name, "libnetworkmenu.so"))
 
330
      {
 
331
        if (iapplet->config_network)
 
332
        {
 
333
          add = TRUE;
 
334
        }
 
335
      }
 
336
 
 
337
      else if (!g_strcmp0(name, "libsession.so"))
 
338
      {
 
339
        if (iapplet->config_ind_app_ses)
 
340
        {
 
341
          add = TRUE;
 
342
        }
 
343
      }
 
344
 
 
345
      else if (!g_strcmp0(name, "libsoundmenu.so"))
 
346
      {
 
347
        if (iapplet->config_sound)
 
348
        {
 
349
          add = TRUE;
 
350
        }
 
351
      }
 
352
 
 
353
      else
 
354
      {
 
355
        if (iapplet->config_other_menus)
 
356
        {
 
357
          add = TRUE;
 
358
        }
 
359
      }
 
360
 
 
361
      if (add)
 
362
      {
 
363
        iapplet->shown_images = g_list_append(iapplet->shown_images, l->data);
 
364
        iapplet->shown_menus = g_list_append(iapplet->shown_menus,
 
365
                                             g_list_nth_data(iapplet->menus, i));
 
366
      }
 
367
    }
 
368
 
 
369
    i++;
 
370
  }
 
371
}
 
372
 
 
373
static gboolean
 
374
pixbuf_changed(GObject *image, GParamSpec *spec, IndicatorApplet *iapplet)
 
375
{
 
376
  if (iapplet->applet_mode)
 
377
  {
 
378
    update_icon_mode(iapplet);
 
379
  }
 
380
  else
 
381
  {
 
382
    gtk_widget_queue_draw(iapplet->da);
 
383
  }
 
384
 
 
385
  return FALSE;
 
386
}
 
387
 
 
388
static void
 
389
entry_added(IndicatorObject *io, IndicatorObjectEntry *entry, IndicatorApplet *iapplet)
 
390
{
 
391
  if (entry->image == NULL || entry->menu == NULL)
 
392
  {
 
393
    /* If either of these is NULL, there will likely be problems when
 
394
     * the entry is removed */
 
395
    return;
 
396
  }
 
397
 
 
398
  g_object_set_data(G_OBJECT(entry->image), "indicator", io);
 
399
  iapplet->images = g_list_append(iapplet->images, entry->image);
 
400
  iapplet->menus = g_list_append(iapplet->menus, entry->menu);
 
401
  iapplet->num++;
 
402
 
 
403
  gint handler = g_signal_connect(G_OBJECT(entry->image), "notify::pixbuf",
 
404
                                  G_CALLBACK(pixbuf_changed), (gpointer)iapplet);
 
405
  g_object_set_data(G_OBJECT(entry->image), "pixbufhandler", (gpointer)handler);
 
406
 
 
407
  gtk_widget_hide(GTK_WIDGET(entry->menu));
 
408
 
 
409
  get_shown_entries(iapplet);
 
410
 
 
411
  update_icon_mode(iapplet);
 
412
 
 
413
  return;
 
414
}
 
415
 
 
416
static void
 
417
entry_removed(IndicatorObject *io, IndicatorObjectEntry *entry, IndicatorApplet *iapplet)
 
418
{
 
419
  iapplet->images = g_list_remove(iapplet->images, entry->image);
 
420
  iapplet->menus = g_list_remove(iapplet->menus, entry->menu);
 
421
  iapplet->num--;
 
422
 
 
423
  gint handler = (gint)g_object_get_data(G_OBJECT(entry->image), "pixbufhandler");
 
424
 
 
425
  if (g_signal_handler_is_connected(G_OBJECT(entry->image), handler))
 
426
  {
 
427
    g_signal_handler_disconnect(G_OBJECT(entry->image), handler);
 
428
  }
 
429
 
 
430
  get_shown_entries(iapplet);
 
431
 
 
432
  update_icon_mode(iapplet);
 
433
}
 
434
 
 
435
static gboolean
 
436
load_module(const gchar * name, IndicatorApplet *iapplet)
 
437
{
 
438
  g_return_val_if_fail(name != NULL, FALSE);
 
439
 
 
440
  if (!g_str_has_suffix(name, G_MODULE_SUFFIX))
 
441
  {
 
442
    return FALSE;
 
443
  }
 
444
 
 
445
  gchar *fullpath = g_build_filename(INDICATOR_DIR, name, NULL);
 
446
  IndicatorObject *io = iapplet->io = indicator_object_new_from_file(fullpath);
 
447
  g_free(fullpath);
 
448
 
 
449
  g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
 
450
    G_CALLBACK(entry_added), iapplet);
 
451
  g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED,
 
452
    G_CALLBACK(entry_removed), iapplet);
 
453
 
 
454
  GList *entries = indicator_object_get_entries(io);
 
455
  GList *entry = NULL;
 
456
 
 
457
  g_object_set_data(G_OBJECT(io), "filename", (gpointer)g_strdup(name));
 
458
 
 
459
  for (entry = entries; entry != NULL; entry = g_list_next(entry))
 
460
  {
 
461
    entry_added(io, (IndicatorObjectEntry*)entry->data, iapplet);
 
462
  }
 
463
 
 
464
  g_list_free(entries);
 
465
 
 
466
  return TRUE;
 
467
}
 
468
 
 
469
/* Drawing, widgets, etc ... */
 
470
static void
 
471
resize_da(IndicatorApplet *iapplet)
 
472
{
 
473
  gint size = awn_applet_get_size(iapplet->applet);
 
474
  GtkPositionType pos = awn_applet_get_pos_type(iapplet->applet);
 
475
  gint rc = iapplet->config_rows_cols;
 
476
 
 
477
  gint pb_size = size * 1.1 / rc;
 
478
 
 
479
  gint num = g_list_length(iapplet->shown_images);
 
480
 
 
481
  if (pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM)
 
482
  {
 
483
    gtk_widget_set_size_request(iapplet->da,
 
484
      ((int)(num / rc) + num % rc) * pb_size, -1);
 
485
  }
 
486
  else
 
487
  {
 
488
    gtk_widget_set_size_request(iapplet->da, -1,
 
489
      ((int)(num / rc) + num % rc) * pb_size);
 
490
  }
 
491
 
 
492
  gtk_widget_queue_draw(iapplet->da);
 
493
}
 
494
 
 
495
static gboolean
 
496
determine_position(IndicatorApplet *iapplet, gint x, gint y)
 
497
{
 
498
  AwnApplet *applet = iapplet->applet;
 
499
  GtkPositionType pos = awn_applet_get_pos_type(applet);
 
500
  gint size = awn_applet_get_size(applet);
 
501
  gint offset = awn_applet_get_offset(applet);
 
502
  gint width = iapplet->da->allocation.width;
 
503
  gint height = iapplet->da->allocation.height;
 
504
  gint rc = iapplet->config_rows_cols;
 
505
  gint pb_size = size * 1.1 / rc;
 
506
 
 
507
  gint col = -1, row = -1, num = -1, dx = -1, dy = -1;
 
508
 
 
509
  switch (pos)
 
510
  {
 
511
    case GTK_POS_BOTTOM:
 
512
      row = (height - y - offset) / pb_size;
 
513
      if (row == -1)
 
514
      {
 
515
        row = 0;
 
516
      }
 
517
      dy = y - height + offset + pb_size * (row + 1);
 
518
 
 
519
      col = (gint)(x / pb_size);
 
520
      dx = x - col * pb_size;
 
521
      num = col * rc + row;
 
522
      break;
 
523
 
 
524
    case GTK_POS_TOP:
 
525
      row = (y - offset) / pb_size;
 
526
      if (row == -1)
 
527
      {
 
528
        row = 0;
 
529
      }
 
530
      dy = y - (offset + pb_size * row);
 
531
 
 
532
      col = (gint)(x / pb_size);
 
533
      dx = x - col * pb_size;
 
534
      num = col * rc + row;
 
535
      break;
 
536
 
 
537
    case GTK_POS_LEFT:
 
538
      col = (x - offset) / pb_size;
 
539
      if (col == -1)
 
540
      {
 
541
        col = 0;
 
542
      }
 
543
      dx = x - (offset + pb_size * col);
 
544
 
 
545
      row = (gint)(y / pb_size);
 
546
      dy = y - row * pb_size;
 
547
      num = row * rc + col;
 
548
      break;
 
549
 
 
550
    default:
 
551
      col = (width - x - offset) / pb_size;
 
552
      if (col == -1)
 
553
      {
 
554
        col = 0;
 
555
      }
 
556
      dx = x - width + offset + pb_size * (col + 1);
 
557
 
 
558
      row = (gint)(y / pb_size);
 
559
      dy = y - row * pb_size;
 
560
      num = row * rc + col;
 
561
      break;
 
562
  }
 
563
 
 
564
  if (row == -1 || col == -1 || num == -1 || num >= g_list_length(iapplet->shown_menus))
 
565
  {
 
566
    return FALSE;
 
567
  }
 
568
 
 
569
  iapplet->popup_num = num;
 
570
  iapplet->dx = dx;
 
571
  iapplet->dy = dy;
 
572
 
 
573
  return TRUE;
 
574
}
 
575
 
 
576
static void
 
577
da_expose_event(GtkWidget *da, GdkEventExpose *event, IndicatorApplet *iapplet)
 
578
{
 
579
  AwnApplet *applet = AWN_APPLET(iapplet->applet);
 
580
 
 
581
  cairo_t *cr = gdk_cairo_create(da->window);
 
582
 
 
583
  cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
 
584
  cairo_paint(cr);
 
585
 
 
586
  cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
 
587
 
 
588
  GtkPositionType pos = awn_applet_get_pos_type(applet);
 
589
  gint offset = awn_applet_get_offset(applet);
 
590
  gint size = awn_applet_get_size(applet);
 
591
  gint w = da->allocation.width;
 
592
  gint h = da->allocation.height;
 
593
  gfloat x = 0.0, y = 0.0;
 
594
  gint rc = iapplet->config_rows_cols;
 
595
  gint pb_size = size * 1.1 / rc;
 
596
 
 
597
  GtkImage *image;
 
598
  GdkPixbuf *pb;
 
599
  GIcon *icon;
 
600
  GtkIconInfo *icon_info;
 
601
  gchar *icon_path;
 
602
  gboolean free_pb;
 
603
 
 
604
  GtkIconTheme *theme = gtk_icon_theme_get_default();
 
605
 
 
606
  gint i;
 
607
  for (i = 0; i < g_list_length(iapplet->shown_images); i++)
 
608
  {
 
609
    /* Get the pixbuf */
 
610
    pb = NULL;
 
611
    free_pb = FALSE;
 
612
    image = GTK_IMAGE(g_list_nth_data(iapplet->shown_images, i));
 
613
    icon = g_object_get_data(G_OBJECT(image), "indicator-names-data");
 
614
 
 
615
    icon_info = gtk_icon_theme_lookup_by_gicon(theme, icon, pb_size,
 
616
      GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_USE_BUILTIN);
 
617
    if (icon_info == NULL)
 
618
    {
 
619
      icon_info = gtk_icon_theme_lookup_by_gicon(theme, icon, 22,
 
620
        GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_USE_BUILTIN);
 
621
    }
 
622
 
 
623
    if (icon_info == NULL)
 
624
    {
 
625
      if (gtk_image_get_storage_type(image) == GTK_IMAGE_PIXBUF)
 
626
      {
 
627
        pb = gtk_image_get_pixbuf(image);
 
628
 
 
629
        if (gdk_pixbuf_get_width(pb) != pb_size || gdk_pixbuf_get_height(pb) != pb_size)
 
630
        {
 
631
          pb = gdk_pixbuf_scale_simple(pb, pb_size, pb_size, GDK_INTERP_BILINEAR);
 
632
          free_pb = TRUE;
 
633
        }
 
634
      }
 
635
    }
 
636
    else
 
637
    {
 
638
      icon_path = (gchar*)gtk_icon_info_get_filename(icon_info);
 
639
      pb = gdk_pixbuf_new_from_file_at_size(icon_path, pb_size, pb_size, NULL);
 
640
      free_pb = TRUE;
 
641
      gtk_icon_info_free(icon_info);
 
642
    }
 
643
 
 
644
    cairo_save(cr);
 
645
 
 
646
    switch (pos)
 
647
    {
 
648
      case GTK_POS_BOTTOM:
 
649
        x = (i - i % rc) * pb_size / rc;
 
650
        y = h - pb_size * (1 + i % rc) - offset;
 
651
        break;
 
652
 
 
653
      case GTK_POS_TOP:
 
654
        x = (i - i % rc) * pb_size / rc;
 
655
        y = pb_size * (i % rc) + offset;
 
656
        break;
 
657
 
 
658
      case GTK_POS_LEFT:
 
659
        x = pb_size * (i % rc) + offset;
 
660
        y = (i - i % rc) * pb_size / rc;
 
661
        break;
 
662
 
 
663
      default:
 
664
        x = w - pb_size * (1 + i % rc) - offset;
 
665
        y = (i - i % rc) * pb_size / rc;
 
666
        break;
 
667
    }
 
668
 
 
669
    cairo_rectangle(cr, x, y, pb_size, pb_size);
 
670
    cairo_clip(cr);
 
671
    cairo_translate(cr, x, y);
 
672
 
 
673
    if (GDK_IS_PIXBUF(pb))
 
674
    {
 
675
      gdk_cairo_set_source_pixbuf(cr, pb, 0.0, 0.0);
 
676
      cairo_paint(cr);
 
677
 
 
678
      cairo_restore(cr);
 
679
 
 
680
      if (free_pb)
 
681
      {
 
682
        g_object_unref(G_OBJECT(pb));
 
683
      }
 
684
    }
 
685
  }
 
686
}
 
687
 
 
688
static void
 
689
update_icon_mode(IndicatorApplet *iapplet)
 
690
{
 
691
  if (iapplet->applet_mode)
 
692
  {
 
693
    gtk_widget_hide(iapplet->da);
 
694
  }
 
695
  else
 
696
  {
 
697
    resize_da(iapplet);
 
698
    gtk_widget_show(iapplet->da);
 
699
 
 
700
    GList *l = NULL;
 
701
    for (l = gtk_container_get_children(GTK_CONTAINER(iapplet->icon_box)); l; l = l->next)
 
702
    {
 
703
      if (GTK_WIDGET(l->data) != iapplet->da)
 
704
      {
 
705
        gtk_widget_hide(GTK_WIDGET(l->data));
 
706
      }
 
707
    }
 
708
 
 
709
    return;
 
710
  }
 
711
 
 
712
  if (iapplet->shown_images == NULL)
 
713
  {
 
714
    return;
 
715
  }
 
716
 
 
717
  gint size = awn_applet_get_size(iapplet->applet);
 
718
  gboolean free_pb;
 
719
  GtkImage *image;
 
720
  GIcon *icon;
 
721
  AwnIcon *awnicon;
 
722
  GdkPixbuf *pb;
 
723
  GtkIconTheme *theme;
 
724
  GtkIconInfo *icon_info;
 
725
 
 
726
  gint nshown = g_list_length(iapplet->shown_images);
 
727
  gint i;
 
728
  for (i = 0; i < nshown; i++)
 
729
  {
 
730
    image = GTK_IMAGE(g_list_nth_data(iapplet->shown_images, i));
 
731
 
 
732
    if (g_list_length(iapplet->awnicons) <= i)
 
733
    {
 
734
      /* Make new AwnIcon... */
 
735
      awnicon = AWN_ICON(awn_themed_icon_new());
 
736
      g_signal_connect(G_OBJECT(awnicon), "button-press-event",
 
737
                       G_CALLBACK(icon_button_press), (gpointer)iapplet);
 
738
      g_signal_connect(G_OBJECT(awnicon), "context-menu-popup",
 
739
                       G_CALLBACK(icon_right_click), (gpointer)iapplet);
 
740
      g_signal_connect(G_OBJECT(awnicon), "scroll-event",
 
741
                       G_CALLBACK(icon_scroll), (gpointer)iapplet);
 
742
      g_object_set_data(G_OBJECT(awnicon), "num", (gpointer)i);
 
743
 
 
744
      gtk_box_pack_start(GTK_BOX(iapplet->icon_box), GTK_WIDGET(awnicon), FALSE, FALSE, 0);
 
745
      gtk_widget_show(GTK_WIDGET(awnicon));
 
746
 
 
747
      iapplet->awnicons = g_list_append(iapplet->awnicons, (gpointer)awnicon);
 
748
    }
 
749
    else
 
750
    {
 
751
      awnicon = AWN_ICON(g_list_nth_data(iapplet->awnicons, i));
 
752
    }
 
753
 
 
754
    awn_icon_set_pos_type(awnicon, awn_applet_get_pos_type(iapplet->applet));
 
755
    awn_icon_set_offset(awnicon, awn_applet_get_offset(iapplet->applet));
 
756
 
 
757
    IndicatorObject *io = INDICATOR_OBJECT(g_object_get_data(G_OBJECT(image), "indicator"));
 
758
    if (INDICATOR_IS_OBJECT(io))
 
759
    {
 
760
      const gchar *name = g_object_get_data(G_OBJECT(io), "filename");
 
761
 
 
762
      if (!g_strcmp0(name, "libme.so"))
 
763
      {
 
764
        awn_icon_set_tooltip_text(awnicon, _("Me menu"));
 
765
      }
 
766
      else if (!g_strcmp0(name, "libmessaging.so"))
 
767
      {
 
768
        awn_icon_set_tooltip_text(awnicon, _("Messaging menu"));
 
769
      }
 
770
      else if (!g_strcmp0(name, "libnetworkmenu.so"))
 
771
      {
 
772
        awn_icon_set_tooltip_text(awnicon, _("Network menu"));
 
773
      }
 
774
      else if (!g_strcmp0(name, "libsession.so"))
 
775
      {
 
776
        awn_icon_set_tooltip_text(awnicon, _("Indicator Applet Session"));
 
777
      }
 
778
      else if (!g_strcmp0(name, "libsoundmenu.so"))
 
779
      {
 
780
        awn_icon_set_tooltip_text(awnicon, _("Sound Menu"));
 
781
      }
 
782
      else
 
783
      {
 
784
        awn_icon_set_tooltip_text(awnicon, _("Indicator Applet"));
 
785
      }
 
786
    }
 
787
 
 
788
    free_pb = FALSE;
 
789
    icon = g_object_get_data(G_OBJECT(image), "indicator-names-data");
 
790
    pb = NULL;
 
791
    theme = gtk_icon_theme_get_default();
 
792
    icon_info = gtk_icon_theme_lookup_by_gicon(theme, icon, size,
 
793
      GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_USE_BUILTIN);
 
794
    if (icon_info == NULL)
 
795
    {
 
796
      icon_info = gtk_icon_theme_lookup_by_gicon(theme, icon, 22,
 
797
        GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_USE_BUILTIN);
 
798
    }
 
799
 
 
800
    if (icon_info == NULL)
 
801
    {
 
802
      if (gtk_image_get_storage_type(image) == GTK_IMAGE_PIXBUF)
 
803
      {
 
804
        pb = gtk_image_get_pixbuf(image);
 
805
 
 
806
        if (gdk_pixbuf_get_width(pb) != size || gdk_pixbuf_get_height(pb) != size)
 
807
        {
 
808
          pb = gdk_pixbuf_scale_simple(pb, size, size, GDK_INTERP_BILINEAR);
 
809
          free_pb = TRUE;
 
810
        }
 
811
      }
 
812
    }
 
813
    else
 
814
    {
 
815
      const gchar *icon_path = gtk_icon_info_get_filename(icon_info);
 
816
      pb = gdk_pixbuf_new_from_file_at_size(icon_path, size, size, NULL);
 
817
      free_pb = TRUE;
 
818
      gtk_icon_info_free(icon_info);
 
819
    }
 
820
 
 
821
    awn_icon_set_from_pixbuf(awnicon, pb);
 
822
    if (free_pb)
 
823
    {
 
824
      g_object_unref(G_OBJECT(pb));
 
825
    }
 
826
 
 
827
    gtk_widget_show(GTK_WIDGET(awnicon));
 
828
  }
 
829
 
 
830
  if (g_list_length(iapplet->awnicons) > i)
 
831
  {
 
832
    gint j;
 
833
    gpointer rm;
 
834
    for (j = g_list_length(iapplet->awnicons); j > i; j--)
 
835
    {
 
836
      rm = g_list_nth_data(iapplet->awnicons, j - 1);
 
837
      iapplet->awnicons = g_list_remove(iapplet->awnicons, rm);
 
838
      gtk_widget_destroy(GTK_WIDGET(rm));
 
839
    }
 
840
  }
 
841
}
 
842
 
 
843
/* AwnIcon-related code ... */
 
844
static void
 
845
icon_menu_position(GtkMenu *menu, gint *x, gint *y, gboolean *move, IndicatorApplet *iapplet)
 
846
{
 
847
  GtkWidget *icon = GTK_WIDGET(g_list_nth_data(iapplet->awnicons, iapplet->popup_num));
 
848
  GtkPositionType pos_type = awn_applet_get_pos_type(iapplet->applet);
 
849
  gint size = awn_applet_get_size(iapplet->applet);
 
850
  gint offset = awn_applet_get_offset(iapplet->applet);
 
851
 
 
852
  gint mw = GTK_WIDGET(menu)->requisition.width;
 
853
  gint mh = GTK_WIDGET(menu)->requisition.height;
 
854
  gint aw = icon->allocation.width;
 
855
  gint ah = icon->allocation.height;
 
856
 
 
857
  GdkScreen *screen = gtk_widget_get_screen(icon);
 
858
  gint sw = gdk_screen_get_width(screen);
 
859
  gint sh = gdk_screen_get_height(screen);
 
860
 
 
861
  switch (pos_type)
 
862
  {
 
863
    case GTK_POS_LEFT:
 
864
      *x = offset + size * 1.1;
 
865
      gdk_window_get_origin(icon->window, NULL, y);
 
866
      break;  
 
867
    case GTK_POS_RIGHT:
 
868
      *x = sw - offset - size * 1.1 - mw;
 
869
      gdk_window_get_origin(icon->window, NULL, y);
 
870
      break;
 
871
    case GTK_POS_TOP:
 
872
      gdk_window_get_origin(icon->window, x, NULL);
 
873
      *y = offset + size * 1.1;
 
874
      break;
 
875
    default:
 
876
      gdk_window_get_origin(icon->window, x, NULL);
 
877
      *y = sh - offset - size * 1.1 - mh;
 
878
      break;
 
879
  }
 
880
 
 
881
  *move = TRUE;
 
882
}
 
883
 
 
884
static gboolean
 
885
icon_button_press(AwnIcon *icon, GdkEventButton *event, IndicatorApplet *iapplet)
 
886
{
 
887
  if (iapplet->shown_menus == NULL || event->button == 3)
 
888
  {
 
889
    return FALSE;
 
890
  }
 
891
 
 
892
  iapplet->popup_num = (gint)g_object_get_data(G_OBJECT(icon), "num");
 
893
 
 
894
  gtk_menu_popup(GTK_MENU(g_list_nth_data(iapplet->shown_menus, iapplet->popup_num)), NULL, NULL,
 
895
    (GtkMenuPositionFunc)icon_menu_position, (gpointer)iapplet, 1, event->time);
 
896
 
 
897
  return FALSE;
 
898
}
 
899
 
 
900
static gboolean
 
901
icon_right_click(AwnIcon *icon, GdkEventButton *event, IndicatorApplet *iapplet)
 
902
{
 
903
  if (!iapplet->awn_menu)
 
904
  {
 
905
    iapplet->awn_menu = awn_applet_create_default_menu(iapplet->applet);
 
906
 
 
907
    GtkWidget *item = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL);
 
908
    g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(show_prefs), (gpointer)iapplet);
 
909
    gtk_menu_shell_append(GTK_MENU_SHELL(iapplet->awn_menu), GTK_WIDGET(item));
 
910
 
 
911
    item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL);
 
912
    g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(show_about), NULL);
 
913
    gtk_menu_shell_append(GTK_MENU_SHELL(iapplet->awn_menu), GTK_WIDGET(item));
 
914
 
 
915
    gtk_widget_show_all(iapplet->awn_menu);
 
916
  }
 
917
 
 
918
  gtk_menu_popup(GTK_MENU(iapplet->awn_menu), NULL, NULL, NULL, NULL,
 
919
                 event->button, event->time);
 
920
 
 
921
  return FALSE;
 
922
}
 
923
 
 
924
static gboolean
 
925
icon_scroll(AwnIcon *icon, GdkEventScroll *event, IndicatorApplet *iapplet)
 
926
{
 
927
  gint num = (gint)g_object_get_data(G_OBJECT(icon), "num");
 
928
 
 
929
  GtkWidget *image = g_list_nth_data(iapplet->shown_images, num);
 
930
  IndicatorObject *io = g_object_get_data(G_OBJECT(image), "indicator");
 
931
  g_signal_emit_by_name(io, "scroll", 1, event->direction);
 
932
 
 
933
  return FALSE;
 
934
}
 
935
 
 
936
/* DrawingArea-related code ... */
 
937
static void
 
938
da_menu_position(GtkMenu *menu, gint *x, gint *y, gboolean *move, IndicatorApplet *iapplet)
 
939
{
 
940
  AwnApplet *applet = AWN_APPLET(iapplet->applet);
 
941
  GtkPositionType pos = awn_applet_get_pos_type(applet);
 
942
  gint size = awn_applet_get_size(applet);
 
943
  gint offset = awn_applet_get_offset(applet);
 
944
  gint mwidth = GTK_WIDGET(menu)->requisition.width;
 
945
  gint mheight = GTK_WIDGET(menu)->requisition.height;
 
946
  gint rc = iapplet->config_rows_cols;
 
947
  gint pb_size = size * 1.1 / rc;
 
948
 
 
949
  switch (pos)
 
950
  {
 
951
    case GTK_POS_BOTTOM:
 
952
      *x -= iapplet->dx;
 
953
      *y -= iapplet->dy + mheight;
 
954
      break;
 
955
    case GTK_POS_TOP:
 
956
      *x -= iapplet->dx;
 
957
      *y += pb_size - iapplet->dy;
 
958
      break;
 
959
    case GTK_POS_LEFT:
 
960
      *x += pb_size - iapplet->dx;
 
961
      *y -= iapplet->dy;
 
962
      break;
 
963
    default:
 
964
      *x -= iapplet->dx + mwidth;
 
965
      *y -= iapplet->dy;
 
966
      break;
 
967
  }
 
968
 
 
969
  *move = TRUE;
 
970
}
 
971
 
 
972
static gboolean
 
973
da_button_press(GtkWidget *widget, GdkEventButton *event, IndicatorApplet *iapplet)
 
974
{
 
975
  AwnApplet *applet = AWN_APPLET(iapplet->applet);
 
976
  if (event->button == 3)
 
977
  {
 
978
    if (!iapplet->awn_menu)
 
979
    {
 
980
      iapplet->awn_menu = awn_applet_create_default_menu(applet);
 
981
 
 
982
      GtkWidget *item = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL);
 
983
      g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(show_prefs), (gpointer)iapplet);
 
984
      gtk_menu_shell_append(GTK_MENU_SHELL(iapplet->awn_menu), GTK_WIDGET(item));
 
985
 
 
986
      item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL);
 
987
      g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(show_about), NULL);
 
988
      gtk_menu_shell_append(GTK_MENU_SHELL(iapplet->awn_menu), GTK_WIDGET(item));
 
989
 
 
990
      gtk_widget_show_all(iapplet->awn_menu);
 
991
    }
 
992
 
 
993
    gtk_menu_popup(GTK_MENU(iapplet->awn_menu), NULL, NULL, NULL, NULL,
 
994
                   event->button, event->time);
 
995
 
 
996
    return FALSE;
 
997
  }
 
998
 
 
999
  if (iapplet->applet_mode || !determine_position(iapplet, (gint)event->x, (gint)event->y))
 
1000
  {
 
1001
    return FALSE;
 
1002
  }
 
1003
 
 
1004
  gtk_menu_popup(GTK_MENU(g_list_nth_data(iapplet->shown_menus, iapplet->popup_num)), NULL, NULL,
 
1005
    (GtkMenuPositionFunc)da_menu_position, (gpointer)iapplet, event->button, event->time);
 
1006
 
 
1007
  return FALSE;
 
1008
}
 
1009
 
 
1010
static gboolean
 
1011
da_scroll(GtkWidget *da, GdkEventScroll *event, IndicatorApplet *iapplet)
 
1012
{
 
1013
  if (!determine_position(iapplet, (gint)event->x, (gint)event->y))
 
1014
  {
 
1015
    return FALSE;
 
1016
  }
 
1017
 
 
1018
  GtkWidget *image = g_list_nth_data(iapplet->shown_images, iapplet->popup_num);
 
1019
  IndicatorObject *io = g_object_get_data(G_OBJECT(image), "indicator");
 
1020
  g_signal_emit_by_name(io, "scroll", 1, event->direction);
 
1021
 
 
1022
  return FALSE;
 
1023
}
 
1024
 
 
1025
static gboolean
 
1026
applet_size_changed(AwnApplet *applet, gint size, IndicatorApplet *iapplet)
 
1027
{
 
1028
  update_icon_mode(iapplet);
 
1029
 
 
1030
  return FALSE;
 
1031
}
 
1032
 
 
1033
static gboolean
 
1034
applet_position_changed(AwnApplet *applet, GtkPositionType pos, IndicatorApplet *iapplet)
 
1035
{
 
1036
  update_icon_mode(iapplet);
 
1037
 
 
1038
  return FALSE;
 
1039
}
 
1040
 
 
1041
AwnApplet*
 
1042
awn_applet_factory_initp(const gchar *name, const gchar *uid, gint panel_id)
 
1043
{
 
1044
  AwnApplet *applet = awn_applet_new(name, uid, panel_id);
 
1045
 
 
1046
  GtkWidget *da = gtk_drawing_area_new();
 
1047
  gtk_widget_add_events(da, GDK_BUTTON_PRESS_MASK);
 
1048
  gtk_widget_show(da);
 
1049
 
 
1050
  GtkWidget *icon_box = awn_icon_box_new_for_applet(applet);
 
1051
  gtk_box_pack_start(GTK_BOX(icon_box), da, FALSE, FALSE, 0);
 
1052
  gtk_widget_show_all(icon_box);
 
1053
  gtk_container_add(GTK_CONTAINER(applet), icon_box);
 
1054
 
 
1055
  IndicatorApplet* iapplet = g_new0(IndicatorApplet, 1);
 
1056
  iapplet->da = da;
 
1057
  iapplet->num = 0;
 
1058
  iapplet->applet = applet;
 
1059
  iapplet->icon_box = icon_box;
 
1060
  iapplet->images = NULL;
 
1061
  iapplet->menus = NULL;
 
1062
  iapplet->shown_images = NULL;
 
1063
  iapplet->shown_menus = NULL;
 
1064
  iapplet->awnicons = NULL;
 
1065
  iapplet->popup_num = -1;
 
1066
  iapplet->last_num = -1;
 
1067
 
 
1068
  iapplet->config = awn_config_get_default_for_applet(iapplet->applet, NULL);
 
1069
  update_config(iapplet);
 
1070
 
 
1071
  g_signal_connect(G_OBJECT(applet), "position-changed",
 
1072
                   G_CALLBACK(applet_position_changed), (gpointer)iapplet);
 
1073
  g_signal_connect(G_OBJECT(applet), "size-changed",
 
1074
                   G_CALLBACK(applet_size_changed), (gpointer)iapplet);
 
1075
 
 
1076
  g_signal_connect(G_OBJECT(da), "button-press-event",
 
1077
                   G_CALLBACK(da_button_press), (gpointer)iapplet);
 
1078
  g_signal_connect(G_OBJECT(da), "expose-event",
 
1079
                   G_CALLBACK(da_expose_event), (gpointer)iapplet);
 
1080
  g_signal_connect(G_OBJECT(da), "scroll-event",
 
1081
                   G_CALLBACK(da_scroll), (gpointer)iapplet);
 
1082
 
 
1083
  gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), INDICATOR_ICONS_DIR);
 
1084
  /* Code (mostly) from gnome-panel's indicator-applet-0.3.6/src/applet-main.c */
 
1085
  if (g_file_test(INDICATOR_DIR, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
 
1086
  {
 
1087
    GDir *dir = g_dir_open(INDICATOR_DIR, 0, NULL);
 
1088
 
 
1089
    const gchar *name;
 
1090
    while ((name = g_dir_read_name(dir)) != NULL)
 
1091
    {
 
1092
      /* Don't load the global menu used in Unity (Ubuntu Netbook Edition) */
 
1093
      if (!g_strcmp0(name, "libappmenu.so"))
 
1094
      {
 
1095
        continue;
 
1096
      }
 
1097
      load_module(name, iapplet);
 
1098
    }
 
1099
    g_dir_close (dir);
 
1100
  }
 
1101
  /* End... */
 
1102
 
 
1103
  update_icon_mode(iapplet);
 
1104
 
 
1105
  return applet;
 
1106
}