示例#1
0
func main() {
	// Connect to the X server using the DISPLAY environment variable.
	X, err := xgbutil.NewConn()
	if err != nil {
		log.Fatal(err)
	}

	// Get a list of all client ids.
	clientids, err := ewmh.ClientListGet(X)
	if err != nil {
		log.Fatal(err)
	}

	// Iterate through each client, find its name and find its size.
	for _, clientid := range clientids {
		name, err := ewmh.WmNameGet(X, clientid)

		// If there was a problem getting _NET_WM_NAME or if its empty,
		// try the old-school version.
		if err != nil || len(name) == 0 {
			name, err = icccm.WmNameGet(X, clientid)

			// If we still can't find anything, give up.
			if err != nil || len(name) == 0 {
				name = "N/A"
			}
		}

		// Now find the geometry, including decorations, of the client window.
		// Note that DecorGeometry actually traverses the window tree by
		// issuing QueryTree requests until a top-level window (i.e., its
		// parent is the root window) is found. The geometry of *that* window
		// is then returned.
		dgeom, err := xwindow.New(X, clientid).DecorGeometry()
		if err != nil {
			log.Printf("Could not get geometry for %s (0x%X) because: %s",
				name, clientid, err)
			continue
		}

		fmt.Printf("%s (0x%x)\n", name, clientid)
		fmt.Printf("\tGeometry: %s\n", dgeom)
	}
}
示例#2
0
func main() {
	X, err := xgbutil.NewConn()
	if err != nil {
		log.Fatal(err)
	}

	// Start generating other source events.
	otherChan := otherSource()

	// Start generating X events (by sending client messages to root window).
	go xSource(X)

	// Listen to those X events.
	xwindow.New(X, X.RootWin()).Listen(xproto.EventMaskSubstructureNotify)

	// Respond to those X events.
	xevent.ClientMessageFun(
		func(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) {
			atmName, err := xprop.AtomName(X, ev.Type)
			if err != nil {
				log.Fatal(err)
			}
			fmt.Printf("ClientMessage: %d. %s\n", ev.Data.Data32[0], atmName)
		}).Connect(X, X.RootWin())

	// Instead of using the usual xevent.Main, we use xevent.MainPing.
	// It runs the main event loop inside a goroutine and returns ping
	// channels, which are sent benign values right before an event is
	// dequeued and right after that event has finished running all callbacks
	// associated with it, respectively.
	pingBefore, pingAfter, pingQuit := xevent.MainPing(X)
	for {
		select {
		case <-pingBefore:
			// Wait for the event to finish processing.
			<-pingAfter
		case otherVal := <-otherChan:
			fmt.Printf("Processing other event: %d\n", otherVal)
		case <-pingQuit:
			fmt.Printf("xevent loop has quit")
			return
		}
	}
}
示例#3
0
func main() {
	// Connect to the X server using the DISPLAY environment variable.
	X, err := xgbutil.NewConn()
	if err != nil {
		log.Fatal(err)
	}

	// Wrap the root window in a nice Window type.
	root := xwindow.New(X, X.RootWin())

	// Get the geometry of the root window.
	rgeom, err := root.Geometry()
	if err != nil {
		log.Fatal(err)
	}

	// Get the rectangles for each of the active physical heads.
	// These are returned sorted in order from left to right and then top
	// to bottom.
	// But first check if Xinerama is enabled. If not, use root geometry.
	var heads xinerama.Heads
	if X.ExtInitialized("XINERAMA") {
		heads, err = xinerama.PhysicalHeads(X)
		if err != nil {
			log.Fatal(err)
		}
	} else {
		heads = xinerama.Heads{rgeom}
	}

	// Fetch the list of top-level client window ids currently managed
	// by the running window manager.
	clients, err := ewmh.ClientListGet(X)
	if err != nil {
		log.Fatal(err)
	}

	// Output the head geometry before modifying them.
	fmt.Println("Workarea for each head:")
	for i, head := range heads {
		fmt.Printf("\tHead #%d: %s\n", i+1, head)
	}

	// For each client, check to see if it has struts, and if so, apply
	// them to our list of head rectangles.
	for _, clientid := range clients {
		strut, err := ewmh.WmStrutPartialGet(X, clientid)
		if err != nil { // no struts for this client
			continue
		}

		// Apply the struts to our heads.
		// This modifies 'heads' in place.
		xrect.ApplyStrut(heads, uint(rgeom.Width()), uint(rgeom.Height()),
			strut.Left, strut.Right, strut.Top, strut.Bottom,
			strut.LeftStartY, strut.LeftEndY,
			strut.RightStartY, strut.RightEndY,
			strut.TopStartX, strut.TopEndX,
			strut.BottomStartX, strut.BottomEndX)
	}

	// Now output the head geometry again after modification.
	fmt.Println("Workarea for each head after applying struts:")
	for i, head := range heads {
		fmt.Printf("\tHead #%d: %s\n", i+1, head)
	}
}