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 731477 - appDisplay: Move focus to popup only if necessary
appDisplay: Move focus to popup only if necessary
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
Depends on:
Blocks:
 
 
Reported: 2014-06-10 18:56 UTC by Carlos Soriano
Modified: 2014-07-17 18:43 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
appDisplay: Move focus to popup only if necessary (1.92 KB, patch)
2014-06-10 18:56 UTC, Carlos Soriano
needs-work Details | Review
appDisplay: Move focus to popup only when necessary (4.67 KB, patch)
2014-06-11 13:30 UTC, Carlos Soriano
needs-work Details | Review
appDisplay: Move focus to popup only when necessary (4.21 KB, patch)
2014-06-11 14:34 UTC, Carlos Soriano
none Details | Review
appDisplay: Move focus to popup only when necessary (4.21 KB, patch)
2014-06-16 08:48 UTC, Carlos Soriano
needs-work Details | Review
appDisplay: Move focus to popup only when necessary (4.06 KB, patch)
2014-07-17 13:14 UTC, Carlos Soriano
reviewed Details | Review
appDisplay: Move focus to popup only when necessary (3.92 KB, patch)
2014-07-17 13:56 UTC, Carlos Soriano
needs-work Details | Review
appDisplay: Move focus to popup only when necessary (3.89 KB, patch)
2014-07-17 16:47 UTC, Carlos Soriano
committed Details | Review

Description Carlos Soriano 2014-06-10 18:56:26 UTC
See patch
Comment 1 Carlos Soriano 2014-06-10 18:56:30 UTC
Created attachment 278220 [details] [review]
appDisplay: Move focus to popup only if necessary

Currently we move the focus to the popup every time we
open a popup.
However, the first item is selected always although the
user didn't press any key.
To avoid that, we move the focus only if we press a key.
To do that we have to steal the focus from the AllView
IconGrid, since the focus is trapped there.
To achieve that add a check on the key event handler in
AllView and move the focus to the current popup if it exists.
Comment 2 Florian Müllner 2014-06-10 20:20:47 UTC
Review of attachment 278220 [details] [review]:

No. For a start, I think that the current behavior is correct when opening the popup via keynav, so we only want to change it otherwise (e.g. when clicking the folder button). But more importantly, this breaks stuff left and right when the focus is *not* on the popup:
 - hitting escape closes the app picker instead of the popup
 - hitting space/return triggers the make-space-for-popup animation again
 - hitting tab/arrows will move focus *both* inside the parent and
   into the popup
Comment 3 Carlos Soriano 2014-06-11 13:30:23 UTC
Created attachment 278270 [details] [review]
appDisplay: Move focus to popup only when necessary

Since we need to only grab focus on one item child when the user
actually press a key we don't use navigate_focus when opening
the popup.
Instead of that, grab the focus on the AppFolderPopup actor
and actually moves the focus to a child only when the user
actually press a key.
It should work with just grab_key_focus on the AppFolderPopup
actor, but since the arrow keys are not wrapping_around the focus
is not grabbed by a child when the widget that has the current focus
is the same that is requesting focus, so to make it works with arrow
keys we need to connect to the key-press-event and navigate_focus
when that happens using TAB_FORWARD or TAB_BACKWARD instead of arrow
keys
Comment 4 Carlos Soriano 2014-06-11 13:32:13 UTC
Not sure how much necessary is the long comment inside the code, but it's kinda difficult to understand why we are doing that without and explanation while reading the code.
Comment 5 Florian Müllner 2014-06-11 13:47:46 UTC
Review of attachment 278270 [details] [review]:

Mostly nits, but the handling of up/down is wrong and needs fixing.

::: js/ui/appDisplay.js
@@ +1239,3 @@
+        // when that happens using TAB_FORWARD or TAB_BACKWARD instead of arrow
+        // keys
+        this.actor.connect('key-press-event', Lang.bind(this,

The method is a bit long for an anonymous function imho (not to mention that it is accompanied by a comment of almost the same length) ...

@@ +1241,3 @@
+        this.actor.connect('key-press-event', Lang.bind(this,
+            function(actor, event) {
+                if (global.stage.get_key_focus() == actor) {

I'd prefer an early return here:

if (global.stage.get_key_focus() != actor)
    return Clutter.EVENT_PROPAGATE;

@@ +1250,3 @@
+                        case Clutter.Down:
+                        case Clutter.Right:
+                            direction = isLtr ? Gtk.DirectionType.TAB_FORWARD :

No, the handling of Down (and Up below) is wrong - mirroring only makes sense for horizontal directions. If you want to avoid code duplication, you could do something like:

  let needsMirroring = false;
  switch(...) {
    case Clutter.Right:
        needsMirroring = isRtl;
    case Clutter.Down:
    case Clutter.Tab:
        direction = Gtk.DirectionType.TAB_FORWARD;
        break;

    case Clutter.LEFT:
        ....
    }

    if (needsMirroring)
        direction = (direction == Gtk.DirectionType.TAB_FORWARD) ? Gtk.DirectionType.TAB_BACKWARD
                                                                 : Gtk.DirectionType.TAB_FORWARD;

But then case statements without break are not that great for readability ...

@@ +1325,3 @@
+        
+        // Grab focus on the AppFolderPopup actor withouth focusing
+        // a child until a key press is actually pressed by the user

Not sure the comment adds much value tbh
Comment 6 Carlos Soriano 2014-06-11 14:02:59 UTC
(In reply to comment #5)
> Review of attachment 278270 [details] [review]:
> 
> Mostly nits, but the handling of up/down is wrong and needs fixing.
> 
> ::: js/ui/appDisplay.js
> @@ +1239,3 @@
> +        // when that happens using TAB_FORWARD or TAB_BACKWARD instead of
> arrow
> +        // keys
> +        this.actor.connect('key-press-event', Lang.bind(this,
> 
> The method is a bit long for an anonymous function imho (not to mention that it
> is accompanied by a comment of almost the same length) ...
right
> 
> @@ +1241,3 @@
> +        this.actor.connect('key-press-event', Lang.bind(this,
> +            function(actor, event) {
> +                if (global.stage.get_key_focus() == actor) {
> 
> I'd prefer an early return here:
> 
> if (global.stage.get_key_focus() != actor)
>     return Clutter.EVENT_PROPAGATE;
> 
> @@ +1250,3 @@
> +                        case Clutter.Down:
> +                        case Clutter.Right:
> +                            direction = isLtr ? Gtk.DirectionType.TAB_FORWARD
> :
> 
> No, the handling of Down (and Up below) is wrong - mirroring only makes sense
> for horizontal directions. If you want to avoid code duplication, you could do
> something like:
> 
>   let needsMirroring = false;
>   switch(...) {
>     case Clutter.Right:
>         needsMirroring = isRtl;
>     case Clutter.Down:
>     case Clutter.Tab:
>         direction = Gtk.DirectionType.TAB_FORWARD;
>         break;
> 
>     case Clutter.LEFT:
>         ....
>     }
> 
>     if (needsMirroring)
>         direction = (direction == Gtk.DirectionType.TAB_FORWARD) ?
> Gtk.DirectionType.TAB_BACKWARD
>                                                                  :
> Gtk.DirectionType.TAB_FORWARD;
> 
> But then case statements without break are not that great for readability ...
> 
sigh right.
Yeah, that case statement confused me tbh. I would see what can I do.
> @@ +1325,3 @@
> +        
> +        // Grab focus on the AppFolderPopup actor withouth focusing
> +        // a child until a key press is actually pressed by the user
> 
> Not sure the comment adds much value tbh
Right
Comment 7 Carlos Soriano 2014-06-11 14:34:27 UTC
Created attachment 278275 [details] [review]
appDisplay: Move focus to popup only when necessary

Since we need to only grab focus on one item child when the user
actually press a key we don't use navigate_focus when opening
the popup.
Instead of that, grab the focus on the AppFolderPopup actor
and actually moves the focus to a child only when the user
actually press a key.
It should work with just grab_key_focus on the AppFolderPopup
actor, but since the arrow keys are not wrapping_around the focus
is not grabbed by a child when the widget that has the current focus
is the same that is requesting focus, so to make it works with arrow
keys we need to connect to the key-press-event and navigate_focus
when that happens using TAB_FORWARD or TAB_BACKWARD instead of arrow
keys
Comment 8 Carlos Soriano 2014-06-16 08:48:06 UTC
Created attachment 278518 [details] [review]
appDisplay: Move focus to popup only when necessary

Since we need to only grab focus on one item child when the user
actually press a key we don't use navigate_focus when opening
the popup.
Instead of that, grab the focus on the AppFolderPopup actor
and actually moves the focus to a child only when the user
actually press a key.
It should work with just grab_key_focus on the AppFolderPopup
actor, but since the arrow keys are not wrapping_around the focus
is not grabbed by a child when the widget that has the current focus
is the same that is requesting focus, so to make it works with arrow
keys we need to connect to the key-press-event and navigate_focus
when that happens using TAB_FORWARD or TAB_BACKWARD instead of arrow
keys
Comment 9 Florian Müllner 2014-07-17 12:48:15 UTC
Review of attachment 278518 [details] [review]:

My keyboard has a couple more keys than left, right, up, down, tab and escape (try something like ctrl-alt-tab or alt-f2 after opening the popup and see it break) ...

Can't you just override the handling of the arrow keys and not interfere with the already correct behavior otherwise?
Comment 10 Carlos Soriano 2014-07-17 13:14:33 UTC
Created attachment 280975 [details] [review]
appDisplay: Move focus to popup only when necessary

Since we need to only grab focus on one item child when the user
actually press a key we don't use navigate_focus when opening
the popup.
Instead of that, grab the focus on the AppFolderPopup actor
and actually moves the focus to a child only when the user
actually press a key.
It should work with just grab_key_focus on the AppFolderPopup
actor, but since the arrow keys are not wrapping_around the focus
is not grabbed by a child when the widget that has the current focus
is the same that is requesting focus, so to make it works with arrow
keys we need to connect to the key-press-event and navigate_focus
when that happens using TAB_FORWARD or TAB_BACKWARD instead of arrow
keys
Comment 11 Florian Müllner 2014-07-17 13:49:34 UTC
Review of attachment 280975 [details] [review]:

::: js/ui/appDisplay.js
@@ +1263,3 @@
+        if (event.get_key_symbol() == Clutter.KEY_Escape) {
+            this.popdown();
+            return Clutter.EVENT_STOP;

Why do you need this?
Comment 12 Carlos Soriano 2014-07-17 13:53:55 UTC
(In reply to comment #11)
> Review of attachment 280975 [details] [review]:
> 
> ::: js/ui/appDisplay.js
> @@ +1263,3 @@
> +        if (event.get_key_symbol() == Clutter.KEY_Escape) {
> +            this.popdown();
> +            return Clutter.EVENT_STOP;
> 
> Why do you need this?

Oh sorry, your grabHelper change was after this patch, so rebasing was not "enough" and I didn't notice that change, so no longer needed.
Comment 13 Carlos Soriano 2014-07-17 13:56:40 UTC
Created attachment 281000 [details] [review]
appDisplay: Move focus to popup only when necessary

Since we need to only grab focus on one item child when the user
actually press a key we don't use navigate_focus when opening
the popup.
Instead of that, grab the focus on the AppFolderPopup actor
and actually moves the focus to a child only when the user
actually press a key.
It should work with just grab_key_focus on the AppFolderPopup
actor, but since the arrow keys are not wrapping_around the focus
is not grabbed by a child when the widget that has the current focus
is the same that is requesting focus, so to make it works with arrow
keys we need to connect to the key-press-event and navigate_focus
when that happens using TAB_FORWARD or TAB_BACKWARD instead of arrow
keys
Comment 14 Florian Müllner 2014-07-17 16:24:22 UTC
Review of attachment 281000 [details] [review]:

::: js/ui/appDisplay.js
@@ +1259,3 @@
+    _onKeyPress: function(actor, event) {
+        if (!this._isOpen)
+            return Clutter.EVENT_PROPAGATE;

Mmmh, is there a case where this._isOpen is false but the popup actor has key focus?

@@ +1288,3 @@
+            case Clutter.Right:
+                direction = isLtr ? Gtk.DirectionType.TAB_FORWARD :
+                                    Gtk.DirectionType.TAB_BACKWARD;

Whoops, wrong direction for up/down under RTL locales ...
Comment 15 Carlos Soriano 2014-07-17 16:47:09 UTC
Created attachment 281021 [details] [review]
appDisplay: Move focus to popup only when necessary

Since we need to only grab focus on one item child when the user
actually press a key we don't use navigate_focus when opening
the popup.
Instead of that, grab the focus on the AppFolderPopup actor
and actually moves the focus to a child only when the user
actually press a key.
It should work with just grab_key_focus on the AppFolderPopup
actor, but since the arrow keys are not wrapping_around the focus
is not grabbed by a child when the widget that has the current focus
is the same that is requesting focus, so to make it works with arrow
keys we need to connect to the key-press-event and navigate_focus
when that happens using TAB_FORWARD or TAB_BACKWARD instead of arrow
keys
Comment 16 Florian Müllner 2014-07-17 18:19:21 UTC
Review of attachment 281021 [details] [review]:

The commit message could use some updates (talking about "grab_key_focus", though that's no longer called directly; also: "the user [...] press" instead of "the user [...] presses" a couple of times). How about:

Unlike for the main app view, where we only move the key focus once the users starts navigating, 
the key focus is moved immediately when opening a folder popup. This is unexpected, so make app 
folders consistent with the main view - as arrow keys will not work while the container itself
has key focus, we handle those explicitly by translating them to TAB_FORWARD and TAB_BACKWARD
respectively.

::: js/ui/appDisplay.js
@@ +1297,3 @@
+            default:
+                return Clutter.EVENT_PROPAGATE;
+                break;

The break is never reached, so you could kill that before pushing
Comment 17 Carlos Soriano 2014-07-17 18:43:30 UTC
Attachment 281021 [details] pushed as 554001c - appDisplay: Move focus to popup only when necessary