Is there a way on Watch Faces to disable the onEnterSleep() entry?

I've written a few watch faces and would like to be able to keep them from going into sleep so I can keep the seconds hand/count displayed all the time.  Some of the Garmin watch faces have always visible seconds, so I was wondering if there's a way to keep the seconds display always running in watch faces that I write myself.

I think I found a workaround by calling onExitSleep() immediately after going into sleep, as there's one final onUpdate() call after sleep is entered.  So I set a flag when onEnterSleep() is called, and then use that flag to call onExitSleep() on the next onUpdate() call.  Is that the normal way to do what I'm trying to do, or are there other ways?

edit: after posting this another thread showed up in the margins talking about onPartialUpdate(), looks like that gets called during sleep instead of onUpdate(), and it seems that I can keep the seconds displayed and incrementing using that method, so I think I'm good.  Any other comments will still be appreciated.

  • Yes, if you don't set a clip region, it's the whole screen.  The update is actually by rows, and if you have multiple clip regions, they are actually combined so the top row of one to the bottom row of the other, but just the pixels in the clip regions are marked as "dirty".  So if you have a clip region at the top of the screen and another at the bottom, you'll see it in the power budget where if the same clip regions are one right above the 2nd, much less of an impact.  This comes up if a WF whats 1hz seconds and heart rate for example.  In the case of HR, I keep track of the HR being displays and only update it (set a clip region, etc) if it's changed.  Not all watches support 1hx as I've mentioned.  I think it was the fr935/Fenix 5 that were the first devices to have the required HW.

  • Is it possible to have multiple clip regions active at the same time?  If you call a second setClip() method, does it add to the previous setClip() call, or simply replace it?

    given what you just described, I'm not sure how to interpret it without knowing the answer to the previous question. 

    If you have two regions, A and B, and do this:

    setClip(A)

    update pixels for A

    clearClip()  (maybe needed, maybe not depending on the answer to my first question)

    setClip(B)

    update pixels for B

    Are you saying that even if you process the screen update as two separate setClip() calls, (with a possible clearClip() in between if the second setClip() adds rather than replaces) and only change what's in those regions one at a time, that the screen update processing does the actual pixel updates for A and B at the same time, rather than once for A and once for B?  So no matter how you divide up the processing if A/B regions are at the top/bottom of the screen you'll see the power hit regardless of how the code execution is written?

  • Using this as an example, I user 1 or two clip regions.  There's a clip for the seconds, and that's updated every call to onPartialUpdate.  There's another that I create for the Heartrate, but only if the HR has changed from what's currently displayed (HR usually doesn't change every second, so this helps with the power budget).  And they way I do it, is I only call clearClip() at the beginning of onUpdate().  

    The combined are that's updated is from the top of the seconds area to the bottom of the HR area (if I'm updating the HR).

    If I moved the battery level above the HR more rows would be involved, and it would bite a bit more into the 30ms average.

  • I'm still not sure about a nuance of what you've described.  I get that you use 2 clip regions, and from the context of your reply it appears that if you run this code:

    setClip(A)  (area used by seconds)

    setClip(B)  (area used by HR)

    the result is both regions A and B are included in the clip, can you confirm/deny?

    If A+B are in the clip, and you don't update B every second because it doesn't always change, it seems that you're paying a power penalty by updating both clips when only one really changed.  If you only call clearClip() when onUpdate() fires, then that's once per minute in sleep mode.  If HR only changed a few times during that minute, you updated that part of the screen many times when it wasn't necessary.

    So, would it be more efficient to keep B out of the clip until its actually needed? 

    Like this:

    setClip(A)

    (code to change value of seconds in display)

    if (HR changed)

      setClip(B)

      (code to change value of HR in display)

      clearClip()

    endif

    This way you only have included in the clip area values that are actually changing on every second, and when you call the code again on the next second the clip gets reduced back to only the A region and the check for HR changing is performed again.

    But what's not clear from your reply is if you're talking about being in sleep mode or not, since you mention the 30ms limit, I assume you are.  If not, then clearClip() will get called every second anyway with onUpdate(), so that's why I'm a bit confused

  • The best way to understand this is to just play around in the sim.  Use watch face diagnostics, and see what happens.

  • I tried the simulation experimentation and confirmed what you said about the power consumption being based on row separation between multiple clip areas.

    The other thing I was able to determine is the setClip() method overwrites any previous calls to that method, it doesn't accumulate the area from each successive call into a "super clip".  I had asked about that a couple times but didn't get an answer in your previous replies, so that was the main thing I wasn't sure about that I wanted to explore in the experiment.

    If I wrote code like this:

    setClip(A)

    setClip(B)

    loop

      < do something to update screen in area A>

      < do something to update screen in area B>

    endloop

    the screen updates would be applied only to area B, updates to area A weren't applied, unless there was an overlap and part of area A was also in area B.

    If I wrote code like this:

    loop

      setClip(A)

      < do something to update screen in area A>

      setClip(B)

      < do something to update screen in area B>

    endloop

    then both areas were updated.

    The reason I asked about this was it might be faster/lower power to pre-define the two fields with the two consecutive setClip() calls one time, and then go into a loop that updates the screen content in those fields as a separate loop, like in the first code example above. My experiment showed that was not a workable option, I had to use the setClip() calls separately inside the loop in order for the clip to have the desired effect on each field, one at a time.

    And also, the clearClip() method is only needed when you want to go back to full screen mode.  Originally, I wasn't sure if I had to call clearClip() every time I switched between clip A and B, but experimentation shows that just calling setClip() with any area removes any previous area assigned to the clip, so no need to clear between successive calls to setClip() with a new area definition.