elkowar / eww

ElKowars wacky widgets
https://elkowar.github.io/eww
MIT License
9.14k stars 379 forks source link

[BUG] Multithread poll not supported? #1178

Open MartyMcFlyInTheSky opened 2 weeks ago

MartyMcFlyInTheSky commented 2 weeks ago

Checklist before submitting an issue

Description of the bug

Have a look at the excerpt from my yuck configuration below.

I set out to create a simple wifi connection menu where I list all the wifi networks and upon click on the button "Connect" it will connect to the selected network. Everything works fine except that I also wanted to integrate something like a spinner icon. For that I set up a polling variable that executes a certain python script in intervals of 100ms, whereas the python script will stdout a progression of the spinner symbol in accordance to system time (so it should look reasonably smooth).

However at the same time the yuck script will make another call to a longer running script (nw_connect.py in the below excerpt). It seems to me that as soon as this script is running, the spinner will just halt and be stuck on the last symbol. However I need both scripts to run in parallel. Is there a way to coerce eww in detaching those scripts on multiple threads?

tl;dr: can't poll variable and execute blocking script at the same time

Reproducing the issue

(defvar var_connecting false)
(defpoll var_conn_spinner
    :interval '50ms'
    :initial 'Connect'
    :run-while var_loading

    `python common/spin.py`)

(defwidget widg_networks []
    (box :orientation "v"
        :class "wifi2"
        (box :orientation 'v'
            :visible { !var_loading_error }
            (label :text "hello")
            (for network in jvar_networks
                (button :class { network["bssid"] == jvar_selection["bssid"] ? 'wifi-selected' : 'network_buttons' }
                        :onclick "${EWW_CMD} update jvar_selection='${ network }'"
                        '${ network["ssid"] } - ${ network["freq"] } -
                        ${ network["in-use"] == "*" ? `y` : `n` } - 
                        ${ network["connecting"] == "y" ? var_conn_spinner :
                            network["connecting"] == "e" ? "!!!" : "" }
                        '
                    )))
        (label :text "Loading error"
            :visible { var_loading_error })
        (box :orientation 'h'
            (button :active { !var_connecting }
                    :class "wifibuttons"
                    :onclick "python win_networks/nw_connect.py '${ jvar_selection }' '${ jvar_networks }'"
                    { var_connecting ? var_conn_spinner : 'Connect' })
            (button :active { !var_loading }
                    :class "spinner"
                    :onclick "python win_networks/update_nw_list.py"
                    { var_loading ? var_load_spinner : 'R' })
            (button :active true
                    :class "wifibuttons"
                    :onclick "${EWW_CMD} close win_networks"
                    "Close")
        )
    )
)

Expected behaviour

Poll variable update (common/spin.py) happens in 100ms intervals while win_networks/nw_connect.py is executed.

Additional context

No response

fabolous005 commented 2 weeks ago

As mentioned in some issues before, but yeah hard to find, setting flush=True in the python print statement will probably resolve your issue.

MartyMcFlyInTheSky commented 2 weeks ago

I do have the sys.stdout.flush() in my python script. That should not be the issue..