This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gui] [PATCH] Fix Menu's signal connection


Hello,

I committed the following patch to the java-gui-branch.  It fixes a
problem with Menus, where the MenuItem peers were not receiving any
mouse event signals.  The problem was that the Menu peer's top-level
GtkWindow was not a part of the global window group.  The purpose of the
window group is to limit which widgets can grab the mouse pointer.  As a
result, all mouse event signals were going straight to the application's
top-level GtkWindow, bypassing the Menu completely.  A simple fix, but
took me a while to figure it out. :)

-David Jee

2004-03-26  David Jee  <djee@redhat.com>

        * gnu/java/awt/peer/gtk/GtkMenuItemPeer.java
        (connectSignals): New native method declaration.
        (GtkMenuItemPeer): Connect signals if the parent is a Menu.
        * java/awt/MenuItem.java
        (getActionCommand): Return the label if the action command is not set.
        * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c
        (Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_addMenu): Use
        gtk_menu_shell_append().
        * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
        (item_activate): Fix argument type.
        (Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_create): Do not connect
        signal here.
        (Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_connectSignals): New
        method.
        * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c
        (Java_gnu_java_awt_peer_gtk_GtkMenuPeer_create): Check if a label is
        given. Add the menu widget's top-level GtkWindow to the global window
        group, so it can grab the pointer.
        (Java_gnu_java_awt_peer_gtk_GtkMenuPeer_addItem): Use
        gtk_menu_shell_append().


Index: gnu/java/awt/peer/gtk/GtkMenuItemPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java,v
retrieving revision 1.3
diff -u -r1.3 GtkMenuItemPeer.java
--- gnu/java/awt/peer/gtk/GtkMenuItemPeer.java	8 Oct 2003 15:49:31 -0000	1.3
+++ gnu/java/awt/peer/gtk/GtkMenuItemPeer.java	26 Mar 2004 15:45:19 -0000
@@ -50,6 +50,7 @@
   implements MenuItemPeer
 {
   native void create (String label);
+  public native void connectSignals ();
 
   public GtkMenuItemPeer (MenuItem item)
   {
@@ -57,6 +58,9 @@
     create (item.getLabel ());
     setEnabled (item.isEnabled ());
     setParent (item);
+
+    if (item.getParent() instanceof Menu)
+      connectSignals();
   }
 
   void setParent (MenuItem item)
Index: java/awt/MenuItem.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/MenuItem.java,v
retrieving revision 1.16
diff -u -r1.16 MenuItem.java
--- java/awt/MenuItem.java	3 Feb 2004 17:10:53 -0000	1.16
+++ java/awt/MenuItem.java	26 Mar 2004 15:45:21 -0000
@@ -310,7 +310,10 @@
 public String
 getActionCommand()
 {
-  return(actionCommand);
+  if (actionCommand == null)
+    return label;
+  else
+    return actionCommand;
 }
 
 /*************************************************************************/
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_awt_peer_gtk_GtkMenuBarPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c	13 Dec 2003 01:15:47 -0000	1.2
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c	26 Mar 2004 15:45:22 -0000
@@ -66,7 +66,7 @@
   menu = NSA_GET_PTR (env, menupeer);
 
   gdk_threads_enter ();
-  gtk_menu_bar_append (GTK_MENU_BAR (mbar), GTK_WIDGET (menu));
+  gtk_menu_shell_append (GTK_MENU_SHELL (mbar), GTK_WIDGET (menu));
   gdk_threads_leave ();
 }
 
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c,v
retrieving revision 1.4
diff -u -r1.4 gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c	13 Dec 2003 01:15:47 -0000	1.4
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c	26 Mar 2004 15:45:22 -0000
@@ -41,18 +41,16 @@
 #include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
 
 static void item_activate (GtkMenuItem *item __attribute__((unused)),
-                           jobject *peer_obj);
+                           jobject peer_obj);
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_create
   (JNIEnv *env, jobject obj, jstring label)
 {
   GtkWidget *widget;
   const char *str;
-  jobject *gref;
 
   /* Create global reference and save it for future use */
   NSA_SET_GLOBAL_REF (env, obj);
-  gref = NSA_GET_GLOBAL_REF (env, obj);
 
   str = (*env)->GetStringUTFChars (env, label, NULL);
 
@@ -63,10 +61,6 @@
   else
     widget = gtk_menu_item_new_with_label (str);
 
-  /* Connect activate hook */
-  g_signal_connect (G_OBJECT (widget), "activate", 
-		      GTK_SIGNAL_FUNC (item_activate), *gref);
-
   gtk_widget_show (widget);
 
   gdk_threads_leave ();
@@ -76,6 +70,22 @@
   NSA_SET_PTR (env, obj, widget);
 }
 
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_connectSignals
+  (JNIEnv *env, jobject obj)
+{
+  void *ptr = NSA_GET_PTR (env, obj);
+  jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
+  g_assert (gref);
+  
+  gdk_threads_enter ();
+  
+  g_signal_connect (G_OBJECT (ptr), "activate",
+                    G_CALLBACK (item_activate), *gref);
+
+  gdk_threads_leave ();
+}
+
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_setLabel
   (JNIEnv *env, jobject obj, jstring label)
 {
@@ -104,9 +114,9 @@
 }
 
 static void
-item_activate (GtkMenuItem *item __attribute__((unused)), jobject *peer_obj)
+item_activate (GtkMenuItem *item __attribute__((unused)), jobject peer_obj)
 {
-  (*gdk_env)->CallVoidMethod (gdk_env, *peer_obj,
+  (*gdk_env)->CallVoidMethod (gdk_env, peer_obj,
 			      postMenuActionEventID);
 }
 
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c,v
retrieving revision 1.4
diff -u -r1.4 gnu_java_awt_peer_gtk_GtkMenuPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c	13 Dec 2003 01:15:47 -0000	1.4
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c	26 Mar 2004 15:45:22 -0000
@@ -101,10 +101,21 @@
   
   menu = gtk_menu_new ();
   
-  menu_title = gtk_menu_item_new_with_label (str);
+  if (str != NULL)
+    menu_title = gtk_menu_item_new_with_label (str);
+  else
+    menu_title = gtk_menu_item_new();
+
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_title), menu);
 
-  gtk_widget_show (menu);
+  // Allow this menu to grab the pointer.
+  GtkWidget *toplevel = gtk_widget_get_toplevel (menu);
+  if (GTK_IS_WINDOW (toplevel))
+    {
+      gtk_window_group_add_window (global_gtk_window_group,
+                                   GTK_WINDOW(toplevel));
+    }
+
   gtk_widget_show (menu_title);
 
   NSA_SET_PTR (env, obj, menu_title);
@@ -125,8 +136,8 @@
 
   gdk_threads_enter ();
 
-  menu = GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu);
-  gtk_menu_append (menu, GTK_WIDGET (ptr2));
+  menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(ptr1));
+  gtk_menu_shell_append (GTK_MENU_SHELL(menu), GTK_WIDGET (ptr2));
 
   if (key)
     {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]