changeset 27428:c8b20597f0fd

(toplevel): Include atimer.h. (toolkit_scroll_bar_interaction): New variable. (Fxt_process_timeouts): Removed. (x_process_timeouts): New function. (xt_action_hook): Clear toolkit_scroll_bar_interaction. (x_send_scroll_bar_event): Set toolkit_scroll_bar_interaction. (x_make_frame_visible): Call poll_for_input_1 instead of input_poll_signal. Don't call alarm. (x_initialize): Install timer calling x_process_timeouts.
author Gerd Moellmann <gerd@gnu.org>
date Tue, 25 Jan 2000 15:55:13 +0000
parents 0036f90725f6
children 1bf632297f7d
files src/xterm.c
diffstat 1 files changed, 48 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/xterm.c	Tue Jan 25 15:54:07 2000 +0000
+++ b/src/xterm.c	Tue Jan 25 15:55:13 2000 +0000
@@ -88,6 +88,7 @@
 #include "keyboard.h"
 #include "intervals.h"
 #include "process.h"
+#include "atimer.h"
 
 #ifdef USE_X_TOOLKIT
 #include <X11/Shell.h>
@@ -298,6 +299,9 @@
 
 struct cursor_pos output_cursor;
 
+/* Non-zero means user is interacting with a toolkit scroll bar.  */
+
+static int toolkit_scroll_bar_interaction;
 
 /* Mouse movement.
 
@@ -7178,21 +7182,27 @@
 }
 
 
-DEFUN ("xt-process-timeouts", Fxt_process_timeouts, Sxt_process_timeouts,
-       0, 0, 0,
-  "Arrange for Xt timeout callbacks to be called.")
-  ()
-{
 #ifdef USE_X_TOOLKIT
-  BLOCK_INPUT;
-  while (XtAppPending (Xt_app_con) & XtIMTimer)
-    XtAppProcessEvent (Xt_app_con, XtIMTimer);
-  UNBLOCK_INPUT;
+
+/* Atimer callback function for TIMER.  Called every 0.1s to process
+   Xt timeouts, if needed.  We must avoid calling XtAppPending as
+   much as possible because that function does an implicit XFlush
+   that slows us down.  */
+
+static void
+x_process_timeouts (timer)
+     struct atimer *timer;
+{
+  if (toolkit_scroll_bar_interaction || popup_activated_flag)
+    {
+      BLOCK_INPUT;
+      while (XtAppPending (Xt_app_con) & XtIMTimer)
+	XtAppProcessEvent (Xt_app_con, XtIMTimer);
+      UNBLOCK_INPUT;
+    }
+}
+
 #endif /* USE_X_TOOLKIT */
-  
-  return Qnil;
-}
-
 
 
 /* Scroll bar support.  */
@@ -7200,6 +7210,7 @@
 /* Given an X window ID, find the struct scroll_bar which manages it.
    This can be called in GC, so we have to make sure to strip off mark
    bits.  */
+
 static struct scroll_bar *
 x_window_to_scroll_bar (window_id)
      Window window_id;
@@ -7301,8 +7312,6 @@
   end_action = "EndScroll";
 #endif /* USE_MOTIF */
 
-  /* Although LessTif uses XtTimeouts like Xaw3d, the timer hack to
-     let Xt timeouts be processed doesn't work.  */
   if (scroll_bar_p
       && strcmp (action_name, end_action) == 0
       && WINDOWP (window_being_scrolled))
@@ -7315,6 +7324,9 @@
       XSCROLL_BAR (w->vertical_scroll_bar)->dragging = Qnil;
       window_being_scrolled = Qnil;
       last_scroll_bar_part = -1;
+
+      /* Xt timeouts no longer needed.  */
+      toolkit_scroll_bar_interaction = 0;
     }
 }
 
@@ -7345,6 +7357,9 @@
   ev->data.l[3] = (long) portion;
   ev->data.l[4] = (long) whole;
 
+  /* Make Xt timeouts work while the scroll bar is active.  */
+  toolkit_scroll_bar_interaction = 1;
+
   /* Setting the event mask to zero means that the message will
      be sent to the client that created the window, and if that
      window no longer exists, no event will be sent.  */
@@ -11370,8 +11385,10 @@
 	    /* It could be confusing if a real alarm arrives while
 	       processing the fake one.  Turn it off and let the
 	       handler reset it.  */
-	    alarm (0);
-	    input_poll_signal (0);
+	    int old_poll_suppress_count = poll_suppress_count;
+	    poll_suppress_count = 1;
+	    poll_for_input_1 ();
+	    poll_suppress_count = old_poll_suppress_count;
 	  }
 
 	/* See if a MapNotify event has been processed.  */
@@ -12918,8 +12935,7 @@
       tail = x_display_name_list;
       while (CONSP (tail) && CONSP (XCDR (tail)))
 	{
-	  if (EQ (XCAR (XCDR (tail)),
-		  dpyinfo->name_list_element))
+	  if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
 	    {
 	      XCDR (tail) = XCDR (XCDR (tail));
 	      break;
@@ -13017,7 +13033,19 @@
   XtToolkitInitialize ();
   Xt_app_con = XtCreateApplicationContext ();
   XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
-#endif
+
+  /* Install an asynchronous timer that processes Xt timeout events
+     every 0.1s.  This is necessary because some widget sets use
+     timeouts internally, for example the LessTif menu bar, or the
+     Xaw3d scroll bar.  When Xt timouts aren't processed, these
+     widgets don't behave normally.  */
+  {
+    EMACS_TIME interval;
+    EMACS_SET_SECS_USECS (interval, 0, 100000);
+    start_atimer (ATIMER_CONTINUOUS, interval, x_process_timeouts, 0);
+  }
+#endif
+  
 #if USE_TOOLKIT_SCROLL_BARS
   xaw3d_arrow_scroll = False;
   xaw3d_pick_top = True;
@@ -13074,7 +13102,6 @@
   x_toolkit_scroll_bars_p = 0;
 #endif
 
-  defsubr (&Sxt_process_timeouts);
   staticpro (&last_mouse_motion_frame);
   last_mouse_motion_frame = Qnil;
 }