Behavior delegate and partial redraw questions

Former Member
Former Member
Trying to develop new app I faced several problems, that I face only on the real watch (FR230).

1. I wanted to process Up/Down button presses and started with InputDelegete. Everything worked in simulator (and mind you, I read about onKeyRelease problems, so I started with onKey insted) but it seems that input delegate is not working at all on watch since I don't get any reaction when pressing buttons. When I replaced InputDelegate with BehaviorDelegate mapping necessary keys to delegate methods, everything works fine even on watch. Almost. When I long press up key and expect only onMenu to happen, I receive two callbacks in sequence: first onPreviousPage and then onMenu. This happens only on watch, in simulator everything works fine. Is there any way to distinguish if onPreviousPage happened because of onMenu? Below is the code exerpt.

...
function getInitialView() {
view = new AppView();
return [ view, new AppDelegate(view) ];
}
...
class AppDelegate extends Ui.BehaviorDelegate {
...
function onPreviousPage() {
return view.updateRowIndex(-1);
}

function onMenu() {
return view.onMenuPressed();
}
}
...


2. Another input related issue: in my app I have main screen, that handles user input and several menus custom coded by extending View. Almost every time after I pushView or popView happens when I return false in onBack of view delegate, first button press is not processed. General scenario: I long press Up, then call Ui.pushView with custom delegate, then first up or down press is not processed (again, this happens only on watch). Maybe this is performance related issue when memory is allocated and/or freed in large segments since if I wait for a couple of seconds before this first press, then it is processed, but if I press same button two times after staring new view without waiting, then relevant delegate method is called immediately. It's not critical, but unexplainable and rather irritating. Please, if someone faced similar app behavior, advise how to resolve such issues.

3. I tried to implement partial screen redraw, setting full redraw flag only in view's onShow, meaning that I need to redraw full screen only in case if view was pushed into screen either from stack or as initial view. Once again, everything works fine in simulator, but on real watch my screen gets distorted. I found out that this happens because of standard slide animations, that happen, for example, during application start when initial view is sliding from right to left. I was unable to find any callback for a view, that will be called after standard slide animation has ended. Is there a way to handle such situations? And yet another redraw question: if i don't bother with partial redraw - I don't have any screen distortions and view is even animated during slides with full content. Does this mean, that redraw performance including dc.clear, 5 to 10 dc.setColor and about 20 drawText every second is not considered a hard work for a watch? Is it even necessary to implement partial redraws to improve battery life in the long run?
  • Former Member
    Former Member over 8 years ago
    Behavior delegate problems

    Several watch firmwares later and still problem 1 persists:
    if I implement behavior delegate subclass to handle both onPreviousPage and onMenu user actions, onPreviousPage happens right before onMenu (only on watch, simulator works fine), meaning that if I press and hold "Up" key on my ForeRunner230, then i receive callback for "Up" key itself first and half a second later for "Menu", onKeyReleased is still not working on FR230. Can someone, please, help to find any kind of workaround to handle Up and Menu actions separately, or I'll just have to accept, that it "bugs as designed"?
  • Former Member
    Former Member over 8 years ago
    behavior delegate

    I did some research with input and behavior delegates and it seems that the problem is in hardware key auto-repeat native behaviour, which means that if you press and hold Up or Down key, then Up or Down key presses will be generated every second until key is released. Since FR23x doesn't have dedicated menu hardware key and Menu action is mapped to long press of Up key and onKeyReleased is not working on actual device, this prevents IQ application to distinguish Up key auto-repeat from Menu action. The only workaround I found so far is using timers, which make Up action happen not instantly in onPreviousPage BehaviorDelegate callback, but in a separate function, which is called after a set amount of milliseconds, and if I catch onMenu callback, then I just stop this timer so that this separate timer callback never happens. Generally, this solves my problem, but gives minor setback of 300ms screen refresh delay I see every time after pressing Up key (300ms is value I found experimentally, that gives onMenu proper time to happen after Up auto-repeat).

    class TheSMARTDelegate extends Ui.BehaviorDelegate {
    ...
    var ppTimer;
    ...
    function onNextPage() {
    // do something for Down key press
    }

    function onPreviousPage() {
    ppTimer.start( method(:execPrevPage), 300, false );
    return false;
    }

    function execPrevPage() {
    // do smoething for Up key single press
    }

    function onMenu() {
    ppTimer.stop();
    // do something for the menu action
    }
    }


    Since nobody ever bothered to answer my question, I'll leave this solution for those developers who'll brave to implement complex applications with user input in a hope that one day Garmin devs of FR23x device family will take note of this obvious SDK bug.
  • Update: Apparently this code won't work on current devices because they don't call onKeyRelease(). I did some testing with onKeyPressed() and onKeyRelease() a while ago and I believe it was working (at least on the device I had to test with at the time), but haven't tested this recently.

    If you handle onKeyPressed() and onKeyReleased(), you should be able to handle the situation where the user just taps and releases the key without the 300ms delay.

    var mPressedTime;
    var mTimer;

    var onKeyPressed(evt) {
    var key = evt.getKey();
    if (key == Ui.KEY_UP) {
    mPressedTime = Sys.getTimer();
    mTimer.start(method(:onKeyHeld), 300, false);
    }

    return true;
    }

    var onKeyReleased(evt) {

    mTimer.stop();

    var key = evt.getKey();
    if (mPressedTime == null) {
    return true;
    }

    var now = Sys.getTimer();
    if ((now - mPressedTime) < 300) {
    // short key press
    }
    else {
    // long key press
    }

    mPressedTime = null;
    }

    function onKeyHeld() {
    // long key press

    mPressedTime = null;
    }
  • Former Member
    Former Member over 8 years ago
    Thank you Travis, I tried this method, but despite expected behavior in simulator onKeyReleased was never called on my FR230 and I checked that after each FW update for the last half of a year. And I read other threads where other developers confirm the similar situation on other devices, so, this method at the very least is not very reliable. So far above code is the only workaround I found that helps to handle situation at least to some extent.

    And to my mind, the problem is more related to auto-repeat feature, which is not documented and cannot be recognized anyhow.
  • hi,
    When I long press up key and expect only onMenu to happen, I receive two callbacks in sequence: first onPreviousPage and then onMenu. This happens only on watch, in simulator everything works fine.

    i am having this too! also with the fr230. i have just implemented onMenu events. i have been looking for the problem, when i have found your post. strange that nobody from garmin said something, isn' t it? i will try your fix. thanks for that.
    EDIT: there is even another thread where this problem was mentioned. but there were never a response: https://forums.garmin.com/showthread.php?348708-onMenu()-not-working-on-Fr230&highlight=onmenu+fr230
    2. I long press Up, then call Ui.pushView with custom delegate, then first up or down press is not processed (again, this happens only on watch).

    yes, this happens to me too.
  • Former Member
    Former Member over 8 years ago
    ...strange that nobody from garmin said something...

    I think that since this problem only apparent to IQ developers who implement complete applications, which processes all possible user input actions (and this is not very common application type on market), and it doesn't break native apps experince, Garmin dev's may have noticed this query, but put it on the long list. Maybe even not. Considering there's still no solution for missed key press after "Select" has been processed, which is another one of this kind, and there are always matters of the greater importance I recon we'll never see this bug fixed at least in current generation of the IQ devices.
  • Hey Everyone,

    It looks like this may have been overlooked. If one of you would post this in the Bug Reports forum following the formatting there I'll have the team take a look at it.

    Link: https://forums.garmin.com/forumdisplay.php?623-Connect-IQ-Bug-Reports

    I'll close this one for now and move or delete it once we get the Bugs Forum post created.

    Thanks,
    Coleman