patch 8.1.1307: cannot reconnect to the X server after it restarted
Problem: Cannot reconnect to the X server after it restarted.
Solution: Add the :xrestore command. (Adrian Kocis, closes #844)
diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt
index 792a715..8437f24 100644
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -1714,6 +1714,7 @@
|:xmapclear| :xmapc[lear] remove all mappings for Visual mode
|:xmap| :xm[ap] like ":map" but for Visual mode
|:xmenu| :xme[nu] add menu for Visual mode
+|:xrestore| :xr[estore] restores the X server connection
|:xnoremap| :xn[oremap] like ":noremap" but for Visual mode
|:xnoremenu| :xnoreme[nu] like ":noremenu" but for Visual mode
|:xunmap| :xu[nmap] like ":unmap" but for Visual mode
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index 7988927..9b61e8b 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -704,6 +704,21 @@
available when compiled with the |+netbeans_intg|
feature}
+ *:xrestore* *:xr*
+:xr[estore] [display] Reinitializes the connection to the X11 server. Useful
+ after the X server restarts, e.g. when running Vim for
+ long time inside screen/tmux and connecting from
+ different machines).
+ [display] should be in the format of the $DISPLAY
+ environment variable (e.g. "localhost:10.0")
+ If [display] is omitted, then it reinitializes the
+ connection to the X11 server using the same value as
+ was used for the previous execution of this command.
+ If the value was never specified, then it uses the
+ value of $DISPLAY environment variable as it was when
+ Vim was started.
+ {only available when compiled with the |+clipboard|
+ feature}
*g_CTRL-A*
g CTRL-A Only when Vim was compiled with MEM_PROFILING defined
diff --git a/src/ex_cmdidxs.h b/src/ex_cmdidxs.h
index 6b96c6c..0103a17 100644
--- a/src/ex_cmdidxs.h
+++ b/src/ex_cmdidxs.h
@@ -29,8 +29,8 @@
/* v */ 503,
/* w */ 521,
/* x */ 535,
- /* y */ 544,
- /* z */ 545
+ /* y */ 545,
+ /* z */ 546
};
/*
@@ -64,9 +64,9 @@
/* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* v */ { 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 12, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0 },
/* w */ { 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 8, 0, 9, 10, 0, 0, 0, 12, 13, 0, 0, 0, 0 },
- /* x */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0 },
+ /* x */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 0, 0, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0 },
/* y */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
-static const int command_count = 558;
+static const int command_count = 559;
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index 37577f7..5ec69be 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -1739,6 +1739,9 @@
EX(CMD_xnoremenu, "xnoremenu", ex_menu,
RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN,
ADDR_OTHER),
+EX(CMD_xrestore, "xrestore", ex_xrestore,
+ EXTRA|TRLBAR|CMDWIN,
+ ADDR_NONE),
EX(CMD_xunmap, "xunmap", ex_unmap,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN,
ADDR_NONE),
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index a2b302d..16f5059 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -394,6 +394,9 @@
#ifndef FEAT_TERMINAL
# define ex_terminal ex_ni
#endif
+#if !defined(FEAT_X11) || !defined(FEAT_XCLIPBOARD)
+# define ex_xrestore ex_ni
+#endif
/*
* Declare cmdnames[].
diff --git a/src/globals.h b/src/globals.h
index 1a055d6..09ac6b5 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1279,9 +1279,14 @@
#endif
#ifdef FEAT_XCLIPBOARD
-EXTERN char *xterm_display INIT(= NULL); /* xterm display name; points
- into argv[] */
-EXTERN Display *xterm_dpy INIT(= NULL); /* xterm display pointer */
+// xterm display name
+EXTERN char *xterm_display INIT(= NULL);
+
+// whether xterm_display was allocated, when FALSE it points into argv[]
+EXTERN int xterm_display_allocated INIT(= FALSE);
+
+// xterm display pointer
+EXTERN Display *xterm_dpy INIT(= NULL);
#endif
#if defined(FEAT_XCLIPBOARD) || defined(FEAT_GUI_X11)
EXTERN XtAppContext app_context INIT(= (XtAppContext)NULL);
diff --git a/src/os_unix.c b/src/os_unix.c
index b5627b1..a6d1a12 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -1659,6 +1659,25 @@
get_x11_title(FALSE);
}
}
+
+ void
+ex_xrestore(exarg_T *eap)
+{
+ if (eap->arg != NULL && STRLEN(eap->arg) > 0)
+ {
+ if (xterm_display_allocated)
+ vim_free(xterm_display);
+ xterm_display = (char *)vim_strsave(eap->arg);
+ xterm_display_allocated = TRUE;
+ }
+ smsg(_("restoring display %s"), xterm_display == NULL
+ ? (char *)mch_getenv("DISPLAY") : xterm_display);
+
+ clear_xterm_clip();
+ x11_window = 0;
+ xterm_dpy_retry_count = 5; // Try reconnecting five times
+ may_restore_clipboard();
+}
#endif
/*
@@ -1761,6 +1780,10 @@
x11_window = (Window)atol(winid);
#ifdef FEAT_XCLIPBOARD
+ if (xterm_dpy == x11_display)
+ // x11_display may have been set to xterm_dpy elsewhere
+ x11_display_from = XD_XTERM;
+
if (xterm_dpy != NULL && x11_window != 0)
{
/* We may have checked it already, but Gnome terminal can move us to
@@ -7661,7 +7684,7 @@
return TRUE;
}
-# if defined(FEAT_GUI) || defined(PROTO)
+# if defined(FEAT_GUI) || defined(FEAT_XCLIPBOARD) || defined(PROTO)
/*
* Destroy the display, window and app_context. Required for GTK.
*/
diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro
index 0117b1e..0e7c609 100644
--- a/src/proto/os_unix.pro
+++ b/src/proto/os_unix.pro
@@ -13,6 +13,7 @@
int vim_handle_signal(int sig);
int mch_check_win(int argc, char **argv);
int mch_input_isatty(void);
+void ex_xrestore(exarg_T *eap);
int mch_can_restore_title(void);
int mch_can_restore_icon(void);
void mch_settitle(char_u *title, char_u *icon);
diff --git a/src/testdir/test_paste.vim b/src/testdir/test_paste.vim
index f3664f6..29206b94 100644
--- a/src/testdir/test_paste.vim
+++ b/src/testdir/test_paste.vim
@@ -110,3 +110,29 @@
bwipe!
endfunc
+
+func CheckCopyPaste()
+ call setline(1, ['copy this', ''])
+ normal 1G0"*y$
+ normal j"*p
+ call assert_equal('copy this', getline(2))
+endfunc
+
+func Test_xrestore()
+ if !has('xterm_clipboard')
+ return
+ endif
+call ch_logfile('logfile', 'w')
+ let display = $DISPLAY
+ new
+ call CheckCopyPaste()
+
+ xrestore
+ call CheckCopyPaste()
+
+ exe "xrestore " .. display
+ call CheckCopyPaste()
+
+call ch_logfile('', '')
+ bwipe!
+endfunc
diff --git a/src/version.c b/src/version.c
index 3b9ef32..ea04ff9 100644
--- a/src/version.c
+++ b/src/version.c
@@ -768,6 +768,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1307,
+/**/
1306,
/**/
1305,