swaywm / swayidle

Idle management daemon for Wayland
MIT License
550 stars 50 forks source link

idle_wake does not work after swayidle receives SIGUSR1 #107

Closed kupospelov closed 2 years ago

kupospelov commented 2 years ago

Steps to reproduce:

  1. Insert idle_wake keyboard into your seat configuration.
  2. Start swayidle with a configured timeout.
  3. Send SIGUSR1 to swayidle to trigger the idle command.
  4. Move the mouse.

At this moment nothing should happen, but swayidle triggers the resume command.

Note: this works as expected if sway switches to the idle state after the configured time of inactivity.

seat.c has some code like this:

int ntimers = 0, nidle = 0;
wl_list_for_each(timeout, &server.idle->idle_timers, link) {
  ++ntimers;
  if (timeout->idle_state) {
      ++nidle;
  }
}

I tried some debugging and noticed that every SIGUSR1 sent to swayidle increases both ntimers (by 2) and nidle (by 1). For example:

  1. ntimers = 0, nidle = 0
  2. ntimers = 1, nidle = 0 (after swayidle starts)
  3. ntimers = 3, nidle = 1 (after I send SIGUSR1 to swayidle and then wake it up)
  4. ntimers = 5, nidle = 2 (after I send SIGUSR1 to swayidle and then wake it up)

When I kill swayidle both counters are reset to 0.

swayidle seems to call org_kde_kwin_idle_timeout_destroy() to destroy the old timeout before creating a new one, so I guess that means that wlroots does not properly destroy the timers in this case.