package xorg /* #cgo pkg-config: xres #include "commands_native.h" #include */ import "C" func ActiveWindowIsXTerm() bool { return C.cthulhu_active_window_is_xterm() != 0 } // Foreground is an immutable X11 client identity and its screen rectangle. // Known with Window == 0 means no foreground client, not missing metadata. type Foreground struct { Known bool Window uint64 PID int // PropertyPID retains _NET_WM_PID for diagnostics. PID uses the X server's // local client identity when available, so Flatpak namespaces agree with AT-SPI. PropertyPID int X, Y, Width, Height int OuterX, OuterY, OuterWidth, OuterHeight int // Frame bounds come from the client's enclosing X11 window, independently // of _NET_FRAME_EXTENTS. Zero dimensions mean no unambiguous frame exists. FrameX, FrameY, FrameWidth, FrameHeight int } // ForegroundReader has no goroutine. Its native event-loop owner opens, reads, // and closes it on that thread; no consumer performs X11 I/O. type ForegroundReader struct { display *C.Display clientPIDs bool pidWindow uint64 propertyPID, clientPID int } func OpenForegroundReader() *ForegroundReader { display := C.XOpenDisplay(nil) if display == nil { return nil } return &ForegroundReader{display: display, clientPIDs: C.cthulhu_xres_client_pids_supported(display) != 0} } func (reader *ForegroundReader) Read() Foreground { if reader == nil { return Foreground{} } value := C.read_foreground(reader.display) window, propertyPID := uint64(value.window), int(value.pid) // The connection's owner also owns this one-client cache. Window departure // (including no foreground) or a changed property discards the old identity. // Resizing and ordinary input never trigger an extra server query. if window != reader.pidWindow || propertyPID != reader.propertyPID { reader.pidWindow, reader.propertyPID, reader.clientPID = window, propertyPID, 0 if window != 0 && reader.clientPIDs { reader.clientPID = int(C.cthulhu_xres_client_pid(reader.display, C.Window(window))) } } pid := propertyPID if reader.clientPID > 0 { pid = reader.clientPID } return Foreground{Known: value.known != 0, Window: window, PID: pid, PropertyPID: propertyPID, X: int(value.x), Y: int(value.y), Width: int(value.width), Height: int(value.height), OuterX: int(value.outerX), OuterY: int(value.outerY), OuterWidth: int(value.outerWidth), OuterHeight: int(value.outerHeight), FrameX: int(value.frameX), FrameY: int(value.frameY), FrameWidth: int(value.frameWidth), FrameHeight: int(value.frameHeight)} } func (reader *ForegroundReader) Close() { if reader != nil { C.XCloseDisplay(reader.display) reader.display = nil } }