patch 8.0.1139: using window toolbar changes state

Problem:    Using window toolbar changes state.
Solution:   Always execute window toolbar actions in Normal mode.
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 29435c2..c740d03 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -10107,19 +10107,61 @@
 }
 
 /*
+ * Save the current State and go to Normal mode.
+ * Return TRUE if the typeahead could be saved.
+ */
+    int
+save_current_state(save_state_T *sst)
+{
+    sst->save_msg_scroll = msg_scroll;
+    sst->save_restart_edit = restart_edit;
+    sst->save_msg_didout = msg_didout;
+    sst->save_State = State;
+    sst->save_insertmode = p_im;
+    sst->save_finish_op = finish_op;
+    sst->save_opcount = opcount;
+
+    msg_scroll = FALSE;	    /* no msg scrolling in Normal mode */
+    restart_edit = 0;	    /* don't go to Insert mode */
+    p_im = FALSE;	    /* don't use 'insertmode' */
+
+    /*
+     * Save the current typeahead.  This is required to allow using ":normal"
+     * from an event handler and makes sure we don't hang when the argument
+     * ends with half a command.
+     */
+    save_typeahead(&sst->tabuf);
+    return sst->tabuf.typebuf_valid;
+}
+
+    void
+restore_current_state(save_state_T *sst)
+{
+    /* Restore the previous typeahead. */
+    restore_typeahead(&sst->tabuf);
+
+    msg_scroll = sst->save_msg_scroll;
+    restart_edit = sst->save_restart_edit;
+    p_im = sst->save_insertmode;
+    finish_op = sst->save_finish_op;
+    opcount = sst->save_opcount;
+    msg_didout |= sst->save_msg_didout;	/* don't reset msg_didout now */
+
+    /* Restore the state (needed when called from a function executed for
+     * 'indentexpr'). Update the mouse and cursor, they may have changed. */
+    State = sst->save_State;
+#ifdef CURSOR_SHAPE
+    ui_cursor_shape();		/* may show different cursor shape */
+#endif
+}
+
+/*
  * ":normal[!] {commands}": Execute normal mode commands.
  */
     void
 ex_normal(exarg_T *eap)
 {
-    int		save_msg_scroll = msg_scroll;
-    int		save_restart_edit = restart_edit;
-    int		save_msg_didout = msg_didout;
-    int		save_State = State;
-    tasave_T	tabuf;
-    int		save_insertmode = p_im;
-    int		save_finish_op = finish_op;
-    int		save_opcount = opcount;
+    save_state_T save_state;
 #ifdef FEAT_MBYTE
     char_u	*arg = NULL;
     int		l;
@@ -10136,11 +10178,6 @@
 	EMSG(_("E192: Recursive use of :normal too deep"));
 	return;
     }
-    ++ex_normal_busy;
-
-    msg_scroll = FALSE;	    /* no msg scrolling in Normal mode */
-    restart_edit = 0;	    /* don't go to Insert mode */
-    p_im = FALSE;	    /* don't use 'insertmode' */
 
 #ifdef FEAT_MBYTE
     /*
@@ -10206,13 +10243,8 @@
     }
 #endif
 
-    /*
-     * Save the current typeahead.  This is required to allow using ":normal"
-     * from an event handler and makes sure we don't hang when the argument
-     * ends with half a command.
-     */
-    save_typeahead(&tabuf);
-    if (tabuf.typebuf_valid)
+    ++ex_normal_busy;
+    if (save_current_state(&save_state))
     {
 	/*
 	 * Repeat the :normal command for each line in the range.  When no
@@ -10240,20 +10272,8 @@
     /* Might not return to the main loop when in an event handler. */
     update_topline_cursor();
 
-    /* Restore the previous typeahead. */
-    restore_typeahead(&tabuf);
-
+    restore_current_state(&save_state);
     --ex_normal_busy;
-    msg_scroll = save_msg_scroll;
-    restart_edit = save_restart_edit;
-    p_im = save_insertmode;
-    finish_op = save_finish_op;
-    opcount = save_opcount;
-    msg_didout |= save_msg_didout;	/* don't reset msg_didout now */
-
-    /* Restore the state (needed when called from a function executed for
-     * 'indentexpr'). Update the mouse and cursor, they may have changed. */
-    State = save_State;
 #ifdef FEAT_MOUSE
     setmouse();
 #endif
diff --git a/src/menu.c b/src/menu.c
index 1ad8a5c..f07be97 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -2242,7 +2242,7 @@
 execute_menu(exarg_T *eap, vimmenu_T *menu)
 {
     char_u	*mode;
-    int		idx;
+    int		idx = -1;
 
     /* Use the Insert mode entry when returning to Insert mode. */
     if (restart_edit
@@ -2306,7 +2306,9 @@
 	if (*p_sel == 'e' && gchar_cursor() != NUL)
 	    ++curwin->w_cursor.col;
     }
-    else
+
+    /* For the WinBar menu always use the Normal mode menu. */
+    if (idx == -1 || eap == NULL)
     {
 	mode = (char_u *)"Normal";
 	idx = MENU_INDEX_NORMAL;
@@ -2322,8 +2324,16 @@
 		|| current_SID != 0
 #endif
 	   )
-	    exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
+	{
+	    save_state_T save_state;
+
+	    ++ex_normal_busy;
+	    if (save_current_state(&save_state))
+		exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
 							   menu->silent[idx]);
+	    restore_current_state(&save_state);
+	    --ex_normal_busy;
+	}
 	else
 	    ins_typebuf(menu->strings[idx], menu->noremap[idx], 0,
 						     TRUE, menu->silent[idx]);
@@ -2406,12 +2416,18 @@
 	if (col >= item->wb_startcol && col <= item->wb_endcol)
 	{
 	    win_T *save_curwin = NULL;
+	    pos_T   save_visual = VIsual;
+	    int	    save_visual_active = VIsual_active;
+	    int	    save_visual_select = VIsual_select;
+	    int	    save_visual_reselect = VIsual_reselect;
+	    int	    save_visual_mode = VIsual_mode;
 
 	    if (wp != curwin)
 	    {
 		/* Clicking in the window toolbar of a not-current window.
-		 * Make that window the current one and go to Normal mode. */
+		 * Make that window the current one and save Visual mode. */
 		save_curwin = curwin;
+		VIsual_active = FALSE;
 		curwin = wp;
 		curbuf = curwin->w_buffer;
 		check_cursor();
@@ -2423,6 +2439,11 @@
 	    {
 		curwin = save_curwin;
 		curbuf = curwin->w_buffer;
+		VIsual = save_visual;
+		VIsual_active = save_visual_active;
+		VIsual_select = save_visual_select;
+		VIsual_reselect = save_visual_reselect;
+		VIsual_mode = save_visual_mode;
 	    }
 	}
     }
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index 116ff4e..3819531 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -51,6 +51,8 @@
 int vim_mkdir_emsg(char_u *name, int prot);
 FILE *open_exfile(char_u *fname, int forceit, char *mode);
 void update_topline_cursor(void);
+int save_current_state(save_state_T *sst);
+void restore_current_state(save_state_T *sst);
 void ex_normal(exarg_T *eap);
 void exec_normal_cmd(char_u *cmd, int remap, int silent);
 void exec_normal(int was_typed);
diff --git a/src/structs.h b/src/structs.h
index 4582dca..946857b 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3405,3 +3405,16 @@
     dictitem_T	*ll_di;		/* The dictitem or NULL */
     char_u	*ll_newkey;	/* New key for Dict in alloc. mem or NULL. */
 } lval_T;
+
+/* Structure used to save the current state.  Used when executing Normal mode
+ * commands while in any other mode. */
+typedef struct {
+    int		save_msg_scroll;
+    int		save_restart_edit;
+    int		save_msg_didout;
+    int		save_State;
+    int		save_insertmode;
+    int		save_finish_op;
+    int		save_opcount;
+    tasave_T	tabuf;
+} save_state_T;
diff --git a/src/version.c b/src/version.c
index a2f71a3..3d5716e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -762,6 +762,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1139,
+/**/
     1138,
 /**/
     1137,