# HG changeset patch # User Bram Moolenaar # Date 1557421208 -7200 # Node ID 0422b14bce58cb2540650a6c07dd9dcffeda89ef # Parent 5c5a7f945ade8212ae02f1e19c452339044348ac patch 8.1.1307: cannot reconnect to the X server after it restarted commit https://github.com/vim/vim/commit/d4aa83af1d691fdabbc8e6aab36db2c96ea4d4b6 Author: Bram Moolenaar Date: Thu May 9 18:59:31 2019 +0200 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 https://github.com/vim/vim/issues/844) diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -1714,6 +1714,7 @@ tag command action ~ |: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 --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -704,6 +704,21 @@ K Run a program to lookup the keyword 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 --- a/src/ex_cmdidxs.h +++ b/src/ex_cmdidxs.h @@ -29,8 +29,8 @@ static const unsigned short cmdidxs1[26] /* v */ 503, /* w */ 521, /* x */ 535, - /* y */ 544, - /* z */ 545 + /* y */ 545, + /* z */ 546 }; /* @@ -64,9 +64,9 @@ static const unsigned char cmdidxs2[26][ /* 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 --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -1739,6 +1739,9 @@ EX(CMD_xnoremap, "xnoremap", ex_map, 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 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -394,6 +394,9 @@ static void ex_folddo(exarg_T *eap); #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 --- a/src/globals.h +++ b/src/globals.h @@ -1279,9 +1279,14 @@ EXTERN linenr_T printer_page_num; #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 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1659,6 +1659,25 @@ may_restore_clipboard(void) 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 @@ get_x11_windis(void) 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 @@ do_xterm_trace(void) 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 --- a/src/proto/os_unix.pro +++ b/src/proto/os_unix.pro @@ -13,6 +13,7 @@ void reset_signals(void); 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 --- a/src/testdir/test_paste.vim +++ b/src/testdir/test_paste.vim @@ -110,3 +110,29 @@ func Test_paste_visual_mode() 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 --- a/src/version.c +++ b/src/version.c @@ -768,6 +768,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1307, +/**/ 1306, /**/ 1305,