diff src/event-Xt.c @ 420:41dbb7a9d5f2 r21-2-18

Import from CVS: tag r21-2-18
author cvs
date Mon, 13 Aug 2007 11:24:09 +0200
parents 697ef44129c6
children 95016f13131a
line wrap: on
line diff
--- a/src/event-Xt.c	Mon Aug 13 11:23:14 2007 +0200
+++ b/src/event-Xt.c	Mon Aug 13 11:24:09 2007 +0200
@@ -78,6 +78,7 @@
 #include "events-mod.h"
 
 static void enqueue_Xt_dispatch_event (Lisp_Object event);
+static void handle_focus_event_1 (struct frame *f, int in_p);
 
 static struct event_stream *Xt_event_stream;
 
@@ -807,7 +808,8 @@
   len = XmImMbLookupString (XtWindowToWidget (event->display, event->window),
 			    event, bufptr, bufsiz, &keysym, &status);
 #else /* XIM_XLIB */
-  len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
+  if (xic)
+    len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
 #endif /* HAVE_XIM */
 
 #ifdef DEBUG_XEMACS
@@ -1046,6 +1048,7 @@
 	  {
 	    XButtonEvent *ev = &x_event->xbutton;
 	    struct frame *frame = x_window_to_frame (d, ev->window);
+
 	    if (! frame)
 	      return 0;	/* not for us */
 	    XSETFRAME (emacs_event->channel, frame);
@@ -1058,7 +1061,11 @@
 	    emacs_event->event.button.button	= ev->button;
 	    emacs_event->event.button.x		= ev->x;
 	    emacs_event->event.button.y		= ev->y;
-
+	    /* because we don't seem to get a FocusIn event for button clicks
+	       when a widget-glyph is selected we will assume that we want the
+	       focus if a button gets pressed. */
+	    if (x_event->type == ButtonPress)
+	      handle_focus_event_1 (frame, 1);
 	  }
       }
     break;
@@ -1304,8 +1311,12 @@
 static void
 handle_focus_event_1 (struct frame *f, int in_p)
 {
-#ifdef HAVE_XIM
-  XIM_focus_event (f, in_p);
+#if XtSpecificationRelease > 5
+  Widget focus_widget = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f));
+#endif
+#if defined(HAVE_XIM) && defined(XIM_XLIB)
+  if (FRAME_X_XIC(f))
+    XIM_focus_event (f, in_p);
 #endif /* HAVE_XIM */
 
   /* On focus change, clear all memory of sticky modifiers
@@ -1319,7 +1330,26 @@
      Actually, we half handle it: we handle it as far as changing the
      box cursor for redisplay, but we don't call any hooks or do any
      select-frame stuff until after the sit-for.
-   */
+
+     Unfortunately native widgets break the model because they grab
+     the keyboard focus and nothing sets it back again. I cannot find
+     any reasonable way to do this elsewhere so we assert here that
+     the keybpard focus is on the emacs text widget. Menus and dialogs
+     do this in their selection callback, but we don't want that since
+     a button having focus is legitimate. An edit field having focus
+     is mandatory. Weirdly you get a FocusOut event when you glick in
+     a widget-glyph but you don't get a correspondng FocusIn when you
+     click in the frame. Why is this?  */
+  if (in_p 
+#if XtSpecificationRelease > 5      
+      && FRAME_X_TEXT_WIDGET (f) != focus_widget
+#endif
+      )
+    {
+      lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f),
+			     FRAME_X_TEXT_WIDGET (f));
+    }
+  /* do the generic event-stream stuff. */
   {
     Lisp_Object frm;
     Lisp_Object conser;
@@ -1404,7 +1434,7 @@
 
       /* Bleagh!!!!!!  Apparently some window managers (e.g. MWM)
 	 send synthetic MapNotify events when a window is first
-	 created, EVENT IF IT'S CREATED ICONIFIED OR INVISIBLE.
+	 created, EVEN IF IT'S CREATED ICONIFIED OR INVISIBLE.
 	 Or something like that.  We initially tried a different
 	 solution below, but that ran into a different window-
 	 manager bug.
@@ -1579,6 +1609,7 @@
 
     case FocusIn:
     case FocusOut:
+
 #ifdef EXTERNAL_WIDGET
       /* External widget lossage: Ben said:
 	 YUCK.  The only way to make focus changes work properly is to
@@ -1613,8 +1644,9 @@
       break;
 
     case ConfigureNotify:
-#ifdef HAVE_XIM
-      XIM_SetGeometry (f);
+#if defined(HAVE_XIM) && defined(XIM_XLIB)
+      if (FRAME_X_XIC(f))
+	XIM_SetGeometry (f);
 #endif
       break;