Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] generic --not-when flag #41

Closed
sidequestboy opened this issue May 14, 2020 · 6 comments
Closed

[Feature Request] generic --not-when flag #41

sidequestboy opened this issue May 14, 2020 · 6 comments

Comments

@sidequestboy
Copy link

It would be nice if we could have a generic --not-when flag that takes a script as an argument and runs the timer conditionally on its exit code. e.g.

xidlehook --not-when youtube --timer 'xscreensaver-command activate'

and we could write our own checking scripts for youtube, etc.

@jD91mZM2
Copy link
Owner

You could always compose your own xidlehook application consisting of the conditions you want, using xidlehook-core.

Though, if you just want to run a bash command you could just do xidlehook --timer 'some-command-here && xscreensaver-command activate'

@sidequestboy
Copy link
Author

sidequestboy commented May 19, 2020

Thanks for the reply!

The differences I see between your proposed workaround and the request are (1) it applies only to one timer, and (2) it moves to the next timer in the chain even if the check fails, which is not the behaviour of the --not-when-* flags which actually prevent the timer (and all subsequent timers) being run.

On a related note to (1), the ability to apply --not-when-* checks to individual timers in the chain could be very useful. For example, I might want my screensaver to come on while there's audio, but to prevent my suspend command. A workaround for this use-case might be to nest xidlehooks:

#! /usr/bin/env bash

suspend_hook() {
    xidlehook --not-when-audio --timer 300 'systemctl suspend' ''
}
export -f suspend_hook

xidlehook --timer 300 'xscreensaver-command -activate' '' \
          --timer 0 suspend_hook ''

But I imagine it would be nicer to write the above like so:

xidlehook --timer 300 'xscreensaver-command -activate' '' \
          --timer 300 'systemctl suspend' '' --not-when-audio

I am curious about Rust, but haven't touched it yet! Implementing my own client might be a good challenge for me though! I'll take a look at xidlehook-core :)

To summarize, I think two improvements could be made to the command syntax -

  • have a generic --not-when flag available, and
  • interpret --not-when* flags as unique to the --timer <timeout> <command> <canceller> flag they follow

I actually can't come up with a reasonable workaround for the first suggestion - I think it would involve process management and nested xidlehooks.

@jD91mZM2
Copy link
Owner

I can see the value in having --not-when-* stick to a timer, feel free to send a PR. The module API should make this rather easy. The Progress enum in xidlehook-core/src/modules/mod.rs needs a "Skip" option, and then I suppose the built-in modules could choose to skip it or something. Or maybe we could do something like --not-when <module> <action> that either aborts the chain or skips ahead. I don't know. :)

But I am very uncertain about having some kind of generic --not-when, because while I like the idea, it seems like overengineering to support custom scripts when we already have an activation hook script right there you can choose to run whatever checks you want in and maybe kill the xidlehook process or disable timers with the socket API.

Keep in mind that xidlehook isn't meant for ease of usage, since you're supposed to just start it in some shell script somewhere rather than run it and have it read some config files. There shall be no --not-when <custom thing> because that is not pure :)

@sidequestboy
Copy link
Author

Gotcha. I understand the desire to keep things minimal. (:

FWIW, I think this bash script achieves the desired functionality

#! /usr/bin/env bash

youtube_is_running() {
    # custom stuff here
    return 1
}

pid=
while true; do
    if ! youtube_is_running; then
        if [ -z $pid ]; then
            xidlehook --timer 5 'xscreensaver-command -activate' '' &
            pid=$!
        fi
    elif [ ! -z $pid ]; then
        kill $pid
        pid=
    fi
    sleep 1
done

@jD91mZM2
Copy link
Owner

@Jameh Does something like this work instead? I'm trying to avoid as many spinloops as possible :)

Pretend this script lives as /my/script/path/here.sh

#! /usr/bin/env bash

youtube_is_running() {
    # custom stuff here
    return 1
}

IFS='' read -r -d '' TIMER_COMMAND <<EOF

if youtube_is_running; then
    # YouTube is running, exit xidlehook for now
    respawn_task() {
        # Do a spin loop waiting for YouTube to exit
        while youtube_is_running; do
            sleep 1 # or whatever delay/trigger you want
        done

        # Restart xidlehook
        exec /my/script/path/here.sh
    }

    # Launch task and exit xidlehook
    respawn_task &
    pkill $PPID
fi

EOF

exec xidlehook --timer 5 "$LOCKER_COMMAND" ''

@MarcelRobitaille
Copy link

Though, if you just want to run a bash command you could just do xidlehook --timer 'some-command-here && xscreensaver-command activate'

What if a timer that exits >0 causes all subsequent timers to not run? That would mean we could use this proposed workaround. I don't know if this would be "pure", but this solution or custom --not-when seems cleaner to me than killing and restarting xidlehook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants