Windows版GVimでカーソル表示のゴミが表示される #960

Closed
h-east opened this Issue Sep 30, 2016 · 23 comments

Projects

None yet

3 participants

@h-east
Member
h-east commented Sep 30, 2016 edited

再現手順:

  1. Vim 8.0.3 Win 64bit +kaoriyaをここからダウンロードし解凍後、任意のフォルダにリネーム&移動させる。(例: C:\Program Files\vim)
  2. $HOME(C:\Users_ユーザー名_)に空の_vimrc_gvimrcを作成する。
  3. gvim.exeを起動する。
  4. 以下のコマンドをGVim上で実行し、jを16回押す。
:h
gm

実行結果:
カーソル表示?のゴミが表示される。(再現率: 100%)
「を」のカーソル表示が本物でその前のがゴミです。
cursor_garbage

Vimのバージョン

GVim 8.0.3 Win 64bit +kaoriya

OSの種類/ディストリ/バージョン

  • Windows 10 Home 64bit
  • Windows 7 Pro 64bit

その他

  • CUI Vimでは発生していない。(Win & Linux)
  • GVim for Linuxでは試していない。
  • ~本家のGVimでは試していない。~→本家のGVimでも発生した。

おそらくマルチバイト絡み。
上記再現手順だとenccp932fencutf-8だが、どちらもcp932の時でも再現した。

@h-east
Member
h-east commented Sep 30, 2016

encutf-8の場合は発生しない。

@k-takata
Member

自前ビルドでもenc=cp932で発生しました。
:set cole=0 すると起きなくなりますね。concealのせいでカーソル位置がずれているのと、スクロールが同時に発生すると起こる?

@h-east
Member
h-east commented Sep 30, 2016

本家のGVim 8.0.19 Win 64bitでも再現しました。
https://github.com/vim/vim-win32-installer/releases/tag/v8.0.0019
のgvim_8.0.0019_x64.zipを解凍してgvim.exeを実行。

ただし、こちらは上記手順では再現しなかったので、gm後にjkでラフにスクロールさせると再現しました。

:so vimrc_example.vim
:e {上記手順にあるヘルプファイルを直接指定}
:h
gm

@k-takata concealなしでも発生すると思います。私が最初に気付いた時はconceal未設定かつ普通のテキストファイル(hoge.txt)でした。
寝て起きてからconceal未設定版の再現手順を確立させます。

@h-east
Member
h-east commented Oct 1, 2016 edited

本家GVimで日本語(cp932)入りノーマルテキストで再現出来ました。

https://github.com/vim/vim-win32-installer/releases/tag/v8.0.0019
のgvim_8.0.0019_x64.zipを解凍してgvim.exeを実行。
(予め、$HOME(C:\Users_ユーザー名_)に空の_vimrc_gvimrcを作成しておいて下さい。)

Kaoriya版のREADME.txt(cp932)を開く。(パスは各自で読み替えて下さい)

:e \Program\ Files\vim\README.txt

以下のコマンドを入力する。

41G
zb
33|
jjjjjjj

実行結果:
cursor_garbage2

補足:

  • 最後のカーソルが本物です。
  • kaoriya版でも同じ手順で再現します。
  • set enc=utf-8の場合は発生しません。
@h-east
Member
h-east commented Oct 1, 2016

以下のpatchで問題が発生することを突き止めました。
vim/vim@144445d

patch 7.4.2003
Problem: Still cursor flickering when a callback updates the screen. (David
Samvelyan)
Solution: Put the cursor in the right position after updating the screen.

これが元のスレッド
Draw issue in gvim when calling matchadd() from timer callback.
https://groups.google.com/d/msg/vim_dev/9XHUNo0CT6k/npeBB3XSCAAJ

これがpatch releaseスレッド
Patch 7.4.2003
https://groups.google.com/d/msg/vim_dev/VxEGkXtlxhI/xZFV_PohCgAJ
ここにBram氏が鋭いレスしてる。

Looks like this fix triggers another cursor positioning problem.
When doing "rx" it first gets displayed in the right place, then drawn
two characters to the left. Not sure where that comes from yet...

7.4.2003って7月初旬。。
GVimでencがDBCS(cp932等)な環境で使っている人少なくないと思うんだけどなぁ。

@h-east
Member
h-east commented Oct 1, 2016

GVim 7.4.2002で元スレッドに書いてある再現手順で再現しなかったので、_gvimrcにカーソルブリンクをまったりさせる設定を書いたら再現するようになった。

set guicursor+=a:blinkon1700-blinkoff700

で、どう修正しましょうか?

@mattn
Member
mattn commented Oct 1, 2016

んー。kaoriya の README.txt で試してるんですが再現しない。 Windows10

@h-east
Member
h-east commented Oct 1, 2016 edited

@mattn enc=cp932にしていますか?
(デフォルトだとそうなっていますが念のため確認しています)

@mattn
Member
mattn commented Oct 1, 2016

はい。guicursor も試したけど再現せず。

@mattn
Member
mattn commented Oct 1, 2016

ちなみに僕は非 kaoriya 版。kaoriya 版使ってる場合、README.txt は ft=memo なんですが h_east さんは ft は空でしょうか?

@h-east
Member
h-east commented Oct 1, 2016

(kaoriyaの)README.txtのmodelineにft=memoが書かれているのでkaoriya版でも非kaoriya版でもset ft?の結果はmemoです。
当然kaoriya版はhighlightされますが、非kaoriya版はhighlightされません。

@mattn
Member
mattn commented Oct 1, 2016

shoei

んー。なんでしょうな。

@h-east
Member
h-east commented Oct 1, 2016

手順の33|はエルじゃなくてオアです。

@mattn
Member
mattn commented Oct 1, 2016

お。再現ed

@mattn
Member
mattn commented Oct 1, 2016 edited

これはあれだな。 w_curswant が右端超えてる時に描画が右端までしか描画されてないからもう1セル足らない系かな。

@mattn
Member
mattn commented Oct 1, 2016 edited

zb した行がもう半角ずれて(先頭に半角入れる)ると 33| でも 34| でも発生しない。TOMB っぽい。

@h-east
Member
h-east commented Oct 1, 2016

これはあれだな。 cursor_want が右端超えてる時に描画が右端までしか描画されてないからもう1セル足らない系かな。

再現手順通り33|の後にjを7回押すとそうではないことが分かるかと思います。
というか、Patch 7.4.2003を外せば直るんです。あとは元スレッドの現象が起きないようにすることが必要です。

@mattn
Member
mattn commented Oct 1, 2016

スクロール後に w_curswant の位置から mb_adjust_cursor してるはずですが、それが効いてないかその時にカーソルがのこりっぱになってるのかも。

@mattn
Member
mattn commented Oct 1, 2016

んー。やっぱりそれっぽい。強制で書いてる箇所をコメントアウトしたら発生しない。

    if (did_undraw && !gui_mch_is_blink_off())
    {
        /* Put the GUI position where the cursor was, gui_update_cursor()
         * uses that. */
        gui.col = gui_cursor_col;
        gui.row = gui_cursor_row;
        //gui_update_cursor(FALSE, FALSE);
        screen_cur_col = gui.col;
        screen_cur_row = gui.row;
    }
@mattn
Member
mattn commented Oct 1, 2016

これでどうでしょう?

diff --git a/src/screen.c b/src/screen.c
index 4604ec7..ad9a865 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -765,6 +765,9 @@ update_screen(int type)
         * uses that. */
        gui.col = gui_cursor_col;
        gui.row = gui_cursor_row;
+#ifdef FEAT_MBYTE
+       gui.col = mb_fix_col(gui.col, gui.row);
+#endif
        gui_update_cursor(FALSE, FALSE);
        screen_cur_col = gui.col;
        screen_cur_row = gui.row;
@h-east
Member
h-east commented Oct 2, 2016

@mattn 直りました👍
patch 7.4.2003(と7.4.2004と7.4.2199)でfixされた挙動も再発していないので大丈夫だと思います。
patchの#ifdef#endifは1カラムネストした方がいいです。
#ifdef# ifdef#endif# endif

@mattn mattn self-assigned this Oct 2, 2016
@h-east
Member
h-east commented Oct 2, 2016

patch 8.0.0021
vim/vim@84dbd49

@mattn 👍

@h-east h-east closed this Oct 2, 2016
@h-east h-east added the xlose/fixed label Oct 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment