| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.856 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.3.856 |
| Problem: When calling system() multi-byte clipboard contents is garbled. |
| Solution: Save and restore the clipboard contents. (Yukihiro Nakadaira) |
| Files: src/gui_gtk_x11.c, src/proto/gui_gtk_x11.pro, src/ops.c, |
| src/proto/ops.pro, src/os_unix.c, src/proto/ui.pro, src/ui.c |
| |
| |
| |
| |
| |
| *** 5674,5685 **** |
| 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); |
| gui_mch_update(); |
| - */ |
| } |
| |
| /* |
| --- 5674,5681 ---- |
| void |
| clip_mch_lose_selection(VimClipboard *cbd UNUSED) |
| { |
| ! gtk_selection_owner_set(NULL, cbd->gtk_sel_atom, gui.event_time); |
| gui_mch_update(); |
| } |
| |
| /* |
| |
| *** 5705,5710 **** |
| --- 5701,5712 ---- |
| { |
| } |
| |
| + int |
| + clip_gtk_owner_exists(VimClipboard *cbd) |
| + { |
| + return gdk_selection_owner_get(cbd->gtk_sel_atom) != NULL; |
| + } |
| + |
| |
| #if defined(FEAT_MENU) || defined(PROTO) |
| /* |
| |
| |
| |
| *** 59,64 **** |
| --- 59,65 ---- |
| 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)); |
| |
| |
| |
| *** 1017,1022 **** |
| --- 1017,1035 ---- |
| 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) |
| |
| |
| |
| *** 15,20 **** |
| --- 15,21 ---- |
| 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)); |
| |
| |
| |
| *** 1138,1143 **** |
| --- 1138,1148 ---- |
| |
| # 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,1163 **** |
| --- 1163,1204 ---- |
| 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,3849 **** |
| --- 3885,3891 ---- |
| settmode(TMODE_COOK); /* set to normal mode */ |
| |
| # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) |
| + save_clipboard(); |
| loose_clipboard(); |
| # endif |
| |
| |
| *** 3917,3922 **** |
| --- 3959,3967 ---- |
| # 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,3970 **** |
| --- 4010,4018 ---- |
| 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,4841 **** |
| --- 4884,4892 ---- |
| # ifdef FEAT_TITLE |
| resettitle(); |
| # endif |
| + # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) |
| + restore_clipboard(); |
| + # endif |
| vim_free(newcmd); |
| |
| return retval; |
| |
| |
| |
| *** 29,34 **** |
| --- 29,35 ---- |
| 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,57 **** |
| --- 53,59 ---- |
| 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)); |
| |
| |
| |
| *** 1456,1461 **** |
| --- 1456,1476 ---- |
| #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,2404 **** |
| Widget myShell; |
| VimClipboard *cbd; |
| { |
| ! XtDisownSelection(myShell, cbd->sel_atom, CurrentTime); |
| } |
| |
| int |
| --- 2413,2420 ---- |
| Widget myShell; |
| VimClipboard *cbd; |
| { |
| ! XtDisownSelection(myShell, cbd->sel_atom, |
| ! XtLastTimestampProcessed(XtDisplay(myShell))); |
| } |
| |
| int |
| |
| *** 2440,2445 **** |
| --- 2456,2468 ---- |
| 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) \ |
| |
| |
| |
| *** 730,731 **** |
| --- 730,733 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 856, |
| /**/ |
| |
| -- |
| hundred-and-one symptoms of being an internet addict: |
| 39. You move into a new house and decide to Netscape before you landscape. |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ an exciting new programming language -- http://www.Zimbu.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |