Closed ynkdir closed 11 years ago
7.3.011 X11 clipboard doesn't work in Athena/Motif GUI. First selection after a shell command doesn't work.
問題は2つ。 文字化け。 クリップボードのテキストがなくなる (他のアプリで貼り付けできない。vimの中ではなにか取れる)。
文字化けはこの辺。直し方は分からない。
diff -r ad7bbe9ea65b src/ops.c
--- a/src/ops.c Tue Feb 26 22:54:11 2013 +0100
+++ b/src/ops.c Thu Feb 28 14:38:10 2013 +0900
@@ -5827,7 +5827,7 @@
if (dpy != NULL && str != NULL && motion_type >= 0
&& len < 1024*1024 && len > 0)
{
-#ifdef FEAT_MBYTE
+#if 0
/* The CUT_BUFFER0 is supposed to always contain latin1. Convert from
* 'enc' when it is a multi-byte encoding. When 'enc' is an 8-bit
* encoding conversion usually doesn't work, so keep the text as-is.
diff -r ad7bbe9ea65b src/ui.c
--- a/src/ui.c Tue Feb 26 22:54:11 2013 +0100
+++ b/src/ui.c Thu Feb 28 14:38:10 2013 +0900
@@ -2451,7 +2451,7 @@
if (nbytes > 0)
{
-#ifdef FEAT_MBYTE
+#if 0
int done = FALSE;
/* CUT_BUFFER0 is supposed to be always latin1. Convert to 'enc' when
なんでfromがlatin-1に限定してるんだろ
これですね
Patch 7.2.221 Problem: X cut_buffer0 text is used as-is, it may be in the wrong encoding. Solution: Convert between 'enc' and latin1. (James Vega) Files: src/gui_gtk_x11.c, src/message.c, src/ops.c, src/proto/ui.pro, src/ui.c
XFetchBuffer の from が utf-8 だ、って確証を探してるけど見つからない...
既出でした。
[I seem to meet a clipboard bug related with unicode] https://groups.google.com/d/topic/vim_dev/ulDs5SRTJ7o/discussion
..., but produce mojibake
mojibake
XConvertSelection で XA_UTF8_STRING に変換できるようです。
http://pyglet.googlecode.com/svn/trunk/contrib/wydget/wydget/clipboard/xlib.py
7.3.852 で修正が来ましたが、直ったのでしょうか?(未確認です) https://groups.google.com/d/topic/vim_dev/DlND8RnZk2c/discussion
直ってないです。 いちおうパッチは書いたので投げる予定ではいます。 その前にBramがやるかもしれないので様子見中。 なんかいまいちな感じなんですよねえ。。。
diff -r 22683fa1b4ed src/gui_gtk_x11.c
--- a/src/gui_gtk_x11.c Thu Mar 07 19:38:54 2013 +0100
+++ b/src/gui_gtk_x11.c Mon Mar 11 19:15:28 2013 +0900
@@ -5674,12 +5674,8 @@
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();
- */
}
/*
@@ -5691,7 +5687,7 @@
int success;
success = gtk_selection_owner_set(gui.drawarea, cbd->gtk_sel_atom,
- gui.event_time);
+ (guint32)GDK_CURRENT_TIME);
gui_mch_update();
return (success) ? OK : FAIL;
}
@@ -5705,6 +5701,12 @@
{
}
+ int
+clip_gtk_owner_exists(VimClipboard *cbd)
+{
+ return gdk_selection_owner_get(cbd->gtk_sel_atom) != NULL;
+}
+
#if defined(FEAT_MENU) || defined(PROTO)
/*
diff -r 22683fa1b4ed src/ops.c
--- a/src/ops.c Thu Mar 07 19:38:54 2013 +0100
+++ b/src/ops.c Mon Mar 11 19:15:28 2013 +0900
@@ -1017,6 +1017,19 @@
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 -r 22683fa1b4ed src/os_unix.c
--- a/src/os_unix.c Thu Mar 07 19:38:54 2013 +0100
+++ b/src/os_unix.c Mon Mar 11 19:15:28 2013 +0900
@@ -1138,6 +1138,10 @@
# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
static void loose_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.
@@ -1151,13 +1155,49 @@
{
x11_export_final_selection();
if (clip_star.owned)
+ {
+ clip_star_save = get_register('*', FALSE);
clip_lose_selection(&clip_star);
+ }
if (clip_plus.owned)
+ {
+ clip_plus_save = get_register('+', FALSE);
clip_lose_selection(&clip_plus);
+ }
if (x11_display != NULL)
XFlush(x11_display);
}
}
+
+/*
+ * Restore clipboard text if no one own the X selection.
+ */
+ static void
+restore_clipboard()
+{
+#ifdef FEAT_GUI
+ if (gui.in_use)
+ gui_mch_update();
+#endif
+
+ 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
/*
@@ -3917,6 +3957,9 @@
# 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() */
@@ -4836,6 +4879,9 @@
# ifdef FEAT_TITLE
resettitle();
# endif
+# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+ restore_clipboard();
+# endif
vim_free(newcmd);
return retval;
diff -r 22683fa1b4ed src/proto/gui_gtk_x11.pro
--- a/src/proto/gui_gtk_x11.pro Thu Mar 07 19:38:54 2013 +0100
+++ b/src/proto/gui_gtk_x11.pro Mon Mar 11 19:15:28 2013 +0900
@@ -59,6 +59,7 @@
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 -r 22683fa1b4ed src/proto/ops.pro
--- a/src/proto/ops.pro Thu Mar 07 19:38:54 2013 +0100
+++ b/src/proto/ops.pro Mon Mar 11 19:15:28 2013 +0900
@@ -15,6 +15,7 @@
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 -r 22683fa1b4ed src/proto/ui.pro
--- a/src/proto/ui.pro Thu Mar 07 19:38:54 2013 +0100
+++ b/src/proto/ui.pro Mon Mar 11 19:15:28 2013 +0900
@@ -52,6 +52,7 @@
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 -r 22683fa1b4ed src/ui.c
--- a/src/ui.c Thu Mar 07 19:38:54 2013 +0100
+++ b/src/ui.c Mon Mar 11 19:15:28 2013 +0900
@@ -1456,6 +1456,21 @@
#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 */
/*****************************************************************************
@@ -2440,6 +2455,13 @@
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) \
もやもやが解決したので投げました
Patch 7.3.856 Problem: When calling system() multi-byte clipboard contents is garbled. Solution: Save and restore the clipboard contents. (Yukihiro Nakadaira)
取り込まれたようですが、パッチの内容理解してなかったのですが、restore してるんですね。
fakeclip.vim みたいに system()
経由でクリップボードを更新する場合もあると思うのですが、問題ないのでしょうか。
+clipboard
がない時のためのプラグインなのでダメでも問題ないかもfork版なら子待ち中にイベントループ回す方法もありますけどね。なんか地雷踏みそうですが。んーどうしたもんでしょう。
diff -r 2e5e2e82a737 src/os_unix.c
--- a/src/os_unix.c Wed Mar 13 20:42:32 2013 +0100
+++ b/src/os_unix.c Thu Mar 14 12:47:35 2013 +0900
@@ -4009,13 +4009,6 @@
if (options & SHELL_COOKED)
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
-
/*
* Do this loop twice:
* 1: find number of arguments
@@ -4788,6 +4781,15 @@
}
else
wait_pid = 0;
+
+# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+# ifdef FEAT_GUI
+ if (gui.in_use)
+ gui_mch_update();
+# endif
+ if (xterm_Shell != (Widget)0)
+ xterm_update();
+# endif
}
finished:
p_more = p_more_save;
@@ -4814,6 +4816,43 @@
close(toshell_fd);
close(fromshell_fd);
}
+ else
+ {
+ for (;;)
+ {
+ if (got_int)
+ {
+ /* CTRL-C sends a signal to the child, we ignore it
+ * ourselves */
+# ifdef HAVE_SETSID
+ kill(-pid, SIGINT);
+# else
+ kill(0, SIGINT);
+# endif
+ got_int = FALSE;
+ }
+# ifdef __NeXT__
+ wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0);
+# else
+ wait_pid = waitpid(pid, &status, WNOHANG);
+# endif
+ if ((wait_pid == (pid_t)-1 && errno == ECHILD)
+ || (wait_pid == pid && WIFEXITED(status)))
+ {
+ wait_pid = pid;
+ break;
+ }
+# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+# ifdef FEAT_GUI
+ if (gui.in_use)
+ gui_mch_update();
+# endif
+ if (xterm_Shell != (Widget)0)
+ xterm_update();
+# endif
+ ui_delay(10L, TRUE);
+ }
+ }
/*
* Wait until our child has exited.
@@ -4884,9 +4923,6 @@
# ifdef FEAT_TITLE
resettitle();
# endif
-# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
- restore_clipboard();
-# endif
vim_free(newcmd);
return retval;
gtk_main_iteration_do(TRUE)
を1回回せば行ける気がします。
あと
gtk_clipboard_wait_for_text
ってのもあります。
すみませんどういうことでしょう
あーすんませんすんません。
いちおう出してみました。
CC: vim-dev 付け忘れた。。。
7.3.866 で修正されました。
乙
Ubuntu-12.10 vim-7.3.843
で文字化けします。
3 の後、例えば firefox では右クリックメニューの [貼り付け] は無効になっています。端末でミドルクリックしてもなにもペーストされません。