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

make custom block command run once #89

Closed
endir opened this issue Aug 28, 2017 · 13 comments · Fixed by #684
Closed

make custom block command run once #89

endir opened this issue Aug 28, 2017 · 13 comments · Fixed by #684

Comments

@endir
Copy link

endir commented Aug 28, 2017

Hello! I am trying to make a block to run only once. I do not know if this is an issue or something i do wrong.

I have this block
[[block]]
block = "custom"
interval = 60
command = "cat /tmp/.email"
on_click = 'python ~/.config/i3/mutt.py'

mutt.py:
import filelock
import os
import sys
import time
parentpid = os.getpid()
lock = filelock.FileLock("/tmp/.mutt_runnning_lock")
try:
with lock.acquire(timeout = .1):
pid = os.fork()
os.kill(parentpid,9)
os.system('termite -e "mutt";~/bin/checkMail.sh &')
lock.release()
except:
exit(0)

what the script does is create a a lockfile. if lockfile can not be acquired it exits.

Problem: when i click multiple times on the block it opens many termite with mutt many times.
When I run the script multiple times from the shell it seems to do what it is supposed to: if mutt is open it does not open multiple instances

@svmnotn
Copy link
Contributor

svmnotn commented Aug 28, 2017

In the config file:

[[block]]
block = "custom"
interval = 60
command = "cat /tmp/.email"
on_click = 'python ~/.config/i3/mutt.py'

mutt.py:

import filelock
import os
import sys
import time
parentpid = os.getpid()
lock = filelock.FileLock("/tmp/.mutt_runnning_lock")
try:
with lock.acquire(timeout = .1):
pid = os.fork()
os.kill(parentpid,9)
os.system('termite -e "mutt";~/bin/checkMail.sh &')
lock.release()
except:
exit(0)

Is the problem you are having is that the python script is not working properly when called by the bar?
Is it just the filelock, or if you try writing to a file (or just making one) and checking if it exist, it does the same?

@endir
Copy link
Author

endir commented Aug 29, 2017

Same problem :( somehow it seems that every click it waits till both the parent and the subprocess are finished.

new python script I use is:
#import filelock
import os
import sys
import time

parentpid = os.getpid()

try:
with open('/tmp/aaa','r'):
print('file found')
os.kill(parentpid,9)

except:
with open('/tmp/aaa', 'w') as f:
f.write("hello")
f.flush()
f.close()
pid = os.fork()
os.kill(parentpid,9)
os.system('termite -e "mutt"')
os.remove('/tmp/aaa')

@svmnotn
Copy link
Contributor

svmnotn commented Aug 29, 2017

The code in the bar does indeed wait for the child process to finish executing before it continues.

It uses .output() which by its docs: "Executes the command as a child process, waiting for it to finish and collecting all of its output."

@endir
Copy link
Author

endir commented Aug 30, 2017

Hi! I made some stupid modification of block:
I added a paramater to controll (which is taken from the confing file) how often would a click command executed. what this basically does is: controll if some time has elapsed since last time a command was executed by clicking and if a longer time than specified elapsed it runs again the click command.

Problem it solves: on my laptop sometimes I accidentally scroll instead of clicking with the touchpad. What happens afterwards, is that the click command, is run a lot of times.
Solution: wait a certain amount of time specified by the user before executing the next click command.

Would it be considered to be merged in the custom block?

@svmnotn
Copy link
Contributor

svmnotn commented Aug 30, 2017

@endir currently the click function works on any kind of click, we could make it so that you can specify which kind of click, for example in the speedtest block, I make sure to check that the Left mouse button was pressed. Which means it does not do anything on scrolling.

Something like being able to define:

[[block]]
block = "custom"
on_(left/middle/right)_click = "<command>"

I think that would represent a better change than just not being able to click multiple times

@endir
Copy link
Author

endir commented Aug 30, 2017

Indeed that would be a much better solution!

@diegodorado
Copy link

It would also be nice to have a block that run only once.

A use case for this is to show whether I am currently with NVIDIA or INTEL graphics ... or any other setting that requires to login to change so it is not necessary to update at any interval.

The workarround now is to have a ridiculously big interval... but could be solved with a run_only_once option defaulted to false

@ammgws
Copy link
Collaborator

ammgws commented Apr 29, 2020

What about making it so setting interval to -1 disables the interval?

@ammgws
Copy link
Collaborator

ammgws commented May 10, 2020

@PicoJr Only if you're interested:

A way to have the custom block run only one time as mentioned above. Instead of introducing another boolean, I think being able to do it via the interval would be nice, but haven't looked into whether that's actually possible or not.

@PicoJr
Copy link
Contributor

PicoJr commented May 10, 2020

pub struct CustomConfig {
    /// Update interval in seconds
    #[serde(
        default = "CustomConfig::default_interval",
        deserialize_with = "deserialize_duration"
    )]
    pub interval: Duration,

interval is deserialized as a std::time::Duration

std::time::Duration is built using pub fn new(secs: u64, nanos: u32) -> Duration

Negative durations cannot be represented (u64, u32), it means we cannot rely on this kind of hack ^^'

It feels like we need something a bit broader than a duration:

#[non_exhaustive]
enum Period {
   Interval(Duration),
   Once,
}

However it would mean adding support for this in the core.

We could minimize impact on existing blocks by implementing std::convert::From<Duration> for Period, and change some interfaces to use Into<Period> instead of Duration.

I am afraid I will soon be busy, I may not be available in the near future 😅

@ammgws
Copy link
Collaborator

ammgws commented May 10, 2020

Thanks for looking into it!

@PicoJr
Copy link
Contributor

PicoJr commented May 14, 2020

Hello, it's only a proof of concept: https://github.com/PicoJr/i3status-rust/tree/feat-once

It can be tested with:

status.toml:

theme = "solarized-dark"
icons = "awesome"

[[block]]
block = "custom"
command = "date"
interval = 2

[[block]]
block = "custom"
command = "date"
# no interval provided => updated only once

Sample output:

❯ ./target/debug/i3status-rs status.toml                                                                                                        PicoJr
{"version": 1, "click_events": true}
[[{"background":null,"color":"#002b36","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#002b36","color":"#93a1a1","full_text":" Thu 14 May 2020 12:13:06 PM CEST ","markup":"pango","name":"21f5522a354e4289a597af7658431f2b","separator":false,"separator_block_width":0},{"background":"#002b36","color":"#002B36FF","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#002B36FF","color":"#93A1A1FF","full_text":" Thu 14 May 2020 12:13:06 PM CEST ","markup":"pango","name":"cf9dc55e51f44014a067dc6e3f522056","separator":false,"separator_block_width":0}],
[{"background":null,"color":"#002b36","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#002b36","color":"#93a1a1","full_text":" Thu 14 May 2020 12:13:08 PM CEST ","markup":"pango","name":"21f5522a354e4289a597af7658431f2b","separator":false,"separator_block_width":0},{"background":"#002b36","color":"#002B36FF","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#002B36FF","color":"#93A1A1FF","full_text":" Thu 14 May 2020 12:13:06 PM CEST ","markup":"pango","name":"cf9dc55e51f44014a067dc6e3f522056","separator":false,"separator_block_width":0}],
[{"background":null,"color":"#002b36","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#002b36","color":"#93a1a1","full_text":" Thu 14 May 2020 12:13:10 PM CEST ","markup":"pango","name":"21f5522a354e4289a597af7658431f2b","separator":false,"separator_block_width":0},{"background":"#002b36","color":"#002B36FF","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#002B36FF","color":"#93A1A1FF","full_text":" Thu 14 May 2020 12:13:06 PM CEST ","markup":"pango","name":"cf9dc55e51f44014a067dc6e3f522056","separator":false,"separator_block_width":0}],
[{"background":null,"color":"#002b36","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#002b36","color":"#93a1a1","full_text":" Thu 14 May 2020 12:13:12 PM CEST ","markup":"pango","name":"21f5522a354e4289a597af7658431f2b","separator":false,"separator_block_width":0},{"background":"#002b36","color":"#002B36FF","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#002B36FF","color":"#93A1A1FF","full_text":" Thu 14 May 2020 12:13:06 PM CEST ","markup":"pango","name":"cf9dc55e51f44014a067dc6e3f522056","separator":false,"separator_block_width":0}],

Only the 1st custom block is updated (it shows it was only updated the first time).

It's really WIP (I modified the default interval for custom block), it also panicks with the following status.toml: (nothing to schedule after 1st update...)

theme = "solarized-dark"
icons = "awesome"

[[block]]
block = "custom"
command = "date"

@ammgws
Copy link
Collaborator

ammgws commented May 14, 2020

it also panicks with the following status.toml: (nothing to schedule after 1st update...

This is a problem I found a little while ago that occurs when the config doesn't contain any blocks that use an update scheduler. I didn't have time to look into it properly so I just kludged the affected blocks (focused_window etc) with a dummy scheduled update so that it doesn't crash the bar. By removing the scheduler here and having only the custom block in your example config you've run into that same problem. Hopefully it can be fixed properly sometime.

PicoJr added a commit to PicoJr/i3status-rust that referenced this issue May 14, 2020
PicoJr added a commit to PicoJr/i3status-rust that referenced this issue May 15, 2020
PicoJr added a commit to PicoJr/i3status-rust that referenced this issue May 16, 2020
PicoJr added a commit to PicoJr/i3status-rust that referenced this issue May 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants