Alexander Avery
2 years ago
3 changed files with 174 additions and 0 deletions
@ -0,0 +1,10 @@ |
|||||
|
module gitea.beetbox.io/Alex/pv |
||||
|
|
||||
|
go 1.18 |
||||
|
|
||||
|
require github.com/linuxdeepin/go-x11-client v0.0.0-20221118020450-811d87e63fec |
||||
|
|
||||
|
require ( |
||||
|
github.com/stretchr/testify v1.8.1 // indirect |
||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect |
||||
|
) |
@ -0,0 +1,25 @@ |
|||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= |
||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
||||
|
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= |
||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= |
||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= |
||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= |
||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= |
||||
|
github.com/linuxdeepin/go-x11-client v0.0.0-20221118020450-811d87e63fec h1:CaVGU829QOYwWrKdvC06uMTXkrj4vwyH4UGAn92bdzE= |
||||
|
github.com/linuxdeepin/go-x11-client v0.0.0-20221118020450-811d87e63fec/go.mod h1:KwpmRZ47A/0a2l9V0V6aTlkuNaqy5j1fOqMFJONuIMY= |
||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= |
||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= |
||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= |
||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= |
||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= |
||||
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= |
||||
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= |
||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= |
||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= |
||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= |
||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
@ -0,0 +1,139 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"fmt" |
||||
|
"log" |
||||
|
"math" |
||||
|
"os" |
||||
|
"os/signal" |
||||
|
"syscall" |
||||
|
|
||||
|
"github.com/linuxdeepin/go-x11-client/util/cursor" |
||||
|
"github.com/linuxdeepin/go-x11-client/util/mousebind" |
||||
|
|
||||
|
x "github.com/linuxdeepin/go-x11-client" |
||||
|
) |
||||
|
|
||||
|
// Give names to the events we care about
|
||||
|
const ( |
||||
|
Pressed uint8 = 4 |
||||
|
Released = 5 |
||||
|
) |
||||
|
|
||||
|
type dragger struct { |
||||
|
Done chan bool |
||||
|
events chan x.GenericEvent |
||||
|
ctx context.Context |
||||
|
pointerDown bool |
||||
|
start [2]int16 |
||||
|
end [2]int16 |
||||
|
} |
||||
|
|
||||
|
// NewDragger returns a new reference to a dragger.
|
||||
|
// This dragger can only be used to watch one drag event.
|
||||
|
func NewDragger(events chan x.GenericEvent, ctx context.Context) *dragger { |
||||
|
return &dragger{ |
||||
|
Done: make(chan bool, 1), |
||||
|
events: events, |
||||
|
ctx: ctx, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Watch begins the process of dragger watching for drag events
|
||||
|
func (s *dragger) Watch() { |
||||
|
for { |
||||
|
select { |
||||
|
case generic := <-s.events: |
||||
|
s.handleEvent(generic) |
||||
|
break |
||||
|
case _ = <-s.ctx.Done(): |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (s *dragger) handleEvent(generic x.GenericEvent) { |
||||
|
event, err := x.NewButtonPressEvent(generic) |
||||
|
if err != nil { |
||||
|
log.Fatal(err) |
||||
|
} |
||||
|
|
||||
|
code := generic.GetEventCode() |
||||
|
|
||||
|
if code == Pressed { |
||||
|
s.pointerDown = true |
||||
|
s.start = [2]int16{event.EventX, event.EventY} |
||||
|
} else { |
||||
|
s.end = [2]int16{event.EventX, event.EventY} |
||||
|
if s.pointerDown { |
||||
|
s.pointerDown = false |
||||
|
s.Done <- true |
||||
|
} else { |
||||
|
s.Done <- false |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Distance returns the total distance of the drag event
|
||||
|
func (s dragger) Distance() int { |
||||
|
diffx := int(s.start[0] - s.end[0]) |
||||
|
diffy := int(s.start[1] - s.end[1]) |
||||
|
distance := math.Sqrt(float64((diffx * diffx) + (diffy * diffy))) |
||||
|
return int(distance) |
||||
|
} |
||||
|
|
||||
|
func loadCursor(conn *x.Conn) (x.Cursor, error) { |
||||
|
img, err := cursor.LoadImage("default", "crosshair", 2) |
||||
|
if err != nil { |
||||
|
return x.CursorNone, err |
||||
|
} |
||||
|
|
||||
|
return img.LoadCursor(conn, "") |
||||
|
} |
||||
|
|
||||
|
func main() { |
||||
|
stop := make(chan os.Signal) |
||||
|
signal.Notify(stop, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) |
||||
|
|
||||
|
display, err := x.NewConnDisplay("") |
||||
|
if err != nil { |
||||
|
log.Fatal(err) |
||||
|
} |
||||
|
defer display.Close() |
||||
|
|
||||
|
screen := display.GetDefaultScreen() |
||||
|
|
||||
|
curs, err := loadCursor(display) |
||||
|
if err != nil { |
||||
|
log.Fatal(err) |
||||
|
} |
||||
|
|
||||
|
mask := uint16(x.EventMaskButtonPress | x.EventMaskButtonRelease) |
||||
|
err = mousebind.GrabPointer(display, screen.Root, mask, x.None, curs) |
||||
|
if err != nil { |
||||
|
log.Fatal(err) |
||||
|
} |
||||
|
|
||||
|
defer mousebind.UngrabPointer(display) |
||||
|
|
||||
|
eventChan := display.MakeAndAddEventChan(1) |
||||
|
|
||||
|
ctx, cancel := context.WithCancel(context.Background()) |
||||
|
dm := NewDragger(eventChan, ctx) |
||||
|
go dm.Watch() |
||||
|
|
||||
|
for { |
||||
|
select { |
||||
|
case v := <-dm.Done: |
||||
|
if v { |
||||
|
fmt.Println(dm.Distance()) |
||||
|
os.Exit(0) |
||||
|
} |
||||
|
break |
||||
|
case <-stop: |
||||
|
cancel() |
||||
|
os.Exit(0) |
||||
|
} |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue