Index: src/Plugins/Qt/QTMWidget.cpp
===================================================================
--- src/Plugins/Qt/QTMWidget.cpp	(revision 2812)
+++ src/Plugins/Qt/QTMWidget.cpp	(working copy)
@@ -36,6 +36,7 @@
 #define PIXEL 256
 
 extern bool qt_update_flag;
+extern bool checking_events;
 extern int time_credit;
 extern int timeout_time;
 
@@ -149,7 +150,8 @@
 
 void
 QTMWidget::postponedUpdate () {
-#ifdef Q_WS_MAC
+//#ifdef Q_WS_MAC
+#if 0
   //FIXME: the call below to update is ignored sometimes (usually in long documents).
   //       It is a confirmed Qt/Mac bug (#251792). See
   //       http://www.qtsoftware.com/developer/task-tracker/index_html?method=entry&id=251792
@@ -162,7 +164,8 @@
 #else
   while (!is_nil (delayed_rects)) {
     QRect rect = delayed_rects->item;
-    if (DEBUG_EVENTS) {
+    //if (DEBUG_EVENTS) 
+    {
       cout << "postponedUpdate (" << rect.x()
       << "," <<  rect.y()
       << "," <<  rect.width()
@@ -188,7 +191,7 @@
 QTMWidget::paintEvent (QPaintEvent* event) {
   //cout << "paint"<< LF;
   QRect rect = event->rect ();
-  bool partial_redraw = false;
+  bool partial_redraw = true;
 
   if (DEBUG_EVENTS) {
     QPainter p(this);
@@ -203,7 +206,7 @@
 
   }
 
-  if (!qt_update_flag) {
+  if (!qt_update_flag && !checking_events) {
     //int start= texmacs_time ();
     basic_renderer_rep *r;
 
@@ -243,11 +246,10 @@
      (rect.x()+rect.width())*PIXEL, -rect.y()*PIXEL);
 
     if (r->interrupted()) {
-      if (DEBUG_EVENTS)
+      //if (DEBUG_EVENTS)
         cout << "Interrupted\n";
-      qt_update_flag= true;
-      partial_redraw = true;
-    }
+        //qt_update_flag= true;
+    } else partial_redraw = false;
 
     r->end();
 
@@ -268,7 +270,7 @@
 
   if (partial_redraw) 
   {
-    if (DEBUG_EVENTS)
+    //if (DEBUG_EVENTS)
       cout << "Postponed redrawing\n";
     delayed_rects= list<QRect> (rect, delayed_rects);
     QTimer::singleShot (1, this, SLOT (postponedUpdate ()));
@@ -374,11 +376,14 @@
     if (DEBUG_EVENTS)
       cout << "key press: " << r << LF;
     //int start= texmacs_time ();
-    wid -> handle_keypress (r, texmacs_time());
+    //wid -> handle_keypress (r, texmacs_time());
+    the_gui -> process_keypress (wid, r, texmacs_time());
     //int end= texmacs_time ();
     //if (end > start) cout << "Keypress " << end - start << "\n";
-    the_gui->update (); // FIXME: remove this line when
+  //  the_gui->update (); // FIXME: remove this line when
                         // edit_typeset_rep::get_env_value will be faster
+    
+//    needs_update();
   }
 }
 
@@ -426,7 +431,8 @@
   scale (point);
   unsigned int mstate= mouse_state (event, false);
   string s= "press-" * mouse_decode (mstate);
-  wid -> handle_mouse (s, point.x (), point.y (), mstate, texmacs_time ());
+  the_gui -> process_mouse (wid, s, point.x (), point.y (), mstate, texmacs_time ());
+ // wid -> handle_mouse (s, point.x (), point.y (), mstate, texmacs_time ());
   if (DEBUG_EVENTS)
     cout << "mouse event: " << s << " at "
          << point.x () << ", " << point.y () << LF;
@@ -440,7 +446,8 @@
   scale (point);
   unsigned int mstate= mouse_state (event, true);
   string s= "release-" * mouse_decode (mstate);
-  wid -> handle_mouse (s, point.x (), point.y (), mstate, texmacs_time ());
+  the_gui -> process_mouse (wid, s, point.x (), point.y (), mstate, texmacs_time ());
+//  wid -> handle_mouse (s, point.x (), point.y (), mstate, texmacs_time ());
   if (DEBUG_EVENTS)
     cout << "mouse event: " << s << " at "
          << point.x () << ", " << point.y () << LF;
@@ -454,7 +461,8 @@
   scale (point);
   unsigned int mstate= mouse_state (event, false);
   string s= "move";
-  wid -> handle_mouse (s, point.x (), point.y (), mstate, texmacs_time ());
+  the_gui -> process_mouse (wid, s, point.x (), point.y (), mstate, texmacs_time ());
+//  wid -> handle_mouse (s, point.x (), point.y (), mstate, texmacs_time ());
   if (DEBUG_EVENTS)
     cout << "mouse event: " << s << " at "
          << point.x () << ", " << point.y () << LF;
@@ -478,7 +486,8 @@
   if (DEBUG_EVENTS) cout << "FOCUSIN" << LF;
   simple_widget_rep *wid = tm_widget ();
   if (wid) {
-    wid -> handle_keyboard_focus (true, texmacs_time ());
+    the_gui -> process_keyboard_focus (wid, true, texmacs_time());
+    //wid -> handle_keyboard_focus (true, texmacs_time ());
   }
   QWidget::focusInEvent (event);
 }
@@ -489,7 +498,8 @@
   if (DEBUG_EVENTS)   cout << "FOCUSOUT" << LF;
   simple_widget_rep *wid = tm_widget ();
   if (wid) {
-    wid -> handle_keyboard_focus (false, texmacs_time ());
+    the_gui -> process_keyboard_focus (wid, false, texmacs_time());
+//    wid -> handle_keyboard_focus (false, texmacs_time ());
   }
   QWidget::focusOutEvent (event);
 }
Index: src/Plugins/Qt/QTMGuiHelper.hpp
===================================================================
--- src/Plugins/Qt/QTMGuiHelper.hpp	(revision 2812)
+++ src/Plugins/Qt/QTMGuiHelper.hpp	(working copy)
@@ -28,7 +28,8 @@
   
 public slots:
   void doUpdate ();
-  void doSocketNotification (int socket);  
+  void doReadSocketNotification (int socket);  
+  void doWriteSocketNotification (int socket);  
   void doCommands ();
 };
 
Index: src/Plugins/Qt/qt_gui.cpp
===================================================================
--- src/Plugins/Qt/qt_gui.cpp	(revision 2812)
+++ src/Plugins/Qt/qt_gui.cpp	(working copy)
@@ -28,6 +28,8 @@
 #include "Scheme/object.hpp"
 //#include "TeXmacs/server.hpp" // for get_server
 
+#include "qt_simple_widget.hpp"
+
 extern window (*get_current_window) (void);
 
 qt_gui_rep* the_gui= NULL;
@@ -36,6 +38,8 @@
 
 int time_credit;
 int timeout_time;
+bool checking_events = false;
+bool qt_updating = false;
 
 /******************************************************************************
 * Constructor and geometry
@@ -184,26 +188,6 @@
 * Main loop
 ******************************************************************************/
 
-bool
-qt_gui_rep::check_event (int type) {
-  switch (type) {
-  /*
-  case INTERRUPT_EVENT:
-    if (interrupted) return true;
-    else {
-      time_t now= texmacs_time ();
-      if (now - timeout_time < 0) return false;
-      interrupted= true;
-      return interrupted;
-    }
-  case INTERRUPTED_EVENT:
-    return interrupted;
-  */
-  default:
-    return false;
-  }
-}
-
 void
 qt_gui_rep::show_wait_indicator (widget w, string message, string arg)  {
   (void) w; (void) message; (void) arg;
@@ -215,6 +199,16 @@
 
 void
 qt_gui_rep::update () {
+  qt_updating = true;
+  
+  if (checking_events) {
+    cout << "UPDATE WHILE CHECKING!!!" << LF;
+    updatetimer->start (1);
+    return;
+  }
+  
+  process_queued_events ();
+  
   // this is called by doUpdate, which in turns is fired by a timer activated in 
   // needs_update, and ensuring that interpose_handler is run during a pass in the eventloop
   // afterwards we reactivate the timer with a pause (see FIXME below) 
@@ -224,6 +218,8 @@
   qt_update_flag = false;
   interrupted = false;  
   
+  qt_updating = false;
+  
   updatetimer->start (1000/6);
   
   // FIXME: we need to ensure that the interpose_handler is run at regular intervals (1/6th of sec)
@@ -255,7 +251,7 @@
 {
   QSocketNotifier *qsn;
 
-  //  cout << "ADD NOTIFIER" << LF;
+    cout << "ADD NOTIFIER " << sn->fd << LF;
   
   // replace any already present notifier
 
@@ -264,10 +260,10 @@
   // installs both a read and a write notifier (the texmacs interface does not specify enough its needs)
   
   read_notifiers (sn) = (pointer) (qsn = new QSocketNotifier(sn->fd, QSocketNotifier::Read, gui_helper)); 
-  QObject::connect(qsn, SIGNAL(activated(int)), gui_helper, SLOT(doSocketNotification(int)) );
+  QObject::connect(qsn, SIGNAL(activated(int)), gui_helper, SLOT(doReadSocketNotification(int)) );
 
   write_notifiers (sn) = (pointer) (qsn = new QSocketNotifier(sn->fd, QSocketNotifier::Write, gui_helper));
-  QObject::connect(qsn, SIGNAL(activated(int)), gui_helper, SLOT(doSocketNotification(int)) );  
+  QObject::connect(qsn, SIGNAL(activated(int)), gui_helper, SLOT(doWriteSocketNotification(int)) );  
 }
 
 void 
@@ -275,7 +271,7 @@
 {  
   QSocketNotifier *qsn;
 
-  //  cout << "REMOVE NOTIFIER" << LF;
+    cout << "REMOVE NOTIFIER" << LF;
 
   // disable the (r/w) notifiers to prevent them to fire past this point
   // and schedule them for deletion at the end of the current runloop
@@ -295,6 +291,18 @@
   write_notifiers->reset (sn);
 }
 
+void 
+qt_gui_rep::enable_notifier (socket_notifier sn, bool flag)
+{
+  QSocketNotifier *qsn;
+  qsn = (QSocketNotifier *)read_notifiers (sn);
+  if (qsn) qsn->setEnabled (flag);
+  qsn = (QSocketNotifier *)write_notifiers (sn);
+  if (qsn) qsn->setEnabled (flag);
+}
+
+
+
 /******************************************************************************
  * Delayed commands
  ******************************************************************************/
@@ -324,7 +332,8 @@
 QTMGuiHelper::doCommands()
 {
   exec_pending_commands ();
-  the_gui->update ();
+  needs_update ();
+  //the_gui->update ();
 }
 
 void restart_global_timer (int pause = 0) {
@@ -509,22 +518,187 @@
 
 
 void
-QTMGuiHelper::doSocketNotification (int socket) {
-//  cout << "SOCKET NOTIFICATION " << socket << " "<< texmacs_time () << LF;
-  iterator<socket_notifier> it = iterate (read_notifiers);
+QTMGuiHelper::doWriteSocketNotification (int socket) {
+  //cout << "WRITE SOCKET NOTIFICATION " << socket << " "<< texmacs_time () << LF;
+  iterator<socket_notifier> it = iterate (write_notifiers);
   while (it->busy ()) {
     socket_notifier sn= it->next ();
-    if (sn->fd == socket) sn->notify();
+    if (sn->fd == socket) {
+      sn->notify();
+      //the_gui->process_socket_notification (sn);
+      //the_gui->enable_write_notifier (sn, false);
+    }
   }
-  it = iterate (write_notifiers);
+}
+
+void
+QTMGuiHelper::doReadSocketNotification (int socket) {
+  //cout << "READ SOCKET NOTIFICATION " << socket << " "<< texmacs_time () << LF;
+  iterator<socket_notifier> it = iterate (read_notifiers);
   while (it->busy ()) {
     socket_notifier sn= it->next ();
-    if (sn->fd == socket) sn->notify();
+    if (sn->fd == socket) {
+      sn->notify();
+      //the_gui->process_socket_notification (sn);
+      //the_gui->enable_read_notifier (sn, false);
+    }
   }
 }
 
 
 /******************************************************************************
+ * Queued processing
+ ******************************************************************************/
+
+enum qp_type_id {
+  QP_NULL,
+  QP_KEYPRESS,
+  QP_KEYBOARD_FOCUS,
+  QP_MOUSE,
+  QP_SOCKET_NOTIFICATION
+};
+
+class qp_type {
+public:
+  qp_type_id sid;
+  inline qp_type (qp_type_id sid2 = QP_NULL): sid (sid2) {}
+  inline qp_type (const qp_type& s): sid (s.sid) {}
+  inline qp_type& operator = (qp_type s) { sid= s.sid; return *this; }
+  inline operator qp_type_id () { return sid; }
+  inline bool operator == (qp_type_id sid2) { return sid == sid2; }
+  inline bool operator != (qp_type_id sid2) { return sid != sid2; }
+  inline bool operator == (qp_type s) { return sid == s.sid; }
+  inline bool operator != (qp_type s) { return sid != s.sid; }
+  inline friend ostream& operator << (ostream& out, qp_type s) { return out << s.sid; }
+};
+
+class queued_event : public pair<qp_type, blackbox> 
+{
+public:
+  queued_event(qp_type _type = qp_type(), blackbox _bb = blackbox()) : pair<qp_type, blackbox>(_type, _bb) {};
+};
+
+
+static array<queued_event> waiting_events;
+
+void 
+qt_gui_rep::process_keypress (simple_widget_rep *wid, string key, time_t t) {
+  typedef triple<simple_widget_rep*, string, time_t > T;
+  waiting_events << queued_event ( QP_KEYPRESS, close_box<T> (T(wid, key, t))); 
+//  wid -> handle_keypress (key, t);
+  needs_update ();
+}
+
+void 
+qt_gui_rep::process_keyboard_focus (simple_widget_rep *wid, bool has_focus, time_t t) {
+  typedef triple<simple_widget_rep*, bool, time_t > T;
+  waiting_events << queued_event ( QP_KEYBOARD_FOCUS, close_box<T> (T(wid, has_focus, t))); 
+//  wid -> handle_keyboard_focus (has_focus, t);
+  needs_update ();
+}
+
+void 
+qt_gui_rep::process_mouse (simple_widget_rep *wid, string kind, SI x, SI y, int mods, time_t t) {
+  typedef quintuple<string, SI, SI, int, time_t > T1;
+  typedef pair<simple_widget_rep*, T1> T;
+  waiting_events << queued_event ( QP_MOUSE, close_box<T> ( T (wid, T1 (kind, x, y, mods, t)))); 
+//  wid -> handle_mouse (kind, x, y, mods, t);
+  needs_update();
+}
+
+void 
+qt_gui_rep::process_socket_notification (socket_notifier sn) {
+  waiting_events << queued_event (QP_SOCKET_NOTIFICATION, close_box< socket_notifier > (sn));
+  needs_update();
+}
+  
+void 
+qt_gui_rep::process_queued_events () {
+
+  array<queued_event> a = waiting_events;
+  waiting_events = array<queued_event> ();
+
+  int i, n = N(a);
+
+  for (i=0; i<n; i++) {
+    switch ((qp_type_id) a[i].x1) {
+      case QP_NULL :
+        break;
+      case QP_KEYPRESS :
+      {
+        typedef triple<simple_widget_rep*, string, time_t > T;
+        T x = open_box <T> (a[i].x2) ;
+        x.x1 -> handle_keypress (x.x2, x.x3) ;
+      }
+        break;
+      case QP_KEYBOARD_FOCUS :
+      {
+        typedef triple<simple_widget_rep*, bool, time_t > T;
+        T x = open_box <T> (a[i].x2) ;
+        x.x1 -> handle_keyboard_focus (x.x2, x.x3) ;
+      }
+        break;
+      case QP_MOUSE :
+      {
+        typedef quintuple<string, SI, SI, int, time_t > T1;
+        typedef pair<simple_widget_rep*, T1> T;
+        T x = open_box <T> (a[i].x2) ;
+        x.x1 -> handle_mouse (x.x2.x1, x.x2.x2, x.x2.x3, x.x2.x4, x.x2.x5) ;
+      }
+        break;
+      case QP_SOCKET_NOTIFICATION :
+      {
+        socket_notifier sn = open_box <socket_notifier> (a[i].x2) ;
+        cout << "QP_SOCKET_NOTIFICATION " << sn->fd << LF;
+        sn -> notify ();
+        enable_notifier (sn, true);
+      }
+        break;
+      default:   
+        ;
+    }
+  }
+}
+
+
+bool
+qt_gui_rep::check_event (int type) {
+ // return false;
+  switch (type) {
+    case INTERRUPT_EVENT:
+      if (interrupted) return true;
+      else {
+        if (checking_events) {
+          cout << "RECURSIVELY PEEKING TO EVENTS: THIS SHOULD NOT HAPPEN" << LF;
+          abort();
+        }
+        int n = N(waiting_events);
+        if ((n == 0) && (!qt_updating)) {
+          checking_events = true;
+          bool flag = updatetimer->isActive ();
+          updatetimer->stop();
+          cout << INDENT;
+          qApp -> processEvents (QEventLoop::ExcludeSocketNotifiers);
+          cout << UNINDENT;
+          checking_events = false;
+          if (flag) updatetimer->start();
+        }
+        if (N(waiting_events) == 0) return false;
+        else {
+          interrupted= true;
+          return interrupted;
+        }
+      }
+    case INTERRUPTED_EVENT:
+      return interrupted;
+    default:
+      return false;
+  }
+}
+
+
+
+/******************************************************************************
 * Font support
 ******************************************************************************/
 
Index: src/Plugins/Qt/qt_gui.hpp
===================================================================
--- src/Plugins/Qt/qt_gui.hpp	(revision 2812)
+++ src/Plugins/Qt/qt_gui.hpp	(working copy)
@@ -31,6 +31,7 @@
 typedef class qt_gui_rep* qt_gui;
 extern qt_gui the_gui;
 class QTMGuiHelper;
+class simple_widget_rep;
 
 class qt_gui_rep {
 public:
@@ -70,6 +71,22 @@
   
   void add_notifier (socket_notifier);
   void remove_notifier (socket_notifier);
+  void enable_notifier (socket_notifier, bool);
+  
+  /* queued processing */
+  void process_keypress (simple_widget_rep *wid, string key, time_t t);
+  void process_keyboard_focus (simple_widget_rep *wid, bool has_focus, time_t t);
+  void process_mouse (simple_widget_rep *wid, string kind, SI x, SI y, int mods, time_t t);
+  void process_socket_notification (socket_notifier sn);
+
+  void process_queued_events ();
+  //void process_get_size_hint (SI& w, SI& h);
+  //void process_notify_resize (SI w, SI h);
+  //void process_set_shrinking_factor (int sf);
+  //void process_clear (SI x1, SI y1, SI x2, SI y2);
+  //void process_repaint (SI x1, SI y1, SI x2, SI y2);
+  
+  
 };
 
 #endif // defined QT_GUI_HPP
Index: src/System/Link/socket_notifier.hpp
===================================================================
--- src/System/Link/socket_notifier.hpp	(revision 2812)
+++ src/System/Link/socket_notifier.hpp	(working copy)
@@ -38,6 +38,11 @@
 };
 CONCRETE_NULL_CODE(socket_notifier);
 
+inline ostream& operator << (ostream& out, socket_notifier sn) {
+  if (is_nil (sn)) return out << "nil socket_notifier";
+else return out << "some socket_notifier"; }
+
+
 void perform_select ();
 void add_notifier (socket_notifier);
 void remove_notifier (socket_notifier);
