"github.com/jezek/xgb/xinerama"
"github.com/jezek/xgb/xproto"
// TODO: Make a separate keysym file and fully populate it.
var attachedScreens
[]xinerama
.ScreenInfo
var xroot xproto
.ScreenInfo
var keymap
[256][]xproto
.Keysym
xConn
, err
:= xgb
.NewConn()
setup
:= xproto
.Setup(xc
)
if setup
== nil ||
len(setup
.Roots
) < 1 {
log
.Fatal("ILLI: Unable to parse received SetupInfo from X11 server.")
if err
:= xinerama
.Init(xc
); err
!= nil {
if r
, err
:= xinerama
.QueryScreens(xc
).Reply(); err
!= nil {
if len(r
.ScreenInfo
) == 0 {
attachedScreens
= []xinerama
.ScreenInfo
{
Width
: setup
.Roots
[0].WidthInPixels
,
Height
: setup
.Roots
[0].HeightInPixels
,
attachedScreens
= r
.ScreenInfo
connInfo
:= xproto
.Setup(xc
)
log
.Fatal("ILLI: Unable to parse X connection information")
if len(connInfo
.Roots
) != 1 {
log
.Fatal("ILLI: Inappropriate number of roots. Did xinerama initialize correctly?")
xroot
= connInfo
.Roots
[0]
// Attempt to register as the window manager
if err
:= TakeWMOwnership(); err
!= nil {
if _
, ok
:= err
.(xproto
.AccessError
); ok
{
log
.Fatal("ILLI: Unable to register as window manager with X server. Perhaps another WM is already running?")
fmt
.Println("ILLI: Successfully registered as WM with X server.")
// -----------------------------------------------------------------------------
m
:= xproto
.GetKeyboardMapping(xc
, loKey
, hiKey
-loKey
+1)
log
.Fatal("Could not load keyboard map")
for i
:= 0; i
< hiKey
-loKey
+1; i
++ {
keymap
[loKey
+i
] = reply
.Keysyms
[i
*int(reply
.KeysymsPerKeycode
) : (i
+1)*int(reply
.KeysymsPerKeycode
)]
modifiers
: xproto
.ModMask1 | xproto
.ModMaskShift
,
modifiers
: xproto
.ModMask1 | xproto
.ModMaskShift
,
for i
, syms
:= range keymap
{
for _
, sym
:= range syms
{
grabs
[c
].codes
= append(grabs
[c
].codes
, xproto
.Keycode(i
))
for _
, grabbed
:= range grabs
{
for _
, code
:= range grabbed
.codes
{
if err
:= xproto
.GrabKeyChecked(
// -----------------------------------------------------------------------------
tree
, err
:= xproto
.QueryTree(xc
, xroot
.Root
).Reply()
//workspaces = make(map[string]*Workspace)
//defaultw := &Workspace{mu: &sync.Mutex{}}
for _
, c
:= range tree
.Children
{
// err := defaultw.Add(c)
fmt
.Println("ILLI: Found a client.")
// if len(attachedScreens) > 0 {
// defaultw.Screen = &attachedScreens[0]
// workspaces["default"] = defaultw
// if err := defaultw.TileWindows(); err != nil {
xevent
, err
:= xc
.WaitForEvent()
switch e
:= xevent
.(type) {
case xproto
.KeyPressEvent
:
if err
:= handleKeyPressEvent(e
); err
!= nil {
func TakeWMOwnership() error
{
return xproto
.ChangeWindowAttributesChecked(
xproto
.EventMaskKeyPress |
xproto
.EventMaskKeyRelease |
xproto
.EventMaskButtonPress |
xproto
.EventMaskButtonRelease |
xproto
.EventMaskStructureNotify |
xproto
.EventMaskSubstructureRedirect
,
func isMappedWindow(windowID xproto
.Window
) bool {
reply
, err
:= xproto
.GetWindowAttributes(xc
, windowID
).Reply()
// It appears that only windows with a `MapState` value of 2 should be 'viewable'.
// - https://github.com/BurntSushi/xgb/blob/master/xproto/xproto.go#L3772
// - https://github.com/BurntSushi/xgb/blob/master/xproto/xproto.go#L10287
if reply
!= nil && reply
.MapState
== 2 {
func handleKeyPressEvent(key xproto
.KeyPressEvent
) error
{
switch keymap
[key
.Detail
][0] {
case xproto
.ModMask1 | xproto
.ModMaskShift
:
// TODO: Where and how do I want to handle exit/restart?
// -------------------------
// We must manually close the X connection since we used
// `defer` when setting it up and os.Exit() short-circuits
case xproto
.ModMask1 | xproto
.ModMaskShift
:
cmd
:= exec
.Command("xterm")
return nil // What do I actually want to return here?