Compare commits
No commits in common. "c48264a2205eed44e4dec919046270e9f6297e55" and "dab360de755a53506ea1175b17c84bf41dd61e57" have entirely different histories.
c48264a220
...
dab360de75
@ -1,73 +0,0 @@
|
|||||||
// Example copy shows how to place text data in the CLIPBOARD selection.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
import "io"
|
|
||||||
import "log"
|
|
||||||
import "bytes"
|
|
||||||
import "github.com/jezek/xgbutil"
|
|
||||||
import "github.com/jezek/xgb/xproto"
|
|
||||||
import "git.tebibyte.media/tomo/xgbsel"
|
|
||||||
import "github.com/jezek/xgbutil/xprop"
|
|
||||||
import "github.com/jezek/xgbutil/xevent"
|
|
||||||
import "github.com/jezek/xgbutil/xwindow"
|
|
||||||
|
|
||||||
// data is a very basic implementation of xgbsel.Data that only serves data of
|
|
||||||
// one type.
|
|
||||||
type data struct {
|
|
||||||
buffer io.ReadSeekCloser
|
|
||||||
mime string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *data) Convert (target xgbsel.Target) (io.ReadSeekCloser, bool) {
|
|
||||||
if mime, _ := target.ToMime(); mime == this.mime {
|
|
||||||
return this.buffer, true
|
|
||||||
} else {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *data) Supported () []xgbsel.Target {
|
|
||||||
return xgbsel.MimeToTargets(this.mime)
|
|
||||||
}
|
|
||||||
|
|
||||||
// nopSeekCloser is like io.NopCloser but for an io.ReadSeeker.
|
|
||||||
type nopSeekCloser struct { io.ReadSeeker }
|
|
||||||
func (nopSeekCloser) Close () error { return nil }
|
|
||||||
|
|
||||||
func main () {
|
|
||||||
// get data from user
|
|
||||||
log.Println("enter data, ^D when done: ")
|
|
||||||
buffer, _ := io.ReadAll(os.Stdin)
|
|
||||||
data := &data {
|
|
||||||
buffer: nopSeekCloser {
|
|
||||||
ReadSeeker: bytes.NewReader(buffer),
|
|
||||||
},
|
|
||||||
mime: "text/plain",
|
|
||||||
}
|
|
||||||
|
|
||||||
// establish connection
|
|
||||||
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)
|
|
||||||
|
|
||||||
// obtain claim on CLIPBOARD
|
|
||||||
log.Println("obtaining claim")
|
|
||||||
clipboard, _ := xprop.Atm(X, "CLIPBOARD")
|
|
||||||
claim := xgbsel.NewClaim(window, clipboard, data)
|
|
||||||
|
|
||||||
// listen for events
|
|
||||||
window.Listen(xproto.EventMaskPropertyChange)
|
|
||||||
xevent.SelectionRequestFun(claim.HandleSelectionRequest).Connect(X, window.Id)
|
|
||||||
|
|
||||||
log.Println("running main event loop")
|
|
||||||
xevent.Main(X)
|
|
||||||
}
|
|
@ -11,8 +11,6 @@ import "github.com/jezek/xgbutil/xprop"
|
|||||||
import "github.com/jezek/xgbutil/xevent"
|
import "github.com/jezek/xgbutil/xevent"
|
||||||
import "github.com/jezek/xgbutil/xwindow"
|
import "github.com/jezek/xgbutil/xwindow"
|
||||||
|
|
||||||
// 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 {
|
type requestor struct {
|
||||||
window *xwindow.Window
|
window *xwindow.Window
|
||||||
}
|
}
|
||||||
@ -24,41 +22,23 @@ func (requestor requestor) Window () *xwindow.Window {
|
|||||||
func (requestor requestor) Success (target xgbsel.Target, data io.ReadCloser) {
|
func (requestor requestor) Success (target xgbsel.Target, data io.ReadCloser) {
|
||||||
defer data.Close()
|
defer data.Close()
|
||||||
text, _ := io.ReadAll(data)
|
text, _ := io.ReadAll(data)
|
||||||
log.Println("got clipboard text:")
|
log.Println("Clipboard text:", string(text))
|
||||||
os.Stdout.Write(text)
|
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (requestor requestor) Failure (err error) {
|
func (requestor requestor) Failure (err error) {
|
||||||
if err == nil {
|
log.Fatalln("could not get clipboard:", err)
|
||||||
log.Fatalln("no available clipboard data")
|
|
||||||
} else {
|
|
||||||
log.Fatalln("could not get clipboard:", err)
|
|
||||||
}
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (requestor requestor) Choose (available []xgbsel.Target) (xgbsel.Target, bool) {
|
func (requestor requestor) Choose (from []xgbsel.Target) (xgbsel.Target, bool) {
|
||||||
log.Println("owner supports these targets:", available)
|
for _, target := range from {
|
||||||
|
if target == "TEXT" {
|
||||||
// try to find the closest thing to text/plain by converting each target
|
return target, true
|
||||||
// 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
|
return "", false
|
||||||
if bestConfidence > xgbsel.ConfidenceNone {
|
|
||||||
return bestTarget, true
|
|
||||||
} else {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main () {
|
func main () {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user