Re: accel activation on invisible pages



On Sat, 2003-11-15 at 03:19, Tim Janik wrote:
> hey owen, james.
> 
> afaik, we still have the problem of activating accelerators
> on invisible notebook pages (and maybe even hidden widgets, iirc).
> while the accel mechanism generally allows for selective activation,
> the current implementation in gtkwidget.c doesn't make use of
> that yet:

[...]

> i'd like to [..fix this..] by introducing a new signal on GtkWidget:
> 
> 	gboolean (*can_activate_accel) (GtkWidget *widget, guint signal_id);
> 
> with a GtkWidget class handler of:
> 
> static gboolean
> widget_can_activate_accel (GtkWidget *widget, guint signal_id)
> {
>   return GTK_WIDGET_IS_SENSITIVE (widget) && gdk_window_is_viewable (widget->window);
> }
> 
> and a GtkMenuItem class handler of:
> 
> static gboolean
> menu_item_can_activate_accel (GtkWidget *widget, guint signal_id)
> {
>   return GTK_WIDGET_IS_SENSITIVE (widget);
> }
> 
> 
> the later is neccessary because ordinary widgets now need to
> be viewable (have all their parent windows mapped => be on a visible
> notebook page) to have their accelerators activated. however for
> menu items, we actually want activation while their menus are hidden.

For reference, what Tim actually committed has something along the lines
of:

 gtk_menu_item_can_activate_accel:
  GTK_WIDGET_IS_SENSITIVE (widget) && GTK_WIDGET_VISIBLE (widget) &&
   gtk_widget_can_activate (widget->parent, signal_id);

 gtk_menu_can_activate_accel:
  gtk_widget_can_activate (menu->attach_widget, signal_id);

I'm not entirely happy with the details of this solution:

 * The appearance of 'signal_id' strikes me as an unnecessary
   complexity; a single object with multiple accelerators on
   different signals is not something I've ever seen used. Having
   those different accelerators act differently for activatation
   should be even rarer.

 * We don't solve the problem of mnemonics at the same time -
   activation of mnemonics on hidden notebook pages is a more 
   commonly reported problem then similar problems
   with accelerators. (I don't think too many people use accel
   groups for popup menus and then attach those accel groups
   to the main window.) 

 * At least the mnemonic issue is also related to the question
   of focus/default on unmapped or insensitive widgets; see e.g:

   69483 (gtk_widget_set_sensitive() do not remove the widget's focus)
   114635 (Don't focus unmapped widgets)

   Currently, nothing prevents the focus or default being put on
   a unmapped page of a notebook; in itself that could be handled
   by a 'can_activate()' approach, but that doesn't handle dynamic
   changes.

 * The use of the 'g_signal_accumulator_true_handled()' accumulator
   doesn't seem right to me. This means that you can never reduce
   the activatibility with a signal handler. The right accumulator
   would be some sort of 'always_stop' accumulator which always
   returned FALSE.

 * It's not completely clear to me why this is a signal; in the
   first versions of GTK+, there was a general idea that all
   virtual functions had an associated signal, but we've moved
   away from that recently (especially with interfaces).

   Clearly, making it a signal makes it easier on language bindings
   to override; but doing that for a "random" subset of virtual
   functions doesn't seem like a good policy to me.

Leaving aside the question of focus and default, the minor 
modification to your scheme that would make sense to me is
to have a 'can_activate()' vfunc (and signal?) that did:

 gtk_widget_real_can_activate()
  GTK_WIDGET_IS_SENSITIVE (widget) && GTK_WIDGET_MAPPED (widget) &&
   (!widget->parent || gtk_widget_can_activate (widget->parent))

 gtk_menu_can_activate()
  GTK_WIDGET_IS_SENSITIVE (widget) &&
   (!menu->attach_widget || gtk_widget_can_activate
(menu->attach_widget))
 
But how do we bring the focus and default into this picture? 
(Note that we want for it to be possible to set the focus and 
default on a unmapped toplevel, so it's not exactly the same
as the notion you've implemented for accelerators)

 A widget is activatible if 
  - the widget is sensitive
  - the widget and all of its ancestors up to but not including
    the toplevel are mapped

 An accelerator is activatible if
  - the widget is activatible
  - gtk_window_accelerators_active (toplevel) is TRUE, where
    gtk_window_accelerators_active() is implemented in some way
    that GtkMenu can chain the activatibility of its toplevel
    to the activatibility of the attach widget.

This is certainly sounding overcomplicated, but what I'm worried 
about is having different concepts introduced for:

 accelerators
 mnemonics
 focus/default widget and gtk_widget_activate()

> i'd apprechiate comments, especially if you can think of any
> problems with this approach.
> also, i'm pondering whether this change would be suitable for 2.2.
> though an extra signal is an API addition, it does fix the
> accel-activation-on-invisible-pages bug.

No, I really don't think it's at all suitable for 2.2. (I'm not sure
we are even going to make another 2.2.x release.)

Have I confused the issue enough?
							Owen





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