[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]

[MD:5455] tooltip が Meadow 以外のウィンドウの上にも表示される



藤井です。

表題のとおり、tooltip が Meadow 以外のウィンドウの上にマウスカーソルが
移動した場合でも表示されることがあります。

# 一旦表示されると消すためには Meadow のウィンドウの上にマウスカーソル
# を戻さないといけないので結構面倒です。

2004/6/9 の修正で殆ど表示されなくなっていたのですが、まだ表示されるこ
とがあるようです。

以下の方法で再現するようです。(Meadow 2.10-dev(Cygwinビルド) で確認)

1. Meadow の tool-bar, tooltip が表示される状態にする。
2. 以下のようにtool-bar の下部分に別アプリケーションのウィンドウを被せる。

 +---------------------------------+
 |Meadow のタイトルバー            |
 +---------------------------------+
 |tool-bar                         |
 +--+------------------------------+----
 |  | 別アプリケーションのウィンドウ
 |  |

3. Meadow のタイトルバーの上にマウスカーソルを移動させる。
4. そのまま素早く別アプリケーションにマウスカーソルを移動させる。
   このとき tool-bar のアイコンの上をマウスカーソルが横切るようにする。

これで、タイミングが良ければマウスカーソルを移動させた先の別アプリケー
ションの上に tooltip が表示されます。

操作としては、上記のとおりですがマシンによっては殆ど発生しないかもしれ
ません。

発生には条件があって、以下の 3 つの条件が必要なようです。

	1. WM_NCMOUSEMOVE イベントと WM_MOUSELEAVE イベントの間に、
	   WM_MOUSEMOVE イベントがただ *一回のみ* 発生すること。
	2. 1. の WM_MOUSEMOVE イベントが発生したときのマウスカーソル
	   の位置が tooltip が表示される位置であること
	3. WM_MOUSEMOVE イベントと WM_MOUSELEAVE イベントの間に
	   note_sync_event() が呼び出されていないこと。

# 私が試した範囲では 1. の条件を満せば確実に 3. の条件が満たされました。

1. については Visual Studio の Spy++ で、3. については printf を上記イ
ベント処理部分と、note_sync_event()の冒頭に追加してそれぞれ確認しまし
た。

現象の原因についてですが、以下のように発生すると考えられます。

	a) WM_NCMOUSEMOVE イベントにより display_info 構造体の 
	   mouse_face_mouse_frame メンバが NULL になる。

	b) WM_MOUSEMOVE イベントにより、last_mouse_motion_frame、
	   last_mouse_motion_message が記憶される。

        ?) ここで note_sync_event が呼び出されていれば、display_info 
	   構造体の mouse_face_mouse_frame メンバに frame が設定される
	   はずなので以下の現象は発生しない。

        c) WM_MOUSELEAVE イベントにより、last_mouse_motion_frame がク
          リアされるはずだが、dpyinfo->mouse_face_mouse_frame が NULL 
          なので、クリアはスキップされる。

	d) note_sync_event() が呼ばれるが、last_mouse_motion_frame が
	   クリアされていないので、Meadow は b) の WM_MOUSEMOVE イベン
	   トが発生ときの座標にマウスカーソルがあるものと誤認する。

	e) しばらくすると、tooltip が表示される。このとき、
	   tooltip の位置がマウスカーソルの位置によって決定されるので、
	   それが別アプリのウィンドウの上であっても表示される。

例えば、以下のように mouse_face_mouse_frame メンバを適当に設定してやれ
ばとりあえず現象は発生しなくなるのですが、根本的な対策ではないと思って
います。

Index: mw32term.c
===================================================================
--- mw32term.c	(revision 3412)
+++ mw32term.c	(working copy)
@@ -8809,7 +8809,10 @@
 
 	  update_mouse_cursor (dpyinfo, msg);
 	  if (f)
-	    XSETFRAME (last_mouse_motion_frame, f);
+	    {
+	      XSETFRAME (last_mouse_motion_frame, f);
+	      dpyinfo->mouse_face_mouse_frame = f;
+	    }
 	  else
 	    clear_mouse_face (dpyinfo);
 

以上、ご報告まで。

--
藤井 正行 / Masayuki FUJII ( boochang@xxxxxxxxxxxx )