(resend, CONTRIBUTING.md points to
http://www.vim.org/maillist.php#vim-dev but mail
to vim-...@vim.org apparently does not make it to the list)

Hi,

I'm suffering from an annoying issue with ballooneval as
used by the taglist plugin. When using gvim built with --enable-gui=gtk3
the balloon sometimes does not hide when the gvim window loses
focus, i.e. the ballon shows on top of other windows even
when gvim is completely hidden behind other windows, or even
when the gvim window is on a different virtual desktop.

This is not easy to reproduce at will, the ingredients to
reproduce it are awesome wm (awesomewm.org) and multiple
gvim and xterm windows on multiple virtual desktops (awesome uses
a concept of tags to implement them). Awesome is a tiling wm but
I'm using floating window layout, i.e. like a non-tiling wm,
i.e. with overlapping windows. Then after some desktop and
window switching the issue usually appears. I have not found
any deterministic way to reproduce it, though.

The issue appears with gvim from Debian unstable's vim-gtk3 package
(there is no gtk2 version anymore in Debian unstable). It can be
reproduced with current git built with
"./configure --prefix=/usr --enable-gui=gtk3 --disable-xim".

I debugged it using the attached vim-gdk-event-debug.patch
and got this log:

Good case:

target_event_cb 3 00203f0e
pointer_event 27 0
Gdk-Message: 10:39:58.996: leave notify:        window 71303175
        subwindow:0
        device: 2
        source device: 9
        notify type: 3
        crossing mode: 0
target_event_cb 11 00203f0e
target_event_cb: GDK_LEAVE_NOTIFY 0
mainwin_event_cb 11 00437310
mainwin_event_cb: GDK_LEAVE_NOTIFY 0
Gdk-Message: 10:39:59.026: focus out:           window: 71303175, detail: 
NotifyNonlinear, mode: NotifyNormal
Gdk-Message: 10:39:59.026: focus out:           window: 71303175, detail: 
NotifyNonlinearVirtual, mode: NotifyNormal
mainwin_event_cb 12 00437310
mainwin_event_cb: GDK_FOCUS_CHANGE


Bad case:

target_event_cb 3 00203f0e
pointer_event 15 0
Gdk-Message: 10:41:33.068: leave notify:        window 56623548
        subwindow:0
        device: 2
        source device: 9
        notify type: 3
        crossing mode: 0
Gdk-Message: 10:41:33.068: leave notify:        window 56623108
        subwindow:0
        device: 2
        source device: 9
        notify type: 4
        crossing mode: 0
mainwin_event_cb 11 00437310
mainwin_event_cb: GDK_LEAVE_NOTIFY 0
mainwin_event_cb 11 00437310
mainwin_event_cb: GDK_LEAVE_NOTIFY 0
Gdk-Message: 10:41:33.087: focus out:           window: 56623108, detail: 
NotifyNonlinear, mode: NotifyNormal
Gdk-Message: 10:41:33.087: focus out:           window: 56623108, detail: 
NotifyNonlinearVirtual, mode: NotifyNormal
mainwin_event_cb 12 00437310
mainwin_event_cb: GDK_FOCUS_CHANGE


I have no clue about the root cause, I suppose it could be
an issue in gtk3 but this is out of scope for me to debug.
The attached gvim-beval-fix.patch fixes (or works around)
the issue for me.

FWIW, the relevant X11 spec for the events is:
https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#events:pointer_window


Best Regards,
Johannes

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/YMMyjNdBs5rWy1S/%40sig21.net.
diff --git a/src/gui_beval.c b/src/gui_beval.c
index 57122ffa9ae2..620ee99b4924 100644
--- a/src/gui_beval.c
+++ b/src/gui_beval.c
@@ -209,6 +209,7 @@ gui_mch_currently_showing_beval(void)
     void
 gui_mch_post_balloon(BalloonEval *beval, char_u *mesg)
 {
+    printf("%s: %s\n", __func__, mesg);
     vim_free(beval->msg);
     beval->msg = mesg == NULL ? NULL : vim_strsave(mesg);
     if (beval->msg != NULL)
@@ -227,6 +228,7 @@ gui_mch_post_balloon(BalloonEval *beval, char_u *mesg)
     void
 gui_mch_unpost_balloon(BalloonEval *beval)
 {
+    printf("%s\n", __func__);
     VIM_CLEAR(beval->msg);
     undrawBalloon(beval);
 }
@@ -236,6 +238,8 @@ gui_mch_unpost_balloon(BalloonEval *beval)
     static void
 addEventHandler(GtkWidget *target, BalloonEval *beval)
 {
+    printf("%s %08x\n", __func__, gtk_widget_get_events(target));
+    gdk_set_show_events(TRUE);
     /*
      * Connect to the generic "event" signal instead of the individual
      * signals for each event type, because the former is emitted earlier.
@@ -253,6 +257,10 @@ addEventHandler(GtkWidget *target, BalloonEval *beval)
     if (gtk_socket_id == 0 && gui.mainwin != NULL
 	    && gtk_widget_is_ancestor(target, gui.mainwin))
     {
+	gtk_widget_add_events(gui.mainwin,
+			      GDK_ENTER_NOTIFY_MASK |
+			      GDK_LEAVE_NOTIFY_MASK |
+			      GDK_FOCUS_CHANGE_MASK);
 	g_signal_connect(G_OBJECT(gui.mainwin), "event",
 			 G_CALLBACK(mainwin_event_cb),
 			 beval);
@@ -280,9 +288,11 @@ target_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
 {
     BalloonEval *beval = (BalloonEval *)data;
 
+    printf("%s %d %08x\n", __func__, event->type, gtk_widget_get_events(widget));
     switch (event->type)
     {
 	case GDK_ENTER_NOTIFY:
+	    printf("%s: GDK_ENTER_NOTIFY\n", __func__);
 	    pointer_event(beval, (int)event->crossing.x,
 				 (int)event->crossing.y,
 				 event->crossing.state);
@@ -323,6 +333,7 @@ target_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
 	    }
 	    break;
 	case GDK_LEAVE_NOTIFY:
+	    printf("%s: GDK_LEAVE_NOTIFY %d\n", __func__, event->crossing.mode);
 	    /*
 	     * Ignore LeaveNotify events that are not "normal".
 	     * Apparently we also get it when somebody else grabs focus.
@@ -352,6 +363,7 @@ mainwin_event_cb(GtkWidget *widget UNUSED, GdkEvent *event, gpointer data)
 {
     BalloonEval *beval = (BalloonEval *)data;
 
+    printf("%s %d %08x\n", __func__, event->type, gtk_widget_get_events(widget));
     switch (event->type)
     {
 	case GDK_KEY_PRESS:
@@ -360,6 +372,15 @@ mainwin_event_cb(GtkWidget *widget UNUSED, GdkEvent *event, gpointer data)
 	case GDK_KEY_RELEASE:
 	    key_event(beval, event->key.keyval, FALSE);
 	    break;
+	case GDK_FOCUS_CHANGE:
+	    printf("%s: GDK_FOCUS_CHANGE\n", __func__);
+	    break;
+	case GDK_ENTER_NOTIFY:
+	    printf("%s: GDK_ENTER_NOTIFY\n", __func__);
+	    break;
+	case GDK_LEAVE_NOTIFY:
+	    printf("%s: GDK_LEAVE_NOTIFY %d\n", __func__, event->crossing.mode);
+	    break;
 	default:
 	    break;
     }
@@ -374,6 +395,7 @@ pointer_event(BalloonEval *beval, int x, int y, unsigned state)
 
     distance = ABS(x - beval->x) + ABS(y - beval->y);
 
+    printf("%s %d %u\n", __func__, distance, state);
     if (distance > 4)
     {
 	/*
fix gtk3 GUI balloon failing to hide

In some rare cases the GDK_LEAVE_NOTIFY event does not
propagate to the target window but instead is sent
to the main window twice. This might be a gtk3 issue.

diff --git a/src/gui_beval.c b/src/gui_beval.c
index 57122ffa9ae2..d2bf8089a357 100644
--- a/src/gui_beval.c
+++ b/src/gui_beval.c
@@ -253,6 +253,9 @@ addEventHandler(GtkWidget *target, BalloonEval *beval)
     if (gtk_socket_id == 0 && gui.mainwin != NULL
 	    && gtk_widget_is_ancestor(target, gui.mainwin))
     {
+	gtk_widget_add_events(gui.mainwin,
+			      GDK_LEAVE_NOTIFY_MASK);
+
 	g_signal_connect(G_OBJECT(gui.mainwin), "event",
 			 G_CALLBACK(mainwin_event_cb),
 			 beval);
@@ -360,6 +363,14 @@ mainwin_event_cb(GtkWidget *widget UNUSED, GdkEvent *event, gpointer data)
 	case GDK_KEY_RELEASE:
 	    key_event(beval, event->key.keyval, FALSE);
 	    break;
+	case GDK_LEAVE_NOTIFY:
+	    /*
+	     * Ignore LeaveNotify events that are not "normal".
+	     * Apparently we also get it when somebody else grabs focus.
+	     */
+	    if (event->crossing.mode == GDK_CROSSING_NORMAL)
+		cancelBalloon(beval);
+	    break;
 	default:
 	    break;
     }

Raspunde prin e-mail lui