Skip to content

Commit ee74fa3

Browse files
ericmigiclaude
andcommitted
fw/services/touch: let system subscriptions opt out of backlight override
touch_has_app_subscribers() derived its answer from the total subscriber count minus the backlight subscription, which was written when the backlight was the only kernel-side subscriber. The watchface long-press hook added a second permanent subscription, making the function always return true: the event loop then lit the backlight on every touchdown and skipped the wake-gesture preference, so a single touch woke the screen even with touch-to-wake set to double tap. Add touch_set_system_subscribed() so system-internal subscriptions can explicitly exclude themselves, and mark the watchface long-press hook with it. Third-party app subscriptions keep the touchdown-driven backlight behavior unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Eric Migicovsky <ericmigi@gmail.com>
1 parent 44b8688 commit ee74fa3

4 files changed

Lines changed: 55 additions & 6 deletions

File tree

include/pbl/services/touch/touch.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@ void touch_init(void);
2424
//! When disabled, the touch sensor is only active if apps have subscribed to touch events.
2525
void touch_set_backlight_enabled(bool enabled);
2626

27-
//! @return true if at least one subscriber is currently registered for touch events.
27+
//! Mark (or unmark) one subscription as a system-internal consumer that must
28+
//! not count towards touch_has_app_subscribers(). Call with true after
29+
//! subscribing and with false before unsubscribing.
30+
void touch_set_system_subscribed(bool subscribed);
31+
32+
//! @return true if at least one subscriber other than the system-internal
33+
//! ones (backlight, subscriptions marked via touch_set_system_subscribed())
34+
//! is currently registered for touch events.
2835
bool touch_has_app_subscribers(void);
2936

3037
//! Globally enable or disable touch. When disabled:

src/fw/services/touch/touch.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ static int16_t s_last_y;
2525
static PebbleMutex *s_touch_mutex;
2626

2727
static uint8_t s_subscriber_count = 0;
28+
//! Subscriptions explicitly marked as system-internal (e.g. the watchface
29+
//! long-press hook): they keep the sensor powered but must not count as
30+
//! "an app is using touch". The backlight subscription is tracked separately
31+
//! via s_backlight_subscribed and excluded the same way.
32+
static uint8_t s_system_subscriber_count = 0;
2833
static bool s_backlight_subscribed = false;
2934
static bool s_globally_enabled = true;
3035
static bool s_rotated = false;
@@ -55,6 +60,17 @@ static void prv_remove_subscriber_cb(PebbleTask task) {
5560
mutex_unlock(s_touch_mutex);
5661
}
5762

63+
void touch_set_system_subscribed(bool subscribed) {
64+
mutex_lock(s_touch_mutex);
65+
if (subscribed) {
66+
s_system_subscriber_count++;
67+
} else {
68+
PBL_ASSERTN(s_system_subscriber_count > 0);
69+
s_system_subscriber_count--;
70+
}
71+
mutex_unlock(s_touch_mutex);
72+
}
73+
5874
void touch_init(void) {
5975
s_touch_mutex = mutex_create();
6076

@@ -66,10 +82,10 @@ void touch_init(void) {
6682

6783
bool touch_has_app_subscribers(void) {
6884
mutex_lock(s_touch_mutex);
69-
// The backlight gesture subscription is tracked in s_subscriber_count as
70-
// well; exclude it so this only reflects real app subscribers.
71-
const uint8_t backlight_count = s_backlight_subscribed ? 1 : 0;
72-
const bool has_apps = s_subscriber_count > backlight_count;
85+
// Exclude the system-internal subscriptions (backlight, marked system
86+
// subscribers) so this only reflects real app subscribers.
87+
const uint8_t excluded = (s_backlight_subscribed ? 1 : 0) + s_system_subscriber_count;
88+
const bool has_apps = s_subscriber_count > excluded;
7389
mutex_unlock(s_touch_mutex);
7490
return has_apps;
7591
}

src/fw/shell/normal/watchface.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#ifdef CONFIG_TOUCH
2525
#include "applib/touch_service.h"
2626
#include "apps/system/watchfaces.h"
27+
#include "pbl/services/touch/touch.h"
2728
#include <pbl/util/math.h>
2829
#endif
2930
#include "pbl/services/notifications/do_not_disturb.h"
@@ -385,8 +386,10 @@ void watchface_init(void) {
385386
#ifdef CONFIG_TOUCH
386387
// Kernel-side subscription: keeps the touch sensor powered so a long press
387388
// on the watchface can open the selector. Foreground gating happens in the
388-
// handler itself.
389+
// handler itself. Marked as a system subscription so it doesn't trigger the
390+
// touch-backlight override meant for third-party touch apps.
389391
touch_service_subscribe(prv_watchface_touch_handler, NULL);
392+
touch_set_system_subscribed(true);
390393
#endif
391394
}
392395

tests/fw/services/test_touch.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,29 @@ void test_touch__has_app_subscribers_backlight(void) {
211211
cl_assert(!touch_has_app_subscribers());
212212
}
213213

214+
void test_touch__has_app_subscribers_system(void) {
215+
// Subscriptions marked as system-internal (e.g. the watchface long-press
216+
// hook) keep the sensor powered but must not count as app subscribers, or
217+
// the event loop would light the backlight on every touchdown and bypass
218+
// the wake-gesture preference. Unmarked subscribers keep counting so the
219+
// touch-backlight behavior for third-party touch apps is unaffected.
220+
cl_assert(!touch_has_app_subscribers());
221+
222+
s_add_subscriber_cb(PebbleTask_KernelMain);
223+
touch_set_system_subscribed(true);
224+
cl_assert(!touch_has_app_subscribers());
225+
226+
s_add_subscriber_cb(PebbleTask_App);
227+
cl_assert(touch_has_app_subscribers());
228+
229+
s_remove_subscriber_cb(PebbleTask_App);
230+
cl_assert(!touch_has_app_subscribers());
231+
232+
touch_set_system_subscribed(false);
233+
s_remove_subscriber_cb(PebbleTask_KernelMain);
234+
cl_assert(!touch_has_app_subscribers());
235+
}
236+
214237
void test_touch__globally_enabled_default_true(void) {
215238
// Default state after init is enabled; no setter call required.
216239
cl_assert(touch_service_is_globally_enabled());

0 commit comments

Comments
 (0)