Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None
    • Environment:

      touch

      Description

      I would like to suggest a change to the Display.shouldRenderSelection() behavior. The problem I have is that when a component (Button) is pressed and released in pure touch mode, further presses on non-focusable components will render the selection of the button. In my example a button would grow a container of mine and the following scrolling by the user will most likely 'light up' the previously selected button.
      Here is a change to the Display class that I applied. It does require most users of the previous method to switch to the new method. One example where a change to the new method is not desired is probably the call within Component.getScrollOpacity().

      # This patch file was generated by NetBeans IDE
      # It uses platform neutral UTF-8 encoding and \n newlines.
      --- Base (BASE)
      +++ Locally Modified (Based On LOCAL)
      @@ -305,7 +305,7 @@
           private Vector inputEvents = new Vector();
       
           private boolean longPointerCharged;
      -    private boolean pointerPressedAndNotReleasedOrDragged;
      +    private int[] pointerPressedAndNotReleasedOrDragged;
           private int pointerX, pointerY;
           private boolean keyRepeatCharged;
           private boolean longPressCharged;
      @@ -1377,7 +1377,6 @@
       
               lastInteractionWasKeypad = false;
               longPointerCharged = true;
      -        pointerPressedAndNotReleasedOrDragged = true;
               longKeyPressTime = System.currentTimeMillis();
               pointerX = x[0];
               pointerY = y[0];
      @@ -1392,7 +1391,6 @@
            */
           public void pointerReleased(final int[] x, final int[] y){
               longPointerCharged = false;
      -        pointerPressedAndNotReleasedOrDragged = false;
               if(impl.getCurrentForm() == null){
                   return;
               }
      @@ -1431,7 +1429,6 @@
               keyRepeatCharged = false;
               longPressCharged = false;
               longPointerCharged = false;
      -        pointerPressedAndNotReleasedOrDragged = false;
               addInputEvent(new int[]{HIDE_NOTIFY});
           }
       
      @@ -1492,14 +1489,18 @@
                   break;
               case POINTER_PRESSED:
                   dragPathLength = 0;
      -            f.pointerPressed(pointerEvent(1, ev), pointerEvent(2, ev));
      +            int[] px = pointerEvent(1, ev);
      +            int[] py = pointerEvent(2, ev);
      +            pointerPressedAndNotReleasedOrDragged = new int[]{px[0], py[0]};
      +            f.pointerPressed(px, py);
                   break;
               case POINTER_RELEASED:
      +            pointerPressedAndNotReleasedOrDragged = null;
                   f.pointerReleased(pointerEvent(1, ev), pointerEvent(2, ev));
                   break;
               case POINTER_DRAGGED:
                   updateDragSpeedStatus(ev);
      -            pointerPressedAndNotReleasedOrDragged = false;
      +            pointerPressedAndNotReleasedOrDragged = null;
                   f.pointerDragged(pointerEvent(1, ev), pointerEvent(2, ev));
                   break;
               case POINTER_HOVER:
      @@ -1516,6 +1517,7 @@
                   f.sizeChangedInternal(ev[1], ev[2]);
                   break;
               case HIDE_NOTIFY:
      +            pointerPressedAndNotReleasedOrDragged = null;
                   f.hideNotify();
                   break;
               case SHOW_NOTIFY:
      @@ -1985,9 +1987,15 @@
            * @return the shouldRenderSelection
            */
           public boolean shouldRenderSelection() {
      -        return !pureTouch || pointerPressedAndNotReleasedOrDragged || lastInteractionWasKeypad;
      +        return !pureTouch || pointerPressedAndNotReleasedOrDragged != null || lastInteractionWasKeypad;
           }
       
      +    public boolean shouldRenderSelection(Component c) {
      +        return !pureTouch || (pointerPressedAndNotReleasedOrDragged != null
      +                && c.contains(pointerPressedAndNotReleasedOrDragged[0], pointerPressedAndNotReleasedOrDragged[1]))
      +                || lastInteractionWasKeypad;
      +    }
      +
           /**
            * A pure touch device has no focus showing when the user is using the touch
            * interface. Selection only shows when the user actually touches the screen
      
      

        Activity

        Hide
        vprise added a comment -

        I don't understand the issue?
        How do you reproduce this problem?

        When I click a button and start dragging focus disappears almost immediately. Is it possible the grow effect somehow interfered with a repaint for the button?

        Show
        vprise added a comment - I don't understand the issue? How do you reproduce this problem? When I click a button and start dragging focus disappears almost immediately. Is it possible the grow effect somehow interfered with a repaint for the button?
        Hide
        thorsten_s added a comment -

        I believe the problem is that the button will still have focus after a press, just the visual focus appearance is suppressed. Maybe it is just the focus state, not sure. But if you then (on the next tap) press a non-focusable component the still focused button will render the focus appearance, even though the press was somewhere else. That is because the Display.shouldRenderSelection() method returns true when a pointer is pressed and does not care where it is pressed.

        Show
        thorsten_s added a comment - I believe the problem is that the button will still have focus after a press, just the visual focus appearance is suppressed. Maybe it is just the focus state, not sure. But if you then (on the next tap) press a non-focusable component the still focused button will render the focus appearance, even though the press was somewhere else. That is because the Display.shouldRenderSelection() method returns true when a pointer is pressed and does not care where it is pressed.
        Hide
        vprise added a comment -

        That was quite difficult to fix. I made a couple of changes to your approach to resolve some resulted regressions with the renderer. Thanks.

        Show
        vprise added a comment - That was quite difficult to fix. I made a couple of changes to your approach to resolve some resulted regressions with the renderer. Thanks.

          People

          • Assignee:
            Unassigned
            Reporter:
            thorsten_s
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: