summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <bram@vim.org>2013-03-13 17:50:25 +0100
committerBram Moolenaar <bram@vim.org>2013-03-13 17:50:25 +0100
commit0c85ab026e32eaaf45c53d07c0995eea13fe0be4 (patch)
tree3801ab5200b4c36c7ec5daafd66f97c37140c314
parent52273fade6694508627dddae0bdbaa897d1e1761 (diff)
downloadvim-0c85ab026e32eaaf45c53d07c0995eea13fe0be4.tar.gz
updated for version 7.3.856v7.3.856v7-3-856
Problem: When calling system() multi-byte clipboard contents is garbled. Solution: Save and restore the clipboard contents. (Yukihiro Nakadaira)
-rw-r--r--src/gui_gtk_x11.c12
-rw-r--r--src/ops.c13
-rw-r--r--src/os_unix.c51
-rw-r--r--src/proto/gui_gtk_x11.pro1
-rw-r--r--src/proto/ops.pro1
-rw-r--r--src/proto/ui.pro2
-rw-r--r--src/ui.c25
-rw-r--r--src/version.c2
8 files changed, 101 insertions, 6 deletions
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index d0eebf37..61432a20 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -5674,12 +5674,8 @@ clip_mch_request_selection(VimClipboard *cbd)
void
clip_mch_lose_selection(VimClipboard *cbd UNUSED)
{
- /* WEIRD: when using NULL to actually disown the selection, we lose the
- * selection the first time we own it. */
- /*
- gtk_selection_owner_set(NULL, cbd->gtk_sel_atom, (guint32)GDK_CURRENT_TIME);
+ gtk_selection_owner_set(NULL, cbd->gtk_sel_atom, gui.event_time);
gui_mch_update();
- */
}
/*
@@ -5705,6 +5701,12 @@ clip_mch_set_selection(VimClipboard *cbd UNUSED)
{
}
+ int
+clip_gtk_owner_exists(VimClipboard *cbd)
+{
+ return gdk_selection_owner_get(cbd->gtk_sel_atom) != NULL;
+}
+
#if defined(FEAT_MENU) || defined(PROTO)
/*
diff --git a/src/ops.c b/src/ops.c
index f3a26da4..2ab90444 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -1017,6 +1017,19 @@ put_register(name, reg)
may_set_selection();
# endif
}
+
+ void
+free_register(reg)
+ void *reg;
+{
+ struct yankreg tmp;
+
+ tmp = *y_current;
+ *y_current = *(struct yankreg *)reg;
+ free_yank_all();
+ vim_free(reg);
+ *y_current = tmp;
+}
#endif
#if defined(FEAT_MOUSE) || defined(PROTO)
diff --git a/src/os_unix.c b/src/os_unix.c
index bb97bbe6..9d948326 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -1138,6 +1138,11 @@ sigcont_handler SIGDEFARG(sigarg)
# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
static void loose_clipboard __ARGS((void));
+static void save_clipboard __ARGS((void));
+static void restore_clipboard __ARGS((void));
+
+static void *clip_star_save = NULL;
+static void *clip_plus_save = NULL;
/*
* Called when Vim is going to sleep or execute a shell command.
@@ -1158,6 +1163,42 @@ loose_clipboard()
XFlush(x11_display);
}
}
+
+/*
+ * Save clipboard text to restore later.
+ */
+ static void
+save_clipboard()
+{
+ if (clip_star.owned)
+ clip_star_save = get_register('*', TRUE);
+ if (clip_plus.owned)
+ clip_plus_save = get_register('+', TRUE);
+}
+
+/*
+ * Restore clipboard text if no one own the X selection.
+ */
+ static void
+restore_clipboard()
+{
+ if (clip_star_save != NULL)
+ {
+ if (!clip_gen_owner_exists(&clip_star))
+ put_register('*', clip_star_save);
+ else
+ free_register(clip_star_save);
+ clip_star_save = NULL;
+ }
+ if (clip_plus_save != NULL)
+ {
+ if (!clip_gen_owner_exists(&clip_plus))
+ put_register('+', clip_plus_save);
+ else
+ free_register(clip_plus_save);
+ clip_plus_save = NULL;
+ }
+}
#endif
/*
@@ -3844,6 +3885,7 @@ mch_call_shell(cmd, options)
settmode(TMODE_COOK); /* set to normal mode */
# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+ save_clipboard();
loose_clipboard();
# endif
@@ -3917,6 +3959,9 @@ mch_call_shell(cmd, options)
# ifdef FEAT_TITLE
resettitle();
# endif
+# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+ restore_clipboard();
+# endif
return x;
#else /* USE_SYSTEM */ /* don't use system(), use fork()/exec() */
@@ -3965,6 +4010,9 @@ mch_call_shell(cmd, options)
settmode(TMODE_COOK); /* set to normal mode */
# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+ /* Disown the clipboard, because is the executed command tries to obtain a
+ * selection and we own it we get a deadlock. */
+ save_clipboard();
loose_clipboard();
# endif
@@ -4836,6 +4884,9 @@ error:
# ifdef FEAT_TITLE
resettitle();
# endif
+# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+ restore_clipboard();
+# endif
vim_free(newcmd);
return retval;
diff --git a/src/proto/gui_gtk_x11.pro b/src/proto/gui_gtk_x11.pro
index 56a779b4..e4b21113 100644
--- a/src/proto/gui_gtk_x11.pro
+++ b/src/proto/gui_gtk_x11.pro
@@ -59,6 +59,7 @@ void clip_mch_request_selection __ARGS((VimClipboard *cbd));
void clip_mch_lose_selection __ARGS((VimClipboard *cbd));
int clip_mch_own_selection __ARGS((VimClipboard *cbd));
void clip_mch_set_selection __ARGS((VimClipboard *cbd));
+int clip_gtk_owner_exists __ARGS((VimClipboard *cbd));
void gui_mch_menu_grey __ARGS((vimmenu_T *menu, int grey));
void gui_mch_menu_hidden __ARGS((vimmenu_T *menu, int hidden));
void gui_mch_draw_menubar __ARGS((void));
diff --git a/src/proto/ops.pro b/src/proto/ops.pro
index 85fb9835..a8c144ea 100644
--- a/src/proto/ops.pro
+++ b/src/proto/ops.pro
@@ -15,6 +15,7 @@ void get_yank_register __ARGS((int regname, int writing));
int may_get_selection __ARGS((int regname));
void *get_register __ARGS((int name, int copy));
void put_register __ARGS((int name, void *reg));
+void free_register __ARGS((void *reg));
int yank_register_mline __ARGS((int regname));
int do_record __ARGS((int c));
int do_execreg __ARGS((int regname, int colon, int addcr, int silent));
diff --git a/src/proto/ui.pro b/src/proto/ui.pro
index 813d496a..234e99fd 100644
--- a/src/proto/ui.pro
+++ b/src/proto/ui.pro
@@ -29,6 +29,7 @@ int clip_gen_own_selection __ARGS((VimClipboard *cbd));
void clip_gen_lose_selection __ARGS((VimClipboard *cbd));
void clip_gen_set_selection __ARGS((VimClipboard *cbd));
void clip_gen_request_selection __ARGS((VimClipboard *cbd));
+int clip_gen_owner_exists __ARGS((VimClipboard *cbd));
int vim_is_input_buf_full __ARGS((void));
int vim_is_input_buf_empty __ARGS((void));
int vim_free_in_input_buf __ARGS((void));
@@ -52,6 +53,7 @@ void clip_x11_request_selection __ARGS((Widget myShell, Display *dpy, VimClipboa
void clip_x11_lose_selection __ARGS((Widget myShell, VimClipboard *cbd));
int clip_x11_own_selection __ARGS((Widget myShell, VimClipboard *cbd));
void clip_x11_set_selection __ARGS((VimClipboard *cbd));
+int clip_x11_owner_exists __ARGS((VimClipboard *cbd));
void yank_cut_buffer0 __ARGS((Display *dpy, VimClipboard *cbd));
int jump_to_mouse __ARGS((int flags, int *inclusive, int which_button));
int mouse_comp_pos __ARGS((win_T *win, int *rowp, int *colp, linenr_T *lnump));
diff --git a/src/ui.c b/src/ui.c
index 4a4506ef..c8353058 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -1456,6 +1456,21 @@ clip_gen_request_selection(cbd)
#endif
}
+ int
+clip_gen_owner_exists(cbd)
+ VimClipboard *cbd;
+{
+#ifdef FEAT_XCLIPBOARD
+# ifdef FEAT_GUI_GTK
+ if (gui.in_use)
+ return clip_gtk_owner_exists(cbd);
+ else
+# endif
+ return clip_x11_owner_exists(cbd);
+#endif
+ return TRUE;
+}
+
#endif /* FEAT_CLIPBOARD */
/*****************************************************************************
@@ -2398,7 +2413,8 @@ clip_x11_lose_selection(myShell, cbd)
Widget myShell;
VimClipboard *cbd;
{
- XtDisownSelection(myShell, cbd->sel_atom, CurrentTime);
+ XtDisownSelection(myShell, cbd->sel_atom,
+ XtLastTimestampProcessed(XtDisplay(myShell)));
}
int
@@ -2440,6 +2456,13 @@ clip_x11_set_selection(cbd)
VimClipboard *cbd UNUSED;
{
}
+
+ int
+clip_x11_owner_exists(cbd)
+ VimClipboard *cbd;
+{
+ return XGetSelectionOwner(X_DISPLAY, cbd->sel_atom) != None;
+}
#endif
#if defined(FEAT_XCLIPBOARD) || defined(FEAT_GUI_X11) \
diff --git a/src/version.c b/src/version.c
index 504ba7f1..90d7a4a2 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 856,
+/**/
855,
/**/
854,