be able to wake neko up with SIGUSR1

This commit is contained in:
Virt 2025-03-09 01:18:32 +01:00
commit 175710fe71
3 changed files with 42 additions and 6 deletions

1
README
View file

@ -17,4 +17,3 @@ The following features are missing from this fork for now:
- Neko does not yet behave differently at night.
- Idle detection is working but implemented sloppily.
- Pointer following is currently removed.
- Waking up Neko with a signal is something that should be possible.

View file

@ -111,6 +111,15 @@ close the surface for a different reason.
.RE
.
.
.SH SIGNALS
.P
\fBSIGUSR1\fR
.RS
You can send `wayneko` this signal to wake Neko up spontaneously. Neko won't notice
anything it she is already awake. Example: `pkill -10 wayneko`
.RE
.
.
.SH AUTHOR
.P
Original code by

View file

@ -99,6 +99,8 @@ uint32_t phase_sleep_max = 1800;
uint32_t phase_awake_min = 120;
uint32_t phase_awake_max = 600;
bool wakeup_shock = false; /* will force a shock, used when woken up */
struct Seat
{
struct wl_list link;
@ -230,6 +232,8 @@ static void handle_term (int signum)
loop = false;
}
static void wakeup(int signum);
/**
* Set up signal handlers.
*/
@ -240,6 +244,8 @@ static void init_signals (void)
signal(SIGINT, handle_term);
signal(SIGTERM, handle_term);
signal(SIGUSR1, wakeup);
}
/************
@ -930,6 +936,14 @@ static bool animation_next_state_with_hotspot (uint32_t x)
/** Returns true if new frame is needed. */
static bool animation_next_state_awake (void)
{
/* neko was just suddenly woken up */
if (wakeup_shock) {
animation_neko_do_shock();
wakeup_shock = false;
return true;
}
switch (current_neko) {
case NEKO_STARE:
switch (rand() % 24)
@ -1044,6 +1058,16 @@ static void check_phase(void) {
}
}
/** called as a signal handler to wake up neko */
static void wakeup(int signum) {
// already awake
if (current_phase == PHASE_AWAKE) return;
animation_ticks_until_next_frame = 0;
ticks_until_phase_change = 0; // will trigger a phase change to awake
wakeup_shock = true;
}
/** Returns true if new frame is needed. */
static bool animation_next_state (void)
{
@ -1578,6 +1602,7 @@ int main (int argc, char *argv[])
}
}
/* Flush pending Wayland events/requests. */
while ( wl_display_prepare_read(wl_display) != 0 )
{
@ -1588,6 +1613,7 @@ int main (int argc, char *argv[])
goto exit_main_loop;
}
}
while (true)
{
/* Returns the amount of bytes flushed. */
@ -1606,18 +1632,20 @@ int main (int argc, char *argv[])
if ( poll(pollfds, 1, current_timeout) < 0 )
{
if ( errno == EINTR ) /* Interrupt: Signal received. */
continue;
if ( errno != EINTR ) {
/* Interrupt is NOT a signal */
fprintf(stderr, "ERROR: poll(): %s.\n", strerror(errno));
ret = EXIT_FAILURE;
break;
}
}
if ( wl_display_read_events(wl_display) == -1 )
{
fprintf(stderr, "ERROR: wl_display_read_events(): %s.\n", strerror(errno));
break;
}
if ( wl_display_dispatch_pending(wl_display) == -1 )
{
fprintf(stderr, "ERROR: wl_display_dispatch_pending(): %s.\n", strerror(errno));