To: vim-dev@vim.org Subject: Patch 7.3.011 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.3.011 Problem: X11 clipboard doesn't work in Athena/Motif GUI. First selection after a shell command doesn't work. Solution: When using the GUI use XtLastTimestampProcessed() instead of changing a property. (partly by Toni Ronkko) When executing a shell command disown the selection. Files: src/ui.c, src/os_unix.c *** ../vim-7.3.010/src/ui.c 2010-08-15 21:57:31.000000000 +0200 --- src/ui.c 2010-09-21 22:08:22.000000000 +0200 *************** *** 469,475 **** */ #ifdef FEAT_X11 /* Always own the selection, we might have lost it without being ! * notified. */ if (cbd->available) { int was_owned = cbd->owned; --- 469,475 ---- */ #ifdef FEAT_X11 /* Always own the selection, we might have lost it without being ! * notified, e.g. during a ":sh" command. */ if (cbd->available) { int was_owned = cbd->owned; *************** *** 1944,1953 **** */ static Boolean clip_x11_convert_selection_cb __ARGS((Widget, Atom *, Atom *, Atom *, XtPointer *, long_u *, int *)); - static void clip_x11_lose_ownership_cb __ARGS((Widget, Atom *)); - static void clip_x11_timestamp_cb __ARGS((Widget w, XtPointer n, XEvent *event, Boolean *cont)); /* * Property callback to get a timestamp for XtOwnSelection. --- 1944,1952 ---- */ static Boolean clip_x11_convert_selection_cb __ARGS((Widget, Atom *, Atom *, Atom *, XtPointer *, long_u *, int *)); static void clip_x11_lose_ownership_cb __ARGS((Widget, Atom *)); static void clip_x11_timestamp_cb __ARGS((Widget w, XtPointer n, XEvent *event, Boolean *cont)); + static void clip_x11_request_selection_cb __ARGS((Widget, XtPointer, Atom *, Atom *, XtPointer, long_u *, int *)); /* * Property callback to get a timestamp for XtOwnSelection. *************** *** 1985,1992 **** return; /* Get the selection, using the event timestamp. */ ! XtOwnSelection(w, xproperty->atom, xproperty->time, ! clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb, NULL); } void --- 1984,2000 ---- return; /* Get the selection, using the event timestamp. */ ! if (XtOwnSelection(w, xproperty->atom, xproperty->time, ! clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb, ! NULL) == OK) ! { ! /* Set the "owned" flag now, there may have been a call to ! * lose_ownership_cb in between. */ ! if (xproperty->atom == clip_plus.sel_atom) ! clip_plus.owned = TRUE; ! else ! clip_star.owned = TRUE; ! } } void *************** *** 1997,2004 **** /*(XtEventHandler)*/clip_x11_timestamp_cb, (XtPointer)NULL); } - static void clip_x11_request_selection_cb __ARGS((Widget, XtPointer, Atom *, Atom *, XtPointer, long_u *, int *)); - static void clip_x11_request_selection_cb(w, success, sel_atom, type, value, length, format) --- 2005,2010 ---- *************** *** 2336,2342 **** void clip_x11_lose_selection(myShell, cbd) ! Widget myShell; VimClipboard *cbd; { XtDisownSelection(myShell, cbd->sel_atom, CurrentTime); --- 2342,2348 ---- void clip_x11_lose_selection(myShell, cbd) ! Widget myShell; VimClipboard *cbd; { XtDisownSelection(myShell, cbd->sel_atom, CurrentTime); *************** *** 2344,2357 **** int clip_x11_own_selection(myShell, cbd) ! Widget myShell; VimClipboard *cbd; { ! /* Get the time by a zero-length append, clip_x11_timestamp_cb will be ! * called with the current timestamp. */ ! if (!XChangeProperty(XtDisplay(myShell), XtWindow(myShell), cbd->sel_atom, ! timestamp_atom, 32, PropModeAppend, NULL, 0)) return FAIL; /* Flush is required in a terminal as nothing else is doing it. */ XFlush(XtDisplay(myShell)); return OK; --- 2350,2378 ---- int clip_x11_own_selection(myShell, cbd) ! Widget myShell; VimClipboard *cbd; { ! /* When using the GUI we have proper timestamps, use the one of the last ! * event. When in the console we don't get events (the terminal gets ! * them), Get the time by a zero-length append, clip_x11_timestamp_cb will ! * be called with the current timestamp. */ ! #ifdef FEAT_GUI ! if (gui.in_use) ! { ! if (XtOwnSelection(myShell, cbd->sel_atom, ! XtLastTimestampProcessed(XtDisplay(myShell)), ! clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb, ! NULL) == False) return FAIL; + } + else + #endif + { + if (!XChangeProperty(XtDisplay(myShell), XtWindow(myShell), + cbd->sel_atom, timestamp_atom, 32, PropModeAppend, NULL, 0)) + return FAIL; + } /* Flush is required in a terminal as nothing else is doing it. */ XFlush(XtDisplay(myShell)); return OK; *** ../vim-7.3.010/src/os_unix.c 2010-08-15 21:57:30.000000000 +0200 --- src/os_unix.c 2010-09-21 21:59:25.000000000 +0200 *************** *** 1123,1128 **** --- 1123,1152 ---- } #endif + # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) + static void loose_clipboard __ARGS((void)); + + /* + * Called when Vim is going to sleep or execute a shell command. + * We can't respond to requests for the X selections. Lose them, otherwise + * other applications will hang. But first copy the text to cut buffer 0. + */ + static void + loose_clipboard() + { + if (clip_star.owned || clip_plus.owned) + { + x11_export_final_selection(); + if (clip_star.owned) + clip_lose_selection(&clip_star); + if (clip_plus.owned) + clip_lose_selection(&clip_plus); + if (x11_display != NULL) + XFlush(x11_display); + } + } + #endif + /* * If the machine has job control, use it to suspend the program, * otherwise fake it by starting a new shell. *************** *** 1137,1155 **** out_flush(); /* needed to disable mouse on some systems */ # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) ! /* Since we are going to sleep, we can't respond to requests for the X ! * selections. Lose them, otherwise other applications will hang. But ! * first copy the text to cut buffer 0. */ ! if (clip_star.owned || clip_plus.owned) ! { ! x11_export_final_selection(); ! if (clip_star.owned) ! clip_lose_selection(&clip_star); ! if (clip_plus.owned) ! clip_lose_selection(&clip_plus); ! if (x11_display != NULL) ! XFlush(x11_display); ! } # endif # if defined(_REENTRANT) && defined(SIGCONT) --- 1161,1167 ---- out_flush(); /* needed to disable mouse on some systems */ # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) ! loose_clipboard(); # endif # if defined(_REENTRANT) && defined(SIGCONT) *************** *** 3706,3711 **** --- 3718,3727 ---- if (options & SHELL_COOKED) settmode(TMODE_COOK); /* set to normal mode */ + # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) + loose_clipboard(); + # endif + # ifdef __EMX__ if (cmd == NULL) x = system(""); /* this starts an interactive shell in emx */ *************** *** 3814,3826 **** # endif int did_settmode = FALSE; /* settmode(TMODE_RAW) called */ out_flush(); if (options & SHELL_COOKED) settmode(TMODE_COOK); /* set to normal mode */ ! newcmd = vim_strsave(p_sh); ! if (newcmd == NULL) /* out of memory */ ! goto error; /* * Do this loop twice: --- 3830,3846 ---- # endif int did_settmode = FALSE; /* settmode(TMODE_RAW) called */ + newcmd = vim_strsave(p_sh); + if (newcmd == NULL) /* out of memory */ + goto error; + out_flush(); if (options & SHELL_COOKED) settmode(TMODE_COOK); /* set to normal mode */ ! # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) ! loose_clipboard(); ! # endif /* * Do this loop twice: *** ../vim-7.3.010/src/version.c 2010-09-21 17:34:26.000000000 +0200 --- src/version.c 2010-09-21 20:45:02.000000000 +0200 *************** *** 716,717 **** --- 716,719 ---- { /* Add new patch number below this line */ + /**/ + 11, /**/ -- hundred-and-one symptoms of being an internet addict: 184. You no longer ask prospective dates what their sign is, instead your line is "Hi, what's your URL?" /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ download, build and distribute -- http://www.A-A-P.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///