~jroose/cairo-dock-plug-ins/Messaging-Menu-alaric-devel

« back to all changes in this revision

Viewing changes to GMenu/src/applet-menu-callbacks.c

  • Committer: jroose at gmail
  • Date: 2010-11-18 14:43:40 UTC
  • Revision ID: jroose@gmail.com-20101118144340-qvrs0rmanr5lr1mj
Messaging-Menu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* E-mail    : see the 'copyright' file.
 
6
*
 
7
* This program is free software; you can redistribute it and/or
 
8
* modify it under the terms of the GNU General Public License
 
9
* as published by the Free Software Foundation; either version 3
 
10
* of the License, or (at your option) any later version.
 
11
*
 
12
* This program is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
* GNU General Public License for more details.
 
16
* You should have received a copy of the GNU General Public License
 
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
#include <string.h>
 
21
#include <cairo-dock.h>
 
22
#include <gdk/gdkkeysyms.h>
 
23
 
 
24
#include "applet-struct.h"
 
25
#include "applet-menu.h"
 
26
#include "applet-util.h"
 
27
#include "applet-recent.h"
 
28
#include "applet-menu-callbacks.h"
 
29
 
 
30
static guint load_icons_id = 0;
 
31
static GList *icons_to_load = NULL;
 
32
static GList *icons_to_add = NULL;
 
33
 
 
34
 
 
35
void handle_gmenu_tree_changed (GMenuTree *tree,
 
36
                           GtkWidget *menu)
 
37
{
 
38
        cd_message ("%s ()", __func__);
 
39
        
 
40
        if (myData.pMenu != NULL)
 
41
        {
 
42
                gtk_widget_destroy (myData.pMenu);
 
43
                myData.pMenu = NULL;
 
44
        }
 
45
        
 
46
        if (myData.pMenu == NULL)
 
47
        {
 
48
                myData.pMenu = create_main_menu (NULL);
 
49
        }
 
50
        return ;
 
51
        
 
52
        guint idle_id;
 
53
 
 
54
        while (GTK_MENU_SHELL (menu)->children)
 
55
                gtk_widget_destroy (GTK_MENU_SHELL (menu)->children->data);
 
56
 
 
57
        g_object_set_data_full (G_OBJECT (menu),
 
58
                                "panel-menu-tree-directory",
 
59
                                NULL, NULL);
 
60
 
 
61
        g_object_set_data (G_OBJECT (menu),
 
62
                           "panel-menu-needs-loading",
 
63
                           GUINT_TO_POINTER (TRUE));
 
64
 
 
65
        idle_id = g_idle_add_full (G_PRIORITY_LOW,
 
66
                                   submenu_to_display_in_idle,
 
67
                                   menu,
 
68
                                   NULL);
 
69
        if (myData.iSidTreeChangeIdle != 0)
 
70
                g_source_remove (myData.iSidTreeChangeIdle);
 
71
        myData.iSidTreeChangeIdle = idle_id;
 
72
        g_object_set_data_full (G_OBJECT (menu),
 
73
                                "panel-menu-idle-id",
 
74
                                GUINT_TO_POINTER (idle_id),
 
75
                                remove_submenu_to_display_idle);
 
76
}
 
77
 
 
78
void remove_gmenu_tree_monitor (GtkWidget *menu,
 
79
                          GMenuTree  *tree)
 
80
{
 
81
        cd_message ("%s (%x)", __func__, tree);
 
82
        gmenu_tree_remove_monitor (tree,
 
83
                                  (GMenuTreeChangedFunc) handle_gmenu_tree_changed,
 
84
                                  menu);
 
85
}
 
86
 
 
87
 
 
88
gboolean menu_dummy_button_press_event (GtkWidget      *menuitem,
 
89
                               GdkEventButton *event)
 
90
{
 
91
        if (event->button == 3)
 
92
                return TRUE;
 
93
 
 
94
        return FALSE;
 
95
}
 
96
 
 
97
 
 
98
void remove_submenu_to_display_idle (gpointer data)
 
99
{
 
100
        guint idle_id = GPOINTER_TO_UINT (data);
 
101
 
 
102
        g_source_remove (idle_id);
 
103
}
 
104
 
 
105
 
 
106
gboolean submenu_to_display_in_idle (gpointer data)
 
107
{
 
108
        GtkWidget *menu = GTK_WIDGET (data);
 
109
        cd_message ("%s (%x)", __func__, menu);
 
110
 
 
111
        g_object_set_data (G_OBJECT (menu), "panel-menu-idle-id", NULL);
 
112
 
 
113
        submenu_to_display (menu);
 
114
 
 
115
        return FALSE;
 
116
}
 
117
 
 
118
void submenu_to_display (GtkWidget *menu)
 
119
{
 
120
        cd_message ("%s (%x)", __func__, menu);
 
121
        GMenuTree           *tree;
 
122
        GMenuTreeDirectory  *directory;
 
123
        const char          *menu_path;
 
124
        void               (*append_callback) (GtkWidget *, gpointer);
 
125
        gpointer             append_data;
 
126
 
 
127
        if (!g_object_get_data (G_OBJECT (menu), "panel-menu-needs-loading"))
 
128
        {
 
129
                cd_debug ("needs no loading\n");
 
130
                return;
 
131
        }
 
132
 
 
133
        g_object_set_data (G_OBJECT (menu), "panel-menu-needs-loading", NULL);
 
134
 
 
135
        directory = g_object_get_data (G_OBJECT (menu),
 
136
                                       "panel-menu-tree-directory");
 
137
        if (!directory) {
 
138
                menu_path = g_object_get_data (G_OBJECT (menu),
 
139
                                               "panel-menu-tree-path");
 
140
                cd_debug ("n'est pas un directory, menu_path : %s\n", menu_path);
 
141
                if (!menu_path)
 
142
                {
 
143
                        cd_warning ("menu_path is empty");
 
144
                        return;
 
145
                }
 
146
                
 
147
                tree = g_object_get_data (G_OBJECT (menu), "panel-menu-tree");
 
148
                if (!tree)
 
149
                {
 
150
                        cd_warning ("no tree found in datas");
 
151
                        return;
 
152
                }
 
153
                directory = gmenu_tree_get_directory_from_path (tree,
 
154
                                                                menu_path);
 
155
 
 
156
                g_object_set_data_full (G_OBJECT (menu),
 
157
                                        "panel-menu-tree-directory",
 
158
                                        directory,
 
159
                                        (GDestroyNotify) gmenu_tree_item_unref);
 
160
        }
 
161
        //g_print ("%s ()\n", __func__);
 
162
        if (directory)
 
163
                populate_menu_from_directory (menu, directory);
 
164
 
 
165
        append_callback = g_object_get_data (G_OBJECT (menu),
 
166
                                             "panel-menu-append-callback");
 
167
        append_data     = g_object_get_data (G_OBJECT (menu),
 
168
                                             "panel-menu-append-callback-data");
 
169
        if (append_callback)
 
170
                append_callback (menu, append_data);
 
171
}
 
172
 
 
173
 
 
174
void panel_desktop_menu_item_append_menu (GtkWidget *menu,
 
175
                                     gpointer   data)
 
176
{
 
177
        //g_print ("%s ()\n", __func__);        
 
178
        CairoDockModuleInstance *myApplet;
 
179
        gboolean              add_separator;
 
180
        GList                *children;
 
181
        GList                *last;
 
182
 
 
183
        myApplet = (CairoDockModuleInstance *) data;
 
184
 
 
185
        add_separator = FALSE;
 
186
        children = gtk_container_get_children (GTK_CONTAINER (menu));
 
187
        last = g_list_last (children);
 
188
 
 
189
        ///if (last != NULL)
 
190
        ///     add_separator = !GTK_IS_SEPARATOR (GTK_WIDGET (last->data));
 
191
 
 
192
        g_list_free (children);
 
193
 
 
194
        if (add_separator)
 
195
                add_menu_separator (menu);
 
196
 
 
197
        //panel_menu_items_append_from_desktop (menu, "yelp.desktop", NULL);
 
198
        //panel_menu_items_append_from_desktop (menu, "gnome-about.desktop", NULL);
 
199
 
 
200
        //if (parent->priv->append_lock_logout)
 
201
        //      panel_menu_items_append_lock_logout (menu);
 
202
}
 
203
void main_menu_append (GtkWidget *main_menu,
 
204
                  gpointer   data)
 
205
{
 
206
        //g_print ("%s ()\n", __func__);        
 
207
        CairoDockModuleInstance *myApplet;
 
208
        GtkWidget   *item;
 
209
        gboolean     add_separator;
 
210
        GList       *children;
 
211
        GList       *last;
 
212
 
 
213
        myApplet = (CairoDockModuleInstance *) data;
 
214
 
 
215
        add_separator = FALSE;
 
216
        children = gtk_container_get_children (GTK_CONTAINER (main_menu));
 
217
        last = g_list_last (children);
 
218
        if (last != NULL) {
 
219
                ///add_separator = !GTK_IS_SEPARATOR (GTK_WIDGET (last->data));
 
220
        }
 
221
        g_list_free (children);
 
222
 
 
223
        if (add_separator)
 
224
                add_menu_separator (main_menu);
 
225
        
 
226
        
 
227
        GtkWidget *desktop_menu;
 
228
 
 
229
        desktop_menu = create_applications_menu ("settings.menu", NULL, main_menu);
 
230
        g_object_set_data_full (G_OBJECT (desktop_menu),
 
231
                        "panel-menu-tree-directory",
 
232
                        NULL, NULL);
 
233
        
 
234
        g_object_set_data (G_OBJECT (desktop_menu),
 
235
                           "panel-menu-append-callback",
 
236
                           panel_desktop_menu_item_append_menu);
 
237
        g_object_set_data (G_OBJECT (desktop_menu),
 
238
                           "panel-menu-append-callback-data",
 
239
                           myApplet);
 
240
        
 
241
        if (myConfig.bShowRecent)
 
242
        {
 
243
                cd_menu_append_recent_to_menu (main_menu, myApplet);
 
244
        }
 
245
        /*item = panel_place_menu_item_new (TRUE);
 
246
        panel_place_menu_item_set_panel (item, panel);
 
247
        gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
 
248
        gtk_widget_show (item);
 
249
 
 
250
        item = panel_desktop_menu_item_new (TRUE, FALSE);
 
251
        panel_desktop_menu_item_set_panel (item, panel);
 
252
        gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
 
253
        gtk_widget_show (item);
 
254
 
 
255
        panel_menu_items_append_lock_logout (main_menu);*/
 
256
}
 
257
 
 
258
/*gboolean show_item_menu (GtkWidget      *item,
 
259
                GdkEventButton *bevent)
 
260
{
 
261
        CairoDockModuleInstance *myApplet;
 
262
        GtkWidget   *menu;
 
263
 
 
264
        if (panel_lockdown_get_locked_down ())
 
265
                return FALSE;
 
266
 
 
267
        panel_widget = menu_get_panel (item);
 
268
 
 
269
        menu = g_object_get_data (G_OBJECT (item), "panel-item-context-menu");
 
270
 
 
271
        if (!menu)
 
272
                menu = create_item_context_menu (item, panel_widget);
 
273
 
 
274
        if (!menu)
 
275
                return FALSE;
 
276
 
 
277
        gtk_menu_set_screen (GTK_MENU (menu),
 
278
                             gtk_window_get_screen (GTK_WINDOW (panel_widget->toplevel)));
 
279
 
 
280
        gtk_menu_popup (GTK_MENU (menu),
 
281
                        NULL, NULL, NULL, NULL,
 
282
                        bevent->button,
 
283
                        bevent->time);
 
284
 
 
285
        return TRUE;
 
286
}
 
287
gboolean panel_menu_key_press_handler (GtkWidget   *widget,
 
288
                              GdkEventKey *event)
 
289
{
 
290
        gboolean retval = FALSE;
 
291
 
 
292
        if ((event->keyval == GDK_Menu) ||
 
293
            (event->keyval == GDK_F10 &&
 
294
            (event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_SHIFT_MASK)) {
 
295
                GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
 
296
 
 
297
                if (menu_shell->active_menu_item &&
 
298
                    GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu == NULL) {
 
299
                        GdkEventButton bevent;
 
300
 
 
301
                        bevent.button = 3;
 
302
                        bevent.time = GDK_CURRENT_TIME;
 
303
                        retval = show_item_menu (menu_shell->active_menu_item,
 
304
//                                               &bevent);
 
305
                }
 
306
                
 
307
        }
 
308
        return retval;
 
309
}*/
 
310
 
 
311
static void menu_item_style_set (GtkImage *image,
 
312
                     gpointer  data)
 
313
{
 
314
        GtkWidget   *widget;
 
315
        GdkPixbuf   *pixbuf;
 
316
        GtkIconSize  icon_size = (GtkIconSize) GPOINTER_TO_INT (data);
 
317
        int          icon_height;
 
318
        gboolean     is_mapped;
 
319
 
 
320
        if (!gtk_icon_size_lookup (icon_size, NULL, &icon_height))
 
321
                return;
 
322
 
 
323
        pixbuf = gtk_image_get_pixbuf (image);
 
324
        if (!pixbuf)
 
325
                return;
 
326
 
 
327
        if (gdk_pixbuf_get_height (pixbuf) == icon_height)
 
328
                return;
 
329
 
 
330
        widget = GTK_WIDGET (image);
 
331
 
 
332
        is_mapped = GTK_WIDGET_MAPPED (widget);
 
333
        if (is_mapped)
 
334
                gtk_widget_unmap (widget);
 
335
 
 
336
        gtk_image_set_from_pixbuf (image, NULL);
 
337
    
 
338
        if (is_mapped)
 
339
                gtk_widget_map (widget);
 
340
}
 
341
static void do_icons_to_add (void)
 
342
{
 
343
        while (icons_to_add) {
 
344
                IconToAdd *icon_to_add = icons_to_add->data;
 
345
 
 
346
                icons_to_add = g_list_delete_link (icons_to_add, icons_to_add);
 
347
 
 
348
                if (icon_to_add->stock_id)
 
349
                        gtk_image_set_from_stock (
 
350
                                GTK_IMAGE (icon_to_add->image),
 
351
                                icon_to_add->stock_id,
 
352
                                icon_to_add->icon_size);
 
353
                else {
 
354
                        g_assert (icon_to_add->pixbuf);
 
355
 
 
356
                        gtk_image_set_from_pixbuf (
 
357
                                GTK_IMAGE (icon_to_add->image),
 
358
                                icon_to_add->pixbuf);
 
359
 
 
360
                        g_signal_connect (icon_to_add->image, "style-set",
 
361
                                          G_CALLBACK (menu_item_style_set),
 
362
                                          GINT_TO_POINTER (icon_to_add->icon_size));
 
363
 
 
364
                        g_object_unref (icon_to_add->pixbuf);
 
365
                }
 
366
 
 
367
                g_object_unref (icon_to_add->image);
 
368
                g_free (icon_to_add);
 
369
        }
 
370
}
 
371
void icon_to_load_free (IconToLoad *icon)
 
372
{
 
373
        if (!icon)
 
374
                return;
 
375
 
 
376
        if (icon->pixmap)
 
377
                g_object_unref (icon->pixmap);
 
378
        icon->pixmap = NULL;
 
379
 
 
380
        if (icon->gicon)
 
381
                g_object_unref (icon->gicon);
 
382
        icon->gicon = NULL;
 
383
 
 
384
        g_free (icon->image);          icon->image = NULL;
 
385
        g_free (icon->fallback_image); icon->fallback_image = NULL;
 
386
        g_free (icon);
 
387
}
 
388
static gboolean load_icons_handler (gpointer data)
 
389
{
 
390
        IconToLoad *icon;
 
391
        gboolean    long_operation = FALSE;
 
392
 
 
393
load_icons_handler_again:
 
394
 
 
395
        if (!icons_to_load) {
 
396
                load_icons_id = 0;
 
397
                do_icons_to_add ();
 
398
 
 
399
                return FALSE;
 
400
        }
 
401
 
 
402
        icon = icons_to_load->data;
 
403
        icons_to_load->data = NULL;
 
404
        /* pop */
 
405
        icons_to_load = g_list_delete_link (icons_to_load, icons_to_load);
 
406
 
 
407
        /* if not visible anymore, just ignore */
 
408
        if ( ! GTK_WIDGET_VISIBLE (icon->pixmap)) {
 
409
                icon_to_load_free (icon);
 
410
                /* we didn't do anything long/hard, so just do this again,
 
411
                 * this is fun, don't go back to main loop */
 
412
                goto load_icons_handler_again;
 
413
        }
 
414
 
 
415
        if (icon->stock_id) {
 
416
                IconToAdd *icon_to_add;
 
417
 
 
418
                icon_to_add            = g_new (IconToAdd, 1);
 
419
                icon_to_add->image     = g_object_ref (icon->pixmap);
 
420
                icon_to_add->stock_id  = icon->stock_id;
 
421
                icon_to_add->pixbuf    = NULL;
 
422
                icon_to_add->icon_size = icon->icon_size;
 
423
 
 
424
                icons_to_add = g_list_prepend (icons_to_add, icon_to_add);
 
425
        }
 
426
        #ifdef HAVE_GIO
 
427
        else if (icon->gicon) {
 
428
                IconToAdd *icon_to_add;
 
429
                char      *icon_name;
 
430
                GdkPixbuf *pb;
 
431
                int        icon_height = PANEL_DEFAULT_MENU_ICON_SIZE;
 
432
 
 
433
                gtk_icon_size_lookup (icon->icon_size, NULL, &icon_height);
 
434
 
 
435
                icon_name = panel_util_get_icon_name_from_g_icon (icon->gicon);
 
436
 
 
437
                if (icon_name) {
 
438
                        pb = panel_make_menu_icon (icon->icon_theme,
 
439
                                                   icon_name,
 
440
                                                   icon->fallback_image,
 
441
                                                   icon_height,
 
442
                                                   &long_operation);
 
443
                        g_free (icon_name);
 
444
                } else {
 
445
                        pb = panel_util_get_pixbuf_from_g_loadable_icon (icon->gicon, icon_height);
 
446
                        if (!pb && icon->fallback_image) {
 
447
                                pb = panel_make_menu_icon (icon->icon_theme,
 
448
                                                           NULL,
 
449
                                                           icon->fallback_image,
 
450
                                                           icon_height,
 
451
                                                           &long_operation);
 
452
                        }
 
453
                }
 
454
 
 
455
                if (!pb) {
 
456
                        icon_to_load_free (icon);
 
457
                        if (long_operation)
 
458
                                /* this may have been a long operation so jump
 
459
                                 * back to the main loop for a while */
 
460
                                return TRUE;
 
461
                        else
 
462
                                /* we didn't do anything long/hard, so just do
 
463
                                 * this again, this is fun, don't go back to
 
464
                                 * main loop */
 
465
                                goto load_icons_handler_again;
 
466
                }
 
467
 
 
468
                icon_to_add            = g_new (IconToAdd, 1);
 
469
                icon_to_add->image     = g_object_ref (icon->pixmap);
 
470
                icon_to_add->stock_id  = NULL;
 
471
                icon_to_add->pixbuf    = pb;
 
472
                icon_to_add->icon_size = icon->icon_size;
 
473
 
 
474
                icons_to_add = g_list_prepend (icons_to_add, icon_to_add);
 
475
        }
 
476
        #endif
 
477
        else {
 
478
                IconToAdd *icon_to_add;
 
479
                GdkPixbuf *pb;
 
480
                int        icon_height = PANEL_DEFAULT_MENU_ICON_SIZE;
 
481
 
 
482
                gtk_icon_size_lookup (icon->icon_size, NULL, &icon_height);
 
483
 
 
484
                pb = panel_make_menu_icon (icon->icon_theme,
 
485
                                           icon->image,
 
486
                                           icon->fallback_image,
 
487
                                           icon_height,
 
488
                                           &long_operation);
 
489
                if (!pb) {
 
490
                        icon_to_load_free (icon);
 
491
                        if (long_operation)
 
492
                                /* this may have been a long operation so jump back to
 
493
                                 * the main loop for a while */
 
494
                                return TRUE;
 
495
                        else
 
496
                                /* we didn't do anything long/hard, so just do this again,
 
497
                                 * this is fun, don't go back to main loop */
 
498
                                goto load_icons_handler_again;
 
499
                }
 
500
 
 
501
                icon_to_add            = g_new (IconToAdd, 1);
 
502
                icon_to_add->image     = g_object_ref (icon->pixmap);
 
503
                icon_to_add->stock_id  = NULL;
 
504
                icon_to_add->pixbuf    = pb;
 
505
                icon_to_add->icon_size = icon->icon_size;
 
506
 
 
507
                icons_to_add = g_list_prepend (icons_to_add, icon_to_add);
 
508
        }
 
509
 
 
510
        icon_to_load_free (icon);
 
511
 
 
512
        if (!long_operation)
 
513
                /* we didn't do anything long/hard, so just do this again,
 
514
                 * this is fun, don't go back to main loop */
 
515
                goto load_icons_handler_again;
 
516
 
 
517
        /* if still more we'll come back */
 
518
        return TRUE;
 
519
}
 
520
static GList * find_in_load_list (GtkWidget *image)
 
521
{
 
522
        GList *li;
 
523
        for (li = icons_to_load; li != NULL; li = li->next) {
 
524
                IconToLoad *icon = li->data;
 
525
                if (icon->pixmap == image)
 
526
                        return li;
 
527
        }
 
528
        return NULL;
 
529
}
 
530
static IconToLoad * icon_to_load_copy (IconToLoad *icon)
 
531
{
 
532
        IconToLoad *retval;
 
533
 
 
534
        if (!icon)
 
535
                return NULL;
 
536
 
 
537
        retval = g_new0 (IconToLoad, 1);
 
538
 
 
539
        retval->pixmap         = g_object_ref (icon->pixmap);
 
540
        if (icon->gicon)
 
541
                retval->gicon  = g_object_ref (icon->gicon);
 
542
        else
 
543
                retval->gicon  = NULL;
 
544
        retval->image          = g_strdup (icon->image);
 
545
        retval->fallback_image = g_strdup (icon->fallback_image);
 
546
        retval->stock_id       = icon->stock_id;
 
547
        retval->icon_size      = icon->icon_size;
 
548
 
 
549
        return retval;
 
550
}
 
551
void image_menu_shown (GtkWidget *image, gpointer data)
 
552
{
 
553
        IconToLoad *new_icon;
 
554
        IconToLoad *icon;
 
555
        
 
556
        icon = (IconToLoad *) data;
 
557
 
 
558
        /* if we've already handled this */
 
559
        if (gtk_image_get_storage_type (GTK_IMAGE (image)) != GTK_IMAGE_EMPTY)
 
560
                return;
 
561
 
 
562
        if (find_in_load_list (image) == NULL) {
 
563
                new_icon = icon_to_load_copy (icon);
 
564
                new_icon->icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (image));
 
565
                icons_to_load = g_list_append (icons_to_load, new_icon);
 
566
        }
 
567
        if (load_icons_id == 0)
 
568
                load_icons_id = g_idle_add (load_icons_handler, NULL);
 
569
}
 
570
 
 
571
void activate_app_def (GtkWidget      *menuitem,
 
572
                  GMenuTreeEntry *entry)
 
573
{
 
574
        const char       *path;
 
575
 
 
576
        path = gmenu_tree_entry_get_desktop_file_path (entry);
 
577
        panel_menu_item_activate_desktop_file (menuitem, path);
 
578
}
 
579
 
 
580
 
 
581
 
 
582
void  drag_begin_menu_cb (GtkWidget *widget, GdkDragContext     *context)
 
583
{
 
584
        /* FIXME: workaround for a possible gtk+ bug
 
585
         *    See bugs #92085(gtk+) and #91184(panel) for details.
 
586
         *    Maybe it's not needed with GtkTooltip?
 
587
         */
 
588
        g_object_set (widget, "has-tooltip", FALSE, NULL);
 
589
}
 
590
 
 
591
/* This is a _horrible_ hack to have this here. This needs to be added to the
 
592
 * GTK+ menuing code in some manner.
 
593
 */
 
594
void  drag_end_menu_cb (GtkWidget *widget, GdkDragContext     *context)
 
595
{
 
596
  GtkWidget *xgrab_shell;
 
597
  GtkWidget *parent;
 
598
 
 
599
  /* Find the last viewable ancestor, and make an X grab on it
 
600
   */
 
601
  parent = widget->parent;
 
602
  xgrab_shell = NULL;
 
603
 
 
604
  /* FIXME: workaround for a possible gtk+ bug
 
605
   *    See bugs #92085(gtk+) and #91184(panel) for details.
 
606
   */
 
607
  g_object_set (widget, "has-tooltip", TRUE, NULL);
 
608
 
 
609
  while (parent)
 
610
    {
 
611
      gboolean viewable = TRUE;
 
612
      GtkWidget *tmp = parent;
 
613
      
 
614
      while (tmp)
 
615
        {
 
616
          if (!GTK_WIDGET_MAPPED (tmp))
 
617
            {
 
618
              viewable = FALSE;
 
619
              break;
 
620
            }
 
621
          tmp = tmp->parent;
 
622
        }
 
623
      
 
624
      if (viewable)
 
625
        xgrab_shell = parent;
 
626
      
 
627
      parent = GTK_MENU_SHELL (parent)->parent_menu_shell;
 
628
    }
 
629
  
 
630
  if (xgrab_shell && !GTK_MENU(xgrab_shell)->torn_off)
 
631
    {
 
632
      GdkCursor *cursor = gdk_cursor_new (GDK_ARROW);
 
633
 
 
634
      if ((gdk_pointer_grab (xgrab_shell->window, TRUE,
 
635
                             GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
 
636
                             GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
 
637
                             GDK_POINTER_MOTION_MASK,
 
638
                             NULL, cursor, GDK_CURRENT_TIME) == 0))
 
639
        {
 
640
          if (gdk_keyboard_grab (xgrab_shell->window, TRUE,
 
641
                                 GDK_CURRENT_TIME) == 0)
 
642
            GTK_MENU_SHELL (xgrab_shell)->have_xgrab = TRUE;
 
643
          else
 
644
            {
 
645
              gdk_pointer_ungrab (GDK_CURRENT_TIME);
 
646
            }
 
647
        }
 
648
 
 
649
      gdk_cursor_unref (cursor);
 
650
    }
 
651
}
 
652
 
 
653
void  drag_data_get_menu_cb (GtkWidget        *widget,
 
654
                       GdkDragContext   *context,
 
655
                       GtkSelectionData *selection_data,
 
656
                       guint             info,
 
657
                       guint             time,
 
658
                       GMenuTreeEntry   *entry)
 
659
{
 
660
        const char *path;
 
661
        char       *uri;
 
662
        char       *uri_list;
 
663
 
 
664
        path = gmenu_tree_entry_get_desktop_file_path (entry);
 
665
        uri = g_filename_to_uri (path, NULL, NULL);
 
666
        uri_list = g_strconcat (uri, "\r\n", NULL);
 
667
        g_free (uri);
 
668
 
 
669
        gtk_selection_data_set (selection_data,
 
670
                                selection_data->target, 8, (guchar *)uri_list,
 
671
                                strlen (uri_list));
 
672
        g_free (uri_list);
 
673
}
 
674
 
 
675
/*gboolean menuitem_button_press_event (GtkWidget      *menuitem,
 
676
                             GdkEventButton *event)
 
677
{
 
678
        if (event->button == 3)
 
679
                return show_item_menu (menuitem, event);
 
680
        
 
681
        return FALSE;
 
682
}*/