diff src/gtkutil.c @ 90737:95d0cdf160ea

Merge from emacs--devo--0 Patches applied: * emacs--devo--0 (patch 586-614) - Update from CVS - Update from erc--emacs--22 - Merge from gnus--rel--5.10 - Merge from erc--main--0 - Make byte compiler correctly write circular constants * gnus--rel--5.10 (patch 186-196) - Update from CVS - Merge from emacs--devo--0 Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-162
author Miles Bader <miles@gnu.org>
date Fri, 26 Jan 2007 06:16:11 +0000
parents bc10a33dd40b 3d45362f1d38
children f83d17e1ace6
line wrap: on
line diff
--- a/src/gtkutil.c	Fri Jan 26 02:30:28 2007 +0000
+++ b/src/gtkutil.c	Fri Jan 26 06:16:11 2007 +0000
@@ -1,5 +1,5 @@
 /* Functions for creating and updating GTK widgets.
-   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -1718,9 +1718,9 @@
 }
 
 /* Callback called when the pointer enters/leaves a menu item.
-   W is the menu item.
+   W is the parent of the menu item.
    EVENT is either an enter event or leave event.
-   CLIENT_DATA points to the xg_menu_item_cb_data associated with the W.
+   CLIENT_DATA is not used.
 
    Returns FALSE to tell GTK to keep processing this event.  */
 
@@ -1730,15 +1730,21 @@
      GdkEventCrossing *event;
      gpointer client_data;
 {
-  if (client_data)
+  GdkEvent ev;
+  GtkWidget *subwidget;
+  xg_menu_item_cb_data *data;
+
+  ev.crossing = *event;
+  subwidget = gtk_get_event_widget (&ev);
+  data = (xg_menu_item_cb_data *) g_object_get_data (G_OBJECT (subwidget),
+                                                     XG_ITEM_DATA);
+  if (data)
     {
-      xg_menu_item_cb_data *data = (xg_menu_item_cb_data*) client_data;
-      gpointer call_data = event->type == GDK_LEAVE_NOTIFY ? 0 : client_data;
-
       if (! NILP (data->help) && data->cl_data->highlight_cb)
         {
+          gpointer call_data = event->type == GDK_LEAVE_NOTIFY ? 0 : data;
           GtkCallback func = (GtkCallback) data->cl_data->highlight_cb;
-          (*func) (w, call_data);
+          (*func) (subwidget, call_data);
         }
     }
 
@@ -2004,7 +2010,7 @@
 
   xg_list_insert (&xg_menu_item_cb_list, &cb_data->ptrs);
 
-  cb_data->unhighlight_id = cb_data->highlight_id = cb_data->select_id = 0;
+  cb_data->select_id = 0;
   cb_data->help = item->help;
   cb_data->cl_data = cl_data;
   cb_data->call_data = item->call_data;
@@ -2025,22 +2031,6 @@
           = g_signal_connect (G_OBJECT (w), "activate", select_cb, cb_data);
     }
 
-  if (! NILP (item->help) && highlight_cb)
-    {
-      /* We use enter/leave notify instead of select/deselect because
-         select/deselect doesn't go well with detached menus.  */
-      cb_data->highlight_id
-        = g_signal_connect (G_OBJECT (w),
-                            "enter-notify-event",
-                            G_CALLBACK (menuitem_highlight_callback),
-                            cb_data);
-      cb_data->unhighlight_id
-        = g_signal_connect (G_OBJECT (w),
-                            "leave-notify-event",
-                            G_CALLBACK (menuitem_highlight_callback),
-                            cb_data);
-    }
-
   return w;
 }
 
@@ -2123,6 +2113,17 @@
       {
         wmenu = gtk_menu_new ();
         xg_set_screen (wmenu, f);
+        /* Connect this to the menu instead of items so we get enter/leave for
+           disabled items also.  TODO:  Still does not get enter/leave for
+           disabled items in detached menus.  */
+        g_signal_connect (G_OBJECT (wmenu),
+                          "enter-notify-event",
+                          G_CALLBACK (menuitem_highlight_callback),
+                          NULL);
+        g_signal_connect (G_OBJECT (wmenu),
+                          "leave-notify-event",
+                          G_CALLBACK (menuitem_highlight_callback),
+                          NULL);
       }
       else wmenu = gtk_menu_bar_new ();
 
@@ -2619,37 +2620,6 @@
           g_signal_handler_disconnect (w, cb_data->select_id);
           cb_data->select_id = 0;
         }
-
-      if (NILP (cb_data->help))
-        {
-          /* Shall not have help.  Remove if any existed previously.  */
-          if (cb_data->highlight_id)
-            {
-              g_signal_handler_disconnect (G_OBJECT (w),
-                                           cb_data->highlight_id);
-              cb_data->highlight_id = 0;
-            }
-          if (cb_data->unhighlight_id)
-            {
-              g_signal_handler_disconnect (G_OBJECT (w),
-                                           cb_data->unhighlight_id);
-              cb_data->unhighlight_id = 0;
-            }
-        }
-      else if (! cb_data->highlight_id && highlight_cb)
-        {
-          /* Have help now, but didn't previously.  Add callback.  */
-          cb_data->highlight_id
-            = g_signal_connect (G_OBJECT (w),
-                                "enter-notify-event",
-                                G_CALLBACK (menuitem_highlight_callback),
-                                cb_data);
-          cb_data->unhighlight_id
-            = g_signal_connect (G_OBJECT (w),
-                                "leave-notify-event",
-                                G_CALLBACK (menuitem_highlight_callback),
-                                cb_data);
-        }
     }
 }