96 lines
2.6 KiB
Go
96 lines
2.6 KiB
Go
// Example paste shows how to read text data from the CLIPBOARD selection.
|
|
package main
|
|
|
|
import "os"
|
|
import "io"
|
|
import "log"
|
|
import "github.com/jezek/xgbutil"
|
|
import "github.com/jezek/xgb/xproto"
|
|
import "github.com/jezek/xgbutil/xprop"
|
|
import "github.com/jezek/xgbutil/xevent"
|
|
import "github.com/jezek/xgbutil/xwindow"
|
|
import "git.tebibyte.media/tomo/xgbsel/v2"
|
|
|
|
// requestor implements xgbsel.Requestor. It asks for text and outputs it to
|
|
// os.Stdout, and any logs to the default logging output (os.Stderr).
|
|
type requestor struct {
|
|
window *xwindow.Window
|
|
}
|
|
|
|
func (requestor requestor) Window () *xwindow.Window {
|
|
return requestor.window
|
|
}
|
|
|
|
func (requestor requestor) Success (target xgbsel.Target, data io.ReadCloser) {
|
|
defer data.Close()
|
|
text, _ := io.ReadAll(data)
|
|
log.Println("got clipboard text:")
|
|
os.Stdout.Write(text)
|
|
os.Exit(0)
|
|
}
|
|
|
|
func (requestor requestor) Failure (err error) {
|
|
if err == nil {
|
|
log.Fatalln("no available clipboard data")
|
|
} else {
|
|
log.Fatalln("could not get clipboard:", err)
|
|
}
|
|
os.Exit(1)
|
|
}
|
|
|
|
func (requestor requestor) Choose (available []xgbsel.Target) (xgbsel.Target, bool) {
|
|
log.Println("owner supports these targets:", available)
|
|
|
|
// try to find the closest thing to text/plain by converting each target
|
|
// to a MIME type and comparing confidence values
|
|
var bestTarget xgbsel.Target
|
|
var bestConfidence xgbsel.Confidence
|
|
for _, target := range available {
|
|
mime, confidence := target.ToMime()
|
|
if mime == "text/plain" && confidence > bestConfidence {
|
|
bestConfidence = confidence
|
|
bestTarget = target
|
|
}
|
|
}
|
|
|
|
// if we have any confidence at all, return the result we got
|
|
if bestConfidence > xgbsel.ConfidenceNone {
|
|
return bestTarget, true
|
|
} else {
|
|
return "", false
|
|
}
|
|
}
|
|
|
|
func main () {
|
|
X, err := xgbutil.NewConn()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// create window
|
|
window, err := xwindow.Generate(X)
|
|
if err != nil {
|
|
log.Fatalln("could not generate a new window X id:", err)
|
|
}
|
|
window.Create(X.RootWin(), 0, 0, 500, 500, xproto.CwBackPixel, 0xffffffff)
|
|
|
|
// get the atom for the clipboard, and the name of the property we want
|
|
// to recieve the selection contents on (which can be anything)
|
|
log.Println("creating request")
|
|
clipboard, _ := xprop.Atm(X, "CLIPBOARD")
|
|
property, _ := xprop.Atm(X, "DESTINATION")
|
|
request, _ := xgbsel.NewRequest (
|
|
requestor { window: window },
|
|
clipboard,
|
|
property,
|
|
xproto.TimeCurrentTime)
|
|
|
|
// listen for events
|
|
window.Listen(xproto.EventMaskPropertyChange)
|
|
xevent.PropertyNotifyFun(request.HandlePropertyNotify).Connect(X, window.Id)
|
|
xevent.SelectionNotifyFun(request.HandleSelectionNotify).Connect(X, window.Id)
|
|
|
|
log.Println("running main event loop")
|
|
xevent.Main(X)
|
|
}
|