~ubuntu-branches/ubuntu/precise/indicator-applet/precise

« back to all changes in this revision

Viewing changes to src/applet-main.c

  • Committer: Package Import Robot
  • Author(s): Ken VanDine, Ted Gould, Ken VanDine
  • Date: 2012-02-08 10:45:27 UTC
  • mfrom: (1.1.26)
  • Revision ID: package-import@ubuntu.com-20120208104527-448buw5npnnndjxi
Tags: 0.4.90-0ubuntu1
[ Ted Gould ]
* New upstream release.
  * Switch to work with GNOME3 Panel (LP: #829491)
* debian/control: Adjusting depends to match new panel reality
* debian/*install: Updating GNOME Panel applet install directory

[ Ken VanDine ]
* debian/control
  * dropped recommends for indicator-me
* debian/rules
  * removed simple-patchsys.mk

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include "libindicator/indicator-object.h"
31
31
#include "tomboykeybinder.h"
32
32
 
33
 
static gchar * indicator_order[] = {
34
 
        "libapplication.so",
35
 
        "libsoundmenu.so",
36
 
        "libmessaging.so",
37
 
        "libdatetime.so",
38
 
        "libme.so",
39
 
        "libsession.so",
40
 
        NULL
 
33
static gchar * indicator_order[][2] = {
 
34
  {"libappmenu.so", NULL},
 
35
  {"libapplication.so", NULL},
 
36
  {"libapplication.so", "gst-keyboard-xkb"},
 
37
  {"libmessaging.so", NULL},
 
38
  {"libpower.so", NULL},
 
39
  {"libapplication.so", "bluetooth-manager"},
 
40
  {"libnetwork.so", NULL},
 
41
  {"libnetworkmenu.so", NULL},
 
42
  {"libapplication.so", "nm-applet"},
 
43
  {"libsoundmenu.so", NULL},
 
44
  {"libdatetime.so", NULL},
 
45
  {"libsession.so", NULL},
 
46
  {NULL, NULL}
41
47
};
42
48
 
43
49
static GtkPackDirection packdirection;
44
50
static PanelAppletOrient orient;
45
51
 
 
52
#define  MENU_DATA_BOX               "box"
46
53
#define  MENU_DATA_INDICATOR_OBJECT  "indicator-object"
47
54
#define  MENU_DATA_INDICATOR_ENTRY   "indicator-entry"
 
55
#define  MENU_DATA_IN_MENUITEM       "in-menuitem"
 
56
#define  MENU_DATA_MENUITEM_PRESSED  "menuitem-pressed"
48
57
 
 
58
#define  IO_DATA_NAME                "indicator-name"
49
59
#define  IO_DATA_ORDER_NUMBER        "indicator-order-number"
50
60
 
51
 
static gboolean     applet_fill_cb (PanelApplet * applet, const gchar * iid, gpointer data);
 
61
static gboolean applet_fill_cb (PanelApplet * applet, const gchar * iid, gpointer data);
52
62
 
53
 
static void cw_panel_background_changed (PanelApplet               *applet,
54
 
                                         PanelAppletBackgroundType  type,
55
 
                                                                 GdkColor                  *colour,
56
 
                                                                 GdkPixmap                 *pixmap,
57
 
                                         GtkWidget                 *menubar);
58
63
static void update_accessible_desc (IndicatorObjectEntry * entry, GtkWidget * menuitem);
59
64
 
60
65
/*************
64
69
#ifdef INDICATOR_APPLET
65
70
PANEL_APPLET_OUT_PROCESS_FACTORY ("IndicatorAppletFactory",
66
71
               PANEL_TYPE_APPLET,
67
 
               "indicator-applet",
68
72
               applet_fill_cb, NULL);
69
73
#endif
70
74
#ifdef INDICATOR_APPLET_SESSION
71
75
PANEL_APPLET_OUT_PROCESS_FACTORY ("FastUserSwitchAppletFactory",
72
76
               PANEL_TYPE_APPLET,
73
 
               "indicator-applet-session",
74
77
               applet_fill_cb, NULL);
75
78
#endif
76
79
#ifdef INDICATOR_APPLET_COMPLETE
77
80
PANEL_APPLET_OUT_PROCESS_FACTORY ("IndicatorAppletCompleteFactory",
78
81
               PANEL_TYPE_APPLET,
79
 
               "indicator-applet-complete",
80
82
               applet_fill_cb, NULL);
81
83
#endif
82
84
#ifdef INDICATOR_APPLET_APPMENU
83
85
PANEL_APPLET_OUT_PROCESS_FACTORY ("IndicatorAppletAppmenuFactory",
84
86
               PANEL_TYPE_APPLET,
85
 
               "indicator-applet-appmenu",
86
87
               applet_fill_cb, NULL);
87
88
#endif
88
89
 
101
102
#ifdef INDICATOR_APPLET_APPMENU
102
103
#define LOG_FILE_NAME  "indicator-applet-appmenu.log"
103
104
#endif
104
 
GOutputStream * log_file = NULL;
 
105
static FILE *log_file = NULL;
105
106
 
106
107
/*****************
107
108
 * Hotkey support 
136
137
#endif
137
138
 
138
139
static const gchar * indicator_env[] = {
139
 
        "indicator-applet",
140
 
        INDICATOR_SPECIFIC_ENV,
141
 
        NULL
 
140
  "indicator-applet",
 
141
  INDICATOR_SPECIFIC_ENV,
 
142
  NULL
142
143
};
143
144
 
144
 
/*************
145
 
 * init function
146
 
 * ***********/
147
 
 
148
145
static gint
149
 
name2order (const gchar * name) {
150
 
        int i;
151
 
 
152
 
        for (i = 0; indicator_order[i] != NULL; i++) {
153
 
                if (g_strcmp0(name, indicator_order[i]) == 0) {
154
 
                        return i;
155
 
                }
156
 
        }
157
 
 
158
 
        return -1;
 
146
name2order (const gchar * name, const gchar * hint) {
 
147
  int i;
 
148
 
 
149
  for (i = 0; indicator_order[i][0] != NULL; i++) {
 
150
    if (g_strcmp0(name, indicator_order[i][0]) == 0 &&
 
151
        g_strcmp0(hint, indicator_order[i][1]) == 0) {
 
152
      return i;
 
153
    }
 
154
  }
 
155
 
 
156
  return -1;
159
157
}
160
158
 
161
159
typedef struct _incoming_position_t incoming_position_t;
162
160
struct _incoming_position_t {
163
 
        gint objposition;
164
 
        gint entryposition;
165
 
        gint menupos;
166
 
        gboolean found;
 
161
  gint objposition;
 
162
  gint entryposition;
 
163
  gint menupos;
 
164
  gboolean found;
167
165
};
168
166
 
169
167
/* This function helps by determining where in the menu list
171
169
   that they're on, and then the individual entries.  Each
172
170
   is progressively more expensive. */
173
171
static void
174
 
place_in_menu (GtkWidget * widget, gpointer user_data)
175
 
{
176
 
        incoming_position_t * position = (incoming_position_t *)user_data;
177
 
        if (position->found) {
178
 
                /* We've already been placed, just finish the foreach */
179
 
                return;
180
 
        }
181
 
 
182
 
        IndicatorObject * io = INDICATOR_OBJECT(g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_OBJECT));
183
 
        g_assert(io != NULL);
184
 
 
185
 
        gint objposition = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(io), IO_DATA_ORDER_NUMBER));
186
 
        /* We've already passed it, well, then this is where
187
 
           we should be be.  Stop! */
188
 
        if (objposition > position->objposition) {
189
 
                position->found = TRUE;
190
 
                return;
191
 
        }
192
 
 
193
 
        /* The objects don't match yet, keep looking */
194
 
        if (objposition < position->objposition) {
195
 
                position->menupos++;
196
 
                return;
197
 
        }
198
 
 
199
 
        /* The objects are the same, let's start looking at entries. */
200
 
        IndicatorObjectEntry * entry = (IndicatorObjectEntry *)g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
201
 
        gint entryposition = indicator_object_get_location(io, entry);
202
 
 
203
 
        if (entryposition > position->entryposition) {
204
 
                position->found = TRUE;
205
 
                return;
206
 
        }
207
 
 
208
 
        if (entryposition < position->entryposition) {
209
 
                position->menupos++;
210
 
                return;
211
 
        }
212
 
 
213
 
        /* We've got the same object and the same entry.  Well,
214
 
           let's just put it right here then. */
215
 
        position->found = TRUE;
216
 
        return;
 
172
place_in_menu_cb (GtkWidget * widget, gpointer user_data)
 
173
{
 
174
  incoming_position_t * position = (incoming_position_t *)user_data;
 
175
  if (position->found) {
 
176
    /* We've already been placed, just finish the foreach */
 
177
    return;
 
178
  }
 
179
 
 
180
  IndicatorObject * io = INDICATOR_OBJECT(g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_OBJECT));
 
181
  g_return_if_fail(INDICATOR_IS_OBJECT(io));
 
182
 
 
183
  gint objposition = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(io), IO_DATA_ORDER_NUMBER));
 
184
  /* We've already passed it, well, then this is where
 
185
     we should be be.  Stop! */
 
186
  if (objposition > position->objposition) {
 
187
    position->found = TRUE;
 
188
    return;
 
189
  }
 
190
 
 
191
  /* The objects don't match yet, keep looking */
 
192
  if (objposition < position->objposition) {
 
193
    position->menupos++;
 
194
    return;
 
195
  }
 
196
 
 
197
  /* The objects are the same, let's start looking at entries. */
 
198
  IndicatorObjectEntry * entry = (IndicatorObjectEntry *)g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
 
199
  gint entryposition = indicator_object_get_location(io, entry);
 
200
 
 
201
  if (entryposition > position->entryposition) {
 
202
    position->found = TRUE;
 
203
    return;
 
204
  }
 
205
 
 
206
  if (entryposition < position->entryposition) {
 
207
    position->menupos++;
 
208
    return;
 
209
  }
 
210
 
 
211
  /* We've got the same object and the same entry.  Well,
 
212
     let's just put it right here then. */
 
213
  position->found = TRUE;
 
214
  return;
 
215
}
 
216
 
 
217
/* Position the entry */
 
218
static void
 
219
place_in_menu (GtkWidget *menubar, 
 
220
               GtkWidget *menuitem, 
 
221
               IndicatorObject *io, 
 
222
               IndicatorObjectEntry *entry)
 
223
{
 
224
  incoming_position_t position;
 
225
 
 
226
  /* Start with the default position for this indicator object */
 
227
  gint io_position = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(io), IO_DATA_ORDER_NUMBER));
 
228
 
 
229
  /* If name-hint is set, try to find the entry's position */
 
230
  if (entry->name_hint != NULL) {
 
231
    const gchar *name = (const gchar *)g_object_get_data(G_OBJECT(io), IO_DATA_NAME);
 
232
    gint entry_position = name2order(name, entry->name_hint);
 
233
 
 
234
    /* If we don't find the entry, fall back to the indicator object's position */
 
235
    if (entry_position > -1)
 
236
      io_position = entry_position;
 
237
  }
 
238
 
 
239
  position.objposition = io_position;
 
240
  position.entryposition = indicator_object_get_location(io, entry);
 
241
  position.menupos = 0;
 
242
  position.found = FALSE;
 
243
 
 
244
  gtk_container_foreach(GTK_CONTAINER(menubar), place_in_menu_cb, &position);
 
245
 
 
246
  gtk_menu_shell_insert(GTK_MENU_SHELL(menubar), menuitem, position.menupos);
217
247
}
218
248
 
219
249
static void
220
250
something_shown (GtkWidget * widget, gpointer user_data)
221
251
{
222
 
        GtkWidget * menuitem = GTK_WIDGET(user_data);
223
 
        gtk_widget_show(menuitem);
 
252
  GtkWidget * menuitem = GTK_WIDGET(user_data);
 
253
  gtk_widget_show(menuitem);
224
254
}
225
255
 
226
256
static void
227
257
something_hidden (GtkWidget * widget, gpointer user_data)
228
258
{
229
 
        GtkWidget * menuitem = GTK_WIDGET(user_data);
230
 
        gtk_widget_hide(menuitem);
 
259
  GtkWidget * menuitem = GTK_WIDGET(user_data);
 
260
  gtk_widget_hide(menuitem);
231
261
}
232
262
 
233
263
static void
234
264
sensitive_cb (GObject * obj, GParamSpec * pspec, gpointer user_data)
235
265
{
236
 
        g_return_if_fail(GTK_IS_WIDGET(obj));
237
 
        g_return_if_fail(GTK_IS_WIDGET(user_data));
 
266
  g_return_if_fail(GTK_IS_WIDGET(obj));
 
267
  g_return_if_fail(GTK_IS_WIDGET(user_data));
238
268
 
239
 
        gtk_widget_set_sensitive(GTK_WIDGET(user_data), gtk_widget_get_sensitive(GTK_WIDGET(obj)));
240
 
        return;
 
269
  gtk_widget_set_sensitive(GTK_WIDGET(user_data), gtk_widget_get_sensitive(GTK_WIDGET(obj)));
 
270
  return;
241
271
}
242
272
 
243
273
static void
244
274
entry_activated (GtkWidget * widget, gpointer user_data)
245
275
{
246
 
        g_return_if_fail(GTK_IS_WIDGET(widget));
247
 
        gpointer pio = g_object_get_data(G_OBJECT(widget), "indicator");
248
 
        g_return_if_fail(INDICATOR_IS_OBJECT(pio));
249
 
        IndicatorObject * io = INDICATOR_OBJECT(pio);
250
 
 
251
 
        return indicator_object_entry_activate(io, (IndicatorObjectEntry *)user_data, gtk_get_current_event_time());
 
276
  g_return_if_fail(GTK_IS_WIDGET(widget));
 
277
 
 
278
  IndicatorObject *io = g_object_get_data (G_OBJECT (widget), MENU_DATA_INDICATOR_OBJECT);
 
279
  IndicatorObjectEntry *entry = g_object_get_data (G_OBJECT (widget), MENU_DATA_INDICATOR_ENTRY);
 
280
 
 
281
  g_return_if_fail(INDICATOR_IS_OBJECT(io));
 
282
 
 
283
  return indicator_object_entry_activate(io, entry, gtk_get_current_event_time());
 
284
}
 
285
 
 
286
static gboolean
 
287
entry_secondary_activated (GtkWidget * widget, GdkEvent * event, gpointer user_data)
 
288
{
 
289
  g_return_val_if_fail(GTK_IS_WIDGET(widget), FALSE);
 
290
 
 
291
  switch (event->type) {
 
292
    case GDK_ENTER_NOTIFY:
 
293
      g_object_set_data(G_OBJECT(widget), MENU_DATA_IN_MENUITEM, GINT_TO_POINTER(TRUE));
 
294
      break;
 
295
 
 
296
    case GDK_LEAVE_NOTIFY:
 
297
      g_object_set_data(G_OBJECT(widget), MENU_DATA_IN_MENUITEM, GINT_TO_POINTER(FALSE));
 
298
      g_object_set_data(G_OBJECT(widget), MENU_DATA_MENUITEM_PRESSED, GINT_TO_POINTER(FALSE));
 
299
      break;
 
300
 
 
301
    case GDK_BUTTON_PRESS:
 
302
      if (event->button.button == 2) {
 
303
        g_object_set_data(G_OBJECT(widget), MENU_DATA_MENUITEM_PRESSED, GINT_TO_POINTER(TRUE));
 
304
      }
 
305
      break;
 
306
 
 
307
    case GDK_BUTTON_RELEASE:
 
308
      if (event->button.button == 2) {
 
309
        gboolean in_menuitem = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), MENU_DATA_IN_MENUITEM));
 
310
        gboolean menuitem_pressed = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), MENU_DATA_MENUITEM_PRESSED));
 
311
 
 
312
        if (in_menuitem && menuitem_pressed) {
 
313
          g_object_set_data(G_OBJECT(widget), MENU_DATA_MENUITEM_PRESSED, GINT_TO_POINTER(FALSE));
 
314
 
 
315
          IndicatorObject *io = g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_OBJECT);
 
316
          IndicatorObjectEntry *entry = g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
 
317
 
 
318
          g_return_val_if_fail(INDICATOR_IS_OBJECT(io), FALSE);
 
319
 
 
320
          g_signal_emit_by_name(io, INDICATOR_OBJECT_SIGNAL_SECONDARY_ACTIVATE, 
 
321
              entry, event->button.time);
 
322
        }
 
323
      }
 
324
      break;
 
325
  }
 
326
 
 
327
  return FALSE;
252
328
}
253
329
 
254
330
static gboolean
255
331
entry_scrolled (GtkWidget *menuitem, GdkEventScroll *event, gpointer data)
256
332
{
257
 
        IndicatorObject *io = g_object_get_data (G_OBJECT (menuitem), MENU_DATA_INDICATOR_OBJECT);
258
 
        IndicatorObjectEntry *entry = g_object_get_data (G_OBJECT (menuitem), MENU_DATA_INDICATOR_ENTRY);
259
 
 
260
 
        g_return_val_if_fail(INDICATOR_IS_OBJECT(io), FALSE);
261
 
 
262
 
        g_signal_emit_by_name (io, "scroll", 1, event->direction);
263
 
        g_signal_emit_by_name (io, "scroll-entry", entry, 1, event->direction);
264
 
 
265
 
        return FALSE;
 
333
  g_return_val_if_fail(GTK_IS_WIDGET(menuitem), FALSE);
 
334
 
 
335
  IndicatorObject *io = g_object_get_data (G_OBJECT (menuitem), MENU_DATA_INDICATOR_OBJECT);
 
336
  IndicatorObjectEntry *entry = g_object_get_data (G_OBJECT (menuitem), MENU_DATA_INDICATOR_ENTRY);
 
337
 
 
338
  g_return_val_if_fail(INDICATOR_IS_OBJECT(io), FALSE);
 
339
 
 
340
  g_signal_emit_by_name (io, INDICATOR_OBJECT_SIGNAL_ENTRY_SCROLLED, entry, 1, event->direction);
 
341
 
 
342
  return FALSE;
266
343
}
267
344
 
268
345
static void
269
346
accessible_desc_update_cb (GtkWidget * widget, gpointer userdata)
270
347
{
271
 
        gpointer data = g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
272
 
 
273
 
        if (data != userdata) {
274
 
                return;
275
 
        }
276
 
 
277
 
        IndicatorObjectEntry * entry = (IndicatorObjectEntry *)data;
278
 
        update_accessible_desc(entry, widget);
 
348
  gpointer data = g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
 
349
 
 
350
  if (data != userdata) {
 
351
    return;
 
352
  }
 
353
 
 
354
  IndicatorObjectEntry * entry = (IndicatorObjectEntry *)data;
 
355
  update_accessible_desc(entry, widget);
279
356
}
280
357
 
281
358
static void
282
359
accessible_desc_update (IndicatorObject * io, IndicatorObjectEntry * entry, GtkWidget * menubar)
283
360
{
284
 
        gtk_container_foreach(GTK_CONTAINER(menubar), accessible_desc_update_cb, entry);
285
 
        return;
 
361
  gtk_container_foreach(GTK_CONTAINER(menubar), accessible_desc_update_cb, entry);
 
362
  return;
286
363
}
287
364
 
288
365
static void
289
366
entry_added (IndicatorObject * io, IndicatorObjectEntry * entry, GtkWidget * menubar)
290
367
{
291
 
        g_debug("Signal: Entry Added");
292
 
        gboolean something_visible = FALSE;
293
 
        gboolean something_sensitive = FALSE;
294
 
 
295
 
        GtkWidget * menuitem = gtk_menu_item_new();
296
 
        GtkWidget * box = (packdirection == GTK_PACK_DIRECTION_LTR) ?
297
 
                        gtk_hbox_new(FALSE, 3) : gtk_vbox_new(FALSE, 3);
298
 
 
299
 
        g_object_set_data (G_OBJECT (menuitem), "indicator", io);
300
 
        g_object_set_data (G_OBJECT (menuitem), "box", box);
301
 
 
302
 
        g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(entry_activated), entry);
303
 
        g_signal_connect(G_OBJECT(menuitem), "scroll-event", G_CALLBACK(entry_scrolled), entry);
304
 
 
305
 
        if (entry->image != NULL) {
306
 
                gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(entry->image), FALSE, FALSE, 1);
307
 
                if (gtk_widget_get_visible(GTK_WIDGET(entry->image))) {
308
 
                        something_visible = TRUE;
309
 
                }
310
 
 
311
 
                if (gtk_widget_get_sensitive(GTK_WIDGET(entry->image))) {
312
 
                        something_sensitive = TRUE;
313
 
                }
314
 
 
315
 
                g_signal_connect(G_OBJECT(entry->image), "show", G_CALLBACK(something_shown), menuitem);
316
 
                g_signal_connect(G_OBJECT(entry->image), "hide", G_CALLBACK(something_hidden), menuitem);
317
 
 
318
 
                g_signal_connect(G_OBJECT(entry->image), "notify::sensitive", G_CALLBACK(sensitive_cb), menuitem);
319
 
        }
320
 
        if (entry->label != NULL) {
321
 
                switch(packdirection) {
322
 
                        case GTK_PACK_DIRECTION_LTR:
323
 
                                gtk_label_set_angle(GTK_LABEL(entry->label), 0.0);
324
 
                                break;
325
 
                        case GTK_PACK_DIRECTION_TTB:
326
 
                                gtk_label_set_angle(GTK_LABEL(entry->label),
327
 
                                                (orient == PANEL_APPLET_ORIENT_LEFT) ? 
328
 
                                                270.0 : 90.0);
329
 
                                break;
330
 
                        default:
331
 
                                break;
332
 
                }               
333
 
                gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(entry->label), FALSE, FALSE, 1);
334
 
 
335
 
                if (gtk_widget_get_visible(GTK_WIDGET(entry->label))) {
336
 
                        something_visible = TRUE;
337
 
                }
338
 
 
339
 
                if (gtk_widget_get_sensitive(GTK_WIDGET(entry->label))) {
340
 
                        something_sensitive = TRUE;
341
 
                }
342
 
 
343
 
                g_signal_connect(G_OBJECT(entry->label), "show", G_CALLBACK(something_shown), menuitem);
344
 
                g_signal_connect(G_OBJECT(entry->label), "hide", G_CALLBACK(something_hidden), menuitem);
345
 
 
346
 
                g_signal_connect(G_OBJECT(entry->label), "notify::sensitive", G_CALLBACK(sensitive_cb), menuitem);
347
 
        }
348
 
        gtk_container_add(GTK_CONTAINER(menuitem), box);
349
 
        gtk_widget_show(box);
350
 
 
351
 
        if (entry->menu != NULL) {
352
 
                gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), GTK_WIDGET(entry->menu));
353
 
        }
354
 
 
355
 
        incoming_position_t position;
356
 
        position.objposition = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(io), IO_DATA_ORDER_NUMBER));
357
 
        position.entryposition = indicator_object_get_location(io, entry);
358
 
        position.menupos = 0;
359
 
        position.found = FALSE;
360
 
 
361
 
        gtk_container_foreach(GTK_CONTAINER(menubar), place_in_menu, &position);
362
 
 
363
 
        gtk_menu_shell_insert(GTK_MENU_SHELL(menubar), menuitem, position.menupos);
364
 
 
365
 
        if (something_visible) {
366
 
                if (entry->accessible_desc != NULL) {
367
 
                        update_accessible_desc(entry, menuitem);
368
 
                }
369
 
                gtk_widget_show(menuitem);
370
 
        }
371
 
        gtk_widget_set_sensitive(menuitem, something_sensitive);
372
 
 
373
 
        g_object_set_data(G_OBJECT(menuitem), MENU_DATA_INDICATOR_ENTRY,  entry);
374
 
        g_object_set_data(G_OBJECT(menuitem), MENU_DATA_INDICATOR_OBJECT, io);
375
 
 
376
 
        return;
 
368
  const char *indicator_name = (const gchar *)g_object_get_data(G_OBJECT(io), IO_DATA_NAME);
 
369
  g_debug("Signal: Entry Added from %s", indicator_name);
 
370
  gboolean something_visible = FALSE;
 
371
  gboolean something_sensitive = FALSE;
 
372
 
 
373
  GtkWidget * menuitem = gtk_menu_item_new();
 
374
  GtkWidget * box = (packdirection == GTK_PACK_DIRECTION_LTR) ?
 
375
      gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3) : gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
 
376
 
 
377
  g_object_set_data (G_OBJECT (menuitem), MENU_DATA_BOX, box);
 
378
  g_object_set_data(G_OBJECT(menuitem), MENU_DATA_INDICATOR_ENTRY,  entry);
 
379
  g_object_set_data(G_OBJECT(menuitem), MENU_DATA_INDICATOR_OBJECT, io);
 
380
 
 
381
  g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(entry_activated), NULL);
 
382
  g_signal_connect(G_OBJECT(menuitem), "button-press-event", G_CALLBACK(entry_secondary_activated), NULL);
 
383
  g_signal_connect(G_OBJECT(menuitem), "button-release-event", G_CALLBACK(entry_secondary_activated), NULL);
 
384
  g_signal_connect(G_OBJECT(menuitem), "enter-notify-event", G_CALLBACK(entry_secondary_activated), NULL);
 
385
  g_signal_connect(G_OBJECT(menuitem), "leave-notify-event", G_CALLBACK(entry_secondary_activated), NULL);
 
386
  g_signal_connect(G_OBJECT(menuitem), "scroll-event", G_CALLBACK(entry_scrolled), NULL);
 
387
 
 
388
  if (entry->image != NULL) {
 
389
    gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(entry->image), FALSE, FALSE, 1);
 
390
    if (gtk_widget_get_visible(GTK_WIDGET(entry->image))) {
 
391
      something_visible = TRUE;
 
392
    }
 
393
 
 
394
    if (gtk_widget_get_sensitive(GTK_WIDGET(entry->image))) {
 
395
      something_sensitive = TRUE;
 
396
    }
 
397
 
 
398
    g_signal_connect(G_OBJECT(entry->image), "show", G_CALLBACK(something_shown), menuitem);
 
399
    g_signal_connect(G_OBJECT(entry->image), "hide", G_CALLBACK(something_hidden), menuitem);
 
400
 
 
401
    g_signal_connect(G_OBJECT(entry->image), "notify::sensitive", G_CALLBACK(sensitive_cb), menuitem);
 
402
  }
 
403
  if (entry->label != NULL) {
 
404
    switch(packdirection) {
 
405
      case GTK_PACK_DIRECTION_LTR:
 
406
        gtk_label_set_angle(GTK_LABEL(entry->label), 0.0);
 
407
        break;
 
408
      case GTK_PACK_DIRECTION_TTB:
 
409
        gtk_label_set_angle(GTK_LABEL(entry->label),
 
410
            (orient == PANEL_APPLET_ORIENT_LEFT) ? 
 
411
            270.0 : 90.0);
 
412
        break;
 
413
      default:
 
414
        break;
 
415
    }    
 
416
    gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(entry->label), FALSE, FALSE, 1);
 
417
 
 
418
    if (gtk_widget_get_visible(GTK_WIDGET(entry->label))) {
 
419
      something_visible = TRUE;
 
420
    }
 
421
 
 
422
    if (gtk_widget_get_sensitive(GTK_WIDGET(entry->label))) {
 
423
      something_sensitive = TRUE;
 
424
    }
 
425
 
 
426
    g_signal_connect(G_OBJECT(entry->label), "show", G_CALLBACK(something_shown), menuitem);
 
427
    g_signal_connect(G_OBJECT(entry->label), "hide", G_CALLBACK(something_hidden), menuitem);
 
428
 
 
429
    g_signal_connect(G_OBJECT(entry->label), "notify::sensitive", G_CALLBACK(sensitive_cb), menuitem);
 
430
  }
 
431
  gtk_container_add(GTK_CONTAINER(menuitem), box);
 
432
  gtk_widget_show(box);
 
433
 
 
434
  if (entry->menu != NULL) {
 
435
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), GTK_WIDGET(entry->menu));
 
436
  }
 
437
 
 
438
  place_in_menu(menubar, menuitem, io, entry);
 
439
 
 
440
  if (something_visible) {
 
441
    if (entry->accessible_desc != NULL) {
 
442
      update_accessible_desc(entry, menuitem);
 
443
    }
 
444
    gtk_widget_show(menuitem);
 
445
  }
 
446
  gtk_widget_set_sensitive(menuitem, something_sensitive);
 
447
 
 
448
  return;
377
449
}
378
450
 
379
451
static void
380
452
entry_removed_cb (GtkWidget * widget, gpointer userdata)
381
453
{
382
 
        gpointer data = g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
383
 
 
384
 
        if (data != userdata) {
385
 
                return;
386
 
        }
387
 
 
388
 
        IndicatorObjectEntry * entry = (IndicatorObjectEntry *)data;
389
 
        if (entry->label != NULL) {
390
 
                g_signal_handlers_disconnect_by_func(G_OBJECT(entry->label), G_CALLBACK(something_shown), widget);
391
 
                g_signal_handlers_disconnect_by_func(G_OBJECT(entry->label), G_CALLBACK(something_hidden), widget);
392
 
                g_signal_handlers_disconnect_by_func(G_OBJECT(entry->label), G_CALLBACK(sensitive_cb), widget);
393
 
        }
394
 
        if (entry->image != NULL) {
395
 
                g_signal_handlers_disconnect_by_func(G_OBJECT(entry->image), G_CALLBACK(something_shown), widget);
396
 
                g_signal_handlers_disconnect_by_func(G_OBJECT(entry->image), G_CALLBACK(something_hidden), widget);
397
 
                g_signal_handlers_disconnect_by_func(G_OBJECT(entry->image), G_CALLBACK(sensitive_cb), widget);
398
 
        }
399
 
 
400
 
        gtk_widget_destroy(widget);
401
 
        return;
 
454
  gpointer data = g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
 
455
 
 
456
  if (data != userdata) {
 
457
    return;
 
458
  }
 
459
 
 
460
  IndicatorObjectEntry * entry = (IndicatorObjectEntry *)data;
 
461
  if (entry->label != NULL) {
 
462
    g_signal_handlers_disconnect_by_func(G_OBJECT(entry->label), G_CALLBACK(something_shown), widget);
 
463
    g_signal_handlers_disconnect_by_func(G_OBJECT(entry->label), G_CALLBACK(something_hidden), widget);
 
464
    g_signal_handlers_disconnect_by_func(G_OBJECT(entry->label), G_CALLBACK(sensitive_cb), widget);
 
465
  }
 
466
  if (entry->image != NULL) {
 
467
    g_signal_handlers_disconnect_by_func(G_OBJECT(entry->image), G_CALLBACK(something_shown), widget);
 
468
    g_signal_handlers_disconnect_by_func(G_OBJECT(entry->image), G_CALLBACK(something_hidden), widget);
 
469
    g_signal_handlers_disconnect_by_func(G_OBJECT(entry->image), G_CALLBACK(sensitive_cb), widget);
 
470
  }
 
471
 
 
472
  gtk_widget_destroy(widget);
 
473
  return;
402
474
}
403
475
 
404
476
static void
405
477
entry_removed (IndicatorObject * io G_GNUC_UNUSED, IndicatorObjectEntry * entry,
406
478
               gpointer user_data)
407
479
{
408
 
        g_debug("Signal: Entry Removed");
409
 
 
410
 
        gtk_container_foreach(GTK_CONTAINER(user_data), entry_removed_cb, entry);
411
 
 
412
 
        return;
 
480
  g_debug("Signal: Entry Removed");
 
481
 
 
482
  gtk_container_foreach(GTK_CONTAINER(user_data), entry_removed_cb, entry);
 
483
 
 
484
  return;
413
485
}
414
486
 
415
487
static void
416
488
entry_moved_find_cb (GtkWidget * widget, gpointer userdata)
417
489
{
418
 
        gpointer * array = (gpointer *)userdata;
419
 
        if (array[1] != NULL) {
420
 
                return;
421
 
        }
422
 
 
423
 
        gpointer data = g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
424
 
 
425
 
        if (data != array[0]) {
426
 
                return;
427
 
        }
428
 
 
429
 
        array[1] = widget;
430
 
        return;
 
490
  gpointer * array = (gpointer *)userdata;
 
491
  if (array[1] != NULL) {
 
492
    return;
 
493
  }
 
494
 
 
495
  gpointer data = g_object_get_data(G_OBJECT(widget), MENU_DATA_INDICATOR_ENTRY);
 
496
 
 
497
  if (data != array[0]) {
 
498
    return;
 
499
  }
 
500
 
 
501
  array[1] = widget;
 
502
  return;
431
503
}
432
504
 
433
505
/* Gets called when an entry for an object was moved. */
435
507
entry_moved (IndicatorObject * io, IndicatorObjectEntry * entry,
436
508
             gint old G_GNUC_UNUSED, gint new G_GNUC_UNUSED, gpointer user_data)
437
509
{
438
 
        GtkWidget * menubar = GTK_WIDGET(user_data);
439
 
 
440
 
        gpointer array[2];
441
 
        array[0] = entry;
442
 
        array[1] = NULL;
443
 
 
444
 
        gtk_container_foreach(GTK_CONTAINER(menubar), entry_moved_find_cb, array);
445
 
        if (array[1] == NULL) {
446
 
                g_warning("Moving an entry that isn't in our menus.");
447
 
                return;
448
 
        }
449
 
 
450
 
        GtkWidget * mi = GTK_WIDGET(array[1]);
451
 
        g_object_ref(G_OBJECT(mi));
452
 
        gtk_container_remove(GTK_CONTAINER(menubar), mi);
453
 
 
454
 
        incoming_position_t position;
455
 
        position.objposition = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(io), IO_DATA_ORDER_NUMBER));
456
 
        position.entryposition = indicator_object_get_location(io, entry);
457
 
        position.menupos = 0;
458
 
        position.found = FALSE;
459
 
 
460
 
        gtk_container_foreach(GTK_CONTAINER(menubar), place_in_menu, &position);
461
 
 
462
 
        gtk_menu_shell_insert(GTK_MENU_SHELL(menubar), mi, position.menupos);
463
 
        g_object_unref(G_OBJECT(mi));
464
 
 
465
 
        return;
 
510
  GtkWidget * menubar = GTK_WIDGET(user_data);
 
511
 
 
512
  gpointer array[2];
 
513
  array[0] = entry;
 
514
  array[1] = NULL;
 
515
 
 
516
  gtk_container_foreach(GTK_CONTAINER(menubar), entry_moved_find_cb, array);
 
517
  if (array[1] == NULL) {
 
518
    g_warning("Moving an entry that isn't in our menus.");
 
519
    return;
 
520
  }
 
521
 
 
522
  GtkWidget * mi = GTK_WIDGET(array[1]);
 
523
  g_object_ref(G_OBJECT(mi));
 
524
  gtk_container_remove(GTK_CONTAINER(menubar), mi);
 
525
  place_in_menu(menubar, mi, io, entry);
 
526
  g_object_unref(G_OBJECT(mi));
 
527
 
 
528
  return;
466
529
}
467
530
 
468
531
static void
469
532
menu_show (IndicatorObject * io, IndicatorObjectEntry * entry,
470
533
           guint32 timestamp, gpointer user_data)
471
534
{
472
 
        GtkWidget * menubar = GTK_WIDGET(user_data);
473
 
 
474
 
        if (entry == NULL) {
475
 
                /* Close any open menus instead of opening one */
476
 
                GList * entries = indicator_object_get_entries(io);
477
 
                GList * entry = NULL;
478
 
                for (entry = entries; entry != NULL; entry = g_list_next(entry)) {
479
 
                        IndicatorObjectEntry * entrydata = (IndicatorObjectEntry *)entry->data;
480
 
                        gtk_menu_popdown(entrydata->menu);
481
 
                }
482
 
                g_list_free(entries);
483
 
 
484
 
                /* And tell the menubar to exit activation mode too */
485
 
                gtk_menu_shell_cancel(GTK_MENU_SHELL(menubar));
486
 
                return;
487
 
        }
488
 
 
489
 
        // TODO: do something sensible here
 
535
  GtkWidget * menubar = GTK_WIDGET(user_data);
 
536
 
 
537
  if (entry == NULL) {
 
538
    /* Close any open menus instead of opening one */
 
539
    GList * entries = indicator_object_get_entries(io);
 
540
    GList * entry = NULL;
 
541
    for (entry = entries; entry != NULL; entry = g_list_next(entry)) {
 
542
      IndicatorObjectEntry * entrydata = (IndicatorObjectEntry *)entry->data;
 
543
      gtk_menu_popdown(entrydata->menu);
 
544
    }
 
545
    g_list_free(entries);
 
546
 
 
547
    /* And tell the menubar to exit activation mode too */
 
548
    gtk_menu_shell_cancel(GTK_MENU_SHELL(menubar));
 
549
    return;
 
550
  }
 
551
 
 
552
  // TODO: do something sensible here
490
553
}
491
554
 
492
555
static void
493
556
update_accessible_desc(IndicatorObjectEntry * entry, GtkWidget * menuitem)
494
557
{
495
 
        /* FIXME: We need to deal with the use case where the contents of the
496
 
           label overrides what is found in the atk object's name, or at least
497
 
           orca speaks the label instead of the atk object name.
498
 
         */
499
 
        AtkObject * menuitem_obj = gtk_widget_get_accessible(menuitem);
500
 
        if (menuitem_obj == NULL) {
501
 
                /* Should there be an error printed here? */
502
 
                return;
503
 
        }
 
558
  /* FIXME: We need to deal with the use case where the contents of the
 
559
     label overrides what is found in the atk object's name, or at least
 
560
     orca speaks the label instead of the atk object name.
 
561
   */
 
562
  AtkObject * menuitem_obj = gtk_widget_get_accessible(menuitem);
 
563
  if (menuitem_obj == NULL) {
 
564
    /* Should there be an error printed here? */
 
565
    return;
 
566
  }
504
567
 
505
 
        if (entry->accessible_desc != NULL) {
506
 
                atk_object_set_name(menuitem_obj, entry->accessible_desc);
507
 
        } else {
508
 
                atk_object_set_name(menuitem_obj, "");
509
 
        }
510
 
        return;
 
568
  if (entry->accessible_desc != NULL) {
 
569
    atk_object_set_name(menuitem_obj, entry->accessible_desc);
 
570
  } else {
 
571
    atk_object_set_name(menuitem_obj, "");
 
572
  }
 
573
  return;
511
574
}
512
575
 
513
576
 
514
577
static gboolean
515
578
load_module (const gchar * name, GtkWidget * menubar)
516
579
{
517
 
        g_debug("Looking at Module: %s", name);
518
 
        g_return_val_if_fail(name != NULL, FALSE);
519
 
 
520
 
        if (!g_str_has_suffix(name, G_MODULE_SUFFIX)) {
521
 
                return FALSE;
522
 
        }
523
 
 
524
 
        g_debug("Loading Module: %s", name);
525
 
 
526
 
        /* Build the object for the module */
527
 
        gchar * fullpath = g_build_filename(INDICATOR_DIR, name, NULL);
528
 
        IndicatorObject * io = indicator_object_new_from_file(fullpath);
529
 
        g_free(fullpath);
530
 
 
531
 
        /* Set the environment it's in */
532
 
        indicator_object_set_environment(io, (const GStrv)indicator_env);
533
 
 
534
 
        /* Attach the 'name' to the object */
535
 
        g_object_set_data(G_OBJECT(io), IO_DATA_ORDER_NUMBER, GINT_TO_POINTER(name2order(name)));
536
 
 
537
 
        /* Connect to its signals */
538
 
        g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,   G_CALLBACK(entry_added),    menubar);
539
 
        g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, G_CALLBACK(entry_removed),  menubar);
540
 
        g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_MOVED,   G_CALLBACK(entry_moved),    menubar);
541
 
        g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_MENU_SHOW,     G_CALLBACK(menu_show),      menubar);
542
 
        g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE, G_CALLBACK(accessible_desc_update), menubar);
543
 
 
544
 
        /* Work on the entries */
545
 
        GList * entries = indicator_object_get_entries(io);
546
 
        GList * entry = NULL;
547
 
 
548
 
        for (entry = entries; entry != NULL; entry = g_list_next(entry)) {
549
 
                IndicatorObjectEntry * entrydata = (IndicatorObjectEntry *)entry->data;
550
 
                entry_added(io, entrydata, menubar);
551
 
        }
552
 
 
553
 
        g_list_free(entries);
554
 
 
555
 
        return TRUE;
 
580
  g_debug("Looking at Module: %s", name);
 
581
  g_return_val_if_fail(name != NULL, FALSE);
 
582
 
 
583
  if (!g_str_has_suffix(name, G_MODULE_SUFFIX)) {
 
584
    return FALSE;
 
585
  }
 
586
 
 
587
  g_debug("Loading Module: %s", name);
 
588
 
 
589
  /* Build the object for the module */
 
590
  gchar * fullpath = g_build_filename(INDICATOR_DIR, name, NULL);
 
591
  IndicatorObject * io = indicator_object_new_from_file(fullpath);
 
592
  g_free(fullpath);
 
593
 
 
594
  /* Set the environment it's in */
 
595
  indicator_object_set_environment(io, (const GStrv)indicator_env);
 
596
 
 
597
  /* Attach the 'name' to the object */
 
598
  g_object_set_data_full(G_OBJECT(io), IO_DATA_NAME, g_strdup(name), g_free);
 
599
  g_object_set_data(G_OBJECT(io), IO_DATA_ORDER_NUMBER, GINT_TO_POINTER(name2order(name, NULL)));
 
600
 
 
601
  /* Connect to its signals */
 
602
  g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,   G_CALLBACK(entry_added),    menubar);
 
603
  g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, G_CALLBACK(entry_removed),  menubar);
 
604
  g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_MOVED,   G_CALLBACK(entry_moved),    menubar);
 
605
  g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_MENU_SHOW,     G_CALLBACK(menu_show),      menubar);
 
606
  g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE, G_CALLBACK(accessible_desc_update), menubar);
 
607
 
 
608
  /* Work on the entries */
 
609
  GList * entries = indicator_object_get_entries(io);
 
610
  GList * entry = NULL;
 
611
 
 
612
  for (entry = entries; entry != NULL; entry = g_list_next(entry)) {
 
613
    IndicatorObjectEntry * entrydata = (IndicatorObjectEntry *)entry->data;
 
614
    entry_added(io, entrydata, menubar);
 
615
  }
 
616
 
 
617
  g_list_free(entries);
 
618
 
 
619
  return TRUE;
556
620
}
557
621
 
558
622
static void
559
 
hotkey_filter (char * keystring G_GNUC_UNUSED, gpointer data)
 
623
hotkey_filter (char * keystring, gpointer data)
560
624
{
561
 
        g_return_if_fail(GTK_IS_MENU_SHELL(data));
562
 
 
563
 
        /* Oh, wow, it's us! */
564
 
        GList * children = gtk_container_get_children(GTK_CONTAINER(data));
565
 
        if (children == NULL) {
566
 
                g_debug("Menubar has no children");
567
 
                return;
568
 
        }
569
 
 
570
 
        if (!GTK_MENU_SHELL(data)->active) {
571
 
                gtk_grab_add (GTK_WIDGET(data));
572
 
                GTK_MENU_SHELL(data)->have_grab = TRUE;
573
 
                GTK_MENU_SHELL(data)->active = TRUE;
574
 
        }
575
 
 
576
 
        gtk_menu_shell_select_item(GTK_MENU_SHELL(data), GTK_WIDGET(g_list_last(children)->data));
577
 
        g_list_free(children);
578
 
        return;
 
625
  g_return_if_fail(GTK_IS_MENU_SHELL(data));
 
626
 
 
627
  g_debug ("Hotkey: %s", keystring);
 
628
 
 
629
  /* Oh, wow, it's us! */
 
630
  GList * children = gtk_container_get_children(GTK_CONTAINER(data));
 
631
  if (children == NULL) {
 
632
    g_debug("Menubar has no children");
 
633
    return;
 
634
  }
 
635
 
 
636
  gtk_menu_shell_select_item(GTK_MENU_SHELL(data), GTK_WIDGET(g_list_last(children)->data));
 
637
  g_list_free(children);
 
638
  return;
579
639
}
580
640
 
581
641
static gboolean
583
643
                    GdkEventButton *event,
584
644
                    gpointer data G_GNUC_UNUSED)
585
645
{
586
 
        if (event->button != 1) {
587
 
                g_signal_stop_emission_by_name(widget, "button-press-event");
588
 
        }
589
 
 
590
 
        return FALSE;
591
 
}
592
 
 
593
 
static gboolean
594
 
menubar_on_expose (GtkWidget * widget,
595
 
                    GdkEventExpose *event G_GNUC_UNUSED,
596
 
                    GtkWidget * menubar)
597
 
{
598
 
        if (GTK_WIDGET_HAS_FOCUS(menubar))
599
 
                gtk_paint_focus(widget->style, widget->window, GTK_WIDGET_STATE(menubar),
600
 
                                NULL, widget, "menubar-applet", 0, 0, -1, -1);
601
 
 
602
 
        return FALSE;
 
646
  if (event->button != 1) {
 
647
    g_signal_stop_emission_by_name(widget, "button-press-event");
 
648
  }
 
649
 
 
650
  return FALSE;
603
651
}
604
652
 
605
653
static void
606
654
about_cb (GtkAction *action G_GNUC_UNUSED,
607
655
          gpointer   data G_GNUC_UNUSED)
608
656
{
609
 
        static const gchar *authors[] = {
610
 
                "Ted Gould <ted@canonical.com>",
611
 
                NULL
612
 
        };
 
657
  static const gchar *authors[] = {
 
658
    "Ted Gould <ted@canonical.com>",
 
659
    NULL
 
660
  };
613
661
 
614
 
        static gchar *license[] = {
 
662
  static gchar *license[] = {
615
663
        N_("This program is free software: you can redistribute it and/or modify it "
616
664
           "under the terms of the GNU General Public License version 3, as published "
617
665
           "by the Free Software Foundation."),
621
669
           "PURPOSE.  See the GNU General Public License for more details."),
622
670
        N_("You should have received a copy of the GNU General Public License along "
623
671
           "with this program.  If not, see <http://www.gnu.org/licenses/>."),
624
 
                NULL
625
 
        };
626
 
        gchar *license_i18n;
627
 
 
628
 
        license_i18n = g_strconcat (_(license[0]), "\n\n", _(license[1]), "\n\n", _(license[2]), NULL);
629
 
 
630
 
        gtk_show_about_dialog(NULL,
631
 
                "version", VERSION,
632
 
                "copyright", "Copyright \xc2\xa9 2009-2010 Canonical, Ltd.",
 
672
    NULL
 
673
  };
 
674
  gchar *license_i18n;
 
675
 
 
676
  license_i18n = g_strconcat (_(license[0]), "\n\n", _(license[1]), "\n\n", _(license[2]), NULL);
 
677
 
 
678
  gtk_show_about_dialog(NULL,
 
679
    "version", VERSION,
 
680
    "copyright", "Copyright \xc2\xa9 2009-2010 Canonical, Ltd.",
633
681
#ifdef INDICATOR_APPLET_SESSION
634
 
                "comments", _("A place to adjust your status, change users or exit your session."),
 
682
    "comments", _("A place to adjust your status, change users or exit your session."),
635
683
#else
636
684
#ifdef INDICATOR_APPLET_APPMENU
637
 
                "comments", _("An applet to hold your application menus."),
638
 
#endif
639
 
                "comments", _("An applet to hold all of the system indicators."),
640
 
#endif
641
 
                "authors", authors,
642
 
                "license", license_i18n,
643
 
                "wrap-license", TRUE,
644
 
                "translator-credits", _("translator-credits"),
645
 
                "logo-icon-name", "indicator-applet",
646
 
                "icon-name", "indicator-applet",
647
 
                "website", "http://launchpad.net/indicator-applet",
648
 
                "website-label", _("Indicator Applet Website"),
649
 
                NULL
650
 
        );
651
 
 
652
 
        g_free (license_i18n);
653
 
 
654
 
        return;
 
685
    "comments", _("An applet to hold your application menus."),
 
686
#endif
 
687
    "comments", _("An applet to hold all of the system indicators."),
 
688
#endif
 
689
    "authors", authors,
 
690
    "license", license_i18n,
 
691
    "wrap-license", TRUE,
 
692
    "translator-credits", _("translator-credits"),
 
693
    "logo-icon-name", "indicator-applet",
 
694
    "icon-name", "indicator-applet",
 
695
    "website", "http://launchpad.net/indicator-applet",
 
696
    "website-label", _("Indicator Applet Website"),
 
697
    NULL
 
698
  );
 
699
 
 
700
  g_free (license_i18n);
 
701
 
 
702
  return;
655
703
}
656
704
 
657
705
static gboolean
658
706
swap_orient_cb (GtkWidget *item, gpointer data)
659
707
{
660
 
        GtkWidget *from = (GtkWidget *) data;
661
 
        GtkWidget *to = (GtkWidget *) g_object_get_data(G_OBJECT(from), "to");
662
 
        g_object_ref(G_OBJECT(item));
663
 
        gtk_container_remove(GTK_CONTAINER(from), item);
664
 
        if (GTK_IS_LABEL(item)) {
665
 
                        switch(packdirection) {
666
 
                        case GTK_PACK_DIRECTION_LTR:
667
 
                                gtk_label_set_angle(GTK_LABEL(item), 0.0);
668
 
                                break;
669
 
                        case GTK_PACK_DIRECTION_TTB:
670
 
                                gtk_label_set_angle(GTK_LABEL(item),
671
 
                                                (orient == PANEL_APPLET_ORIENT_LEFT) ? 
672
 
                                                270.0 : 90.0);
673
 
                                break;
674
 
                        default:
675
 
                                break;
676
 
                }               
677
 
        }
678
 
        gtk_box_pack_start(GTK_BOX(to), item, FALSE, FALSE, 0);
679
 
        return TRUE;
 
708
  GtkWidget *from = (GtkWidget *) data;
 
709
  GtkWidget *to = (GtkWidget *) g_object_get_data(G_OBJECT(from), "to");
 
710
  g_object_ref(G_OBJECT(item));
 
711
  gtk_container_remove(GTK_CONTAINER(from), item);
 
712
  if (GTK_IS_LABEL(item)) {
 
713
      switch(packdirection) {
 
714
      case GTK_PACK_DIRECTION_LTR:
 
715
        gtk_label_set_angle(GTK_LABEL(item), 0.0);
 
716
        break;
 
717
      case GTK_PACK_DIRECTION_TTB:
 
718
        gtk_label_set_angle(GTK_LABEL(item),
 
719
            (orient == PANEL_APPLET_ORIENT_LEFT) ? 
 
720
            270.0 : 90.0);
 
721
        break;
 
722
      default:
 
723
        break;
 
724
    }    
 
725
  }
 
726
  gtk_box_pack_start(GTK_BOX(to), item, FALSE, FALSE, 0);
 
727
  return TRUE;
680
728
}
681
729
 
682
730
static gboolean
683
731
reorient_box_cb (GtkWidget *menuitem, gpointer data)
684
732
{
685
 
        GtkWidget *from = g_object_get_data(G_OBJECT(menuitem), "box");
686
 
        GtkWidget *to = (packdirection == GTK_PACK_DIRECTION_LTR) ?
687
 
                        gtk_hbox_new(FALSE, 0) : gtk_vbox_new(FALSE, 0);
688
 
        g_object_set_data(G_OBJECT(from), "to", to);
689
 
        gtk_container_foreach(GTK_CONTAINER(from), (GtkCallback)swap_orient_cb,
690
 
                        from);
691
 
        gtk_container_remove(GTK_CONTAINER(menuitem), from);
692
 
        gtk_container_add(GTK_CONTAINER(menuitem), to);
693
 
        g_object_set_data(G_OBJECT(menuitem), "box", to);
694
 
        gtk_widget_show_all(menuitem);
695
 
        return TRUE;
 
733
  GtkWidget *from = g_object_get_data(G_OBJECT(menuitem), MENU_DATA_BOX);
 
734
  GtkWidget *to = (packdirection == GTK_PACK_DIRECTION_LTR) ?
 
735
      gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0) : gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
 
736
  g_object_set_data(G_OBJECT(from), "to", to);
 
737
  gtk_container_foreach(GTK_CONTAINER(from), (GtkCallback)swap_orient_cb,
 
738
      from);
 
739
  gtk_container_remove(GTK_CONTAINER(menuitem), from);
 
740
  gtk_container_add(GTK_CONTAINER(menuitem), to);
 
741
  g_object_set_data(G_OBJECT(menuitem), MENU_DATA_BOX, to);
 
742
  gtk_widget_show_all(menuitem);
 
743
  return TRUE;
696
744
}
697
745
 
698
746
static gboolean
699
747
panelapplet_reorient_cb (GtkWidget *applet, PanelAppletOrient neworient,
700
 
                gpointer data)
 
748
    gpointer data)
701
749
{
702
 
        GtkWidget *menubar = (GtkWidget *)data;
703
 
        if ((((neworient == PANEL_APPLET_ORIENT_UP) || 
704
 
                        (neworient == PANEL_APPLET_ORIENT_DOWN)) && 
705
 
                        ((orient == PANEL_APPLET_ORIENT_LEFT) || 
706
 
                        (orient == PANEL_APPLET_ORIENT_RIGHT))) || 
707
 
                        (((neworient == PANEL_APPLET_ORIENT_LEFT) || 
708
 
                        (neworient == PANEL_APPLET_ORIENT_RIGHT)) && 
709
 
                        ((orient == PANEL_APPLET_ORIENT_UP) ||
710
 
                        (orient == PANEL_APPLET_ORIENT_DOWN)))) {
711
 
                packdirection = (packdirection == GTK_PACK_DIRECTION_LTR) ?
712
 
                                GTK_PACK_DIRECTION_TTB : GTK_PACK_DIRECTION_LTR;
713
 
                gtk_menu_bar_set_pack_direction(GTK_MENU_BAR(menubar),
714
 
                                packdirection);
715
 
                orient = neworient;
716
 
                gtk_container_foreach(GTK_CONTAINER(menubar),
717
 
                                (GtkCallback)reorient_box_cb, NULL);
718
 
        }
719
 
        orient = neworient;
720
 
        return FALSE;
 
750
  GtkWidget *menubar = (GtkWidget *)data;
 
751
  if ((((neworient == PANEL_APPLET_ORIENT_UP) || 
 
752
      (neworient == PANEL_APPLET_ORIENT_DOWN)) && 
 
753
      ((orient == PANEL_APPLET_ORIENT_LEFT) || 
 
754
      (orient == PANEL_APPLET_ORIENT_RIGHT))) || 
 
755
      (((neworient == PANEL_APPLET_ORIENT_LEFT) || 
 
756
      (neworient == PANEL_APPLET_ORIENT_RIGHT)) && 
 
757
      ((orient == PANEL_APPLET_ORIENT_UP) ||
 
758
      (orient == PANEL_APPLET_ORIENT_DOWN)))) {
 
759
    packdirection = (packdirection == GTK_PACK_DIRECTION_LTR) ?
 
760
        GTK_PACK_DIRECTION_TTB : GTK_PACK_DIRECTION_LTR;
 
761
    gtk_menu_bar_set_pack_direction(GTK_MENU_BAR(menubar),
 
762
        packdirection);
 
763
    orient = neworient;
 
764
    gtk_container_foreach(GTK_CONTAINER(menubar),
 
765
        (GtkCallback)reorient_box_cb, NULL);
 
766
  }
 
767
  orient = neworient;
 
768
  return FALSE;
721
769
}
722
770
 
723
771
#ifdef N_
726
774
#define N_(x) x
727
775
 
728
776
static void
729
 
log_to_file_cb (GObject * source_obj G_GNUC_UNUSED,
730
 
                GAsyncResult * result G_GNUC_UNUSED, gpointer user_data)
731
 
{
732
 
        g_free(user_data);
733
 
        return;
734
 
}
735
 
 
736
 
static void
737
 
log_to_file (const gchar * domain G_GNUC_UNUSED,
738
 
             GLogLevelFlags level G_GNUC_UNUSED,
 
777
log_to_file (const gchar * domain,
 
778
             GLogLevelFlags level,
739
779
             const gchar * message,
740
 
             gpointer data G_GNUC_UNUSED)
 
780
             gpointer data)
741
781
{
742
 
        if (log_file == NULL) {
743
 
                GError * error = NULL;
744
 
                gchar * filename = g_build_filename(g_get_user_cache_dir(), LOG_FILE_NAME, NULL);
745
 
                GFile * file = g_file_new_for_path(filename);
746
 
                g_free(filename);
747
 
 
748
 
                if (!g_file_test(g_get_user_cache_dir(), G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
749
 
                        GFile * cachedir = g_file_new_for_path(g_get_user_cache_dir());
750
 
                        g_file_make_directory_with_parents(cachedir, NULL, &error);
751
 
 
752
 
                        if (error != NULL) {
753
 
                                g_error("Unable to make directory '%s' for log file: %s", g_get_user_cache_dir(), error->message);
754
 
                                return;
755
 
                        }
756
 
                }
757
 
 
758
 
                g_file_delete(file, NULL, NULL);
759
 
 
760
 
                GFileIOStream * io = g_file_create_readwrite(file,
761
 
                                          G_FILE_CREATE_REPLACE_DESTINATION, /* flags */
762
 
                                          NULL, /* cancelable */
763
 
                                          &error); /* error */
764
 
                if (error != NULL) {
765
 
                        g_error("Unable to replace file: %s", error->message);
766
 
                        return;
767
 
                }
768
 
 
769
 
                log_file = g_io_stream_get_output_stream(G_IO_STREAM(io));
770
 
        }
771
 
 
772
 
        gchar * outputstring = g_strdup_printf("%s\n", message);
773
 
        g_output_stream_write_async(log_file,
774
 
                                    outputstring, /* data */
775
 
                                    strlen(outputstring), /* length */
776
 
                                    G_PRIORITY_LOW, /* priority */
777
 
                                    NULL, /* cancelable */
778
 
                                    log_to_file_cb, /* callback */
779
 
                                    outputstring); /* data */
780
 
 
781
 
        return;
 
782
  if (log_file == NULL) {
 
783
    gchar *path;
 
784
 
 
785
    g_mkdir_with_parents(g_get_user_cache_dir(), 0755);
 
786
    path = g_build_filename(g_get_user_cache_dir(), LOG_FILE_NAME, NULL);
 
787
 
 
788
    log_file = fopen(path, "w");
 
789
 
 
790
    g_free(path);
 
791
  }
 
792
 
 
793
  if(log_file) {
 
794
    const gchar *prefix;
 
795
 
 
796
    switch(level & G_LOG_LEVEL_MASK) {
 
797
      case G_LOG_LEVEL_ERROR:
 
798
        prefix = "ERROR:";
 
799
        break;
 
800
      case G_LOG_LEVEL_CRITICAL:
 
801
        prefix = "CRITICAL:";
 
802
        break;
 
803
      case G_LOG_LEVEL_WARNING:
 
804
        prefix = "WARNING:";
 
805
        break;
 
806
      case G_LOG_LEVEL_MESSAGE:
 
807
        prefix = "MESSAGE:";
 
808
        break;
 
809
      case G_LOG_LEVEL_INFO:
 
810
        prefix = "INFO:";
 
811
        break;
 
812
      case G_LOG_LEVEL_DEBUG:
 
813
        prefix = "DEBUG:";
 
814
        break;
 
815
      default:
 
816
        prefix = "LOG:";
 
817
        break;
 
818
    }
 
819
 
 
820
    fprintf(log_file, "%s %s - %s\n", prefix, domain, message);
 
821
    fflush(log_file);
 
822
  }
 
823
 
 
824
  g_log_default_handler(domain, level, message, data);
 
825
 
 
826
  return;
782
827
}
783
828
 
784
829
static gboolean
785
830
applet_fill_cb (PanelApplet * applet, const gchar * iid G_GNUC_UNUSED,
786
831
                gpointer data G_GNUC_UNUSED)
787
832
{
788
 
        static const GtkActionEntry menu_actions[] = {
789
 
                {"About", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL, G_CALLBACK(about_cb)}
790
 
        };
791
 
        static const gchar *menu_xml = "<menuitem name=\"About\" action=\"About\"/>";
792
 
 
793
 
        static gboolean first_time = FALSE;
794
 
        GtkWidget *menubar;
795
 
        gint indicators_loaded = 0;
796
 
        GtkActionGroup *action_group;
797
 
 
798
 
#ifdef INDICATOR_APPLET_SESSION
799
 
        /* check if we are running stracciatella session */
800
 
        if (g_strcmp0(g_getenv("GDMSESSION"), "gnome-stracciatella") == 0) {
801
 
                g_debug("Running stracciatella GNOME session, disabling myself");
802
 
                return TRUE;
803
 
        }
804
 
#endif
805
 
 
806
 
        if (!first_time)
807
 
        {
808
 
                first_time = TRUE;
809
 
#ifdef INDICATOR_APPLET
810
 
                g_set_application_name(_("Indicator Applet"));
811
 
#endif
812
 
#ifdef INDICATOR_APPLET_SESSION
813
 
                g_set_application_name(_("Indicator Applet Session"));
814
 
#endif
815
 
#ifdef INDICATOR_APPLET_COMPLETE
816
 
                g_set_application_name(_("Indicator Applet Complete"));
817
 
#endif
818
 
#ifdef INDICATOR_APPLET_APPMENU
819
 
                g_set_application_name(_("Indicator Applet Application Menu"));
820
 
#endif
821
 
                
822
 
                g_log_set_default_handler(log_to_file, NULL);
823
 
 
824
 
                tomboy_keybinder_init();
825
 
        }
826
 
 
827
 
        /* Set panel options */
828
 
        gtk_container_set_border_width(GTK_CONTAINER (applet), 0);
829
 
        panel_applet_set_flags(applet, PANEL_APPLET_EXPAND_MINOR);
830
 
        menubar = gtk_menu_bar_new();
831
 
        action_group = gtk_action_group_new ("Indicator Applet Actions");
832
 
        gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
833
 
        gtk_action_group_add_actions (action_group, menu_actions,
834
 
                                      G_N_ELEMENTS (menu_actions),
835
 
                                      menubar);
836
 
        panel_applet_setup_menu(applet, menu_xml, action_group);
837
 
        g_object_unref(action_group);
838
 
#ifdef INDICATOR_APPLET
839
 
        atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (applet)),
840
 
                             "indicator-applet");
841
 
#endif
842
 
#ifdef INDICATOR_APPLET_SESSION
843
 
        atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (applet)),
844
 
                             "indicator-applet-session");
845
 
#endif
846
 
#ifdef INDICATOR_APPLET_COMPLETE
847
 
        atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (applet)),
848
 
                             "indicator-applet-complete");
849
 
#endif
850
 
#ifdef INDICATOR_APPLET_APPMENU
851
 
        atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (applet)),
852
 
                             "indicator-applet-appmenu");
853
 
#endif
854
 
 
855
 
        /* Init some theme/icon stuff */
856
 
        gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
857
 
                                          INDICATOR_ICONS_DIR);
858
 
        /* g_debug("Icons directory: %s", INDICATOR_ICONS_DIR); */
859
 
        gtk_rc_parse_string (
860
 
            "style \"indicator-applet-style\"\n"
861
 
        "{\n"
862
 
        "    GtkMenuBar::shadow-type = none\n"
863
 
        "    GtkMenuBar::internal-padding = 0\n"
864
 
        "    GtkWidget::focus-line-width = 0\n"
865
 
        "    GtkWidget::focus-padding = 0\n"
866
 
        "}\n"
867
 
            "style \"indicator-applet-menubar-style\"\n"
868
 
        "{\n"
869
 
        "    GtkMenuBar::shadow-type = none\n"
870
 
        "    GtkMenuBar::internal-padding = 0\n"
871
 
        "    GtkWidget::focus-line-width = 0\n"
872
 
        "    GtkWidget::focus-padding = 0\n"
873
 
        "    GtkMenuItem::horizontal-padding = 0\n"
874
 
        "}\n"
875
 
            "style \"indicator-applet-menuitem-style\"\n"
876
 
        "{\n"
877
 
        "    GtkWidget::focus-line-width = 0\n"
878
 
        "    GtkWidget::focus-padding = 0\n"
879
 
        "    GtkMenuItem::horizontal-padding = 0\n"
880
 
        "}\n"
881
 
        "widget \"*.fast-user-switch-applet\" style \"indicator-applet-style\""
882
 
        "widget \"*.fast-user-switch-menuitem\" style \"indicator-applet-menuitem-style\""
883
 
        "widget \"*.fast-user-switch-menubar\" style \"indicator-applet-menubar-style\"");
884
 
        //gtk_widget_set_name(GTK_WIDGET (applet), "indicator-applet-menubar");
885
 
        gtk_widget_set_name(GTK_WIDGET (applet), "fast-user-switch-applet");
886
 
 
887
 
        /* Build menubar */
888
 
        orient = (panel_applet_get_orient(applet));
889
 
        packdirection = ((orient == PANEL_APPLET_ORIENT_UP) ||
890
 
                        (orient == PANEL_APPLET_ORIENT_DOWN)) ? 
891
 
                        GTK_PACK_DIRECTION_LTR : GTK_PACK_DIRECTION_TTB;
892
 
        gtk_menu_bar_set_pack_direction(GTK_MENU_BAR(menubar),
893
 
                        packdirection);
894
 
        GTK_WIDGET_SET_FLAGS (menubar, GTK_WIDGET_FLAGS(menubar) | GTK_CAN_FOCUS);
895
 
        gtk_widget_set_name(GTK_WIDGET (menubar), "fast-user-switch-menubar");
896
 
        g_signal_connect(menubar, "button-press-event", G_CALLBACK(menubar_press), NULL);
897
 
        g_signal_connect_after(menubar, "expose-event", G_CALLBACK(menubar_on_expose), menubar);
898
 
        g_signal_connect(applet, "change-orient", 
899
 
                        G_CALLBACK(panelapplet_reorient_cb), menubar);
900
 
        gtk_container_set_border_width(GTK_CONTAINER(menubar), 0);
901
 
 
902
 
        /* Add in filter func */
903
 
        tomboy_keybinder_bind(hotkey_keycode, hotkey_filter, menubar);
904
 
 
905
 
        /* load 'em */
906
 
        if (g_file_test(INDICATOR_DIR, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
907
 
                GDir * dir = g_dir_open(INDICATOR_DIR, 0, NULL);
908
 
 
909
 
                const gchar * name;
910
 
                while ((name = g_dir_read_name(dir)) != NULL) {
911
 
#ifdef INDICATOR_APPLET_APPMENU
912
 
                        if (g_strcmp0(name, "libappmenu.so")) {
913
 
                                continue;
914
 
                        }
 
833
  static const GtkActionEntry menu_actions[] = {
 
834
    {"About", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL, G_CALLBACK(about_cb)}
 
835
  };
 
836
  static const gchar *menu_xml = "<menuitem name=\"About\" action=\"About\"/>";
 
837
 
 
838
  static gboolean first_time = FALSE;
 
839
  GtkWidget *menubar;
 
840
  gint indicators_loaded = 0;
 
841
  GtkActionGroup *action_group;
 
842
  GError *error = NULL;
 
843
 
 
844
#ifdef INDICATOR_APPLET_SESSION
 
845
  /* check if we are running stracciatella session */
 
846
  if (g_strcmp0(g_getenv("GDMSESSION"), "gnome-stracciatella") == 0) {
 
847
    g_debug("Running stracciatella GNOME session, disabling myself");
 
848
    return TRUE;
 
849
  }
 
850
#endif
 
851
 
 
852
  if (!first_time)
 
853
  {
 
854
    first_time = TRUE;
 
855
#ifdef INDICATOR_APPLET
 
856
    g_set_application_name(_("Indicator Applet"));
 
857
#endif
 
858
#ifdef INDICATOR_APPLET_SESSION
 
859
    g_set_application_name(_("Indicator Applet Session"));
 
860
#endif
 
861
#ifdef INDICATOR_APPLET_COMPLETE
 
862
    g_set_application_name(_("Indicator Applet Complete"));
 
863
#endif
 
864
#ifdef INDICATOR_APPLET_APPMENU
 
865
    g_set_application_name(_("Indicator Applet Application Menu"));
 
866
#endif
 
867
    
 
868
    g_log_set_default_handler(log_to_file, NULL);
 
869
 
 
870
    tomboy_keybinder_init();
 
871
  }
 
872
 
 
873
  /* Set panel options */
 
874
  gtk_container_set_border_width(GTK_CONTAINER (applet), 0);
 
875
  panel_applet_set_flags(applet, PANEL_APPLET_EXPAND_MINOR);
 
876
  menubar = gtk_menu_bar_new();
 
877
  action_group = gtk_action_group_new ("Indicator Applet Actions");
 
878
  gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
 
879
  gtk_action_group_add_actions (action_group, menu_actions,
 
880
                                G_N_ELEMENTS (menu_actions),
 
881
                                menubar);
 
882
  panel_applet_setup_menu(applet, menu_xml, action_group);
 
883
  g_object_unref(action_group);
 
884
#ifdef INDICATOR_APPLET
 
885
  atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (applet)),
 
886
                       "indicator-applet");
 
887
#endif
 
888
#ifdef INDICATOR_APPLET_SESSION
 
889
  atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (applet)),
 
890
                       "indicator-applet-session");
 
891
#endif
 
892
#ifdef INDICATOR_APPLET_COMPLETE
 
893
  atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (applet)),
 
894
                       "indicator-applet-complete");
 
895
#endif
 
896
#ifdef INDICATOR_APPLET_APPMENU
 
897
  atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (applet)),
 
898
                       "indicator-applet-appmenu");
 
899
#endif
 
900
 
 
901
  /* Init some theme/icon stuff */
 
902
  gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
 
903
                                    INDICATOR_ICONS_DIR);
 
904
  g_debug("Icons directory: %s", INDICATOR_ICONS_DIR);
 
905
 
 
906
  gtk_widget_set_name(GTK_WIDGET (applet), "fast-user-switch-applet");
 
907
 
 
908
  /* Build menubar */
 
909
  orient = (panel_applet_get_orient(applet));
 
910
  packdirection = ((orient == PANEL_APPLET_ORIENT_UP) ||
 
911
      (orient == PANEL_APPLET_ORIENT_DOWN)) ? 
 
912
      GTK_PACK_DIRECTION_LTR : GTK_PACK_DIRECTION_TTB;
 
913
  gtk_menu_bar_set_pack_direction(GTK_MENU_BAR(menubar),
 
914
      packdirection);
 
915
  gtk_widget_set_can_focus (GTK_WIDGET (menubar), TRUE);
 
916
  gtk_widget_set_name(GTK_WIDGET (menubar), "fast-user-switch-menubar");
 
917
  g_signal_connect(menubar, "button-press-event", G_CALLBACK(menubar_press), NULL);
 
918
  g_signal_connect(applet, "change-orient", 
 
919
      G_CALLBACK(panelapplet_reorient_cb), menubar);
 
920
  gtk_container_set_border_width(GTK_CONTAINER(menubar), 0);
 
921
 
 
922
  /* Add in filter func */
 
923
  tomboy_keybinder_bind(hotkey_keycode, hotkey_filter, menubar);
 
924
 
 
925
  /* load 'em */
 
926
  if (g_file_test(INDICATOR_DIR, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
 
927
    GDir * dir = g_dir_open(INDICATOR_DIR, 0, NULL);
 
928
 
 
929
    const gchar * name;
 
930
    while ((name = g_dir_read_name(dir)) != NULL) {
 
931
#ifdef INDICATOR_APPLET_APPMENU
 
932
      if (g_strcmp0(name, "libappmenu.so")) {
 
933
        continue;
 
934
      }
915
935
#else
916
 
                        if (!g_strcmp0(name, "libappmenu.so")) {
917
 
                                continue;
918
 
                        }
 
936
      if (!g_strcmp0(name, "libappmenu.so")) {
 
937
        continue;
 
938
      }
919
939
#endif
920
940
#ifdef INDICATOR_APPLET
921
 
                        if (!g_strcmp0(name, "libsession.so")) {
922
 
                                continue;
923
 
                        }
924
 
                        if (!g_strcmp0(name, "libme.so")) {
925
 
                                continue;
926
 
                        }
927
 
                        if (!g_strcmp0(name, "libdatetime.so")) {
928
 
                                continue;
929
 
                        }
 
941
      if (!g_strcmp0(name, "libsession.so")) {
 
942
        continue;
 
943
      }
 
944
      if (!g_strcmp0(name, "libme.so")) {
 
945
        continue;
 
946
      }
 
947
      if (!g_strcmp0(name, "libdatetime.so")) {
 
948
        continue;
 
949
      }
930
950
#endif
931
951
#ifdef INDICATOR_APPLET_SESSION
932
 
                        if (g_strcmp0(name, "libsession.so") && g_strcmp0(name, "libme.so")) {
933
 
                                continue;
934
 
                        }
 
952
      if (g_strcmp0(name, "libsession.so") && g_strcmp0(name, "libme.so")) {
 
953
        continue;
 
954
      }
935
955
#endif
936
 
                        if (load_module(name, menubar)) {
937
 
                                indicators_loaded++;
938
 
                        }
939
 
                }
940
 
                g_dir_close (dir);
941
 
        }
942
 
 
943
 
        if (indicators_loaded == 0) {
944
 
                /* A label to allow for click through */
945
 
                GtkWidget * item = gtk_label_new(_("No Indicators"));
946
 
                gtk_container_add(GTK_CONTAINER(applet), item);
947
 
                gtk_widget_show(item);
948
 
        } else {
949
 
                gtk_container_add(GTK_CONTAINER(applet), menubar);
950
 
                panel_applet_set_background_widget(applet, menubar);
951
 
                gtk_widget_show(menubar);
952
 
        }
953
 
 
954
 
        /* Background of applet */
955
 
        g_signal_connect(applet, "change-background",
956
 
                          G_CALLBACK(cw_panel_background_changed), menubar);
957
 
 
958
 
        gtk_widget_show(GTK_WIDGET(applet));
959
 
 
960
 
        return TRUE;
961
 
 
962
 
}
963
 
 
964
 
static void
965
 
cw_panel_background_changed (PanelApplet               *applet,
966
 
                             PanelAppletBackgroundType  type,
967
 
                             GdkColor                  *colour,
968
 
                             GdkPixmap                 *pixmap,
969
 
                             GtkWidget                 *menubar)
970
 
{
971
 
        GtkRcStyle *rc_style;
972
 
        GtkStyle *style;
973
 
 
974
 
        /* reset style */
975
 
        gtk_widget_set_style(GTK_WIDGET (applet), NULL);
976
 
        gtk_widget_set_style(menubar, NULL);
977
 
        rc_style = gtk_rc_style_new ();
978
 
        gtk_widget_modify_style(GTK_WIDGET (applet), rc_style);
979
 
        gtk_widget_modify_style(menubar, rc_style);
980
 
        gtk_rc_style_unref(rc_style);
981
 
 
982
 
        switch (type)
983
 
        {
984
 
                case PANEL_NO_BACKGROUND:
985
 
                        break;
986
 
                case PANEL_COLOR_BACKGROUND:
987
 
                        gtk_widget_modify_bg(GTK_WIDGET (applet), GTK_STATE_NORMAL, colour);
988
 
                        gtk_widget_modify_bg(menubar, GTK_STATE_NORMAL, colour);
989
 
                        break;
990
 
 
991
 
                case PANEL_PIXMAP_BACKGROUND:
992
 
                        style = gtk_style_copy(GTK_WIDGET (applet)->style);
993
 
                        if (style->bg_pixmap[GTK_STATE_NORMAL])
994
 
                                g_object_unref(style->bg_pixmap[GTK_STATE_NORMAL]);
995
 
                        style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref (pixmap);
996
 
                        gtk_widget_set_style(GTK_WIDGET (applet), style);
997
 
                        gtk_widget_set_style(GTK_WIDGET (menubar), style);
998
 
                        g_object_unref(style);
999
 
                        break;
1000
 
  }
 
956
      if (load_module(name, menubar)) {
 
957
        indicators_loaded++;
 
958
      }
 
959
    }
 
960
    g_dir_close (dir);
 
961
  }
 
962
 
 
963
  if (indicators_loaded == 0) {
 
964
    /* A label to allow for click through */
 
965
    GtkWidget * item = gtk_label_new(_("No Indicators"));
 
966
    gtk_container_add(GTK_CONTAINER(applet), item);
 
967
    gtk_widget_show(item);
 
968
  } else {
 
969
    gtk_container_add(GTK_CONTAINER(applet), menubar);
 
970
    panel_applet_set_background_widget(applet, menubar);
 
971
    gtk_widget_show(menubar);
 
972
  }
 
973
 
 
974
  gtk_widget_show(GTK_WIDGET(applet));
 
975
 
 
976
  return TRUE;
1001
977
}
1002
978