21
21
#include <cairo-dock.h>
23
23
#include "applet-struct.h"
24
#include "applet-menu-callbacks.h"
25
#include "applet-util.h"
26
24
#include "applet-menu.h"
29
GtkWidget * add_menu_separator (GtkWidget *menu)
33
menuitem = gtk_separator_menu_item_new ();
34
gtk_widget_set_sensitive (menuitem, FALSE);
35
gtk_widget_show (menuitem);
36
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
41
GtkWidget * create_fake_menu (GMenuTreeDirectory *directory)
46
menu = create_empty_menu ();
48
g_object_set_data_full (G_OBJECT (menu),
49
"panel-menu-tree-directory",
50
gmenu_tree_item_ref (directory),
51
(GDestroyNotify) gmenu_tree_item_unref);
53
g_object_set_data (G_OBJECT (menu),
54
"panel-menu-needs-loading",
55
GUINT_TO_POINTER (TRUE));
57
g_signal_connect (menu, "show",
58
G_CALLBACK (submenu_to_display), NULL);
60
idle_id = g_idle_add_full (G_PRIORITY_LOW,
61
submenu_to_display_in_idle,
64
g_object_set_data_full (G_OBJECT (menu),
66
GUINT_TO_POINTER (idle_id),
67
remove_submenu_to_display_idle);
72
void image_menu_destroy (GtkWidget *image, gpointer *data)
74
myData.image_menu_items = g_slist_remove (myData.image_menu_items, image);
75
if (myConfig.bLoadIconsAtStartup && ! myData.bIconsLoaded && myData.pPreloadedImagesList && data)
76
{ // we want to preload icon, the task has not been launched, the list is not empty and we receive data
77
myData.pPreloadedImagesList = g_list_remove (myData.pPreloadedImagesList, data);
83
void reload_image_menu_items (void)
87
for (l = myData.image_menu_items; l; l = l->next) {
88
GtkWidget *image = l->data;
91
///is_mapped = GTK_WIDGET_MAPPED (image);
92
is_mapped = gtk_widget_get_mapped (image);
95
gtk_widget_unmap (image);
97
gtk_image_set_from_pixbuf (GTK_IMAGE (image), NULL);
100
gtk_widget_map (image);
106
remove_pixmap_from_loaded (gpointer data, GObject *where_the_object_was)
110
if (myData.loaded_icons != NULL)
111
g_hash_table_remove (myData.loaded_icons, key);
115
GdkPixbuf * panel_make_menu_icon (GtkIconTheme *icon_theme,
117
const char *fallback,
119
gboolean *long_operation)
125
g_return_val_if_fail (size > 0, NULL);
129
file = panel_find_icon (icon_theme, icon, size);
130
if (file == NULL && fallback != NULL)
131
file = panel_find_icon (icon_theme, fallback, size);
136
if (long_operation != NULL)
137
*long_operation = TRUE;
143
key = g_strdup_printf ("%d:%s", size, file);
145
if (myData.loaded_icons != NULL &&
146
(pb = g_hash_table_lookup (myData.loaded_icons, key)) != NULL) {
148
g_object_ref (G_OBJECT (pb));
152
pb = gdk_pixbuf_new_from_file (file, NULL);
156
width = gdk_pixbuf_get_width (pb);
157
height = gdk_pixbuf_get_height (pb);
159
/* if we want 24 and we get 22, do nothing;
161
if (!(size - 2 <= width && width <= size &&
162
size - 2 <= height && height <= size)) {
165
tmp = gdk_pixbuf_scale_simple (pb, size, size,
166
GDK_INTERP_BILINEAR);
173
/* add icon to the hash table so we don't load it again */
184
(gdk_pixbuf_get_width (pb) != size &&
185
gdk_pixbuf_get_height (pb) != size)) {
192
width = gdk_pixbuf_get_width (pb);
193
height = gdk_pixbuf_get_height (pb);
195
if (height > width) {
196
dest_width = (size * width) / height;
200
dest_height = (size * height) / width;
203
pb2 = gdk_pixbuf_scale_simple (pb, dest_width, dest_height,
204
GDK_INTERP_BILINEAR);
205
g_object_unref (G_OBJECT (pb));
210
if (myData.loaded_icons == NULL)
211
myData.loaded_icons = g_hash_table_new_full
212
(g_str_hash, g_str_equal,
213
(GDestroyNotify) g_free,
214
(GDestroyNotify) g_object_unref);
215
g_hash_table_replace (myData.loaded_icons,
217
g_object_ref (G_OBJECT (pb)));
218
g_object_weak_ref (G_OBJECT (pb),
219
(GWeakNotify) remove_pixmap_from_loaded,
222
/* we didn't load from disk */
223
if (long_operation != NULL)
224
*long_operation = FALSE;
233
void panel_load_menu_image_deferred (GtkWidget *image_menu_item,
234
GtkIconSize icon_size,
235
///const char *stock_id,
237
const char *image_filename,
238
const char *fallback_image_filename)
242
int icon_height = myData.iPanelDefaultMenuIconSize;
244
icon = g_new0 (IconToLoad, 1);
246
gtk_icon_size_lookup (icon_size, NULL, &icon_height);
248
image = gtk_image_new ();
249
///image->requisition.width = icon_height;
250
///image->requisition.height = icon_height;
251
gtk_widget_set_size_request (image, icon_height, icon_height);
253
/* this takes over the floating ref */
254
icon->pixmap = g_object_ref (G_OBJECT (image));
255
g_object_ref_sink (G_OBJECT (image));
257
/**icon->stock_id = stock_id;
259
icon->gicon = g_object_ref (gicon);
261
icon->gicon = NULL;*/
262
icon->image = g_strdup (image_filename);
263
icon->fallback_image = g_strdup (fallback_image_filename);
264
icon->icon_size = icon_size;
266
/**g_object_set_data_full (G_OBJECT (image_menu_item),
268
g_object_ref (image),
269
(GDestroyNotify) g_object_unref);*/
271
g_signal_connect_data (image, "map",
272
G_CALLBACK (image_menu_shown), icon,
273
(GClosureNotify) icon_to_load_free, 0);
275
// pre-load all icons
276
gpointer *data = NULL;
277
if (myConfig.bLoadIconsAtStartup && ! myData.bIconsLoaded)
279
data = g_new0 (gpointer, 2);
282
myData.pPreloadedImagesList = g_list_append (myData.pPreloadedImagesList, data);
285
_gtk_image_menu_item_set_image (
286
GTK_IMAGE_MENU_ITEM (image_menu_item), image);
288
gtk_widget_show (image);
290
g_signal_connect (image, "destroy",
291
G_CALLBACK (image_menu_destroy), data);
293
myData.image_menu_items = g_slist_prepend (myData.image_menu_items, image);
295
GtkWidget * create_submenu_entry (GtkWidget *menu,
296
GMenuTreeDirectory *directory)
300
menuitem = gtk_image_menu_item_new ();
302
panel_load_menu_image_deferred (menuitem,
303
32, //panel_menu_icon_get_size (),
305
gmenu_tree_directory_get_icon (directory),
308
setup_menuitem (menuitem,
309
32, //panel_menu_icon_get_size (),
311
gmenu_tree_directory_get_name (directory));
313
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
315
gtk_widget_show (menuitem);
320
void create_submenu (GtkWidget *menu,
321
GMenuTreeDirectory *directory,
322
GMenuTreeDirectory *alias_directory)
328
menuitem = create_submenu_entry (menu, alias_directory);
330
menuitem = create_submenu_entry (menu, directory);
332
submenu = create_fake_menu (directory);
334
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
337
void create_header (GtkWidget *menu,
338
GMenuTreeHeader *header)
340
GMenuTreeDirectory *directory;
343
directory = gmenu_tree_header_get_directory (header);
344
menuitem = create_submenu_entry (menu, directory);
345
gmenu_tree_item_unref (directory);
347
g_object_set_data_full (G_OBJECT (menuitem),
348
"panel-gmenu-tree.header",
349
gmenu_tree_item_ref (header),
350
(GDestroyNotify) gmenu_tree_item_unref);
352
g_signal_connect (menuitem, "activate",
353
G_CALLBACK (gtk_false), NULL);
356
void create_menuitem (GtkWidget *menu,
357
GMenuTreeEntry *entry,
358
GMenuTreeDirectory *alias_directory)
362
menuitem = gtk_image_menu_item_new ();
364
g_object_set_data_full (G_OBJECT (menuitem),
365
"panel-menu-tree-entry",
366
gmenu_tree_item_ref (entry),
367
(GDestroyNotify) gmenu_tree_item_unref);
370
//FIXME: we should probably use this data when we do dnd or
371
//context menu for this menu item
372
g_object_set_data_full (G_OBJECT (menuitem),
373
"panel-menu-tree-alias-directory",
374
gmenu_tree_item_ref (alias_directory),
375
(GDestroyNotify) gmenu_tree_item_unref);
377
panel_load_menu_image_deferred (menuitem,
378
myData.iPanelDefaultMenuIconSize, //panel_menu_icon_get_size (),
380
alias_directory ? gmenu_tree_directory_get_icon (alias_directory) :
381
gmenu_tree_entry_get_icon (entry),
384
setup_menuitem (menuitem,
385
myData.iPanelDefaultMenuIconSize, //panel_menu_icon_get_size (),
387
alias_directory ? gmenu_tree_directory_get_name (alias_directory) :
388
gmenu_tree_entry_get_name (entry));
390
if ((alias_directory &&
391
gmenu_tree_directory_get_comment (alias_directory)) ||
393
gmenu_tree_entry_get_comment (entry)))
394
panel_util_set_tooltip_text (menuitem,
396
gmenu_tree_directory_get_comment (alias_directory) :
397
gmenu_tree_entry_get_comment (entry));
399
/*g_signal_connect_after (menuitem, "button_press_event",
400
G_CALLBACK (menuitem_button_press_event), NULL);*/
402
//if (!panel_lockdown_get_locked_down ()) {
404
static GtkTargetEntry menu_item_targets[] = {
405
{ (gchar*)"text/uri-list", 0, 0 }
408
gtk_drag_source_set (menuitem,
409
GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
410
menu_item_targets, 1,
413
if (gmenu_tree_entry_get_icon (entry) != NULL) {
417
icon = gmenu_tree_entry_get_icon (entry);
418
if (!g_path_is_absolute (icon)) {
419
icon_no_ext = panel_util_icon_remove_extension (icon);
420
gtk_drag_source_set_icon_name (menuitem,
422
g_free (icon_no_ext);
426
///g_signal_connect (G_OBJECT (menuitem), "drag_begin",
427
/// G_CALLBACK (drag_begin_menu_cb), NULL);
428
g_signal_connect (menuitem, "drag_data_get",
429
G_CALLBACK (drag_data_get_menu_cb), entry);
430
///g_signal_connect (menuitem, "drag_end",
431
/// G_CALLBACK (drag_end_menu_cb), NULL);
434
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
436
g_signal_connect (menuitem, "activate",
437
G_CALLBACK (activate_app_def), entry);
439
gtk_widget_show (menuitem);
442
void create_menuitem_from_alias (GtkWidget *menu,
443
GMenuTreeAlias *alias)
445
GMenuTreeItem *aliased_item;
447
aliased_item = gmenu_tree_alias_get_item (alias);
449
switch (gmenu_tree_item_get_type (aliased_item)) {
450
case GMENU_TREE_ITEM_DIRECTORY:
451
create_submenu (menu,
452
GMENU_TREE_DIRECTORY (aliased_item),
453
gmenu_tree_alias_get_directory (alias));
456
case GMENU_TREE_ITEM_ENTRY:
457
create_menuitem (menu,
458
GMENU_TREE_ENTRY (aliased_item),
459
gmenu_tree_alias_get_directory (alias));
466
gmenu_tree_item_unref (aliased_item);
471
image_menuitem_size_request (GtkWidget *menuitem,
472
GtkRequisition *requisition,
475
GtkIconSize icon_size = (GtkIconSize) GPOINTER_TO_INT (data);
479
if (!gtk_icon_size_lookup (icon_size, NULL, &icon_height))
482
// If we don't have a pixmap for this menuitem
483
// at least make sure its the same height as
485
// This is a bit ugly, since we should keep this in sync with what's in
486
// gtk_menu_item_size_request()
487
req_height = icon_height;
488
req_height += (GTK_CONTAINER (menuitem)->border_width +
489
menuitem->style->thickness) * 2;
490
requisition->height = MAX (requisition->height, req_height);
492
void setup_menuitem (GtkWidget *menuitem,
493
GtkIconSize icon_size,
501
/* this creates a label with an invisible mnemonic */
502
label = g_object_new (GTK_TYPE_ACCEL_LABEL, NULL);
503
_title = menu_escape_underscores_and_prepend (title);
504
gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _title);
507
gtk_label_set_pattern (GTK_LABEL (label), "");
509
gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), menuitem);
511
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
512
gtk_widget_show (label);
514
gtk_container_add (GTK_CONTAINER (menuitem), label);
517
g_object_set_data_full (G_OBJECT (menuitem),
519
g_object_ref (image),
520
(GDestroyNotify) g_object_unref);
521
gtk_widget_show (image);
522
_gtk_image_menu_item_set_image (
523
GTK_IMAGE_MENU_ITEM (menuitem), image);
524
} else if (icon_size != GTK_ICON_SIZE_INVALID)
525
g_signal_connect (menuitem, "size_request",
526
G_CALLBACK (image_menuitem_size_request),
527
GINT_TO_POINTER (icon_size));
529
gtk_widget_show (menuitem);
532
GtkWidget * populate_menu_from_directory (GtkWidget *menu,
533
GMenuTreeDirectory *directory)
537
gboolean add_separator;
539
///add_separator = (GTK_MENU_SHELL (menu)->children != NULL);
540
GList *children = gtk_container_get_children (GTK_CONTAINER (menu));
541
add_separator = (children != NULL);
542
g_list_free (children); // not very optimized ...
544
items = gmenu_tree_directory_get_contents (directory);
546
for (l = items; l; l = l->next) {
547
GMenuTreeItem *item = l->data;
550
gmenu_tree_item_get_type (item) == GMENU_TREE_ITEM_SEPARATOR) {
551
add_menu_separator (menu);
552
add_separator = FALSE;
555
switch (gmenu_tree_item_get_type (item)) {
556
case GMENU_TREE_ITEM_DIRECTORY:
557
create_submenu (menu, GMENU_TREE_DIRECTORY (item), NULL);
560
case GMENU_TREE_ITEM_ENTRY:
561
create_menuitem (menu, GMENU_TREE_ENTRY (item), NULL);
564
case GMENU_TREE_ITEM_SEPARATOR :
568
case GMENU_TREE_ITEM_ALIAS:
569
create_menuitem_from_alias (menu, GMENU_TREE_ALIAS (item));
572
case GMENU_TREE_ITEM_HEADER:
573
create_header (menu, GMENU_TREE_HEADER (item));
580
gmenu_tree_item_unref (item);
583
g_slist_free (items);
590
/**void icon_theme_changed (GtkIconTheme *icon_theme,
593
reload_image_menu_items ();
596
static inline GtkWidget * panel_create_menu (void)
599
static gboolean registered_icon_theme_changer = FALSE;
601
if (!registered_icon_theme_changer) {
602
registered_icon_theme_changer = TRUE;
604
g_signal_connect (gtk_icon_theme_get_default (), "changed",
605
G_CALLBACK (icon_theme_changed), NULL);
608
retval = gtk_menu_new ();
612
GtkWidget * create_empty_menu (void)
616
///retval = panel_create_menu ();
617
retval = gtk_menu_new ();
622
static void _on_remove_tree (GMenuTree *tree)
624
cd_message ("%s (%x)", __func__, tree);
625
//gmenu_tree_unref (tree);
628
GtkWidget * create_applications_menu (const char *menu_file,
629
const char *menu_path, GtkWidget *parent_menu)
635
menu = (parent_menu ? parent_menu : create_empty_menu ());
637
cd_message ("%s (%s)", __func__, menu_file);
638
tree = gmenu_tree_lookup (menu_file, GMENU_TREE_FLAGS_NONE);
639
cd_debug (" tree : %x", tree);
641
g_object_set_data_full (G_OBJECT (menu),
643
gmenu_tree_ref (tree),
644
(GDestroyNotify) _on_remove_tree);
646
g_object_set_data_full (G_OBJECT (menu),
647
"panel-menu-tree-path",
648
g_strdup (menu_path ? menu_path : "/"),
649
(GDestroyNotify) g_free);
651
g_object_set_data (G_OBJECT (menu),
652
"panel-menu-needs-loading",
653
GUINT_TO_POINTER (TRUE));
655
// load the menu in idle, and force the loading if it's shown before.
656
g_signal_connect (menu, "show",
657
G_CALLBACK (submenu_to_display), NULL);
659
idle_id = g_idle_add_full (G_PRIORITY_LOW,
660
submenu_to_display_in_idle,
663
g_object_set_data_full (G_OBJECT (menu),
664
"panel-menu-idle-id",
665
GUINT_TO_POINTER (idle_id),
666
remove_submenu_to_display_idle);
668
gmenu_tree_add_monitor (tree,
669
(GMenuTreeChangedFunc) handle_gmenu_tree_changed,
671
g_signal_connect (menu, "destroy",
672
G_CALLBACK (remove_gmenu_tree_monitor), tree);
674
gmenu_tree_unref (tree);
679
// $XDG_CONFIG_DIRS => /etc/xdg/xdg-cairo-dock:/etc/xdg
680
// http://developer.gnome.org/menu-spec/
681
gchar ** cd_gmenu_get_xdg_menu_dirs (void)
683
const gchar *cMenuPrefix = g_getenv ("XDG_CONFIG_DIRS");
684
if (! cMenuPrefix || *cMenuPrefix == '\0')
685
cMenuPrefix = "/etc/xdg/menus";
687
return g_strsplit (cMenuPrefix, ":", 0);
690
// check if the file exists and if yes, *cMenuName is created
691
gboolean _check_file_exists (const gchar *cDir, const gchar *cPrefix, gchar **cMenuName)
693
gchar *cMenuFilePathWithPrefix = g_strdup_printf ("%s/menus/%sapplications.menu", cDir, cPrefix);
695
gboolean bFileExists = g_file_test (cMenuFilePathWithPrefix, G_FILE_TEST_EXISTS);
697
*cMenuName = g_strdup_printf ("%sapplications.menu", cPrefix);
699
cd_debug ("Check: %s: %d", cMenuFilePathWithPrefix, bFileExists);
700
g_free (cMenuFilePathWithPrefix);
704
static const gchar *cPrefixNames[] = {"", "gnome-", "kde-", "kde4-", "xfce-", "lxde-", NULL};
706
GtkWidget * create_main_menu (CairoDockModuleInstance *myApplet)
708
GtkWidget *main_menu;
710
gchar *cMenuFileName = NULL, *cXdgMenuPath = NULL;
711
const gchar *cMenuPrefix = g_getenv ("XDG_MENU_PREFIX"); // e.g. on xfce, it contains "xfce-", nothing on gnome
712
gchar **cXdgPath = cd_gmenu_get_xdg_menu_dirs ();
715
for (i = 0; cXdgPath[i] != NULL; i++)
717
g_free (cXdgMenuPath);
718
cXdgMenuPath = g_strdup_printf ("%s/menus", cXdgPath[i]);
719
if (! g_file_test (cXdgMenuPath, G_FILE_TEST_IS_DIR)) // cXdgPath can contain an invalid dir
722
// this test should be the good one: with or without the prefix
723
if (_check_file_exists (cXdgPath[i], cMenuPrefix ? cMenuPrefix : "", &cMenuFileName))
726
// let's check with common prefixes
727
for (int iPrefix = 0; cPrefixNames[iPrefix] != NULL; iPrefix++)
729
if (_check_file_exists (cXdgPath[i], cPrefixNames[iPrefix], &cMenuFileName))
733
if (cMenuFileName == NULL) // let's check any *-applications.menu
735
const gchar *cFileName;
736
GDir *dir = g_dir_open (cXdgPath[i], 0, NULL);
25
#include "applet-recent.h"
26
#include "applet-tree.h"
28
static void cd_menu_append_poweroff_to_menu (GtkWidget *menu, CairoDockModuleInstance *myApplet);
31
static gboolean _make_menu_from_trees (CDSharedMemory *pSharedMemory)
35
myData.pTrees = pSharedMemory->pTrees;
36
pSharedMemory->pTrees = NULL;
38
myData.pMenu = pSharedMemory->pMenu;
39
pSharedMemory->pMenu = NULL;
41
// append recent events
42
if (myConfig.bShowRecent)
43
cd_menu_append_recent_to_menu (myData.pMenu, myApplet);
46
if (myConfig.iShowQuit != CD_GMENU_SHOW_QUIT_NONE)
47
cd_menu_append_poweroff_to_menu (myData.pMenu, myApplet);
49
if (myData.bShowMenuPending)
52
myData.bShowMenuPending = FALSE;
55
cairo_dock_discard_task (myData.pTask);
58
CD_APPLET_LEAVE (FALSE);
61
static void _load_trees_async (CDSharedMemory *pSharedMemory)
63
GMenuTree *tree = cd_load_tree_from_file ("applications.menu");
65
pSharedMemory->pTrees = g_list_append (pSharedMemory->pTrees, tree);
67
tree = cd_load_tree_from_file ("settings.menu");
69
pSharedMemory->pTrees = g_list_append (pSharedMemory->pTrees, tree);
72
pSharedMemory->pMenu = gtk_menu_new ();
74
/* append the trees we got
75
* + it will populate menu and create all things
76
* (it will have a look at new images and maybe preload them)
77
* => do that in the separated thread
80
for (t = pSharedMemory->pTrees; t != NULL; t = t->next)
83
cd_append_tree_in_menu (tree, pSharedMemory->pMenu);
87
static void _free_shared_memory (CDSharedMemory *pSharedMemory)
89
g_list_foreach (pSharedMemory->pTrees, (GFunc)g_object_unref, NULL);
90
g_list_free (pSharedMemory->pTrees);
91
if (pSharedMemory->pMenu)
92
gtk_widget_destroy (pSharedMemory->pMenu);
93
g_free (pSharedMemory);
96
void cd_menu_start (void)
98
CDSharedMemory *pSharedMemory = g_new0 (CDSharedMemory, 1);
100
myData.pTask = cairo_dock_new_task_full (0, // 1 shot task.
101
(CairoDockGetDataAsyncFunc) _load_trees_async,
102
(CairoDockUpdateSyncFunc) _make_menu_from_trees,
103
(GFreeFunc) _free_shared_memory,
106
if (cairo_dock_is_loading ())
107
cairo_dock_launch_task_delayed (myData.pTask, 0); // 0 <=> g_idle
109
cairo_dock_launch_task (myData.pTask);
112
void cd_menu_stop (void)
114
cairo_dock_discard_task (myData.pTask);
117
g_list_foreach (myData.pTrees, (GFunc)g_object_unref, NULL);
118
g_list_free (myData.pTrees);
119
myData.pTrees = NULL;
121
if (myData.pMenu != NULL)
123
gtk_widget_destroy (myData.pMenu);
125
myData.pRecentMenuItem = NULL;
131
// == cairo_dock_add_in_menu_with_stock_and_data with icon size 24
132
static GtkWidget *_append_one_item_to_menu (const gchar *cLabel, const gchar *gtkStock, GFunc pFunction, GtkWidget *pMenu, gpointer pData)
134
GtkWidget *pMenuItem = gtk_image_menu_item_new_with_label (cLabel);
137
GtkWidget *image = NULL;
138
if (*gtkStock == '/')
140
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (gtkStock, myData.iPanelDefaultMenuIconSize, myData.iPanelDefaultMenuIconSize, NULL);
141
image = gtk_image_new_from_pixbuf (pixbuf);
142
g_object_unref (pixbuf);
146
const gchar *cIconPath = cairo_dock_search_icon_s_path (gtkStock, myData.iPanelDefaultMenuIconSize);
147
if (cIconPath == NULL)
739
while ((cFileName = g_dir_read_name (dir)))
741
if (g_str_has_suffix (cFileName, "-applications.menu"))
743
cMenuFileName = g_strdup (cFileName);
748
if (cMenuFileName != NULL)
149
cIconPath = g_strconcat (MY_APPLET_SHARE_DATA_DIR"/", gtkStock, ".svg", NULL);
151
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (cIconPath, myData.iPanelDefaultMenuIconSize, myData.iPanelDefaultMenuIconSize, NULL);
152
image = gtk_image_new_from_pixbuf (pixbuf);
153
g_object_unref (pixbuf);
754
cd_debug ("Menu: Found %s in %s (%s)", cMenuFileName, cXdgPath[i], cXdgMenuPath);
756
if (cMenuFileName == NULL) // arf
757
cMenuFileName = g_strdup ("applications.menu");
759
main_menu = create_applications_menu (cMenuFileName, NULL, NULL);
761
g_object_set_data (G_OBJECT (main_menu),
762
"panel-menu-append-callback",
764
g_object_set_data (G_OBJECT (main_menu),
765
"panel-menu-append-callback-data",
768
g_strfreev (cXdgPath);
769
g_free (cMenuFileName);
770
g_free (cXdgMenuPath);
155
_gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (pMenuItem), image);
157
gtk_menu_shell_append (GTK_MENU_SHELL (pMenu), pMenuItem);
159
g_signal_connect (G_OBJECT (pMenuItem), "activate", G_CALLBACK (pFunction), pData);
163
static void cd_menu_append_poweroff_to_menu (GtkWidget *menu, CairoDockModuleInstance *myApplet)
165
GtkWidget *menuitem = gtk_separator_menu_item_new ();
166
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
167
gtk_widget_show (menuitem);
169
if (myConfig.iShowQuit == CD_GMENU_SHOW_QUIT_LOGOUT || myConfig.iShowQuit == CD_GMENU_SHOW_QUIT_BOTH)
170
_append_one_item_to_menu (D_("Logout"), "system-log-out", (GFunc) cairo_dock_fm_logout, menu, NULL);
172
if (myConfig.iShowQuit == CD_GMENU_SHOW_QUIT_SHUTDOWN || myConfig.iShowQuit == CD_GMENU_SHOW_QUIT_BOTH)
173
_append_one_item_to_menu (D_("Shutdown"), "system-shutdown", (GFunc) cairo_dock_fm_shutdown, menu, NULL);
176
void cd_menu_show_menu (void)
178
if (myData.pMenu != NULL)
180
CD_APPLET_POPUP_MENU_ON_MY_ICON (myData.pMenu);
184
myData.bShowMenuPending = TRUE;