Subject: patch 5.4p.13
From: Bram Moolenaar <[email-masked]>
To: [email-masked]
Date: Sat, 24 Jul 1999 13:02:36 +0200

This is the "official" version of the previous copy/paste hang problem fix.
I also included the change to make vim work with GTK 1.0.6.

Patch 5.4p.13
Problem:    GTK: pasting selected text sometimes caused a hang.
	    Hang with GTK 1.0.6.  
Solution:   In clip_mch_request_selection() there was a gui_mch_update() call
	    in the wrong place.
	    Also: Skip getting a normal string selection if the Vim selection
	    was already obtained successfully.
	    Added idle_function() back. (Kahn)
Files:	    src/gui_gtk_x11.c

*** ../vim-5.4p/src/gui_gtk_x11.c	Mon Jul 19 11:09:06 1999
--- src/gui_gtk_x11.c	Fri Jul 23 12:45:47 1999
***************
*** 582,588 ****
      return TRUE;
  }
  
! static int did_receive_selection = FALSE;
  
  /*ARGSUSED*/
  static void
--- 582,591 ----
      return TRUE;
  }
  
! #define RS_NONE	0	/* selection_received_event() not called yet */
! #define RS_OK	1	/* selection_received_event() called and OK */
! #define RS_FAIL	2	/* selection_received_event() called and failed */
! static int received_selection;
  
  /*ARGSUSED*/
  static void
***************
*** 592,600 ****
      long_u len;
      char_u *p;
  
-     did_receive_selection = TRUE;
- 
      if ((!data->data) || (data->length <= 0)) {
  	/* clip_free_selection(); ??? */
  	if (gtk_main_level() > 0)
  	    gtk_main_quit();
--- 595,602 ----
      long_u len;
      char_u *p;
  
      if ((!data->data) || (data->length <= 0)) {
+ 	received_selection = RS_FAIL;
  	/* clip_free_selection(); ??? */
  	if (gtk_main_level() > 0)
  	    gtk_main_quit();
***************
*** 611,616 ****
--- 613,619 ----
  	len--;
      }
      clip_yank_selection(motion_type, p, (long) len);
+ 	received_selection = RS_OK;
      if (gtk_main_level() > 0)
  	gtk_main_quit();
  }
***************
*** 2047,2052 ****
--- 2056,2072 ----
      gdk_gc_destroy(gc);
  }
  
+ #ifndef GTK_HAVE_FEATURES_1_1_0
+ static gint
+ idle_function(GtkWidget * label)
+ {
+     if (gtk_main_level() > 0)
+ 	gtk_main_quit();
+ 
+     return FALSE;
+ }
+ #endif
+ 
  
  /*
   * Catch up with any queued X11 events.  This may put keyboard input into the
***************
*** 2057,2066 ****
  void
  gui_mch_update()
  {
      while (gtk_events_pending() && !vim_is_input_buf_full())
  	gtk_main_iteration_do(FALSE);
  
!     return;
  }
  
  static gint
--- 2077,2098 ----
  void
  gui_mch_update()
  {
+ #ifdef GTK_HAVE_FEATURES_1_1_0
      while (gtk_events_pending() && !vim_is_input_buf_full())
  	gtk_main_iteration_do(FALSE);
+ #else
+     int pending;
+ 
+     /* Somehow the above loop hangs on GTK 1.0.6.  Use the idle_function() to
+      * work around this weird problem. */
+     while (((pending = gtk_events_pending()) > 1) && !vim_is_input_buf_full())
+ 	gtk_main_iteration();
  
!     if ((pending == 1) && !vim_is_input_buf_full()) {
! 	gtk_idle_add((GtkFunction)idle_function, gui.mainwin);
! 	gtk_main_iteration_do(FALSE);
!     }
! #endif
  }
  
  static gint
***************
*** 2322,2342 ****
  clip_mch_request_selection()
  {
      /* First try to get the content of our own special clipboard. */
      (void)gtk_selection_convert(gui.drawarea,
  				    GDK_SELECTION_PRIMARY, clipboard.atom,
  				    GDK_CURRENT_TIME);
!     did_receive_selection = FALSE;
!     while (!did_receive_selection)
! 	gtk_main();		/* wait until signal arrives */
  
!     /* Ok now try to get it out of the usual string selection. */
!     (void)gtk_selection_convert(gui.drawarea, GDK_SELECTION_PRIMARY,
  				    GDK_TARGET_STRING,
  				    GDK_CURRENT_TIME);
!     gui_mch_update();
!     did_receive_selection = FALSE;
!     while (!did_receive_selection)
! 	gtk_main();		/* wait until signal arrives */
  }
  
  void
--- 2354,2376 ----
  clip_mch_request_selection()
  {
      /* First try to get the content of our own special clipboard. */
+     received_selection = RS_NONE;
      (void)gtk_selection_convert(gui.drawarea,
  				    GDK_SELECTION_PRIMARY, clipboard.atom,
  				    GDK_CURRENT_TIME);
!     while (received_selection == RS_NONE)
! 	gtk_main();		/* wait for selection_received_event */
  
!     if (received_selection == RS_FAIL)
!     {
! 	/* Now try to get it out of the usual string selection. */
! 	received_selection = RS_NONE;
! 	(void)gtk_selection_convert(gui.drawarea, GDK_SELECTION_PRIMARY,
  				    GDK_TARGET_STRING,
  				    GDK_CURRENT_TIME);
! 	while (received_selection == RS_NONE)
! 	    gtk_main();		/* wait for selection_received_event */
!     }
  }
  
  void

--
hundred-and-one symptoms of being an internet addict:
246. You use up your free 100 hours in less than a week.

--/-/---- Bram Moolenaar ---- [email-masked] ---- [email-masked] ---\-\--
  \ \    www.vim.org/iccf      www.moolenaar.net       www.vim.org    / /