Package xwindow

import "github.com/BurntSushi/xgbutil/xwindow"
Overview
Index

Overview ▾

Package xwindow defines a window type that provides easy access to common window operations while hiding many of the more obscure X parameters. Examples of such window operations include, but are not limited to, creating a window, mapping a window, moving/resizing a window and getting the geometry of a top-level client window including the window manager's decorations.

New and Generate functions are provided as constructors. New should be used when you already have a window id, and it cannot fail. Generate should be used when you need to allocate a new window identifier. Since allocating a new window identifier can fail, an error could be returned.

Note that methods starting with 'WM' should only be used with a window manager running that supports the EWMH specification. You should otherwise try to use the corresponding methods without the 'WM' prefix.

A quick example

To create a window with a blue background that is 500 pixels wide and 200 pixels tall and map the window, use something like:

win, err := xwindow.Generate(X)
if err != nil {
	log.Fatal(err)
}
win.Create(X.RootWin(), 0, 0, 500, 200, xproto.CwBackPixel, 0x0000ff)
win.Map()

You may also want to use CreateChecked instead of Create if you want to see if there was an error when creating a window.

More examples

The xwindow package is used in many of the examples in the examples directory of the xgbutil package. Of particular interest is window-name-sizes, which prints the name and size of each top-level client window. (The geometry of the window is found using DecorGeometry.)

Index ▾

func RawGeometry(xu *xgbutil.XUtil, win xproto.Drawable) (xrect.Rect, error)
func RootGeometry(xu *xgbutil.XUtil) xrect.Rect
type Window
    func Create(xu *xgbutil.XUtil, parent xproto.Window) (*Window, error)
    func Generate(xu *xgbutil.XUtil) (*Window, error)
    func Must(win *Window, err error) *Window
    func New(xu *xgbutil.XUtil, win xproto.Window) *Window
    func (w *Window) Change(valueMask int, valueList ...uint32)
    func (w *Window) Clear(x, y, width, height int)
    func (w *Window) ClearAll()
    func (win *Window) Configure(flags, x, y, w, h int, sibling xproto.Window, stackMode byte)
    func (w *Window) Create(parent xproto.Window, x, y, width, height, valueMask int, valueList ...uint32)
    func (w *Window) CreateChecked(parent xproto.Window, x, y, width, height, valueMask int, valueList ...uint32) error
    func (w *Window) DecorGeometry() (xrect.Rect, error)
    func (w *Window) Destroy()
    func (w *Window) Detach()
    func (w *Window) Focus()
    func (w *Window) FocusParent(tstamp xproto.Timestamp)
    func (w *Window) Geometry() (xrect.Rect, error)
    func (w *Window) Kill()
    func (w *Window) Listen(evMasks ...int) error
    func (w *Window) MROpt(flags, x, y, width, height int)
    func (w *Window) Map()
    func (w *Window) Move(x, y int)
    func (w *Window) MoveResize(x, y, width, height int)
    func (w *Window) Parent() (*Window, error)
    func (w *Window) Resize(width, height int)
    func (w *Window) Stack(mode byte)
    func (w *Window) StackSibling(sibling xproto.Window, mode byte)
    func (w *Window) Unmap()
    func (w *Window) WMGracefulClose(cb func(w *Window))
    func (w *Window) WMMove(x, y int) error
    func (w *Window) WMMoveResize(x, y, width, height int) error
    func (w *Window) WMResize(width, height int) error
    func (w *Window) WMTakeFocus(cb func(w *Window, tstamp xproto.Timestamp))

Package files

doc.go ewmh.go icccm.go xwindow.go

func RawGeometry

func RawGeometry(xu *xgbutil.XUtil, win xproto.Drawable) (xrect.Rect, error)

RawGeometry isn't smart. It just queries the window given for geometry.

func RootGeometry

func RootGeometry(xu *xgbutil.XUtil) xrect.Rect

RootGeometry gets the geometry of the root window. It will panic on failure.

type Window

type Window struct {
    X         *xgbutil.XUtil
    Id        xproto.Window
    Geom      xrect.Rect
    Destroyed bool
}

Window represents an X window. It contains an XUtilValue to simplfy the parameter lists for methods declared on the Window type. Geom is updated whenever Geometry is called, or when Move, Resize or MoveResize are called.

func Create

func Create(xu *xgbutil.XUtil, parent xproto.Window) (*Window, error)

Create is a convenience constructor that will generate a new window id (with the Generate constructor) and make a bare-bones call to CreateChecked (with geometry (0, 0) 1x1). An error can be generated from Generate or CreateChecked.

func Generate

func Generate(xu *xgbutil.XUtil) (*Window, error)

Generate is just like New, but generates a new X resource id for you. Geom is initialized to (0, 0) 1x1. It is possible for id generation to return an error, in which case, an error is returned here.

func Must

func Must(win *Window, err error) *Window

Must panics if err is non-nil or if win is nil. Otherwise, win is returned.

func New

func New(xu *xgbutil.XUtil, win xproto.Window) *Window

New creates a new window value from a window id and an XUtil type. Geom is initialized to zero values. Use Window.Geometry to load it. Note that the geometry is the size of this particular window and nothing else. If you want the geometry of a client window including decorations, please use Window.DecorGeometry.

func (*Window) Change

func (w *Window) Change(valueMask int, valueList ...uint32)

Change issues a ChangeWindowAttributes request with the provided mask and value list. Please see Window.Create for an example on how to use the mask and value list.

func (*Window) Clear

func (w *Window) Clear(x, y, width, height int)

Clear paints the region of the window specified with the corresponding background pixmap. If the window doesn't have a background pixmap, this has no effect. If width/height is 0, then it is set to the width/height of the background pixmap minus x/y.

func (*Window) ClearAll

func (w *Window) ClearAll()

ClearAll is the same as Clear, but does it for the entire background pixmap.

func (*Window) Configure

func (win *Window) Configure(flags, x, y, w, h int,
    sibling xproto.Window, stackMode byte)

Configure issues a raw Configure request with the parameters given and updates the geometry of the window. This should probably only be used when passing along ConfigureNotify events (from the perspective of the window manager). In other cases, one should opt for [WM][Move][Resize] or Stack[Sibling].

func (*Window) Create

func (w *Window) Create(parent xproto.Window, x, y, width, height,
    valueMask int, valueList ...uint32)

Create issues a CreateWindow request for Window. Its purpose is to omit several boiler-plate parameters to CreateWindow and expose the commonly useful ones. The value mask describes which values are present in valueList. Value masks can be found in xgb/xproto with the prefix 'Cw'. The value list must contain values in the same order as the constants are defined in xgb/xproto.

For example, the following creates a window positioned at (20, 50) with width 500 and height 700 with a background color of white.

w, err := xwindow.Generate(X)
if err != nil {
	log.Fatalf("Could not generate a new resource identifier: %s", err)
}
w.Create(X.RootWin(), 20, 50, 500, 700,
	xproto.CwBackPixel, 0xffffff)

func (*Window) CreateChecked

func (w *Window) CreateChecked(parent xproto.Window, x, y, width, height,
    valueMask int, valueList ...uint32) error

CreateChecked issues a CreateWindow checked request for Window. A checked request is a synchronous request. Meaning that if the request fails, you can get the error returned to you. However, it also forced your program to block for a round trip to the X server, so it is slower. See the docs for Create for more info.

func (*Window) DecorGeometry

func (w *Window) DecorGeometry() (xrect.Rect, error)

DecorGeometry retrieves the client's width and height including decorations. This can be tricky. In a non-parenting window manager, the width/height of a client can be found by inspecting the client directly. In a reparenting window manager like Openbox, the parent of the client reflects the true width/height. Still yet, in KWin, it's the parent of the parent of the client that reflects the true width/height. The idea then is to traverse up the tree until we hit the root window. Therefore, we're at a top-level window which should accurately reflect the width/height.

func (*Window) Destroy

func (w *Window) Destroy()

Destroy is a simple alias to destroy a window. You should use this when you no longer intend to use this window. (It will free the X resource identifier for use in other places.)

func (*Window) Detach

func (w *Window) Detach()

Detach will detach this window's event handlers from all xevent, keybind and mousebind callbacks.

func (*Window) Focus

func (w *Window) Focus()

Focus tries to issue a SetInputFocus to get the focus. If you're trying to change the top-level active window, please use ewmh.ActiveWindowReq instead.

func (*Window) FocusParent

func (w *Window) FocusParent(tstamp xproto.Timestamp)

FocusParent is just like Focus, except it sets the "revert-to" mode to Parent. This should be used when setting focus to a sub-window.

func (*Window) Geometry

func (w *Window) Geometry() (xrect.Rect, error)

Geometry retrieves an up-to-date version of the this window's geometry. It also loads the geometry into the Geom member of Window.

func (*Window) Kill

func (w *Window) Kill()

Kill forcefully destroys a client. It is almost never what you want, and if you do it to one your clients, you'll lose your connection. (This is typically used in a special client like `xkill` or in a window manager.)

func (*Window) Listen

func (w *Window) Listen(evMasks ...int) error

Listen will tell X to report events corresponding to the event masks provided for the given window. If a call to Listen is omitted, you will not receive the events you desire. Event masks are constants declare in the xgb/xproto package starting with the EventMask prefix.

func (*Window) MROpt

func (w *Window) MROpt(flags, x, y, width, height int)

MROpt is like MoveResize, but exposes the X value mask so that any combination of x/y/width/height can be set. It's a strictly convenience function. (i.e., when you need to set 'y' and 'height' but not 'x' or 'width'.)

func (*Window) Map

func (w *Window) Map()

Map is a simple alias to map the window.

func (*Window) Move

func (w *Window) Move(x, y int)

Move issues a ConfigureRequest for this window with the provided x and y positions. If you're trying to move a top-level window in a window manager that supports EWMH, please use WMMove instead.

func (*Window) MoveResize

func (w *Window) MoveResize(x, y, width, height int)

MoveResize issues a ConfigureRequest for this window with the provided x, y, width and height. Note that if width or height is 0, X will stomp all over you. Really hard. Don't do it. If you're trying to move/resize a top-level window in a window manager that supports EWMH, please use WMMoveResize instead.

func (*Window) Parent

func (w *Window) Parent() (*Window, error)

Parent queries the QueryTree and finds the parent window.

func (*Window) Resize

func (w *Window) Resize(width, height int)

Resize issues a ConfigureRequest for this window with the provided width and height. Note that if width or height is 0, X will stomp all over you. Really hard. Don't do it. If you're trying to resize a top-level window in a window manager that supports EWMH, please use WMResize instead.

func (*Window) Stack

func (w *Window) Stack(mode byte)

Stack issues a configure request to change the stack mode of Window. If you're using a window manager that supports EWMH, you may want to try and use ewmh.RestackWindow instead. Although this should still work. 'mode' values can be found as constants in xgb/xproto with the prefix StackMode. A value of xproto.StackModeAbove will put the window to the top of the stack, while a value of xproto.StackMoveBelow will put the window to the bottom of the stack. Remember that stacking is at the discretion of the window manager, and therefore may not always work as one would expect.

func (*Window) StackSibling

func (w *Window) StackSibling(sibling xproto.Window, mode byte)

StackSibling issues a configure request to change the sibling and stack mode of Window. If you're using a window manager that supports EWMH, you may want to try and use ewmh.RestackWindowExtra instead. Although this should still work. 'mode' values can be found as constants in xgb/xproto with the prefix StackMode. 'sibling' refers to the sibling window in the stacking order through which 'mode' is interpreted. Note that 'sibling' should be taken literally. A window can only be stacked with respect to a *sibling* in the window tree. This means that a client window that has been wrapped in decorations cannot be stacked with respect to another client window. (This is why you should use ewmh.RestackWindowExtra instead.)

func (*Window) Unmap

func (w *Window) Unmap()

Unmap is a simple alias to unmap the window.

func (*Window) WMGracefulClose

func (w *Window) WMGracefulClose(cb func(w *Window))

WMGracefulClose will do all the necessary setup to implement the WM_DELETE_WINDOW protocol. This will prevent well-behaving window managers from killing your client whenever one of your windows is closed. (Killing a client is bad because it will destroy your X connection and any other clients you have open.) You must provide a callback function that is called when the window manager asks you to close your window. (You may provide some means of confirmation to the user, i.e., "Do you really want to quit?", but you should probably just wrap things up and call DestroyWindow.)

func (*Window) WMMove

func (w *Window) WMMove(x, y int) error

WMMove changes the position of a window without touching the size. This should be used when moving a top-level client window with reparenting winow managers that support EWMH.

func (*Window) WMMoveResize

func (w *Window) WMMoveResize(x, y, width, height int) error

WMMoveResize is an accurate means of resizing a window, accounting for decorations. Usually, the x,y coordinates are fine---we just need to adjust the width and height. This should be used when moving/resizing top-level client windows with reparenting window managers that support EWMH.

func (*Window) WMResize

func (w *Window) WMResize(width, height int) error

WMResize changes the size of a window without touching the position. This should be used when resizing a top-level client window with reparenting window managers that support EWMH.

func (*Window) WMTakeFocus

func (w *Window) WMTakeFocus(cb func(w *Window, tstamp xproto.Timestamp))

WMTakeFocus will do all the necessary setup to support the WM_TAKE_FOCUS protocol using the "LocallyActive" input model described in Section 4.1.7 of the ICCCM. Namely, listening to ClientMessage events and running the callback function provided when a WM_TAKE_FOCUS ClientMessage has been received.

Typically, the callback function should include a call to SetInputFocus with the "Parent" InputFocus type, the sub-window id of the window that should have focus, and the 'tstamp' timestamp.