Re: Submenu navigation status?



Thus spake Mrcooger:
> On 1 Sep 2000, Owen Taylor wrote:
> 
> >   
> > Well, mostly on the side of code cleanliness, I definitely see
> > a reason - the navigation region is basically state for a
> > particular menu. Motion events in other menus should not
> > be interpreted with respect to the navigation region.
> > 
> > To 'prove' that the current approach leads to problems, I've
> > identified at least 2 bugs prominent with it:
> > 
> >  - If another menu is popped up before the navigation region
> >    is removed in the timeout, then the navigation region
> >    will be leaked. (OK, this has nothing much to do with
> >    the location of the navigatio region...)
> > 
> >  - if the menu that currently has the navigation region is 
> >    destroyed before the navigation region is removed, your
> >    code will segfault. The easiest way to solve this is 
> >    to put the timeout ID in the GtkMenu structure, and once
> >    you do that, you might as well put the reion in there
> >    as well.
> >  
> > Anyways, to save you the task of rewriting it in such a 
> > repugnant way ;-), I've done so myself. My revised version
> > of the patch follows.
> 
> Well, when you state it like that, it does make more sense to make it part
> of the GtkMenu structure. Also, never ran into that segfault problem,
> good thing you found that. :)

Okay, got it: in GTK, things can happen at any time, so you need to
anticipate this? E.g., widgets can be destroyed `unexpectedly' etc.

> > Doing this turned up some oddities in the event handling
> > for menus that made it a little less straightforward than
> > one might expect. But the comments I've added should help
> > people understand what is going on in the future.

Yeah, this was perhaps not the best place for me to learn about GTK
signal handling/propogation.
Your comments make it pretty clear; prolly as clearly as can be hoped.

> > > There was some discussion (between David and Nils Philippsen) about
> > > making the hysteresis timeout be user-definable, which could be
> > > done in an ad-hoc way (patches welcome, I'm sure), but...I agree with
> > > David that it's better to work on a general gtk config system, rather
> > > than causing API bloat with 200 functions of the form:
> > > gtk_..._[get,set]_minor_feature
> > 
> > As you say, this should be done (if at all) as part of a
> > general customization framework.
> > 
> > I'm not completley sure that the current timeout approach
> > is perfect - if I move slowly on the diagonal, sometimes
> > the timeout will trigger when it shouldn't. It might
> > be good to use a slightly shorter timeout and then 
> > reset it on motion events in a way such that it is dependent
> > on the speed of (vertical?) motion.
> 
> I disagree here, though. I played around with that when I was first
> working on it, and I think the current approach is very good. The
> idea is to allow users to be a little sloppy when they head down to a
> submenu, especially when they are going fast. I think when this is working
> right, most users won't even realize that this is happening, in their
> minds the menu item under the mouse is always selected, and they're
> "hotshots" with getting into submenus. It's too easy to get into
> situations where the mouse is subtly moving diagonally, but though the
> user doesn't intend to head into a submenu, the menu items aren't
> switching (Especially with very tall submenus).  

Agreed. Basically, what we have here is (more or less) the way the Mac
does it. When simply using menus on the mac, things seem to `just
work' and you don't think about. Once you know/figure out the
algorithm, it's easy to play with the mouse to make it do unexpected
things (move towards a submenu then stop, and play with the pointer
for a few deciseconds in the navigation_region until the submenu
collapses). However, this doesn't come up in actual use.

Trying to ``read the user's mind'' in a more sophisticated way is
nailing jello to the wall: some user actions -are- ambiguous (e.g.,
the user -very- slowly moves the pointer diagonally down-left: are
they slowly moving to a submenu item, or aimlessly drifting to the
next menu item?).

The best we can hope for in designing tools that work sensibly and
predictably, not ones that anticipate (often incorrectly) what the
user wants/needs. This is one of the main reasons that Microsoft
products are un-userfriendly: instead of providing a tool that behaves
consistently (so the user can construct a mental model of it, say), it
attempts to make quasi-intelligent agents that are more a nuisance
than a tool (e.g., all I want is a f*@%'ing wordprocessor! why did all
the menu items rearrange themselves? ...and of course the paper clip).

That said, maybe the timeout should be a bit longer (say, 500
milliseconds), and ideally later we should have gnome-ui people do
some usability testing to find a good default value, but I think the
current algorithm is, if not perfect, the best we can hope for: the
triangle encapsulates the idea that the user must be moving over a bit
for every unit moved down, and does so in a resource-friendly, clean
way. 

> > ====
> > +  send_event.crossing.window = gdk_window_at_pointer (NULL, NULL);
> > +  send_event.crossing.type = GDK_ENTER_NOTIFY;
> > +  send_event.crossing.time = GDK_CURRENT_TIME;
> > +  send_event.crossing.send_event = TRUE;
> > +
> > +  gtk_widget_event (GTK_WIDGET (user_data), &send_event);
> > ====
> > 
> > I don't think this was working at all - the widget that 
> > needs to receive the enter event is the menu that is the
> > parent of the menu item (user_data), and gtk_widget_event()
> > doesn't do event propagation up the widget heirarchy.
> > 
> > I didn't spend a lot of time tracing this down since I did
> > things a bit differently, but I think that this just appeared
> > to work because gtk_menu_motion_notify() was (because of
> > an old bug) continually sending enter events.

Oh, I noticed this bug when debugging, and was confused but didn't say
anything. Basically every motion event sent another enter event,
right? (I guess I should have asked about this...)

Owen: has this been fixed?

> Hm. Well, I specifically remember the timeout not selecting the menu-item
> under the cursor after the time expired (unless you moved the mouse
> yourself) until I added that code (and it was only that code that I
> added). No matter, your version is better anyhow; I simply copied that
> code more or less from gtk_menu_motion_notify(), and it started working.
> :) 

I think what Owen's saying is that the code works/worked, but not for
the right reason; instead, it worked b/c of bugs/implementation
details in the signal emmision/propogation.
Owen seems to have fixed/hacked up gtk_menu_motion_notify () too so it
now behaves properly (look at the patch, specifically the chunk at
@@ -1125,15 +1178,220 @@)

-- 
  -nils
Public key: http://www.fas.harvard.edu/~nbarth/pub-key.txt

PGP signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]