Skip to content

Conversation

tgc-dk
Copy link
Contributor

@tgc-dk tgc-dk commented Oct 5, 2022

To avoid random touches ends up changing settings or starting a timer, this introduces a restricted mode where no touch input is accepted unless the hardware button is used to turn on the watch. A settings is introduces to enable this.
The restricted mode is only active on watchfaces.

This is not a perfect solution since it will require the button to be pressed several times to leave the restricted mode once in it.


edit 2025-05-24: updated description by @NeroBurner :

When the device is woken through pressing the button everything is the same.

But when woken through other means like single-tap or raise-to-wake,
then the screen is locked (and showing a lock screen on touch input)
until the button is pressed.

Only exception is when the alarm wakes the screen, then touch input is
still valid for the user to be able to press the red "stop alarm"
button.

@minacode
Copy link
Contributor

minacode commented Oct 6, 2022

The restricted mode is only active on watchfaces.

Why is this necessary? Wouldn't this feature be useful regardless of the active app?

@tgc-dk
Copy link
Contributor Author

tgc-dk commented Oct 7, 2022

The restricted mode is only active on watchfaces.

Why is this necessary? Wouldn't this feature be useful regardless of the active app?

The reasoning is that if you (for example) are playing the "2" game and the screen goes to sleep due to no activity, if you then wake up the screen by shaking your arm, touch input will be ignored and if you push the hardware button you will exit the game, loosing the progress.
One way to solve this is of course to make the first hardware button push unlock the restricted mode, but IMHO this would probably be a bit confusing for users since it would change how the button-push is handled depending on how the wakeup was done...

@minacode
Copy link
Contributor

minacode commented Oct 7, 2022

I think this is exactly how this should be done. The watch goes into a lock mode where the first button press does nothing but exiting that mode. Maybe we could have a popup with a lock symbol and something like "press the button to unlock" on touch events so users can better understand what is going on.

Another thing is a lock screen. We could always show the watch face on non-button wakeup (with a clue that this is a lock screen) and after pressing the button go back to the current screen. This is closer to what other devices like phones do.

@taukakao
Copy link

taukakao commented Oct 7, 2022

I agree with @minacode although I don't think a real "lock screen" makes sense. Maybe a visual indicator but a lock screen for a watch that only has a couple of modes is a bit much.

One reason I prefer it is because it enables you to have for example the navigation or timer app open on the watch and look at it from time to time. Right now this would always randomly switch to different watch faces on it's own.

@taukakao
Copy link

taukakao commented Oct 7, 2022

And because I know it will be mentioned:
No, I don't think this is a weird workaround for the issue of a too sensitive touch panel.
This is for when you currently don't want to interact with your watch but still look at it.

@tgc-dk
Copy link
Contributor Author

tgc-dk commented Oct 9, 2022

Thanks for the into @minacode and @Joheyy! I'll look into the possibility of implementing a "pop up" notifying about the lock and that the hardware button should be used to unlock.

@minacode
Copy link
Contributor

Keep in mind that the watch can wake itself (for example via notifications).

@tgc-dk
Copy link
Contributor Author

tgc-dk commented Oct 16, 2022

I've just pushed a new commit that adds a 'Popup' notification and display it when a touch input is received during 'locked' wakeup. The lock is now active on all screens, though not when an app as caused the wakeup.
I have only tested this in the simulator so far...
Let me know what you think!
I've attached a small animation that shows the lock in action.

InfiniSim_2022-10-16_195522

@Avamander
Copy link
Collaborator

That approach seems good, also very similar to that of say Apple Watch.

@minacode
Copy link
Contributor

I like it.

Can you explain the intuition behind the three WokenBy values? Button explains itself, but what exactly are WakeUpAction and Other? What cases do and don't they cover?

@tgc-dk
Copy link
Contributor Author

tgc-dk commented Oct 17, 2022

Can you explain the intuition behind the three WokenBy values? Button explains itself, but what exactly are WakeUpAction and Other? What cases do and don't they cover?

The WokenBy values are:

  • Button: Pretty self explanatory as you say)
  • WakeUpAction: The actions selected in the wakeup settings, single/double tap, raise, shake
  • Other: Other things that can wake the watch up, basically apps and notifications.

In reality it might be possible to replace the values with a simple boolean wokenByAction, but I'm not yet sure...

@minacode
Copy link
Contributor

I would like that in a comment, in the code. Or better names, I don't know. UserButtonWakeup, UserNonButtonWakeup, SystemAutoWakeup? Sounds weird as well..

Copy link
Contributor

@NeroBurner NeroBurner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be a good idea to move the popup to displayapp and use displayapp/Messages.h to communicate between the systemtask and DisplayApp

@tgc-dk
Copy link
Contributor Author

tgc-dk commented Nov 7, 2022

I think it would be a good idea to move the popup to displayapp and use displayapp/Messages.h to communicate between the systemtask and DisplayApp

Changed as suggested

@tgc-dk tgc-dk requested a review from NeroBurner November 7, 2022 21:23
@NeroBurner NeroBurner added the enhancement Enhancement to an existing app/feature label Nov 29, 2022
@github-actions
Copy link

github-actions bot commented May 2, 2023

Build size and comparison to main:

Section Size Difference
text 380660B 528B
data 944B 0B
bss 22552B 8B

Run in InfiniEmu

@pipe01
Copy link
Contributor

pipe01 commented Oct 26, 2023

Any updates on this?

@tgc-dk
Copy link
Contributor Author

tgc-dk commented Nov 28, 2023

I've introduced a second page to the WakeUp settings since there was no room left for new checkbox.
Note that the CI simulator build fails due to changes needed in InfiniSim to build with the changes in this PR, see InfiniTimeOrg/InfiniSim#131

@NeroBurner Are you up for a re-review?

@riban-bw
Copy link

riban-bw commented Jan 19, 2024

I've just pushed a new commit that adds a 'Popup' notification and display it when a touch input is received during 'locked' wakeup. The lock is now active on all screens, though not when an app as caused the wakeup. I have only tested this in the simulator so far... Let me know what you think! I've attached a small animation that shows the lock in action.

InfiniSim_2022-10-16_195522

The popup seems rather intrusive. If we are trying to avoid activity that occurs fairly frequently then it is possible that the popup will obscure the display when the user wants to view the watchface. Could we just use a lock icon instead? This is a user configured feature that would probably be disabled by default so the user must enable it and therefore shoudl understand the purpose of the icon. (It could be reinforced by showing the same icon in the settings screen.) The lock icon could show in a notification space, e.g. top of screen. It could either be always visible when locked, shown on activity or visible and highlight on activity. This may also reduce the memory increase. (One icon may be less than lots of text?)

I really like the idea of a lock mechanism (as I too suffer the issue of unexpected activity) but don't want something obscuring the screen.

@NeroBurner
Copy link
Contributor

I'm in favor of the lock as it doesn't need to be translated and should be easily understood. I like the visual hint to use the lock in the setting screen as well

@jgonyea
Copy link

jgonyea commented Jan 25, 2024

I also would love to see this feature added. I don't know how, but I constantly am waking the screen and accidentally tapping on screen elements. This would solve this issue for me!

@tgc-dk
Copy link
Contributor Author

tgc-dk commented Jan 27, 2024

@riban-bw

The popup seems rather intrusive. If we are trying to avoid activity that occurs fairly frequently then it is possible that the popup will obscure the display when the user wants to view the watchface.

Please note that the lock screen first shows up after the screen has been woken up AND a touch gesture has been identified, meaning that the lock screen does not automatically show when the display is on.

@riban-bw @NeroBurner

I'm in favor of the lock as it doesn't need to be translated and should be easily understood. I like the visual hint to use the lock in the setting screen as well

This is a valid point, I'll change the lock screen to use an actual icon. Regarding using the lock in the in the settings, how do you envision this to be done? See the screenshot below for the current settings screen, shown is the (new) second settings page under "Wake Up". Where should the lock icon be placed?

InfiniSim_2024-01-27_181545

The lock icon could show in a notification space, e.g. top of screen. It could either be always visible when locked, shown on activity or visible and highlight on activity.

If I understand you correctly, this would be nice, but it would require that InfiniTime has a global notification bar for it to be consisted across screens, which it don't, so I think I'll stick with the pop-up for now.

@tgc-dk
Copy link
Contributor Author

tgc-dk commented Jan 27, 2024

@NeroBurner @riban-bw
Using the popup with a lock icon could look like this:
InfiniSim_2024-01-27_220733

@jgonyea
Copy link

jgonyea commented Jan 27, 2024 via email

@NeroBurner
Copy link
Contributor

Now having 7 days of uptime. Seems stable 🎉

@mattvchandler
Copy link

I've been using this branch in my own build for over a year now. It's been really nice to prevent accidental touches.
However, I've noticed that if you touch the screen while a notification is shown, return to the watch face without unlocking, and then press the button, the watch crashes.

Here's a detailed method that seems to be 100% reproducible for me.

  1. Have the watch face open - this only seems to happen consistently with the watch face, not with other apps.
  2. Turn off the screen, either with the HW button or let it time out
  3. Receive a notification. The screen turns on and goes to the notification preview
  4. Touch the screen before the preview times out
  5. After the preview times out and returns to the watch face, but before the screen turns off, push the hardware button
  6. The watch will crash and reboot

I've also gotten a crash by waking the screen with a timer or alarm, and then double-pressing the button to get to the notifications. It seems less consistent, and I've never accidentally triggered a crash this way, but I noticed the possibility of the same problem as I was trying to find a solution to this crash, and tested it out as well.

  1. Have the screen be off / locked, again with the watch face as the current app
  2. Wake the screen by tapping, shaking, raising, an alarm or timer, etc. Any method other than the HW button.
  3. Double-press the HW button to bring up the notification app
  4. Touch the screen
  5. Long press the HW button to return to the watch face
  6. Press the HW button
  7. The watch will crash and reboot

I haven't been able to reproduce either these methods consistently in InfiniSim.

For my own build, I worked around the problem by setting unlockedByButton = true in SystemTask.cpp when getting a new notification, or when double-pressing the button. It prevents the crash, but at least in the case of receiving a notification unlocks the screen without user interaction and can lead (and for me has led) to accidental presses, so it's not an ideal fix.

I haven't been able to track down the root cause. I think it's got to be something to do with the active app changing whilst locked, but I haven't been able to get any further than that.

@NeroBurner
Copy link
Contributor

can reproduce (the second guide with double-press). Thanks a lot for finding it and the thorough steps to reproduce the issue

@atomdmac
Copy link

I've been using this branch for about a week and it's made my PineTime much more usable for me. The accidental touches were constantly causing my watch to end up on non-clock screens. Thank you!!

@p1gp1g
Copy link

p1gp1g commented Jul 17, 2025

Thank you for the PR!

When I touch the screen while it is locked, I see the popup until the screen is off. I think it would be better to show the lock for ~ half a second: it is enough to know that the screen is locked and allow to see the watch face after that

Less important, but it may be a good idea to show the popup for long press and swipe only on the watch face

BTW, it is possible to make the lock more transparent, it is very white with the casio face ?

@p1gp1g
Copy link

p1gp1g commented Jul 20, 2025

can reproduce (the second guide with double-press). Thanks a lot for finding it and the thorough steps to reproduce the issue

There is a double free, I'm opening a PR on your repo

EDIT: tgc-dk#6 this can be fixed by calling popupMessage.SetHidden(true); whenever we change app

tgc-dk and others added 4 commits July 20, 2025 15:43
When the device is woken through pressing the button everything is the
same.

But when woken through other means like single-tap or raise-to-wake,
then the screen is locked (and showing a lock screen on touch input)
until the button is pressed.

Only exception is when the alarm wakes the screen, then touch input is
still valid for the user to be able to press the red "stop alarm"
button.

Co-authored-by: NeroBurner <pyro4hell@gmail.com>
It fixes a potential double-free when removing lock popup
@NeroBurner
Copy link
Contributor

Can confirm the second crash reproduction is now fixed. Thanks @p1gp1g

@NeroBurner
Copy link
Contributor

@p1gp1g

When I touch the screen while it is locked, I see the popup until the screen is off. I think it would be better to show the lock for ~ half a second: it is enough to know that the screen is locked and allow to see the watch face after that

I agree, but I'd like this PR to be kept simple. I essentially hijacked it and would like it to be merged as soon as possible. So I try to keep the PR itself to be simple and easily reviewable. So I propose a new PR after this one is merged

Less important, but it may be a good idea to show the popup for long press and swipe only on the watch face

Good idea. I'd need to see if this a simple change or if it makes the code more complicated

BTW, it is possible to make the lock more transparent, it is very white with the casio face ?

I'm no designer, so I'd like to delegate this to someone else (i.e. please open a a new PR after this one is merged)

@p1gp1g
Copy link

p1gp1g commented Jul 22, 2025

I've found another bug (tested before my patch too), I'll dig it later to get a patch, but I think I know what to do:

  • Lock the watch
  • Single tap to wake the watch
  • Double click to go to notifications app
  • Single tap to show the popup
  • Wait until it goes to sleep

It will crash

I think it can be fixed by calling setHiddent(true) in SystemTask::GoToSleep

@NeroBurner
Copy link
Contributor

can reproduce 😅 thanks a lot!

@WhyNotHugo
Copy link
Contributor

Fixes #1839

@mark9064
Copy link
Member

mark9064 commented Aug 7, 2025

Ping me when this is ready for review :)

@WhyNotHugo
Copy link
Contributor

I've been testing this for a couple of weeks. My main issue is that the lock icon is shown as an overlay covering the time, so I can't read the time when it's visible. I'd prefer the lock to be shown on top of the time (e.g.: near the batter/bluetooth icons maybe), so I can still read the time while it's displayed.

@atomdmac
Copy link

@WhyNotHugo That's basically how Bangle JS handles this mechanic and it works really well, IMO.

@NeroBurner
Copy link
Contributor

I've found another bug (tested before my patch too), I'll dig it later to get a patch, but I think I know what to do:

* Lock the watch
* Single tap to wake the watch
* Double click to go to notifications app
* Single tap to show the popup
* Wait until it goes to sleep

It will crash

I think it can be fixed by calling setHiddent(true) in SystemTask::GoToSleep

I just wanted to implement you fix, but that is effectively already done.

displayApp.PushMessage(Pinetime::Applications::Display::Messages::HideIgnoreTouchPopup);

Do you maybe have other ideas, or did I misunderstand your fix?

@NeroBurner
Copy link
Contributor

found another workaround. Double press button also unlocks the watch

@NeroBurner NeroBurner requested a review from mark9064 August 22, 2025 21:10
@kieranc
Copy link
Contributor

kieranc commented Aug 26, 2025

I just had a crash I think related to this PR, only changes are this plus font bpp changes the the bpp stuff has been stable for quite a while.

Notification arrived, I tried to swipe and got the lock icon, so I pressed the button to unlock, tried to swipe but the screen was unresponsive, then the watch rebooted.

I just made it happen again, I pressed the button just after/at the same time as the notification disappeared, perhaps related?

@NeroBurner
Copy link
Contributor

thanks for trying it out and finding a bug. I think I'll have to call hide overlay before changing the screen to be sure it is always properly unloaded from each frame. otherwise lvgl will delete it as part of the screens decunstructor

@NeroBurner
Copy link
Contributor

we already do that... so why does it segfault/reboot 🤔

popupMessage.SetHidden(true);

@p1gp1g
Copy link

p1gp1g commented Sep 4, 2025

I've found another bug (tested before my patch too), I'll dig it later to get a patch, but I think I know what to do:

* Lock the watch
* Single tap to wake the watch
* Double click to go to notifications app
* Single tap to show the popup
* Wait until it goes to sleep

It will crash
I think it can be fixed by calling setHiddent(true) in SystemTask::GoToSleep

I just wanted to implement you fix, but that is effectively already done.

displayApp.PushMessage(Pinetime::Applications::Display::Messages::HideIgnoreTouchPopup);

Do you maybe have other ideas, or did I misunderstand your fix?

It may be because displayApp.PushMessage(Pinetime::Applications::Display::Messages::HideIgnoreTouchPopup); is called after displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep);

Try:

 void SystemTask::GoToSleep() {
   if (IsSleeping()) {
     return;
   }
   if (IsSleepDisabled()) {
     return;
   }
   NRF_LOG_INFO("[systemtask] Going to sleep");
+  displayApp.PushMessage(Pinetime::Applications::Display::Messages::HideIgnoreTouchPopup);
   if (settingsController.GetAlwaysOnDisplay()) {
     displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToAOD);
   } else {
     displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep);
   }
   heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep);
   unlockedByButton = false;
-  displayApp.PushMessage(Pinetime::Applications::Display::Messages::HideIgnoreTouchPopup);
 
   state = SystemTaskState::GoingToSleep;
 };

@NeroBurner
Copy link
Contributor

Thanks @p1gp1g committed your change. That could be it.

@kieranc could you test again?

@tituscmd
Copy link
Contributor

I think it would be better if this feature wasn’t enabled by default and could be turned off in the settings. I personally don’t run into the problem this PR fixes, so I likely wouldn’t use the feature and would appreciate the option to disable it.

Maybe the setting for this could be placed under an "Accessibility" page in the settings menu? This would be descriptive enough to be intuitive and allow future features to be included as well, unlike a "Unlock Watch" setting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Enhancement to an existing app/feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.