wm/vend/xgbutil/_examples/workarea-struts/main.go

89 lines
2.5 KiB
Go

// Example workarea-struts shows how to find the all of the struts set by
// top-level clients and apply them to each active monitor to get the true
// workarea for each monitor.
//
// For example, consider a monitor with a 1920x1080 resolution and a panel
// on the bottom of the desktop 50 pixels tall. The actual workarea for the
// desktop then, is (0, 0) 1920x1030. (When there is more than one monitor,
// the x and y coordinates will be adjusted too.)
package main
import (
"fmt"
"log"
"github.com/jezek/xgbutil"
"github.com/jezek/xgbutil/ewmh"
"github.com/jezek/xgbutil/xinerama"
"github.com/jezek/xgbutil/xrect"
"github.com/jezek/xgbutil/xwindow"
)
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)
}
}