mirror of
https://codeberg.org/scip/swayipc.git
synced 2025-12-16 20:20:56 +01:00
add descratcher example
This commit is contained in:
@@ -66,7 +66,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Also take a look into the **_examples** folder for more examples.
|
Also take a look into the **_examples** folder for more examples. For
|
||||||
|
a more comprehensive and practical example look at the
|
||||||
|
`_examples/descratcher` program which you can use to selectively
|
||||||
|
retrieve a window from the scratchpad.
|
||||||
|
|
||||||
You may take a look at the [tool swaycycle](https://github.com/tlinden/swaycycle)
|
You may take a look at the [tool swaycycle](https://github.com/tlinden/swaycycle)
|
||||||
which is using this module.
|
which is using this module.
|
||||||
|
|||||||
5
_examples/descratch/descratcher-rofi.sh
Executable file
5
_examples/descratch/descratcher-rofi.sh
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
descratch \
|
||||||
|
| rofi -matching fuzzy -dmenu -p "Select window from scratchpad to show" \
|
||||||
|
| cut -d' ' -f1 | xargs -I{} --no-run-if-empty "descratch" {}
|
||||||
106
_examples/descratch/main.go
Normal file
106
_examples/descratch/main.go
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is a more practical example. With sway you can move windows to
|
||||||
|
a "scratchpad", i.e. like iconify it. There may be an official way
|
||||||
|
to get back such windows, but I didn't find a good one. There's the
|
||||||
|
"scratchpad show" command, but it doesn't allow you to select a
|
||||||
|
window, it just shows the next one (and it keeps it in the floating
|
||||||
|
state).
|
||||||
|
|
||||||
|
So, this example program lists all windows currently garaged on the
|
||||||
|
scratchpad. When called with a windows id, it gets back the window
|
||||||
|
to the current workspace and gives it focus - thus descratching it.
|
||||||
|
|
||||||
|
To add comfort to the process I added a small script which you can
|
||||||
|
use as a ui to it. It uses rofi which makes a handy ui. To use it,
|
||||||
|
compile descratch with "go build", copy the descratch binary to
|
||||||
|
some location within your $PATH and run the script.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/alecthomas/repr"
|
||||||
|
"github.com/tlinden/swayipc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// we need a session to sway via IPC
|
||||||
|
ipc := swayipc.NewSwayIPC()
|
||||||
|
|
||||||
|
err := ipc.Connect()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer ipc.Close()
|
||||||
|
|
||||||
|
// first, retrieve the whole sway root node
|
||||||
|
root, err := ipc.GetTree()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the hidden scratchpad workspace
|
||||||
|
scratch := getScratch(root)
|
||||||
|
|
||||||
|
if len(os.Args) > 1 {
|
||||||
|
// called with an arg, consider it to be a container id
|
||||||
|
id, err := strconv.Atoi(os.Args[1])
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to convert arg %s to integer: %w", os.Args[1], err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// switch to it
|
||||||
|
retrieveWindow(ipc, scratch, id)
|
||||||
|
} else {
|
||||||
|
// no args, just list scratched windows
|
||||||
|
listScratchedContainer(scratch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func retrieveWindow(ipc *swayipc.SwayIPC, scratch *swayipc.Node, id int) {
|
||||||
|
// make sure the id exists
|
||||||
|
var exists bool
|
||||||
|
for _, con := range scratch.FloatingNodes {
|
||||||
|
if con.Id == id {
|
||||||
|
exists = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
log.Fatalf("no window with id %d exists on the scratchpad", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// scratched windows are floating, so we move it to current
|
||||||
|
// workspace, disable the floating state and switch focus to it
|
||||||
|
responses, err := ipc.RunContainerCommand(id, "move workspace current, floating toggle, focus")
|
||||||
|
if err != nil {
|
||||||
|
repr.Println(responses)
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func listScratchedContainer(scratch *swayipc.Node) {
|
||||||
|
// list the windows
|
||||||
|
for _, con := range scratch.FloatingNodes {
|
||||||
|
fmt.Printf("%d %s\n", con.Id, con.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getScratch(root *swayipc.Node) *swayipc.Node {
|
||||||
|
// the root node only has output nodes, we iterate over them and
|
||||||
|
// look for the internal one named__i3. This in turn only has one
|
||||||
|
// workspace, the scratchpad workspace, which we return.
|
||||||
|
for _, output := range root.Nodes {
|
||||||
|
if output.Name == "__i3" {
|
||||||
|
return output.Nodes[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user