Acknowledged

Request - specify if WatchUi.View.onUpdate() is required or optional

If onUpdate() calls would allow differentiating between updates that are required and that are optional, it would allow avoiding unnecessary repainting.

For example, if a watch face does not require updating every second (by showing just HH:MM), then 59 repaints every minute in high-power mode go to waste.

On the other hand, if the OS wipes the screen clean for some reason, then onUpdate() obviously must execute.

The request is to change onUpdate to include an extra parameter to specify if the update is optional or not:

onUpdate(dc as Graphics.Dc, required as Boolean) as Void

This would help writing more power-efficient code.

  • It's causing CIQ faces to feel sluggish when entering high-power mode, and it's draining batteries.”

    According to “accepted forum wisdom” there’s no possible advantage to only updating part of the display in onUpdate() (even if the API was able to communicate under which circumstances this is possible / permissible.)

  • This is probably the single biggest issue impacting the CIQ developers right now.  It's causing CIQ faces to feel sluggish when entering high-power mode, and it's draining batteries.  There's a HUGE bug on Epix 2 Pro that paints the screen every single second in low-power mode.  Battery drain is ridiculous for CIQ faces.

    I finally bit the bullet and developed this exact system.  It worked great on my Epix 2 Pro, and I thought I had a breakthrough in responsiveness and battery usage.  The sleep-wakes were super responsive.  And the battery usage was MUCh better.

    But once I rolled it out, users on other devices flooded in with bug reports.  It turns out that some devices clear the screen, making a paint on every call necessary.  So all those customers were getting "black screens" when an unnecessary paint was called.

    I reverted back to a prior version, and here I am now trying to see if I can figure out a new fix.  It was night-and-day better with the fix, but maybe I can only deploy that on my own device (Epix 2 Pro)?

    Here's my thread on this in the forums:
    forums.garmin.com/.../when-woken-onupdate-is-called-6-times-before-onexitsleep-called


  • I'm not against this kind of change in principle, but the exact suggested implementation (adding a new parameter to onUpdate()) is not feasible, bc it would break backwards compatibility with all existing code. Passing too many (or too few) arguments to a function is a runtime error, and a compile-time error (when the type checker is enabled). (As a matter of fact, Garmin's own API has an issue related to Garmin code passing in the wrong number of arguments to a CIQ callback method.)

    I think Garmin would need to provide another overridable function to the View class named onUpdate2() (or whatever you want to call it), with the new signature / behavior you specified.

    The default implementation of onUpdate2() could look like this:

    function onUpdate2(dc as Graphics.Dc, required as Boolean) as Void {
      onUpdate(dc);
    }
    If you want the new behavior, override onUpdate2() in your app and do your update there. If your app also overrides onUpdate(), it won't be called by the framework (but you can call it yourself, if necessary).

    I do feel like this would be difficult for Garmin to document properly (*) and hard for new devs to understand. (* the existing docs for "normal stuff" aren't perfect.)

    It would also open up some issues if someone overrides a View-derived class that overrides onUpdate2(). They may try to override onUpdate(), only to find that it doesn't work.

    Maybe a better solution would be to simply add the information you want to Graphics.Dc.

    > On the other hand, if the OS wipes the screen clean for some reason, then onUpdate() obviously must execute.

    I'll also point out, as others have, that it's not just screen clearing that necessitates redrawing the whole screen in onUpdate(), notifications (like the move alert) can also cover up part of your app's screen. If we really want to get in the weeds here, maybe to be *really* power efficient, we would want to know *which region of the screen* needs to be redrawn.

  • This is a hack, not a solution. In fact, this doesn't work on an AMOLED watch I have. It requires onUpdate to execute on every call.

  • You can save the last time it was called and not draw if it's less than a second. Though in theory it could be that even though only 100ms passed there was something drawn over it and then you would need to draw...