89 lines
2.5 KiB
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)
|
||
|
}
|
||
|
}
|