Repository: ultrabug/py3status

Issue:
[Scratchpad] Buggy in sway
**Describe the bug**

Scratchpad behavior running in sway is buggy.

**Your py3status version**

py3status version 3.36 (python 3.9.2) on sway/Arch.

**To Reproduce**

Weird behavior depending on the formatting string used in config.

1.  There are 2 windows in the scratchpad...qutebrowser and firefox.  I found this command to list them:

```
swaymsg -t get_tree |   jq -r 'recurse(.nodes[]?) | select(.name == "__i3_scratch").floating_nodes[].app_id, select(.name == "__i3_scratch").floating_nodes[].window_properties.title' | grep -v null
```
Result:
```
org.qutebrowser.qutebrowser
firefox
```
2. Configure module like this '....'
```
scratchpad {
	color = '#A54242'
	format = '[\?not_zero ⌫ [\?color=scratchpad {scratchpad}]]'
	on_click 1 = 'scratchpad show'
}
```
No scratchpad indicator.

Changing the format line to the default:

```
scratchpad {
	color = '#A54242'
	#format = '[\?if=not_zero ⌫ [\?color=scratchpad {scratchpad}]]'
	on_click 1 = 'scratchpad show'
}
```
Scratchpad indicator present, color is correct; count is 0 (zero)

The ```on_click 1``` command works as expected.

**Additional context**

No special flags for starting py3status:

```
status_command py3status
```




Discussion:
>Changing the format line to the default:
>`# format = '[\?if=not_zero ⌫ [\?color=scratchpad {scratchpad}]]'`

Invalid format `if=not_zero`. The examples you gave here looks switched up too.

See if it's same with this (untested) format.
```
order += "scratchpad test"
scratchpad test {
	format = '\[{ipc}\] [\?color=scratchpad {scratchpad}] / '
    format += '\[if\] [\?if=scratchpad ⌫ [\?color=scratchpad {scratchpad}]] / '
    format += '\[nz\] [\?not_zero ⌫ [\?color=scratchpad {scratchpad}]]'

    thresholds = [(0, '#d3d3d3'), (1, '#a54242')]
    on_click 1 = 'scratchpad show'
}
```
> Invalid format ```if=not_zero```

Yeah, my mistake.  I was trying things as I was doing the report.  The format line is as it it in the docs.

> See if it's same with this (untested) format.

This is what is on the bar, regardless of anything actually being in the scratchpad:

![20210412_16h24m38s_grim](https://user-images.githubusercontent.com/42914546/114457921-961b8c00-9bac-11eb-9e63-4c638a888631.png)

```on_click 1``` works if something is in the scratchpad.
It looks like there is nothing wrong with `if` and `nz` because it's zero. You're auto using `i3ipc` though so `sway-msg` have nothing to do with. If you want, you can try swaymsg too by adding hidden config `ipc` to scratchpad config.
```
order += "scratchpad i3ipc"
scratchpad i3ipc {
	format = '\[{ipc}\] [\?color=scratchpad {scratchpad}]'

    ipc = 'i3ipc'
    thresholds = [(0, '#d3d3d3'), (1, 'pink')]
    on_click 1 = 'scratchpad show'
}

order += "scratchpad swaymsg"
scratchpad swaymsg {
	format = '\[{ipc}\] [\?color=scratchpad {scratchpad}]'

    ipc = 'swaymsg'
    thresholds = [(0, '#d3d3d3'), (1, 'lightblue')]
    on_click 1 = 'scratchpad show'
}
```

The `scratchpad` number is no more than just `len(i3.get_tree().scratchpad().leaves())`. 
https://github.com/ultrabug/py3status/blob/cd549649686f2454d463d0bad9f664c8be0a7ba5/py3status/modules/scratchpad.py#L97-L100

It looks like i3ipc is just giving you `0`. I think it may be because you may be on wayland. We might need to fix `scratchpad` to support wayland too. IIRC `window_properties` stuff above is for x11.

- Check if i3ipc is latest (2.21?).
- Open terminal, `python3` and try `i3ipc` scatchpad-related inputs. See if it gave you `0` too.
- Find what you need to make this work.
@lasers - you are the `$BEING`!  :)

`scratchpad i3ipc` really did nothing, other than remove the ```if``` and ```nz``` in your `scratchpad test`; same behavior.

`scratchpad swaymsg` got close -  (again, firefox and qutebrowser in the pad):

![20210412_22h12m31s_grim](https://user-images.githubusercontent.com/42914546/114486609-35a44300-9bdc-11eb-8485-98a33b12d15d.png)

So, on a lark I added the `ipc = 'swaymsg'` directive to my original config, and added a couple of terminals for good measure:

```
scratchpad {
	color = '#A54242'
	ipc = 'swaymsg'
        format = '[\?not_zero ⌫ [\?color=scratchpad {scratchpad}]]'
	on_click 1 = 'scratchpad show'
}
```

Bingo!!!

![20210412_22h22m00s_grim](https://user-images.githubusercontent.com/42914546/114487391-849ea800-9bdd-11eb-8c36-02e08605b9cc.png)

Got to love those hidden configs!

Thanks again!
>scratchpad swaymsg got close - (again, firefox and qutebrowser in the pad):

To clarify this, was there anything off between both modules?

With `swaymsg`, that module get updated every `cache_timeout`.
With `i3ipc`, that module get updated instantly on any scratchpad changes.

If it's showing wrong for you somewhere because you're on wayland, then I'd want to try and fix it. 
> was there anything off between both modules

I'm not sure what you mean...if you're asking if either of those hide the output (with nothing in the pad), then no.

`i3ipc` does not give a count beyond 0.

`swaymsg` updates the count IAW `cache_timeout` like you said.

My updated config also updates IAW `cache_timeout`, and no module output on the bar with the pad empty.

>i3ipc does not give a count beyond 0.

Then it's a bug with using `scratchpad` on sway + i3ipc. Leave this open until it gets solved, mate. :)
> Leave this open until it gets solved

Done.
I never used Sway, so we'll have to hope for a Sway user to propose a fix. @mlmatlock would you like to give it a shot?
@ultrabug, Sorry, but I'm one of *those types* that just can't (no matter how hard I try), wrap my head around any type of coding...similar to having the same blank stare at a German citizen talking to me in German, even after 3.5 years stationed there.  
np @mlmatlock ahah :)

so I'm unsure what to do here tbh, nothing much I can do for now

Resolving patch:
diff --git a/py3status/modules/scratchpad.py b/py3status/modules/scratchpad.py
--- a/py3status/modules/scratchpad.py
+++ b/py3status/modules/scratchpad.py
@@ -94,7 +94,13 @@ def start(self):
         i3.main()
 
     def update(self, i3, event=None):
-        leaves = i3.get_tree().scratchpad().leaves()
+        scratchpad = i3.get_tree().scratchpad()
+        if not scratchpad:
+            return
+
+        # Workaround for I3ipc 2.2.1 not finding leaves() in sway. Fixing: #2038
+        leaves = getattr(scratchpad, "floating_nodes", [])
+
         temporary = {
             "ipc": self.parent.ipc,
             "scratchpad": len(leaves),


Test patch: