Re: Accelerators and gtk_grab_add



Tim Janik wrote:
> 
> On Wed, 26 Jul 2000, Matt Carlson wrote:
> 
> > Tim Janik wrote:
> > >
> > > On 24 Jul 2000, Havoc Pennington wrote:
> > >
> > > >
> > > > Matt Carlson <mindbender@lokigames.com> writes:
> > > > > Hi folks.  I'm having trouble with menu accelerators whenever I
> > > > > bring up a modal dialog.  I tried to disable them through the use of
> > > > > gtk_grab_add(), but accelerators don't seem to be affected by this
> > > > > function.  Is there a way to do this?  Thanks in advance for your
> > > > > time.
> > > > >
> > > >
> > > > Yikes, that seems like a pretty serious bug. CC'd Tim to see if he has
> > > > comments.
> > >
> > > i'm not able to reproduce this, and i couldn't imagine how
> > > accelerators could get delivered to windows while there's
> > > a modal dialog popped up (dialog modality does involve gtk_grab_add()
> > > btw).
> >
> > Yah, I know.  If fact, I don't even bother with the gtk_window_set_modal()
> > function.
> >
> > > so if you could send me a short test case matt, that'd be aprechiated.
> >
> > I've attached it.  I've programmatically set the menuitem accelerator to the
> > 'N' key...for convenience.  Just run the program, select the "Do Something"
> > menu option, move the window out of the way, move the cursor over the main
> > window, use the 'N' key to bring up another dialog (which shouldn't happen).
> > Thanks for your help. :)
> 
> ok, that's something to work from. the problem is the accelerator
> you setup programmatically:
> 
>         /* Just for kicks let's add an accelerator programmatically */
>         gtk_widget_add_accelerator( menuitem, "activate",
>                                     gtk_accel_group_get_default(),
>                                     GDK_N, 0, GTK_ACCEL_VISIBLE );
> 
> you're using the global default accelerator group that _all_ windows will
> resort to if they can't handle the keypress.
> what you actually want is to create a new accelerator group per menubar,
> install the accelerators on that and add it to the window with
> gtk_window_add_accel_group().
> 
> i can see why you used this though, i'll put the foolowing on my 2.0 todo list:
> 
> 1) provide gtk_menu_bar_get_accel_group() (creates the menubar accel group for you,
>    you just need to add it to the window then)
> 2) gtk_window_get_default_accel_group() (should be provided by havoc's recent patches
>    already), to be used for non-menu, per-window accelerators
> 3) rename gtk_accel_group_get_default() to gtk_accel_group_get_global(), since that's
>    how it's really used.
> 
> [i didn't actually run your programm when i saw your usage of
>  gtk_accel_group_get_default(), so if the above advice doesn't fix
>  things for you, bug me again ;)]

Hmmm...  I may be misunderstanding your proposed solution.  The reason I used
gtk_accel_group_default() is because that is where the user defined
accelerators for the menus wind up.  Here is the substitution if you would like
to see it.

#if 0

   GtkWidget * menuitem = gtk_menu_item_new_with_label( "Do Something" );
   gtk_menu_append( GTK_MENU(submenu), menuitem );
   gtk_signal_connect( GTK_OBJECT(menuitem), "activate",
                       GTK_SIGNAL_FUNC(MenuItemEventHandler), NULL );
   /* Just for kicks let's add an accelerator programmatically */
   gtk_widget_add_accelerator( menuitem, "activate",
                               gtk_accel_group_get_default(),
                               GDK_N, 0, GTK_ACCEL_VISIBLE );
   gtk_widget_show( menuitem );

#else

   GtkWidget * menuitem1 = gtk_menu_item_new_with_label( "Do Something" );
   gtk_menu_append( GTK_MENU(submenu), menuitem1 );
   gtk_signal_connect( GTK_OBJECT(menuitem1), "activate",
                       GTK_SIGNAL_FUNC(MenuItemEventHandler), NULL );

   GtkAccelGroup* accelgroup = gtk_accel_group_new();
   gtk_accel_group_add( accelgroup, GDK_N, (GdkModifierType)0,
                        GTK_ACCEL_VISIBLE, GTK_OBJECT(menuitem), "activate" );
   gtk_accel_group_attach( accelgroup, GTK_OBJECT(menu) );
   gtk_widget_show( menuitem );


   /* Now let's add another menu option to test where the user
    * defined accelerator will be assigned.  Our accelerator or the default?
    */
   GtkWidget * menuitem2 = gtk_menu_item_new_with_label( "Do Something Else" );
   gtk_menu_append( GTK_MENU(submenu), menuitem2 );
   gtk_signal_connect( GTK_OBJECT(menuitem2), "activate",
                       GTK_SIGNAL_FUNC(MenuItemEventHandler), NULL );
   gtk_accel_group_attach( accelgroup, GTK_OBJECT(menuitem2) );
   gtk_widget_show( menuitem2 );

#endif

The user defined assignment happens at runtime, not at creation time.  The
function you identified was only to avoid the hassle of resetting the
accelerator key during test cases, if multiple runs were required to nail
down the problem.  Sorry <:)

I imagine the solution would look something more like :

   1) Create the menubar accelerator at creation time.
   2) Do all of what you proposed.  I'd imagine the
      gtk_menu_bar_get_accel_group() would be reduced to an accessibility
      function.
   3) Change menu bar accelerator assignment so that they get assigned to the
      menubar's accelerator group instead of the default accelerator group.

If this is what you meant, then sorry for wasting the bandwidth.

===============================================================================
Matt Carlson                                      250 El Camino Real, Suite 100
Programmer                                                     Tustin, CA 92780
Loki Entertainment Software                http://www.lokigames.com/~mindbender




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