@@ -582,10 +582,47 @@ static void mouse_cleanup(void)
582582#define TOGGLE_DEBOUNCE_MS 2000 // ignore rapid repeated long-presses
583583
584584static long long last_typesync_broadcast_ms = 0 ;
585+ static int toggle_long_press_fired = 0 ; /* 1 once the mid-hold broadcast fires */
586+
587+ /* Fire the type-sync broadcast now and record the time. */
588+ static void fire_typesync_broadcast (long long now )
589+ {
590+ last_typesync_broadcast_ms = now ;
591+ toggle_long_press_fired = 1 ;
592+ log_message ("TOGGLE long-press threshold reached -> type-sync broadcast" );
593+ system ("am broadcast -a com.offlineinc.dumbdownlauncher.TOGGLE_TYPESYNC "
594+ "-n com.offlineinc.dumbdownlauncher/.TypeSyncToggleReceiver "
595+ "--receiver-foreground > /dev/null 2>&1 &" );
596+ }
597+
598+ /*
599+ * Called on every event-loop timeout (every ~200ms) while the star key is
600+ * held down. Fires the broadcast the moment the hold crosses the threshold
601+ * so the toast appears while the user's finger is still on the key.
602+ */
603+ static void check_long_press_timer (void )
604+ {
605+ if (app_state .mouse .toggle_down_at_ms == 0 ) return ; /* key not held */
606+ if (toggle_long_press_fired ) return ; /* already fired */
607+
608+ struct timeval tv ;
609+ gettimeofday (& tv , NULL );
610+ long long now = (long long )tv .tv_sec * 1000 + tv .tv_usec / 1000 ;
611+ long long held = now - app_state .mouse .toggle_down_at_ms ;
612+
613+ if (held >= TOGGLE_TAP_MAX_MS )
614+ {
615+ if (now - last_typesync_broadcast_ms >= TOGGLE_DEBOUNCE_MS )
616+ fire_typesync_broadcast (now );
617+ else
618+ log_message ("TOGGLE long-press debounced (last=%lldms ago)" ,
619+ now - last_typesync_broadcast_ms );
620+ }
621+ }
585622
586623static int mouse_toggle (struct input_event * ev )
587624{
588- if (ev -> value == 1 ) // key down
625+ if (ev -> value == 1 ) /* key down */
589626{
590627 long long now = ev_time_ms (ev );
591628
@@ -595,43 +632,32 @@ if (ev->value == 1) // key down
595632 }
596633
597634 app_state .mouse .toggle_down_at_ms = now ;
635+ toggle_long_press_fired = 0 ;
598636 log_message ("TOGGLE DOWN code=%d t=%lldms" , ev -> code , now );
599637 return CHANGED_TO_MOUSE ;
600638}
601639
602- if (ev -> value == 0 && app_state .mouse .toggle_down_at_ms != 0 ) // key up
640+ if (ev -> value == 0 && app_state .mouse .toggle_down_at_ms != 0 ) /* key up */
603641 {
604- long long now = ev_time_ms (ev );
642+ long long now = ev_time_ms (ev );
605643 long long held = now - app_state .mouse .toggle_down_at_ms ;
606644
607- log_message ("TOGGLE UP code=%d t=%lldms held=%lldms" , ev -> code , now , held );
645+ log_message ("TOGGLE UP code=%d t=%lldms held=%lldms fired=%d" ,
646+ ev -> code , now , held , toggle_long_press_fired );
608647
609- int was = app_state .mouse .enabled ;
610-
611- if (held <= TOGGLE_TAP_MAX_MS )
648+ if (!toggle_long_press_fired && held <= TOGGLE_TAP_MAX_MS )
612649 {
650+ /* Short tap — toggle the mouse */
651+ int was = app_state .mouse .enabled ;
613652 app_state .mouse .enabled = !app_state .mouse .enabled ;
614653 write_status_file ();
615654 on_enabled_transition (was , app_state .mouse .enabled , "manual" );
616655 log_message ("TOGGLE TAP accepted -> enabled=%d" , app_state .mouse .enabled );
617656 }
618- else
619- {
620- log_message ("TOGGLE long-press held=%lldms -> type-sync broadcast" , held );
621- if (now - last_typesync_broadcast_ms >= TOGGLE_DEBOUNCE_MS )
622- {
623- last_typesync_broadcast_ms = now ;
624- system ("am broadcast -a com.offlineinc.dumbdownlauncher.TOGGLE_TYPESYNC "
625- "-n com.offlineinc.dumbdownlauncher/.TypeSyncToggleReceiver "
626- "--receiver-foreground > /dev/null 2>&1 &" );
627- }
628- else
629- {
630- log_message ("TOGGLE long-press debounced (last=%lldms ago)" , now - last_typesync_broadcast_ms );
631- }
632- }
657+ /* If toggle_long_press_fired the broadcast already went out mid-hold; nothing more to do. */
633658
634659 app_state .mouse .toggle_down_at_ms = 0 ;
660+ toggle_long_press_fired = 0 ;
635661 return CHANGED_TO_MOUSE ;
636662 }
637663
@@ -955,7 +981,13 @@ static int run_event_loop(void)
955981 if (sel > 0 && app_state .control_fd >= 0 && FD_ISSET (app_state .control_fd , & rfds ))
956982 control_handle_ready ();
957983
958- if (sel == 0 ) continue ;
984+ /* On timeout (no events), check whether the star key has been held long
985+ * enough to trigger the type-sync broadcast mid-hold. */
986+ if (sel == 0 )
987+ {
988+ check_long_press_timer ();
989+ continue ;
990+ }
959991
960992 for (device_t * d = app_state .devices ; d ; d = d -> next )
961993 {
0 commit comments