99b86a7
To: vim-dev@vim.org
99b86a7
Subject: patch 7.1.095
99b86a7
Fcc: outbox
99b86a7
From: Bram Moolenaar <Bram@moolenaar.net>
99b86a7
Mime-Version: 1.0
99b86a7
Content-Type: text/plain; charset=ISO-8859-1
99b86a7
Content-Transfer-Encoding: 8bit
99b86a7
------------
99b86a7
99b86a7
Patch 7.1.095
99b86a7
Problem:    The FocusLost and FocusGained autocommands are triggered
99b86a7
	    asynchronously in the GUI.  This may cause arbitrary problems.
99b86a7
Solution:   Put the focus event in the input buffer and handle it when ready
99b86a7
	    for it.
99b86a7
Files:	    src/eval.c, src/getchar.c, src/gui.c, src/gui_gtk_x11.c,
99b86a7
	    src/keymap.h
99b86a7
99b86a7
99b86a7
*** ../vim-7.1.094/src/eval.c	Thu Aug 30 11:10:38 2007
99b86a7
--- src/eval.c	Mon Sep  3 22:48:09 2007
99b86a7
***************
99b86a7
*** 9912,9929 ****
99b86a7
  
99b86a7
      ++no_mapping;
99b86a7
      ++allow_keys;
99b86a7
!     if (argvars[0].v_type == VAR_UNKNOWN)
99b86a7
! 	/* getchar(): blocking wait. */
99b86a7
! 	n = safe_vgetc();
99b86a7
!     else if (get_tv_number_chk(&argvars[0], &error) == 1)
99b86a7
! 	/* getchar(1): only check if char avail */
99b86a7
! 	n = vpeekc();
99b86a7
!     else if (error || vpeekc() == NUL)
99b86a7
! 	/* illegal argument or getchar(0) and no char avail: return zero */
99b86a7
! 	n = 0;
99b86a7
!     else
99b86a7
! 	/* getchar(0) and char avail: return char */
99b86a7
! 	n = safe_vgetc();
99b86a7
      --no_mapping;
99b86a7
      --allow_keys;
99b86a7
  
99b86a7
--- 9912,9935 ----
99b86a7
  
99b86a7
      ++no_mapping;
99b86a7
      ++allow_keys;
99b86a7
!     for (;;)
99b86a7
!     {
99b86a7
! 	if (argvars[0].v_type == VAR_UNKNOWN)
99b86a7
! 	    /* getchar(): blocking wait. */
99b86a7
! 	    n = safe_vgetc();
99b86a7
! 	else if (get_tv_number_chk(&argvars[0], &error) == 1)
99b86a7
! 	    /* getchar(1): only check if char avail */
99b86a7
! 	    n = vpeekc();
99b86a7
! 	else if (error || vpeekc() == NUL)
99b86a7
! 	    /* illegal argument or getchar(0) and no char avail: return zero */
99b86a7
! 	    n = 0;
99b86a7
! 	else
99b86a7
! 	    /* getchar(0) and char avail: return char */
99b86a7
! 	    n = safe_vgetc();
99b86a7
! 	if (n == K_IGNORE)
99b86a7
! 	    continue;
99b86a7
! 	break;
99b86a7
!     }
99b86a7
      --no_mapping;
99b86a7
      --allow_keys;
99b86a7
  
99b86a7
*** ../vim-7.1.094/src/getchar.c	Thu May 10 18:43:02 2007
99b86a7
--- src/getchar.c	Wed Aug 29 22:38:49 2007
99b86a7
***************
99b86a7
*** 1596,1603 ****
99b86a7
  		continue;
99b86a7
  	    }
99b86a7
  #endif
99b86a7
- 
99b86a7
  #ifdef FEAT_GUI
99b86a7
  	    /* Translate K_CSI to CSI.  The special key is only used to avoid
99b86a7
  	     * it being recognized as the start of a special key. */
99b86a7
  	    if (c == K_CSI)
99b86a7
--- 1596,1610 ----
99b86a7
  		continue;
99b86a7
  	    }
99b86a7
  #endif
99b86a7
  #ifdef FEAT_GUI
99b86a7
+ 	    /* The caller doesn't need to know that the focus event is delayed
99b86a7
+ 	     * until getting a character. */
99b86a7
+ 	    if (c == K_FOCUSGAINED || c == K_FOCUSLOST)
99b86a7
+ 	    {
99b86a7
+ 		ui_focus_change(c == K_FOCUSGAINED);
99b86a7
+ 		continue;
99b86a7
+ 	    }
99b86a7
+ 
99b86a7
  	    /* Translate K_CSI to CSI.  The special key is only used to avoid
99b86a7
  	     * it being recognized as the start of a special key. */
99b86a7
  	    if (c == K_CSI)
99b86a7
*** ../vim-7.1.094/src/gui.c	Thu Aug 30 13:51:52 2007
99b86a7
--- src/gui.c	Thu Aug 30 14:10:48 2007
99b86a7
***************
99b86a7
*** 4519,4525 ****
99b86a7
      xim_set_focus(in_focus);
99b86a7
  # endif
99b86a7
  
99b86a7
!     ui_focus_change(in_focus);
99b86a7
  #endif
99b86a7
  }
99b86a7
  
99b86a7
--- 4519,4536 ----
99b86a7
      xim_set_focus(in_focus);
99b86a7
  # endif
99b86a7
  
99b86a7
!     /* Put events in the input queue only when allowed.
99b86a7
!      * ui_focus_change() isn't called directly, because it invokes
99b86a7
!      * autocommands and that must not happen asynchronously. */
99b86a7
!     if (!hold_gui_events)
99b86a7
!     {
99b86a7
! 	char_u  bytes[3];
99b86a7
! 
99b86a7
! 	bytes[0] = CSI;
99b86a7
! 	bytes[1] = KS_EXTRA;
99b86a7
! 	bytes[2] = in_focus ? (int)KE_FOCUSGAINED : (int)KE_FOCUSLOST;
99b86a7
! 	add_to_input_buf(bytes, 3);
99b86a7
!     }
99b86a7
  #endif
99b86a7
  }
99b86a7
  
99b86a7
*** ../vim-7.1.094/src/gui_gtk_x11.c	Tue Jun 19 18:07:52 2007
99b86a7
--- src/gui_gtk_x11.c	Wed Aug 29 22:43:34 2007
99b86a7
***************
99b86a7
*** 813,822 ****
99b86a7
      if (blink_state == BLINK_NONE)
99b86a7
  	gui_mch_start_blink();
99b86a7
  
99b86a7
!     /* make sure keyboard input goes to the draw area (if this is focus for a window) */
99b86a7
      if (widget != gui.drawarea)
99b86a7
  	gtk_widget_grab_focus(gui.drawarea);
99b86a7
  
99b86a7
      return TRUE;
99b86a7
  }
99b86a7
  
99b86a7
--- 813,827 ----
99b86a7
      if (blink_state == BLINK_NONE)
99b86a7
  	gui_mch_start_blink();
99b86a7
  
99b86a7
!     /* make sure keyboard input goes to the draw area (if this is focus for a
99b86a7
!      * window) */
99b86a7
      if (widget != gui.drawarea)
99b86a7
  	gtk_widget_grab_focus(gui.drawarea);
99b86a7
  
99b86a7
+     /* make sure the input buffer is read */
99b86a7
+     if (gtk_main_level() > 0)
99b86a7
+ 	gtk_main_quit();
99b86a7
+ 
99b86a7
      return TRUE;
99b86a7
  }
99b86a7
  
99b86a7
***************
99b86a7
*** 828,833 ****
99b86a7
--- 833,842 ----
99b86a7
  
99b86a7
      if (blink_state != BLINK_NONE)
99b86a7
  	gui_mch_stop_blink();
99b86a7
+ 
99b86a7
+     /* make sure the input buffer is read */
99b86a7
+     if (gtk_main_level() > 0)
99b86a7
+ 	gtk_main_quit();
99b86a7
  
99b86a7
      return TRUE;
99b86a7
  }
99b86a7
*** ../vim-7.1.094/src/keymap.h	Sat May  5 19:34:22 2007
99b86a7
--- src/keymap.h	Wed Aug 29 22:17:51 2007
99b86a7
***************
99b86a7
*** 254,259 ****
99b86a7
--- 254,261 ----
99b86a7
      , KE_DROP		/* DnD data is available */
99b86a7
      , KE_CURSORHOLD	/* CursorHold event */
99b86a7
      , KE_NOP		/* doesn't do something */
99b86a7
+     , KE_FOCUSGAINED	/* focus gained */
99b86a7
+     , KE_FOCUSLOST	/* focus lost */
99b86a7
  };
99b86a7
  
99b86a7
  /*
99b86a7
***************
99b86a7
*** 445,450 ****
99b86a7
--- 447,454 ----
99b86a7
  #define K_CMDWIN	TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)
99b86a7
  
99b86a7
  #define K_DROP		TERMCAP2KEY(KS_EXTRA, KE_DROP)
99b86a7
+ #define K_FOCUSGAINED	TERMCAP2KEY(KS_EXTRA, KE_FOCUSGAINED)
99b86a7
+ #define K_FOCUSLOST	TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST)
99b86a7
  
99b86a7
  #define K_CURSORHOLD	TERMCAP2KEY(KS_EXTRA, KE_CURSORHOLD)
99b86a7
  
99b86a7
*** ../vim-7.1.094/src/version.c	Thu Aug 30 19:36:52 2007
99b86a7
--- src/version.c	Wed Sep  5 21:42:41 2007
99b86a7
***************
99b86a7
*** 668,669 ****
99b86a7
--- 668,671 ----
99b86a7
  {   /* Add new patch number below this line */
99b86a7
+ /**/
99b86a7
+     95,
99b86a7
  /**/
99b86a7
99b86a7
-- 
99b86a7
ARTHUR:      Who are you?
99b86a7
TALL KNIGHT: We are the Knights Who Say "Ni"!
99b86a7
BEDEVERE:    No!  Not the Knights Who Say "Ni"!
99b86a7
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
99b86a7
99b86a7
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
99b86a7
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
99b86a7
\\\        download, build and distribute -- http://www.A-A-P.org        ///
99b86a7
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///