~ubuntu-branches/ubuntu/saucy/cairo-dock-plug-ins/saucy

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2009-08-26 21:07:39 UTC
  • Revision ID: james.westby@ubuntu.com-20090826210739-gyjuuqezrzuluao4
Tags: upstream-2.0.8.1
ImportĀ upstreamĀ versionĀ 2.0.8.1

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