77 lines
3.5 KiB
Go
77 lines
3.5 KiB
Go
|
/*
|
||
|
Package xevent provides an event handler interface for attaching callback
|
||
|
functions to X events, and an implementation of an X event loop.
|
||
|
|
||
|
The X event loop
|
||
|
|
||
|
One of the biggest conveniences offered by xgbutil is its event handler system.
|
||
|
That is, the ability to attach an arbitrary callback function to any X event.
|
||
|
In order for such things to work, xgbutil needs to control the main X event
|
||
|
loop and act as a dispatcher for all event handlers created by you.
|
||
|
|
||
|
To run the X event loop, use xevent.Main or xevent.MainPing. The former
|
||
|
runs a normal event loop in the current goroutine and processes events. The
|
||
|
latter runs the event loop in a new goroutine and returns a pingBefore and
|
||
|
a pingAfter channel. The pingBefore channel is sent a benign value right before
|
||
|
an event is dequeued, and the pingAfter channel is sent a benign value right
|
||
|
after after all callbacks for that event have finished execution. These
|
||
|
synchronization points in the main event loop can be combined with a 'select'
|
||
|
statement to process data from other input sources. An example of this is given
|
||
|
in the documentation for the MainPing function. A complete example called
|
||
|
multiple-source-event-loop can also be found in the examples directory of the
|
||
|
xgbutil package.
|
||
|
|
||
|
To quit the main event loop, you may use xevent.Quit, but there is nothing
|
||
|
inherently wrong with stopping dead using os.Exit. xevent.Quit is provided for
|
||
|
your convenience should you need to run any clean-up code after the main event
|
||
|
loop returns.
|
||
|
|
||
|
The X event queue
|
||
|
|
||
|
xgbutil's event queue contains values that are either events or errors. (Never
|
||
|
both and never neither.) Namely, errors are received in the event loop from
|
||
|
unchecked requests. (Errors generated by checked requests are guaranteed to be
|
||
|
returned to the caller and are never received in the event loop.) Also, a
|
||
|
default error handler function can be set with xevent.ErrorHandlerSet.
|
||
|
|
||
|
To this end, xgbutil's event queue can be inspected. This is advantageous when
|
||
|
information about what events will be processed in the future could be helpful
|
||
|
(i.e., if there is an UnmapNotify event waiting to be processed.) The event
|
||
|
queue can also be manipulated to facilitate event compression. (Two events that
|
||
|
are common candidates for compression are ConfigureNotify and MotionNotify.)
|
||
|
|
||
|
Detach events
|
||
|
|
||
|
Whenever a window can no longer receive events (i.e., when it is destroyed),
|
||
|
all event handlers related to that window should be detached. (If this is
|
||
|
omitted, then Go's garbage collector will not be able to reuse memory occupied
|
||
|
by the now-unused event handlers for that window.) Moreover, its possible that
|
||
|
a window id can be reused after it has been discarded, which could result in
|
||
|
odd behavior in your application.
|
||
|
|
||
|
To detach a window from all event handlers in the xevent package, use
|
||
|
xevent.Detach. If you're also using the keybind and mousebind packages, you'll
|
||
|
need to call keybind.Detach and mousebind.Detach too. So to detach your window
|
||
|
from all possible event handlers in xgbutil, use something like:
|
||
|
|
||
|
xevent.Detach(XUtilValue, your-window-id)
|
||
|
keybind.Detach(XUtilValue, your-window-id)
|
||
|
mousebind.Detach(XUtilValue, your-window-id)
|
||
|
|
||
|
Quick example
|
||
|
|
||
|
A small example that shows how to respond to ConfigureNotify events sent to
|
||
|
your-window-id.
|
||
|
|
||
|
xevent.ConfigureNotifyFun(
|
||
|
func(X *xgbutil.XUtil, e xevent.ConfigureNotifyEvent) {
|
||
|
fmt.Printf("(%d, %d) %dx%d\n", e.X, e.Y, e.Width, e.Height)
|
||
|
}).Connect(XUtilValue, your-window-id)
|
||
|
|
||
|
More examples
|
||
|
|
||
|
The xevent package is used in several of the examples in the examples directory
|
||
|
in the xgbutil package.
|
||
|
*/
|
||
|
package xevent
|