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 { events chan x.GenericEvent start [2]int16 end [2]int16 } // Watch begins the process of dragger watching for drag events func (s *dragger) Watch(ctx context.Context) int { c := make(chan int, 1) for { select { case c <- s.watch(): return <-c case _ = <-ctx.Done(): return 0 } } } func (s *dragger) watch() int { for { generic := <-s.events event, err := x.NewButtonPressEvent(generic) if err != nil { log.Fatal(err) } if generic.GetEventCode() == Pressed { s.start = [2]int16{event.EventX, event.EventY} } else { s.end = [2]int16{event.EventX, event.EventY} return s.distance() } } } 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) responseChan := make(chan int, 1) ctx, cancel := context.WithCancel(context.Background()) d := dragger{events: eventChan} for { select { case responseChan <- d.Watch(ctx): fmt.Println(<-responseChan) os.Exit(0) case <-stop: cancel() os.Exit(0) } } }