~ubuntu-branches/ubuntu/wily/xfce4-panel/wily

« back to all changes in this revision

Viewing changes to .pc/02_support-dmtool.patch/plugins/actions/actions.c

  • Committer: Package Import Robot
  • Author(s): Sean Davis
  • Date: 2014-10-14 06:15:01 UTC
  • Revision ID: package-import@ubuntu.com-20141014061501-ygi4heglyhwryuup
Tags: 4.11.1-0ubuntu2
* debian/patches/02_support-dmtool.patch
  - Add support for dm-tool for user-switching (LP: #1320560)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2009-2011 Nick Schermer <nick@xfce.org>
 
3
 * Copyright (c) 2009      Brian Tarricone <brian@tarricone.org>
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or modify it
 
6
 * under the terms of the GNU General Public License as published by the Free
 
7
 * Software Foundation; either version 2 of the License, or (at your option)
 
8
 * any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful, but WITHOUT
 
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 
13
 * more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General Public
 
16
 * License along with this library; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
18
 */
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include <config.h>
 
22
#endif
 
23
 
 
24
#include <gtk/gtk.h>
 
25
#include <libxfce4panel/libxfce4panel.h>
 
26
#include <libxfce4util/libxfce4util.h>
 
27
#include <libxfce4ui/libxfce4ui.h>
 
28
#include <exo/exo.h>
 
29
#include <dbus/dbus-glib.h>
 
30
 
 
31
#include <common/panel-private.h>
 
32
#include <common/panel-xfconf.h>
 
33
#include <common/panel-utils.h>
 
34
 
 
35
#include "actions.h"
 
36
#include "actions-dialog_ui.h"
 
37
 
 
38
 
 
39
 
 
40
#define DEFAULT_ICON_SIZE (16)
 
41
#define DEFAULT_TIMEOUT   (30)
 
42
 
 
43
 
 
44
 
 
45
static void       actions_plugin_get_property        (GObject               *object,
 
46
                                                      guint                  prop_id,
 
47
                                                      GValue                *value,
 
48
                                                      GParamSpec            *pspec);
 
49
static void       actions_plugin_set_property        (GObject               *object,
 
50
                                                      guint                  prop_id,
 
51
                                                      const GValue          *value,
 
52
                                                      GParamSpec            *pspec);
 
53
static void       actions_plugin_construct           (XfcePanelPlugin       *panel_plugin);
 
54
static void       actions_plugin_free_data           (XfcePanelPlugin       *panel_plugin);
 
55
static gboolean   actions_plugin_size_changed        (XfcePanelPlugin       *panel_plugin,
 
56
                                                      gint                   size);
 
57
static void       actions_plugin_configure_plugin    (XfcePanelPlugin       *panel_plugin);
 
58
static void       actions_plugin_mode_changed        (XfcePanelPlugin       *panel_plugin,
 
59
                                                      XfcePanelPluginMode    mode);
 
60
static void       actions_plugin_pack                (ActionsPlugin         *plugin);
 
61
static GPtrArray *actions_plugin_default_array       (void);
 
62
static void       actions_plugin_menu                (GtkWidget             *button,
 
63
                                                      ActionsPlugin         *plugin);
 
64
 
 
65
 
 
66
 
 
67
typedef enum
 
68
{
 
69
  APPEARANCE_TYPE_BUTTONS,
 
70
  APPEARANCE_TYPE_MENU
 
71
}
 
72
AppearanceType;
 
73
 
 
74
enum
 
75
{
 
76
  PROP_0,
 
77
  PROP_ITEMS,
 
78
  PROP_APPEARANCE,
 
79
  PROP_INVERT_ORIENTATION,
 
80
  PROP_ASK_CONFIRMATION
 
81
};
 
82
 
 
83
enum
 
84
{
 
85
  COLUMN_VISIBLE,
 
86
  COLUMN_DISPLAY_NAME,
 
87
  COLUMN_NAME,
 
88
  COLUMN_TYPE
 
89
};
 
90
 
 
91
struct _ActionsPluginClass
 
92
{
 
93
  XfcePanelPluginClass __parent__;
 
94
};
 
95
 
 
96
struct _ActionsPlugin
 
97
{
 
98
  XfcePanelPlugin __parent__;
 
99
 
 
100
  AppearanceType  type;
 
101
  GPtrArray      *items;
 
102
  GtkWidget      *menu;
 
103
  guint           invert_orientation : 1;
 
104
  guint           ask_confirmation : 1;
 
105
  guint           pack_idle_id;
 
106
};
 
107
 
 
108
typedef enum
 
109
{
 
110
  ACTION_TYPE_SEPARATOR     = 1 << 1,
 
111
  ACTION_TYPE_LOGOUT        = 1 << 2,
 
112
  ACTION_TYPE_LOGOUT_DIALOG = 1 << 3,
 
113
  ACTION_TYPE_SWITCH_USER   = 1 << 4,
 
114
  ACTION_TYPE_LOCK_SCREEN   = 1 << 5,
 
115
  ACTION_TYPE_HIBERNATE     = 1 << 6,
 
116
  ACTION_TYPE_SUSPEND       = 1 << 7,
 
117
  ACTION_TYPE_RESTART       = 1 << 8,
 
118
  ACTION_TYPE_SHUTDOWN      = 1 << 9
 
119
}
 
120
ActionType;
 
121
 
 
122
typedef struct
 
123
{
 
124
  ActionType   type;
 
125
  const gchar *name;
 
126
  const gchar *display_name;
 
127
  const gchar *mnemonic;
 
128
  const gchar *question;
 
129
  const gchar *status;
 
130
  const gchar *icon_name;
 
131
}
 
132
ActionEntry;
 
133
 
 
134
typedef struct
 
135
{
 
136
  ActionEntry *entry;
 
137
  GtkWidget   *dialog;
 
138
  gint         time_left;
 
139
  guint        unattended : 1;
 
140
}
 
141
ActionTimeout;
 
142
 
 
143
static ActionEntry action_entries[] =
 
144
{
 
145
  { ACTION_TYPE_SEPARATOR,
 
146
    "separator",
 
147
    NULL, NULL, NULL, NULL, NULL /* not needed */
 
148
  },
 
149
  { ACTION_TYPE_LOGOUT,
 
150
    "logout-dialog",
 
151
    N_("Log Out"),
 
152
    N_("_Log Out"),
 
153
    N_("Are you sure you want to log out?"),
 
154
    N_("Logging out in %d seconds."),
 
155
    "system-log-out"
 
156
  },
 
157
  { ACTION_TYPE_LOGOUT_DIALOG,
 
158
    "logout",
 
159
    N_("Log Out..."),
 
160
    N_("Log _Out..."),
 
161
    NULL, NULL, /* already shows a dialog */
 
162
    "system-log-out"
 
163
  },
 
164
  { ACTION_TYPE_SWITCH_USER,
 
165
    "switch-user",
 
166
    N_("Switch User"),
 
167
    N_("_Switch User"),
 
168
    NULL, NULL, /* not needed */
 
169
    "system-users"
 
170
  },
 
171
  { ACTION_TYPE_LOCK_SCREEN,
 
172
    "lock-screen",
 
173
    N_("Lock Screen"),
 
174
    N_("Loc_k Screen"),
 
175
    NULL, NULL, /* not needed */
 
176
    "system-lock-screen"
 
177
  },
 
178
  { ACTION_TYPE_HIBERNATE,
 
179
    "hibernate",
 
180
    N_("Hibernate"),
 
181
    N_("_Hibernate"),
 
182
    N_("Do you want to suspend to disk?"),
 
183
    N_("Hibernating computer in %d seconds."),
 
184
    "system-hibernate"
 
185
  },
 
186
  { ACTION_TYPE_SUSPEND,
 
187
    "suspend",
 
188
    N_("Suspend"),
 
189
    N_("Sus_pend"),
 
190
    N_("Do you want to suspend to RAM?"),
 
191
    N_("Suspending computer in %d seconds."),
 
192
    "system-suspend"
 
193
  },
 
194
  { ACTION_TYPE_RESTART,
 
195
    "restart",
 
196
    N_("Restart"),
 
197
    N_("_Restart"),
 
198
    N_("Are you sure you want to restart?"),
 
199
    N_("Restarting computer in %d seconds."),
 
200
    "xfsm-reboot"
 
201
  },
 
202
  { ACTION_TYPE_SHUTDOWN,
 
203
    "shutdown",
 
204
    N_("Shut Down"),
 
205
    N_("Shut _Down"),
 
206
    N_("Are you sure you want to shut down?"),
 
207
    N_("Turning off computer in %d seconds."),
 
208
    "system-shutdown"
 
209
  }
 
210
};
 
211
 
 
212
 
 
213
 
 
214
/* define the plugin */
 
215
XFCE_PANEL_DEFINE_PLUGIN (ActionsPlugin, actions_plugin)
 
216
 
 
217
 
 
218
 
 
219
static GtkIconSize menu_icon_size = GTK_ICON_SIZE_INVALID;
 
220
static GQuark      action_quark = 0;
 
221
 
 
222
 
 
223
 
 
224
static void
 
225
actions_plugin_class_init (ActionsPluginClass *klass)
 
226
{
 
227
  XfcePanelPluginClass *plugin_class;
 
228
  GObjectClass         *gobject_class;
 
229
 
 
230
  gobject_class = G_OBJECT_CLASS (klass);
 
231
  gobject_class->set_property = actions_plugin_set_property;
 
232
  gobject_class->get_property = actions_plugin_get_property;
 
233
 
 
234
  plugin_class = XFCE_PANEL_PLUGIN_CLASS (klass);
 
235
  plugin_class->construct = actions_plugin_construct;
 
236
  plugin_class->free_data = actions_plugin_free_data;
 
237
  plugin_class->size_changed = actions_plugin_size_changed;
 
238
  plugin_class->configure_plugin = actions_plugin_configure_plugin;
 
239
  plugin_class->mode_changed = actions_plugin_mode_changed;
 
240
 
 
241
  g_object_class_install_property (gobject_class,
 
242
                                   PROP_ITEMS,
 
243
                                   g_param_spec_boxed ("items",
 
244
                                                       NULL, NULL,
 
245
                                                       PANEL_PROPERTIES_TYPE_VALUE_ARRAY,
 
246
                                                       EXO_PARAM_READWRITE));
 
247
 
 
248
  g_object_class_install_property (gobject_class,
 
249
                                   PROP_APPEARANCE,
 
250
                                   g_param_spec_uint ("appearance",
 
251
                                                      NULL, NULL,
 
252
                                                      APPEARANCE_TYPE_BUTTONS,
 
253
                                                      APPEARANCE_TYPE_MENU,
 
254
                                                      APPEARANCE_TYPE_MENU,
 
255
                                                      EXO_PARAM_READWRITE));
 
256
 
 
257
  g_object_class_install_property (gobject_class,
 
258
                                   PROP_INVERT_ORIENTATION,
 
259
                                   g_param_spec_boolean ("invert-orientation",
 
260
                                                         NULL, NULL,
 
261
                                                         FALSE,
 
262
                                                         EXO_PARAM_READWRITE));
 
263
 
 
264
  g_object_class_install_property (gobject_class,
 
265
                                   PROP_ASK_CONFIRMATION,
 
266
                                   g_param_spec_boolean ("ask-confirmation",
 
267
                                                         NULL, NULL,
 
268
                                                         TRUE,
 
269
                                                         EXO_PARAM_READWRITE));
 
270
 
 
271
  menu_icon_size = gtk_icon_size_from_name ("panel-actions-menu");
 
272
  if (menu_icon_size == GTK_ICON_SIZE_INVALID)
 
273
    menu_icon_size = gtk_icon_size_register ("panel-actions-menu",
 
274
                                             DEFAULT_ICON_SIZE,
 
275
                                             DEFAULT_ICON_SIZE);
 
276
 
 
277
  action_quark = g_quark_from_string ("panel-action-quark");
 
278
}
 
279
 
 
280
 
 
281
 
 
282
static void
 
283
actions_plugin_init (ActionsPlugin *plugin)
 
284
{
 
285
  plugin->type = APPEARANCE_TYPE_MENU;
 
286
  plugin->invert_orientation = FALSE;
 
287
  plugin->ask_confirmation = TRUE;
 
288
}
 
289
 
 
290
 
 
291
 
 
292
static void
 
293
actions_plugin_get_property (GObject    *object,
 
294
                             guint       prop_id,
 
295
                             GValue     *value,
 
296
                             GParamSpec *pspec)
 
297
{
 
298
  ActionsPlugin *plugin = XFCE_ACTIONS_PLUGIN (object);
 
299
 
 
300
  switch (prop_id)
 
301
    {
 
302
    case PROP_ITEMS:
 
303
      g_value_set_boxed (value, plugin->items);
 
304
      break;
 
305
 
 
306
    case PROP_APPEARANCE:
 
307
      g_value_set_uint (value, plugin->type);
 
308
      break;
 
309
 
 
310
    case PROP_INVERT_ORIENTATION:
 
311
      g_value_set_boolean (value, plugin->invert_orientation);
 
312
      break;
 
313
 
 
314
    case PROP_ASK_CONFIRMATION:
 
315
      g_value_set_boolean (value, plugin->ask_confirmation);
 
316
      break;
 
317
 
 
318
    default:
 
319
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
320
      break;
 
321
    }
 
322
}
 
323
 
 
324
 
 
325
 
 
326
static void
 
327
actions_plugin_set_property (GObject      *object,
 
328
                             guint         prop_id,
 
329
                             const GValue *value,
 
330
                             GParamSpec   *pspec)
 
331
{
 
332
  ActionsPlugin *plugin = XFCE_ACTIONS_PLUGIN (object);
 
333
 
 
334
  switch (prop_id)
 
335
    {
 
336
    case PROP_ITEMS:
 
337
      if (plugin->items != NULL)
 
338
        xfconf_array_free (plugin->items);
 
339
      plugin->items = g_value_dup_boxed (value);
 
340
      actions_plugin_pack (plugin);
 
341
      break;
 
342
 
 
343
    case PROP_APPEARANCE:
 
344
      plugin->type = g_value_get_uint (value);
 
345
      actions_plugin_pack (plugin);
 
346
      break;
 
347
 
 
348
    case PROP_INVERT_ORIENTATION:
 
349
      plugin->invert_orientation = g_value_get_boolean (value);
 
350
      actions_plugin_pack (plugin);
 
351
      break;
 
352
 
 
353
    case PROP_ASK_CONFIRMATION:
 
354
      plugin->ask_confirmation = g_value_get_boolean (value);
 
355
      break;
 
356
 
 
357
    default:
 
358
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
359
      break;
 
360
    }
 
361
}
 
362
 
 
363
 
 
364
 
 
365
static void
 
366
actions_plugin_construct (XfcePanelPlugin *panel_plugin)
 
367
{
 
368
  ActionsPlugin       *plugin = XFCE_ACTIONS_PLUGIN (panel_plugin);
 
369
  const PanelProperty  properties[] =
 
370
  {
 
371
    { "items", PANEL_PROPERTIES_TYPE_VALUE_ARRAY },
 
372
    { "appearance", G_TYPE_UINT },
 
373
    { "invert-orientation", G_TYPE_BOOLEAN },
 
374
    { "ask-confirmation", G_TYPE_BOOLEAN },
 
375
    { NULL }
 
376
  };
 
377
 
 
378
  /* show the properties dialog */
 
379
  xfce_panel_plugin_menu_show_configure (XFCE_PANEL_PLUGIN (plugin));
 
380
 
 
381
  /* bind all properties */
 
382
  panel_properties_bind (NULL, G_OBJECT (plugin),
 
383
                         xfce_panel_plugin_get_property_base (panel_plugin),
 
384
                         properties, FALSE);
 
385
 
 
386
  actions_plugin_pack (plugin);
 
387
 
 
388
  /* set orientation and size */
 
389
  actions_plugin_mode_changed (panel_plugin,
 
390
      xfce_panel_plugin_get_mode (panel_plugin));
 
391
}
 
392
 
 
393
 
 
394
 
 
395
static void
 
396
actions_plugin_free_data (XfcePanelPlugin *panel_plugin)
 
397
{
 
398
  ActionsPlugin *plugin = XFCE_ACTIONS_PLUGIN (panel_plugin);
 
399
 
 
400
  if (plugin->pack_idle_id != 0)
 
401
    g_source_remove (plugin->pack_idle_id);
 
402
 
 
403
  if (plugin->items != NULL)
 
404
    xfconf_array_free (plugin->items);
 
405
 
 
406
  if (plugin->menu != NULL)
 
407
    gtk_widget_destroy (plugin->menu);
 
408
}
 
409
 
 
410
 
 
411
 
 
412
static void
 
413
actions_plugin_size_changed_child (GtkWidget *child,
 
414
                                   gpointer   data)
 
415
{
 
416
  gint size = GPOINTER_TO_INT (data);
 
417
 
 
418
  if (!GTK_IS_SEPARATOR (child))
 
419
    gtk_widget_set_size_request (child, size, size);
 
420
}
 
421
 
 
422
 
 
423
 
 
424
static gboolean
 
425
actions_plugin_size_changed (XfcePanelPlugin *panel_plugin,
 
426
                             gint             size)
 
427
{
 
428
  ActionsPlugin *plugin = XFCE_ACTIONS_PLUGIN (panel_plugin);
 
429
  GtkWidget     *box;
 
430
  GList         *children, *li;
 
431
  gint           n_children;
 
432
  gint           child_size;
 
433
  gint           max_size;
 
434
 
 
435
  if (plugin->type == APPEARANCE_TYPE_BUTTONS)
 
436
    {
 
437
      max_size = size / xfce_panel_plugin_get_nrows (panel_plugin);
 
438
      box = gtk_bin_get_child (GTK_BIN (plugin));
 
439
      if (box != NULL)
 
440
        {
 
441
          if (plugin->invert_orientation !=
 
442
              (xfce_panel_plugin_get_mode (panel_plugin) == XFCE_PANEL_PLUGIN_MODE_DESKBAR))
 
443
            {
 
444
              children = gtk_container_get_children (GTK_CONTAINER (box));
 
445
              if (G_UNLIKELY (children == NULL))
 
446
                return TRUE;
 
447
              n_children = g_list_length (children);
 
448
 
 
449
              for (li = children; li != NULL; li = li->next)
 
450
                {
 
451
                  child_size = MIN (size / n_children, max_size);
 
452
                  size -= child_size;
 
453
                  n_children--;
 
454
 
 
455
                  gtk_widget_set_size_request (GTK_WIDGET (li->data),
 
456
                                               child_size, child_size);
 
457
                }
 
458
            }
 
459
          else
 
460
            {
 
461
              gtk_container_foreach (GTK_CONTAINER (box),
 
462
                  actions_plugin_size_changed_child,
 
463
                  GINT_TO_POINTER (max_size));
 
464
            }
 
465
        }
 
466
    }
 
467
 
 
468
  return TRUE;
 
469
}
 
470
 
 
471
 
 
472
 
 
473
static gboolean
 
474
actions_plugin_configure_store (gpointer data)
 
475
{
 
476
  ActionsPlugin *plugin = XFCE_ACTIONS_PLUGIN (data);
 
477
  GtkTreeModel  *model;
 
478
  GtkTreeIter    iter;
 
479
  GPtrArray     *array;
 
480
  gboolean       visible;
 
481
  gchar         *name;
 
482
  GValue        *val;
 
483
  gchar          save_name[32];
 
484
 
 
485
  model = g_object_get_data (G_OBJECT (plugin), "items-store");
 
486
  panel_return_val_if_fail (GTK_IS_LIST_STORE (model), FALSE);
 
487
 
 
488
  array = g_ptr_array_new ();
 
489
 
 
490
  if (gtk_tree_model_get_iter_first (model, &iter))
 
491
    {
 
492
      for (;;)
 
493
        {
 
494
          gtk_tree_model_get (model, &iter,
 
495
                              COLUMN_VISIBLE, &visible,
 
496
                              COLUMN_NAME, &name, -1);
 
497
 
 
498
          val = g_new0 (GValue, 1);
 
499
          g_value_init (val, G_TYPE_STRING);
 
500
          g_snprintf (save_name, sizeof (save_name), "%s%s",
 
501
                      visible ? "+" : "-", name);
 
502
          g_value_set_string (val, save_name);
 
503
          g_ptr_array_add (array, val);
 
504
          g_free (name);
 
505
 
 
506
          if (!gtk_tree_model_iter_next (model, &iter))
 
507
            break;
 
508
        }
 
509
    }
 
510
 
 
511
  /* Store the new array */
 
512
  if (plugin->items != NULL)
 
513
    xfconf_array_free (plugin->items);
 
514
  plugin->items = array;
 
515
  g_object_notify (G_OBJECT (plugin), "items");
 
516
 
 
517
  return FALSE;
 
518
}
 
519
 
 
520
 
 
521
 
 
522
static void
 
523
actions_plugin_configure_store_idle (ActionsPlugin *plugin)
 
524
{
 
525
  g_idle_add (actions_plugin_configure_store, plugin);
 
526
}
 
527
 
 
528
 
 
529
 
 
530
static void
 
531
actions_plugin_configure_visible_toggled (GtkCellRendererToggle *renderer,
 
532
                                          const gchar           *path_string,
 
533
                                          ActionsPlugin         *plugin)
 
534
{
 
535
  GtkTreeIter   iter;
 
536
  gboolean      visible;
 
537
  GtkTreeModel *model;
 
538
 
 
539
  panel_return_if_fail (XFCE_IS_ACTIONS_PLUGIN (plugin));
 
540
 
 
541
  model = g_object_get_data (G_OBJECT (plugin), "items-store");
 
542
  panel_return_if_fail (GTK_IS_LIST_STORE (model));
 
543
  if (gtk_tree_model_get_iter_from_string (model, &iter, path_string))
 
544
    {
 
545
      gtk_tree_model_get (model, &iter, COLUMN_VISIBLE, &visible, -1);
 
546
      gtk_list_store_set (GTK_LIST_STORE (model), &iter,
 
547
                          COLUMN_VISIBLE, !visible, -1);
 
548
 
 
549
      actions_plugin_configure_store (plugin);
 
550
    }
 
551
}
 
552
 
 
553
 
 
554
 
 
555
static ActionEntry *
 
556
actions_plugin_lookup_entry (const gchar *name)
 
557
{
 
558
  guint i;
 
559
 
 
560
  for (i = 0; i < G_N_ELEMENTS (action_entries); i++)
 
561
    if (g_strcmp0 (name, action_entries[i].name) == 0)
 
562
      return &action_entries[i];
 
563
 
 
564
  return NULL;
 
565
}
 
566
 
 
567
 
 
568
 
 
569
static void
 
570
actions_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
 
571
{
 
572
  ActionsPlugin *plugin = XFCE_ACTIONS_PLUGIN (panel_plugin);
 
573
  GtkBuilder    *builder;
 
574
  GObject       *dialog;
 
575
  GObject       *object;
 
576
  GObject       *combo;
 
577
  ActionEntry   *entry;
 
578
  guint          i;
 
579
  const GValue  *val;
 
580
  const gchar   *name;
 
581
  guint          n;
 
582
  GObject       *store;
 
583
  gboolean       found;
 
584
  GtkTreeIter    iter;
 
585
  gchar         *sep_str;
 
586
  const gchar   *display_name;
 
587
 
 
588
  panel_return_if_fail (XFCE_IS_ACTIONS_PLUGIN (plugin));
 
589
  panel_return_if_fail (plugin->items != NULL);
 
590
 
 
591
  /* setup the dialog */
 
592
  PANEL_UTILS_LINK_4UI
 
593
  builder = panel_utils_builder_new (panel_plugin, actions_dialog_ui,
 
594
                                     actions_dialog_ui_length, &dialog);
 
595
  if (G_UNLIKELY (builder == NULL))
 
596
    return;
 
597
 
 
598
  combo = gtk_builder_get_object (builder, "combo-mode");
 
599
  exo_mutual_binding_new (G_OBJECT (plugin), "appearance",
 
600
                          G_OBJECT (combo), "active");
 
601
 
 
602
  object = gtk_builder_get_object (builder, "invert-orientation");
 
603
  exo_mutual_binding_new (G_OBJECT (plugin), "invert-orientation",
 
604
                          G_OBJECT (object), "active");
 
605
  exo_binding_new_with_negation (G_OBJECT (combo), "active",
 
606
                                 G_OBJECT (object), "sensitive");
 
607
 
 
608
  object = gtk_builder_get_object (builder, "confirmation-dialog");
 
609
  exo_mutual_binding_new (G_OBJECT (plugin), "ask-confirmation",
 
610
                          G_OBJECT (object), "active");
 
611
 
 
612
  store = gtk_builder_get_object (builder, "items-store");
 
613
  panel_return_if_fail (GTK_IS_LIST_STORE (store));
 
614
  g_object_set_data (G_OBJECT (plugin), "items-store", store);
 
615
 
 
616
  object = gtk_builder_get_object (builder, "visible-toggle");
 
617
  panel_return_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (object));
 
618
  g_signal_connect (G_OBJECT (object), "toggled",
 
619
      G_CALLBACK (actions_plugin_configure_visible_toggled), plugin);
 
620
 
 
621
  sep_str = g_markup_printf_escaped ("<span color='grey' style='italic'>%s</span>", _("Separator"));
 
622
 
 
623
  /* add items from the settings */
 
624
  for (i = 0; i < plugin->items->len; i++)
 
625
    {
 
626
      /* get the value and check if it is within range */
 
627
      val = g_ptr_array_index (plugin->items, i);
 
628
      name = g_value_get_string (val);
 
629
      if (exo_str_is_empty (name))
 
630
        continue;
 
631
 
 
632
      /* find the entry in the available actions */
 
633
      entry = actions_plugin_lookup_entry (name + 1);
 
634
      if (entry == NULL)
 
635
        continue;
 
636
 
 
637
      if (entry->type == ACTION_TYPE_SEPARATOR)
 
638
        display_name = sep_str;
 
639
      else
 
640
        display_name = _(entry->display_name);
 
641
 
 
642
      /* insert in the model */
 
643
      gtk_list_store_insert_with_values (GTK_LIST_STORE (store), NULL, i,
 
644
                                         COLUMN_VISIBLE, *name == '+',
 
645
                                         COLUMN_DISPLAY_NAME, display_name,
 
646
                                         COLUMN_NAME, entry->name,
 
647
                                         COLUMN_TYPE, entry->type,
 
648
                                         -1);
 
649
    }
 
650
 
 
651
  g_free (sep_str);
 
652
 
 
653
  /* check if there are known actions not in the settings */
 
654
  for (i = 0; i < G_N_ELEMENTS (action_entries); i++)
 
655
    {
 
656
      entry = &action_entries[i];
 
657
      found = FALSE;
 
658
 
 
659
      for (n = 0; n < plugin->items->len; n++)
 
660
        {
 
661
          val = g_ptr_array_index (plugin->items, n);
 
662
          name = g_value_get_string (val);
 
663
          if (g_strcmp0 (entry->name, name + 1) == 0)
 
664
            {
 
665
              found = TRUE;
 
666
              break;
 
667
            }
 
668
        }
 
669
 
 
670
      if (!found)
 
671
        {
 
672
          gtk_list_store_append (GTK_LIST_STORE (store), &iter);
 
673
          gtk_list_store_set (GTK_LIST_STORE (store), &iter,
 
674
                              COLUMN_VISIBLE, FALSE,
 
675
                              COLUMN_DISPLAY_NAME, _(entry->display_name),
 
676
                              COLUMN_TYPE, entry->type,
 
677
                              COLUMN_NAME, entry->name,
 
678
                              -1);
 
679
        }
 
680
    }
 
681
 
 
682
  /* save on dnd changes */
 
683
  g_signal_connect_swapped (G_OBJECT (store), "row-inserted",
 
684
      G_CALLBACK (actions_plugin_configure_store_idle), plugin);
 
685
 
 
686
  gtk_widget_show (GTK_WIDGET (dialog));
 
687
}
 
688
 
 
689
 
 
690
 
 
691
static void
 
692
actions_plugin_mode_changed (XfcePanelPlugin     *panel_plugin,
 
693
                             XfcePanelPluginMode  mode)
 
694
{
 
695
  actions_plugin_pack (XFCE_ACTIONS_PLUGIN (panel_plugin));
 
696
}
 
697
 
 
698
 
 
699
 
 
700
static gboolean
 
701
actions_plugin_action_confirmation_time (gpointer data)
 
702
{
 
703
  ActionTimeout *timeout = data;
 
704
 
 
705
  panel_return_val_if_fail (timeout->entry != NULL, FALSE);
 
706
 
 
707
  if (timeout->time_left == 0)
 
708
    {
 
709
      /* unattended shutdown, don't save the session to avoid blocking the logout */
 
710
      timeout->unattended = TRUE;
 
711
 
 
712
      gtk_dialog_response (GTK_DIALOG (timeout->dialog),
 
713
                           GTK_RESPONSE_ACCEPT);
 
714
    }
 
715
  else
 
716
    {
 
717
      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (timeout->dialog),
 
718
                                                _(timeout->entry->status),
 
719
                                                timeout->time_left);
 
720
    }
 
721
 
 
722
  return --timeout->time_left >= 0;
 
723
}
 
724
 
 
725
 
 
726
 
 
727
static gboolean
 
728
actions_plugin_action_confirmation (ActionsPlugin *plugin,
 
729
                                    ActionEntry   *entry,
 
730
                                    gboolean      *unattended)
 
731
{
 
732
  GtkWidget     *dialog;
 
733
  GtkWidget     *button;
 
734
  gint           result;
 
735
  GtkWidget     *image;
 
736
  ActionTimeout *timeout;
 
737
  guint          timeout_id;
 
738
 
 
739
  panel_return_val_if_fail (entry->question != NULL, FALSE);
 
740
  panel_return_val_if_fail (entry->status != NULL, FALSE);
 
741
 
 
742
  dialog = gtk_message_dialog_new (NULL, 0,
 
743
                                   GTK_MESSAGE_QUESTION, GTK_BUTTONS_CANCEL,
 
744
                                   "%s", _(entry->question));
 
745
  gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);
 
746
  gtk_window_stick (GTK_WINDOW (dialog));
 
747
  gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE);
 
748
  gtk_window_set_title (GTK_WINDOW (dialog), _(entry->name));
 
749
 
 
750
  button = gtk_dialog_add_button (GTK_DIALOG (dialog), _(entry->mnemonic), GTK_RESPONSE_ACCEPT);
 
751
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
 
752
 
 
753
  image = gtk_image_new_from_icon_name (entry->icon_name, GTK_ICON_SIZE_BUTTON);
 
754
  gtk_button_set_image (GTK_BUTTON (button), image);
 
755
 
 
756
  timeout = g_slice_new0 (ActionTimeout);
 
757
  timeout->entry = entry;
 
758
  timeout->time_left = DEFAULT_TIMEOUT;
 
759
  timeout->dialog = dialog;
 
760
  timeout->unattended = FALSE;
 
761
 
 
762
  /* first second looks out of sync with a second timer */
 
763
  timeout_id = g_timeout_add (1000, actions_plugin_action_confirmation_time, timeout);
 
764
  actions_plugin_action_confirmation_time (timeout);
 
765
 
 
766
  result = gtk_dialog_run (GTK_DIALOG (dialog));
 
767
 
 
768
  if (unattended != NULL)
 
769
    *unattended = timeout->unattended;
 
770
 
 
771
  g_source_remove (timeout_id);
 
772
  gtk_widget_destroy (dialog);
 
773
  g_slice_free (ActionTimeout, timeout);
 
774
 
 
775
  return result == GTK_RESPONSE_ACCEPT;
 
776
}
 
777
 
 
778
 
 
779
 
 
780
static DBusGProxy *
 
781
actions_plugin_action_dbus_proxy_session (DBusGConnection *conn)
 
782
{
 
783
  return dbus_g_proxy_new_for_name (conn,
 
784
                                    "org.xfce.SessionManager",
 
785
                                    "/org/xfce/SessionManager",
 
786
                                    "org.xfce.Session.Manager");
 
787
}
 
788
 
 
789
 
 
790
 
 
791
static gboolean
 
792
actions_plugin_action_dbus_xfsm (const gchar  *method,
 
793
                                 gboolean      show_dialog,
 
794
                                 gboolean      allow_save,
 
795
                                 GError      **error)
 
796
{
 
797
  DBusGConnection *conn;
 
798
  DBusGProxy      *proxy;
 
799
  gboolean         retval = FALSE;
 
800
 
 
801
  conn = dbus_g_bus_get (DBUS_BUS_SESSION, error);
 
802
  if (conn == NULL)
 
803
    return FALSE;
 
804
 
 
805
  proxy = actions_plugin_action_dbus_proxy_session (conn);
 
806
  if (G_LIKELY (proxy != NULL))
 
807
    {
 
808
      if (g_strcmp0 (method, "Logout") == 0)
 
809
        {
 
810
          retval = dbus_g_proxy_call (proxy, method, error,
 
811
                                      G_TYPE_BOOLEAN, show_dialog,
 
812
                                      G_TYPE_BOOLEAN, allow_save,
 
813
                                      G_TYPE_INVALID, G_TYPE_INVALID);
 
814
        }
 
815
      else if (g_strcmp0 (method, "Suspend") == 0
 
816
               || g_strcmp0 (method, "Hibernate") == 0)
 
817
        {
 
818
          retval = dbus_g_proxy_call (proxy, method, error,
 
819
                                      G_TYPE_INVALID, G_TYPE_INVALID);
 
820
        }
 
821
      else
 
822
        {
 
823
          retval = dbus_g_proxy_call (proxy, method, error,
 
824
                                      G_TYPE_BOOLEAN, allow_save,
 
825
                                      G_TYPE_INVALID, G_TYPE_INVALID);
 
826
        }
 
827
 
 
828
      g_object_unref (G_OBJECT (proxy));
 
829
    }
 
830
 
 
831
  return retval;
 
832
}
 
833
 
 
834
 
 
835
 
 
836
static gboolean
 
837
actions_plugin_action_dbus_can (DBusGProxy  *proxy,
 
838
                                const gchar *method)
 
839
{
 
840
  gboolean allowed = FALSE;
 
841
 
 
842
  if (dbus_g_proxy_call (proxy, method, NULL,
 
843
                         G_TYPE_INVALID,
 
844
                         G_TYPE_BOOLEAN, &allowed,
 
845
                         G_TYPE_INVALID))
 
846
    return allowed;
 
847
 
 
848
  return FALSE;
 
849
}
 
850
 
 
851
 
 
852
 
 
853
static ActionType
 
854
actions_plugin_actions_allowed (void)
 
855
{
 
856
  DBusGConnection *conn;
 
857
  ActionType       allow_mask = ACTION_TYPE_SEPARATOR;
 
858
  gchar           *path;
 
859
  DBusGProxy      *proxy;
 
860
  GError          *error = NULL;
 
861
 
 
862
  /* check for commands we use */
 
863
  path = g_find_program_in_path ("gdmflexiserver");
 
864
  if (path != NULL)
 
865
    PANEL_SET_FLAG (allow_mask, ACTION_TYPE_SWITCH_USER);
 
866
  g_free (path);
 
867
 
 
868
  path = g_find_program_in_path ("xflock4");
 
869
  if (path != NULL)
 
870
    PANEL_SET_FLAG (allow_mask, ACTION_TYPE_LOCK_SCREEN);
 
871
  g_free (path);
 
872
 
 
873
  /* session bus for querying the managers */
 
874
  conn = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
 
875
  if (conn != NULL)
 
876
    {
 
877
      /* xfce4-session */
 
878
      proxy = actions_plugin_action_dbus_proxy_session (conn);
 
879
      if (G_LIKELY (proxy != NULL))
 
880
        {
 
881
          /* when xfce4-session is connected, we can logout */
 
882
          PANEL_SET_FLAG (allow_mask, ACTION_TYPE_LOGOUT | ACTION_TYPE_LOGOUT_DIALOG);
 
883
 
 
884
          if (actions_plugin_action_dbus_can (proxy, "CanShutdown"))
 
885
            PANEL_SET_FLAG (allow_mask, ACTION_TYPE_SHUTDOWN);
 
886
 
 
887
          if (actions_plugin_action_dbus_can (proxy, "CanRestart"))
 
888
            PANEL_SET_FLAG (allow_mask, ACTION_TYPE_RESTART);
 
889
        
 
890
          if (actions_plugin_action_dbus_can (proxy, "CanSuspend"))
 
891
            PANEL_SET_FLAG (allow_mask, ACTION_TYPE_SUSPEND);
 
892
          
 
893
          if (actions_plugin_action_dbus_can (proxy, "CanHibernate"))
 
894
            PANEL_SET_FLAG (allow_mask, ACTION_TYPE_HIBERNATE);
 
895
 
 
896
          g_object_unref (G_OBJECT (proxy));
 
897
        }
 
898
    }
 
899
  else
 
900
    {
 
901
      g_critical ("Unable to open DBus session bus: %s", error->message);
 
902
      g_error_free (error);
 
903
    }
 
904
 
 
905
  return allow_mask;
 
906
}
 
907
 
 
908
 
 
909
 
 
910
static void
 
911
actions_plugin_action_activate (GtkWidget      *widget,
 
912
                                ActionsPlugin  *plugin)
 
913
{
 
914
  ActionEntry *entry;
 
915
  gboolean     unattended = FALSE;
 
916
  GError      *error = NULL;
 
917
  gboolean     succeed = FALSE;
 
918
 
 
919
  entry = g_object_get_qdata (G_OBJECT (widget), action_quark);
 
920
  panel_return_if_fail (entry != NULL);
 
921
 
 
922
  if (plugin->ask_confirmation
 
923
      && entry->question != NULL
 
924
      && entry->status != NULL
 
925
      && !actions_plugin_action_confirmation (plugin, entry, &unattended))
 
926
    return;
 
927
 
 
928
  switch (entry->type)
 
929
    {
 
930
    case ACTION_TYPE_LOGOUT:
 
931
      succeed = actions_plugin_action_dbus_xfsm ("Logout", FALSE,
 
932
                                                 !unattended, &error);
 
933
      break;
 
934
 
 
935
    case ACTION_TYPE_LOGOUT_DIALOG:
 
936
      succeed = actions_plugin_action_dbus_xfsm ("Logout", TRUE,
 
937
                                                 !unattended, &error);
 
938
      break;
 
939
 
 
940
    case ACTION_TYPE_RESTART:
 
941
      succeed = actions_plugin_action_dbus_xfsm ("Restart", FALSE,
 
942
                                                 !unattended, &error);
 
943
      break;
 
944
 
 
945
    case ACTION_TYPE_SHUTDOWN:
 
946
      succeed = actions_plugin_action_dbus_xfsm ("Shutdown", FALSE,
 
947
                                                 !unattended, &error);
 
948
      break;
 
949
 
 
950
    case ACTION_TYPE_HIBERNATE:
 
951
      succeed = actions_plugin_action_dbus_xfsm ("Hibernate", FALSE,
 
952
                                                 FALSE, &error);
 
953
      break;
 
954
 
 
955
    case ACTION_TYPE_SUSPEND:
 
956
      succeed = actions_plugin_action_dbus_xfsm ("Suspend", FALSE,
 
957
                                                 FALSE, &error);
 
958
      break;
 
959
 
 
960
    case ACTION_TYPE_SWITCH_USER:
 
961
      succeed = g_spawn_command_line_async ("gdmflexiserver", &error);
 
962
      break;
 
963
 
 
964
    case ACTION_TYPE_LOCK_SCREEN:
 
965
      succeed = g_spawn_command_line_async ("xflock4", &error);
 
966
      break;
 
967
 
 
968
    default:
 
969
      panel_assert_not_reached ();
 
970
      return;
 
971
    }
 
972
 
 
973
  if (!succeed)
 
974
    {
 
975
      xfce_dialog_show_error (NULL, error,
 
976
                              _("Failed to run action \"%s\""),
 
977
                              _(entry->display_name));
 
978
    }
 
979
}
 
980
 
 
981
 
 
982
 
 
983
static GtkWidget *
 
984
actions_plugin_action_button (ActionsPlugin  *plugin,
 
985
                              const gchar    *name,
 
986
                              GtkOrientation  orientation,
 
987
                              ActionType     *type)
 
988
{
 
989
  GtkWidget   *widget;
 
990
  GtkWidget   *image;
 
991
  ActionEntry *entry;
 
992
 
 
993
  /* lookup the action entry */
 
994
  entry = actions_plugin_lookup_entry (name);
 
995
  if (entry == NULL)
 
996
    return NULL;
 
997
 
 
998
  if (type)
 
999
    *type = entry->type;
 
1000
 
 
1001
  if (entry->type == ACTION_TYPE_SEPARATOR)
 
1002
    {
 
1003
      if (orientation == GTK_ORIENTATION_HORIZONTAL)
 
1004
        widget = gtk_vseparator_new ();
 
1005
      else
 
1006
        widget = gtk_hseparator_new ();
 
1007
    }
 
1008
  else
 
1009
    {
 
1010
      widget = xfce_panel_create_button ();
 
1011
      gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE);
 
1012
      g_object_set_qdata (G_OBJECT (widget), action_quark, entry);
 
1013
      gtk_widget_set_tooltip_text (widget, _(entry->display_name));
 
1014
      g_signal_connect (G_OBJECT (widget), "clicked",
 
1015
          G_CALLBACK (actions_plugin_action_activate), plugin);
 
1016
 
 
1017
      image = xfce_panel_image_new_from_source (entry->icon_name);
 
1018
      gtk_container_add (GTK_CONTAINER (widget), image);
 
1019
      gtk_widget_show (image);
 
1020
    }
 
1021
 
 
1022
  xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), widget);
 
1023
 
 
1024
  return widget;
 
1025
}
 
1026
 
 
1027
 
 
1028
 
 
1029
static GtkWidget *
 
1030
actions_plugin_action_menu_item (ActionsPlugin *plugin,
 
1031
                                 const gchar   *name,
 
1032
                                 gint           size,
 
1033
                                 ActionType    *type)
 
1034
{
 
1035
  GtkWidget   *mi;
 
1036
  GtkWidget   *image;
 
1037
  ActionEntry *entry;
 
1038
 
 
1039
  /* lookup the action entry */
 
1040
  entry = actions_plugin_lookup_entry (name);
 
1041
  if (entry == NULL)
 
1042
    return NULL;
 
1043
 
 
1044
  if (type)
 
1045
    *type = entry->type;
 
1046
 
 
1047
  if (entry->type == ACTION_TYPE_SEPARATOR)
 
1048
    return gtk_separator_menu_item_new ();
 
1049
 
 
1050
  mi = gtk_image_menu_item_new_with_mnemonic (_(entry->mnemonic));
 
1051
  g_object_set_qdata (G_OBJECT (mi), action_quark, entry);
 
1052
  g_signal_connect (G_OBJECT (mi), "activate",
 
1053
      G_CALLBACK (actions_plugin_action_activate), plugin);
 
1054
 
 
1055
  if (size > 0)
 
1056
    {
 
1057
      image = xfce_panel_image_new_from_source (entry->icon_name);
 
1058
      xfce_panel_image_set_size (XFCE_PANEL_IMAGE (image), size);
 
1059
      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image);
 
1060
      gtk_widget_show (image);
 
1061
    }
 
1062
 
 
1063
  return mi;
 
1064
}
 
1065
 
 
1066
 
 
1067
 
 
1068
static gboolean
 
1069
actions_plugin_pack_idle (gpointer data)
 
1070
{
 
1071
  ActionsPlugin       *plugin = XFCE_ACTIONS_PLUGIN (data);
 
1072
  GtkWidget           *label;
 
1073
  GtkWidget           *button;
 
1074
  GtkWidget           *widget;
 
1075
  const gchar         *username;
 
1076
  GtkWidget           *child;
 
1077
  GtkWidget           *box;
 
1078
  guint                i;
 
1079
  const GValue        *val;
 
1080
  const gchar         *name;
 
1081
  GtkOrientation       orientation;
 
1082
  ActionType           allowed_types;
 
1083
  ActionType           type;
 
1084
  XfcePanelPluginMode  mode;
 
1085
 
 
1086
  child = gtk_bin_get_child (GTK_BIN (plugin));
 
1087
  if (child != NULL)
 
1088
    gtk_widget_destroy (child);
 
1089
 
 
1090
  if (plugin->menu != NULL)
 
1091
    gtk_widget_destroy (plugin->menu);
 
1092
 
 
1093
  if (plugin->items == NULL)
 
1094
    plugin->items = actions_plugin_default_array ();
 
1095
 
 
1096
  allowed_types = actions_plugin_actions_allowed ();
 
1097
 
 
1098
  if (plugin->type == APPEARANCE_TYPE_BUTTONS)
 
1099
    {
 
1100
      if (xfce_panel_plugin_get_mode (XFCE_PANEL_PLUGIN (plugin)) == XFCE_PANEL_PLUGIN_MODE_VERTICAL)
 
1101
        orientation = GTK_ORIENTATION_VERTICAL;
 
1102
      else
 
1103
        orientation = GTK_ORIENTATION_HORIZONTAL;
 
1104
 
 
1105
      if (plugin->invert_orientation)
 
1106
        orientation = !orientation;
 
1107
      box = xfce_hvbox_new (orientation, FALSE, 0);
 
1108
      gtk_container_add (GTK_CONTAINER (plugin), box);
 
1109
      gtk_widget_show (box);
 
1110
 
 
1111
      for (i = 0; i < plugin->items->len; i++)
 
1112
        {
 
1113
          val = g_ptr_array_index (plugin->items, i);
 
1114
          name = g_value_get_string (val);
 
1115
          if (name == NULL || *name != '+')
 
1116
            continue;
 
1117
 
 
1118
          /* skip separators when packing buttons in the opposite
 
1119
           * orientation */
 
1120
          if (plugin->invert_orientation !=
 
1121
              (xfce_panel_plugin_get_mode (XFCE_PANEL_PLUGIN (plugin)) == XFCE_PANEL_PLUGIN_MODE_DESKBAR)
 
1122
              && g_strcmp0 (name + 1, "separator") == 0)
 
1123
            continue;
 
1124
 
 
1125
          widget = actions_plugin_action_button (plugin, name + 1, orientation, &type);
 
1126
          if (widget != NULL)
 
1127
            {
 
1128
              gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
 
1129
              gtk_widget_set_sensitive (widget, PANEL_HAS_FLAG (allowed_types, type));
 
1130
              gtk_widget_show (widget);
 
1131
            }
 
1132
        }
 
1133
 
 
1134
      actions_plugin_size_changed (XFCE_PANEL_PLUGIN (plugin),
 
1135
          xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin)));
 
1136
    }
 
1137
  else
 
1138
    {
 
1139
      /* get a decent username, not the glib defaults */
 
1140
      username = g_get_real_name ();
 
1141
      if (exo_str_is_empty (username)
 
1142
          || strcmp (username, "Unknown") == 0)
 
1143
        {
 
1144
          username = g_get_user_name ();
 
1145
          if (exo_str_is_empty (username)
 
1146
              || strcmp (username, "somebody") == 0)
 
1147
            username = _("John Doe");
 
1148
        }
 
1149
 
 
1150
      button = xfce_arrow_button_new (GTK_ARROW_NONE);
 
1151
      gtk_widget_set_name (button, "actions-button");
 
1152
      gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
 
1153
      xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), button);
 
1154
      gtk_container_add (GTK_CONTAINER (plugin), button);
 
1155
      g_signal_connect (G_OBJECT (button), "toggled",
 
1156
          G_CALLBACK (actions_plugin_menu), plugin);
 
1157
      gtk_widget_show (button);
 
1158
 
 
1159
      label = gtk_label_new (username);
 
1160
      gtk_container_add (GTK_CONTAINER (button), label);
 
1161
      mode = xfce_panel_plugin_get_mode (XFCE_PANEL_PLUGIN (plugin));
 
1162
      gtk_label_set_angle (GTK_LABEL (label),
 
1163
          (mode == XFCE_PANEL_PLUGIN_MODE_VERTICAL) ? 270 : 0);
 
1164
      gtk_widget_show (label);
 
1165
    }
 
1166
 
 
1167
  return FALSE;
 
1168
}
 
1169
 
 
1170
 
 
1171
 
 
1172
static void
 
1173
actions_plugin_pack_idle_destoyed (gpointer data)
 
1174
{
 
1175
  XFCE_ACTIONS_PLUGIN (data)->pack_idle_id = 0;
 
1176
}
 
1177
 
 
1178
 
 
1179
 
 
1180
static void
 
1181
actions_plugin_pack (ActionsPlugin *plugin)
 
1182
{
 
1183
  if (plugin->pack_idle_id == 0)
 
1184
    {
 
1185
      plugin->pack_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, actions_plugin_pack_idle,
 
1186
                                              plugin, actions_plugin_pack_idle_destoyed);
 
1187
    }
 
1188
}
 
1189
 
 
1190
 
 
1191
 
 
1192
static GPtrArray *
 
1193
actions_plugin_default_array (void)
 
1194
{
 
1195
  GPtrArray   *array;
 
1196
  GValue      *val;
 
1197
  guint        i;
 
1198
  const gchar *defaults[] =
 
1199
    {
 
1200
      "+lock-screen",
 
1201
      "+switch-user",
 
1202
      "+separator",
 
1203
      "+suspend",
 
1204
      "-hibernate",
 
1205
      "-separator",
 
1206
      "+shutdown",
 
1207
      "-restart",
 
1208
      "+separator",
 
1209
      "+logout"
 
1210
    };
 
1211
 
 
1212
  array = g_ptr_array_sized_new (G_N_ELEMENTS (defaults));
 
1213
  for (i = 0; i < G_N_ELEMENTS (defaults); i++)
 
1214
    {
 
1215
      val = g_new0 (GValue, 1);
 
1216
      g_value_init (val, G_TYPE_STRING);
 
1217
      g_value_set_static_string (val, defaults[i]);
 
1218
      g_ptr_array_add (array, val);
 
1219
    }
 
1220
 
 
1221
  return array;
 
1222
}
 
1223
 
 
1224
 
 
1225
 
 
1226
static void
 
1227
actions_plugin_menu_deactivate (GtkWidget *menu,
 
1228
                                GtkWidget *button)
 
1229
{
 
1230
  panel_return_if_fail (button == NULL || GTK_IS_TOGGLE_BUTTON (button));
 
1231
  panel_return_if_fail (GTK_IS_MENU (menu));
 
1232
 
 
1233
  /* button is NULL when we popup the menu under the cursor position */
 
1234
  if (button != NULL)
 
1235
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
 
1236
 
 
1237
  gtk_menu_popdown (GTK_MENU (menu));
 
1238
}
 
1239
 
 
1240
 
 
1241
 
 
1242
static void
 
1243
actions_plugin_menu (GtkWidget     *button,
 
1244
                     ActionsPlugin *plugin)
 
1245
{
 
1246
  guint         i;
 
1247
  const GValue *val;
 
1248
  const gchar  *name;
 
1249
  GtkWidget    *mi;
 
1250
  gint          w, h, size;
 
1251
  ActionType    type;
 
1252
  ActionType    allowed_types;
 
1253
 
 
1254
  panel_return_if_fail (XFCE_IS_ACTIONS_PLUGIN (plugin));
 
1255
  panel_return_if_fail (button != NULL);
 
1256
 
 
1257
  /* do not popup the menu if the button is being toggled off */
 
1258
  if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
 
1259
    return;
 
1260
 
 
1261
  if (plugin->menu == NULL)
 
1262
    {
 
1263
      plugin->menu = gtk_menu_new ();
 
1264
      g_signal_connect (G_OBJECT (plugin->menu), "selection-done",
 
1265
          G_CALLBACK (actions_plugin_menu_deactivate), button);
 
1266
      g_object_add_weak_pointer (G_OBJECT (plugin->menu), (gpointer) &plugin->menu);
 
1267
 
 
1268
      size = DEFAULT_ICON_SIZE;
 
1269
      if (gtk_icon_size_lookup (menu_icon_size, &w, &h))
 
1270
        size = MIN (w, h);
 
1271
 
 
1272
      allowed_types = actions_plugin_actions_allowed ();
 
1273
 
 
1274
      for (i = 0; i < plugin->items->len; i++)
 
1275
        {
 
1276
          val = g_ptr_array_index (plugin->items, i);
 
1277
          name = g_value_get_string (val);
 
1278
          if (name == NULL || *name != '+')
 
1279
            continue;
 
1280
 
 
1281
          mi = actions_plugin_action_menu_item (plugin, name + 1, size, &type);
 
1282
          if (mi != NULL)
 
1283
            {
 
1284
              gtk_menu_shell_append (GTK_MENU_SHELL (plugin->menu), mi);
 
1285
              gtk_widget_set_sensitive (mi, PANEL_HAS_FLAG (allowed_types, type));
 
1286
              gtk_widget_show (mi);
 
1287
            }
 
1288
        }
 
1289
    }
 
1290
 
 
1291
  gtk_menu_popup (GTK_MENU (plugin->menu), NULL, NULL,
 
1292
                  button != NULL ? xfce_panel_plugin_position_menu : NULL,
 
1293
                  plugin, 1, gtk_get_current_event_time ());
 
1294
}