To: lablgtk at kaba.or.jp Subject: Re: strange data problems References: <874r3aemtx.fsf at cs.cmu.edu> <16090.34885.62505.554832@karryall.dnsalias.org> <87smqti1l9.fsf@cs.cmu.edu> <16091.1193.119501.516027@karryall.dnsalias.org> From: Michael Welsh Duggan Date: Tue, 03 Jun 2003 00:41:20 -0400 In-Reply-To: <16091.1193.119501.516027 at karryall.dnsalias.org> (Olivier Andrieu's message of "Mon, 2 Jun 2003 10:02:49 +0200") Message-ID: <87u1b7kc27.fsf at cs.cmu.edu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: Michael Welsh Duggan Olivier Andrieu writes: > Michael Welsh Duggan [Sunday 1 June 2003] : > > > > Olivier Andrieu writes: > > [...] > > > OK I think it's a libgnomecanvas problem. > > > > > > It's related to the way events for canvas items are handled. Canvas > > > items are not widgets, so it's the canvas itself (a true GtkWidget) > > > that intercepts events and forwards them to the appropriate items > > > (according to the items hierarchy). On some occasions, the canvas > > > itself synthetises ENTER/LEAVE notify events for canvas items but it > > > does not initializes all the fields in the GdkEventCrossing structure, > > > only the type, detail and subwindow fields (see > > > gnome-canvas.c(pick_current_item) line 2693). > > > > > > That's what happening here. The bottom line is, some canvas item > > > events are "faked" events and some of their fields are uninitialized > > > (maybe because it wouldn't make any sense in the context of a canvas > > > item ?). So access to these fields with lablgtk accessor fonctions is > > > UB, just like in C. > > > > I've considered that, and have poked around the libgnomecanvas code > > myself under the debugger. Unfortunately, I do not think that this > > is what is happening in this circumstance. For one, > > pick_current_item does a very good job of filling the crossing event > > data. > > You're right, I read the code too quickly, the problem isn't exactly > what I was saying. But I still think pick_current_item is to blame for > the corruption. > > ,----[ pick_current_item, line 2697 ] > | GdkEvent new_event; > | GnomeCanvasItem *item; > | > | item = canvas->current_item; > | > | new_event = canvas->pick_event; > | new_event.type = GDK_LEAVE_NOTIFY; > | > | new_event.crossing.detail = GDK_NOTIFY_ANCESTOR; > | new_event.crossing.subwindow = NULL; > | canvas->in_repick = TRUE; > | retval = emit_event (canvas, &new_event); > | canvas->in_repick = FALSE; > `---- > > Here the canvas->pick_event is copied into new_event but they do not > check if they have the same layout (ie if canvas->pick_event is a > GdkEventCrossing). If I add an assert in the code above : > > g_log("libgnomecanvas", G_LOG_LEVEL_DEBUG, > "canvas->pick_event.type = %d", canvas->pick_event.type); > g_assert(canvas->pick_event.type == GDK_LEAVE_NOTIFY || > canvas->pick_event.type == GDK_ENTER_NOTIFY); > > it fails with your program. It seems that canvas->pick_event is of > type GDK_BUTTON_PRESS which has a different layout than a > GdkEventCrossing (hence the corrupted fields). > > (I'll try to have a closer look with a debugger) As far as I can determine from following the logic, this shouldn't happen. Unfortunately, it does. Also unfortunately, it also *doesn't* happen when I set a breakpoint at gnome-canvas.c:2785 (right after case GDK_3BUTTON_PRESS in gnome_canvas_button). It's really quite freaky. -- Michael Welsh Duggan (md5i@cs.cmu.edu)