75 lines
2.7 KiB
Go
75 lines
2.7 KiB
Go
package xorg
|
|
|
|
/*
|
|
#cgo pkg-config: xres
|
|
#include "commands_native.h"
|
|
#include <X11/XKBlib.h>
|
|
*/
|
|
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
|
|
}
|
|
}
|