After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 322640 - Add notification for failed navigation within a single widget
Add notification for failed navigation within a single widget
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: .General
unspecified
Other All
: Normal enhancement
: ---
Assigned To: gtk-bugs
gtk-bugs
AP4
: 99650 (view as bug list)
Depends on:
Blocks: 99650
 
 
Reported: 2005-11-28 11:56 UTC by Markku Vire
Modified: 2011-02-04 16:11 UTC
See Also:
GNOME target: ---
GNOME version: Unversioned Enhancement


Attachments
Patch implementing above infrastructure plus two widgets using it (8.51 KB, patch)
2006-05-11 14:22 UTC, Michael Natterer
none Details | Review
Updated patch (8.17 KB, patch)
2006-09-07 14:45 UTC, Michael Natterer
none Details | Review
New, combined patch (47.26 KB, patch)
2006-09-21 15:35 UTC, Michael Natterer
none Details | Review
Next version (50.78 KB, patch)
2006-09-28 14:14 UTC, Michael Natterer
none Details | Review
Next one (50.83 KB, patch)
2006-10-12 14:50 UTC, Michael Natterer
none Details | Review
Get rid of offsets and fix a conflict (50.91 KB, patch)
2006-11-13 15:11 UTC, Michael Natterer
none Details | Review
Added docs (53.92 KB, patch)
2006-11-14 15:46 UTC, Michael Natterer
none Details | Review
Next version with some fixes (60.35 KB, patch)
2006-11-15 15:15 UTC, Michael Natterer
none Details | Review
Argh, and one more (60.50 KB, patch)
2006-11-15 16:17 UTC, Michael Natterer
committed Details | Review
Add keynav-failed support to treeview (1.55 KB, patch)
2006-11-23 14:01 UTC, Michael Natterer
none Details | Review

Description Markku Vire 2005-11-28 11:56:36 UTC
Some widgets use arrow keys for moving cursor within a widget (like GtkEntry or
GtkTextView). It would be usefull if notification would be sent when user tries
to navigate to a nonexisting line (for example, left from first character of the
entry). I sent a mail to gtk-devel-list about this a couple of weeks ago
(http://mail.gnome.org/archives/gtk-devel-list/2005-November/msg00051.html).

This would be usefull for following cases:
* When there is no tab/shift/ctrl etc keys available one cannot escape 
  these widgets otherwise (bug 318827).
* If needed one can issue some kind of visual feedback about
  nonexisting line/character etc (bug 70986).

I wrote a gtk module that installs a couple of handlers that solve the
bug 318827 if some kind of signal is sent by used widgets when navigation
fails.

Do you find this feature usefull?
Comment 1 Calum Benson 2006-04-26 16:59:37 UTC
Apologies for spam-- marking AP4 to reflect accessibility impact.
Comment 2 Calum Benson 2006-04-26 17:11:52 UTC
Apologies for spam... ensuring Sun a11y folks are cc'ed on all current accessibility bugs.
Comment 3 Michael Natterer 2006-05-10 10:29:22 UTC
Ok, after reading all(?) related mails and bugs, it seems we need
some meduim-complex solution here in order to make everybody
happy:

- bug #70986 asks for a beep when keynav fails.
- bug #318827, bug #334726 and bug #334742 ask for simply
  leaving the widget when keynav fails.

IMHO this bug and the related mail mentioned in the original
report offer the best solution to the problem.

I propose to do the following:

1. add a new signal:

   gboolean GtkWidget::keynav_failed (GtkWidget*,GtkDirectionType)

   where the return value has the same meaning as the return
   value of GtkWidget::focus(), namely:

   TRUE == stay in the widget, the key event is handled
   FALSE == leave the widget

2. add a setting that specifies that we have only cursor keys
   (see bug #334742, e.g. "gtk-cursor-only-focus")

3. add a default handler which looks at the setting and either
   beep()s and returns TRUE, or returns FALSE so the widget
   can return FALSE from GtkWidget::focus() and keynav continues
   in the parent container.

4. in all widgets which currently stop navigating, look at the
   return value of gtk_widget_keynav_failed() instead in order
   to decide what to do.

5. add special code to some widgets like GtkRadioButton which
   must modify their behavior if there are only cursor keys
   (see bug #334742 again).

Would this be an acceptable solution? And would it work for all
keynav problems people have in e.g. phone environments or on
the Nokia 770?
Comment 4 Matthias Clasen 2006-05-11 13:56:23 UTC
It would be good to get a comment on it from some phone people (maemo?), 
and from the a11y guys, but the approach sounds very reasonable to
me. 
Comment 5 Michael Natterer 2006-05-11 14:22:48 UTC
Created attachment 65245 [details] [review]
Patch implementing above infrastructure plus two widgets using it

The patch nicely shows a case where my proposal doesn't really work.
Look at the change in gtkrange.c, intra-widget keynav done by bindings
is somewhat tricky...
Comment 6 gang 2006-05-29 06:57:06 UTC
based on the solution from Michael, I added the following patch to gtkentry.c to enable the same behaviour desired by Markku:

--- gtk/gtkentry.c      2005-08-18 22:10:57.000000000 +0800
+++ gtk/gtkentry.c      2006-05-29 14:42:55.980731414 +0800
@@ -2386,6 +2386,13 @@ gtk_entry_move_cursor (GtkEntry       *e
          break;
        case GTK_MOVEMENT_VISUAL_POSITIONS:
          new_pos = gtk_entry_move_visually (entry, new_pos, count);
+         if (entry->current_pos == new_pos && !extend_selection)
+         {
+           if (!gtk_widget_keynav_failed (GTK_WIDGET(entry), count > 0 ? GTK_DIR_RIGHT : GTK_DIR_LEFT))
+           {
+               gtk_widget_child_focus (gtk_widget_get_toplevel (GTK_WIDGET(entry)), count > 0 ? GTK_DIR_TAB_FORWARD : GTK_DIR_TAB_BACKWARD);
+           }
+         }
          break;
        case GTK_MOVEMENT_WORDS:
          while (count > 0)


Comment 7 Michael Natterer 2006-09-07 14:45:39 UTC
Created attachment 72374 [details] [review]
Updated patch

After some discussion with Tim, we came to the conclusion that the
beeping needs a separate setting. Attached patch factors it out to
a new GtkWidget function so it can be used from places where keynav
fails and which are not affected by the gtk-cursor-only-focus setting
(like when wrap-around in menus is disabled).
Comment 8 Michael Natterer 2006-09-21 15:35:44 UTC
Created attachment 73147 [details] [review]
New, combined patch

This new patch addresses several keynav related issues because they are
all related:

- Keynav with cursor keys only
- wrap-around
- Beeping on keynav failures

It introduces 3 new settings:

- gtk-keynav-cursor-only
- gtk-keynav-wrap-around
- gtk-keynav-failed-beep

Related bugs, additionally to the ones listed in comment #3 are
#309291 and #322640
Comment 9 Matthias Clasen 2006-09-25 14:21:25 UTC
Some initial comments from reading the patch:

- Could the value for GtkSettings:gtk-keynav-cursor-only 
  be found by looking at GdkKeymap ?

- GtkSettings:gtk-keynav-failed-beep - the docs should perhaps
  mention that "beep" may be interpreted by the system, and e.g.
  displayed visually.

- GtkSettings:gtk-keynav-wrap-around - if we had an overview
  section over keynav in the docs, it should probably contain
  a list of widgets affected by this...

- keynav_failed is a slight misnomer, considering you are using
  it for failed mouse actions too.

- I think the names of the new GtkWidget functions are
  somewhat confusing. When am I supposed to use 
  gtk_widget_keynav_failed, and when gtk_widget_notify_keynav_failed ?
  Maybe docs would help...

Other than this, the patch looks like a reasonable approach to me
Comment 10 Michael Natterer 2006-09-28 14:14:03 UTC
Created attachment 73561 [details] [review]
Next version

- GtkSettings: s/gtk-keynav-error-beep/gtk-error-bell/
- GtkWidget:   s/gtk_widget_notify_keynav_failed/gtk_widget_error_bell/
- GtkIconView: added beeping
- GtkComboBox: added beeping and gtk-keynav-cursor-only support
Comment 11 Michael Natterer 2006-10-12 14:50:45 UTC
Created attachment 74569 [details] [review]
Next one

- applies cleanly again after CVS changes
- adapted to the new combo box bindings
- doesn't disable navigation in the combo box any more since
  it can now be configured arbitrarily
Comment 12 Michael Natterer 2006-11-13 15:11:59 UTC
Created attachment 76488 [details] [review]
Get rid of offsets and fix a conflict
Comment 13 Matthias Clasen 2006-11-14 14:21:04 UTC
gtk_widget_keynav_failed 
gtk_widget_error_bell
GtkWidget::keynav-failed

need api docs, and the docs for the new settings could be a little
more detailed:

"When TRUE, some widgets will wrap around when doing keyboard navigation."

I think it would be good to list the known widgets which are affected
by this: ...such as menus, menu bars and radio groups...



"When TRUE, keyboard navigation and other errors will cause a beep."

would it be more precise to say "other input-related errors" here ?
Might be worth mentioning that the system may be configured to e.g.
display the bell visually.


Also, please use %TRUE in docstrings for consistent doc formatting.

Othat than that (and without trying it), the patch looks good and impressive to me.
Comment 14 Michael Natterer 2006-11-14 15:46:20 UTC
Created attachment 76571 [details] [review]
Added docs
Comment 15 Tim Janik 2006-11-15 13:32:36 UTC
(In reply to comment #14)
> Created an attachment (id=76571) [edit]
> Added docs

the patch looks very good to me. other than some IRC comments of mine which already got fixed, i'd just like to suggest getting rid of using up a class method pointer to preserve gtk_reserved_4 (since the need to override this signal in a derived class seems to be pretty seldom).
Comment 16 Kristian Rietveld 2006-11-15 13:37:54 UTC
*** Bug 99650 has been marked as a duplicate of this bug. ***
Comment 17 Michael Natterer 2006-11-15 15:15:17 UTC
Created attachment 76644 [details] [review]
Next version with some fixes

- don't use a reserved vtale entry, use _gtk_binding_signal_new() instead
- beep on failed home/end in treeview
- beep on failed column reordering in treeview
- beep on failed search up/down in treeview
- s/TRUE/%TRUE/ in settings
- add missing break in gtk_widget_real_focus()
Comment 18 Michael Natterer 2006-11-15 16:17:10 UTC
Created attachment 76647 [details] [review]
Argh, and one more

Treeview serach beeped way too often.
Comment 19 Matthias Clasen 2006-11-15 18:50:19 UTC
Spurious whitespace change in gtkwidget.h, and I believe we just say
"setting" in the docs, not "settings property", 
Other than that, it looks good to me. 

When you commit this, it might be a good idea to prompt the reporters
of the various keynav bugs that we hope to close with this, and ask
them for some feedback.
Comment 20 Michael Natterer 2006-11-16 13:03:11 UTC
Fixed in CVS. Bug reporters, please check your use cases and file
new bugs against the new features if anything doesn't work. It doesn't
make sense to keep 6 bugs open.

2006-11-16  Michael Natterer  <mitch@imendio.com>

	Add new infrastructure for notifications of failed keyboard
	navigation and navigation with restricted set of keys.

	The patch handles configurable beeping, navigating the GUI with
	cursor keys only (as in phone environments), and configurable
	wrap-around. Fixes bugs #322640, #70986, #318827, #334726, #334742
	and #309291.

	* gtk/gtksettings.c: added properties gtk-keynav-cursor-only,
	gtk-keynav-wrap-around and gtk-error-bell.

	* gtk/gtkwidget.[ch]: added new signal "keynav-failed" and public
	API to emit it. Added New function gtk_widget_error_bell() which
	looks at the gtk-error-bell setting and calls gdk_window_beep()
	accordingly.

	* gtk/gtk.symbols: add the new widget symbols.

	* gtk/gtkcellrendereraccel.c
	* gtk/gtkimcontextsimple.c
	* gtk/gtkmenu.c
	* gtk/gtknotebook.c: use gtk_widget_error_bell() or look at the
	gtk-error-bell setting instead of calling gdk_display_beep()
	unconditionally.

	* gtk/gtkcombobox.c
	* gtk/gtkentry.c
	* gtk/gtkiconview.c
	* gtk/gtklabel.c
	* gtk/gtkmenushell.c
	* gtk/gtkspinbutton.c
	* gtk/gtktextview.c
	* gtk/gtktreeview.c: call gtk_widget_error_bell() on failed keynav.

	* gtk/gtkentry.c
	* gtk/gtklabel.c
	* gtk/gtkrange.c
	* gtk/gtktextview.c: consult gtk_widget_keynav_failed() on failed
	cursor navigation and leave the widget if it returns FALSE.

	* gtk/gtkmenushell.c
	* gtk/gtknotebook.c: only wrap around if gtk-keynav-wrap-around
	is TRUE.

	* gtk/gtkradiobutton.c: ask gtk_widget_keynav_failed() to decide
	whether to to wrap-around, and don't select active items on cursor
	navigation if gtk-keynav-cursor-only is TRUE. Should look at
	gtk-keynav-wrap-around too, will look into that.
Comment 21 Michael Natterer 2006-11-16 14:33:41 UTC
Made radio buttons honor all relevant settings correctly:

2006-11-16  Michael Natterer  <mitch@imendio.com>

	* gtk/gtkradiobutton.c (gtk_radio_button_focus): don't use
	gtk_widget_keynav_failed(). Instead, look at gtk-keynav-cursor-only
	and gtk-keynav-wrap-around and wrap around, beep or continue outside
	the group manually (bug #322640).
Comment 22 Markku Vire 2006-11-23 11:43:16 UTC
Looks nice, guys :) 

However, did I miss something, or is one still stuck within GtkTreeView when only arrow keys are used? I didn't notice any keynav_failed calls within treeview.
Comment 23 Michael Natterer 2006-11-23 14:01:07 UTC
Created attachment 77060 [details] [review]
Add keynav-failed support to treeview

Attached patch seems to work fine, but I'd like to hear Kris' word
on that, since looking at tree_view->private->shift_pressed looks
like a bad hack to me.
Comment 24 Michael Natterer 2006-11-24 13:19:07 UTC
Fixed the treeview:

2006-11-24  Michael Natterer  <mitch@imendio.com>

	* gtk/gtktreeview.c (gtk_tree_view_move_cursor_up_down): if we
	can't go up/down, consult gtk_widget_keynav_failed() and leave the
	widget if it returns FALSE (bug #322640).