evdaemon is a rather simple event-based framework for python, initially designed for my i3 and swaybar configs.
It uses the os.select()
feature to read from file descriptors and wait for
timeouts in a non-blocking way.
MAINTENANCE NOTE: This project is discontinued.
evdaemon has no dependencies, just install via pip install --editable .
.
This installs evdaemon
, evdmodule_i3
, and evdmodule_wm
.
Create a daemon with evdaemon.Daemon()
and register modules that derive from
evdaemon.Module
on it with daemon.register(module)
.
Modules can be unregistered again with daemon.unregister(module)
.
Run the event loop with daemon.run()
.
Emit toplevel events with daemon.emit(*args)
(takes an arbitrary event path
and arguments)
For using evd
modules a daemon instance needs to be created on which modules
can be registered
Daemon()
: simple constructordaemon.modules
: dictionary of registered modulesdaemon.state
: global daemon statedaemon.register(module)
: register a moduledaemon.unregister(module)
: unregister a moduledaemon.emit(*path)
: emit an event to all modulesdaemon.run()
: start the event loop. Continues until no timeouts and no registered files exist any more.
Each module in evd
can emit and listen for events, register files to be read
from asynchronously, set timeouts or intervals, and set a state object that
other modules on the daemon can see and interact with.
Module()
: simple constructormodule.name
: the name of the module, must be set. also used as the name of the attribute inmodule.global_state
module.global_state
: a handle to the global state object of the daemonmodule.state
: this module's state object (identical togetattr(module.global_state, module.name)
)module.register_daemon(daemon)
: called when the module is first registered to the daemon. Use this to load dependency daemon modules into the daemon. Always callsuper().register_daemon(daemon)
.module.unregister_daemon(daemon)
: called when the module is unregistered from the daemon. Always callsuper().unregister_daemon(daemon)
.module.register_file(file, *path)
: register a file to the daemon.path
is the event path to emit when the file becomes readable. The event is emitted privately to this module.module.unregister_file(file)
: unregister a file from the daemon.module.files()
: get all registered filesmodule.trigger_file(file)
: manually trigger a file as if it were ready to be read. Used internally byDaemon
to trigger file events.module.timeouts()
: get all registered timeout listenersmodule.timeout(secs, fn)
: callfn
aftersecs
secondsmodule.listen(*path, fn)
: listen for events withpath
and callfn
with the rest arguments.module.listen_once(*path, fn)
: listen for one event withpath
and callfn
with the rest arguments.module.remove(*path)
: remove all listeners from this module that listen forpath
.module.emit(*path)
: emit an event withpath
to all deamon modules.module.emit_local(*path)
: emit an event withpath
to only this module.module.listen_private(*path, fn)
: listen privately for one event withpath
and callfn
with the rest arguments. (only for private events from this module)module.listen_once_private(*path, fn)
: listen privately for one event withpath
and callfn
with the rest arguments. (only for private events from this module)module.remove_private(*path)
: remove all listeners from this module that listen privately forpath
.module.emit_private(*path)
: emit an event withpath
to privately listenig listeners in this module.
This module represents a window manager and its state. It provides a central state object where other window manager modules can publish information on the running window manager.
Not all information must be presented by window manager modules. Missing
information should be None
.
Events with the prefix wm
should be used to indicate parts of the state have
been updated. (e.g. "wm", "title" should mean state.title
has been updated)
state.mode
: the current "mode" of the window managerstate.title
: the currently active window titlestate.monitors
: a dictionary of monitor ids to monitorsstate.workspaces
: a dict of workspace ids to workspaces
Represents a monitor connected to the system
Monitor(rect, name)
: construct a monitormonitor.rect
: the rectangle on the screen filled by the monitormonitor.name
: the name of the monitormonitor.active
: indicates whether the monitor is activemonitor.primary
: indicates whether the monitor is the primary monitormonitor.workspaces
: list of all workspaces that belong to this monitor. empty if workspaces aren't associated with monitors
Represents a workspace
Workspace(rect, name, num)
: construct a workspacews.rect
: the rectangle on the screen filled by this workspacews.name
: the name of this workspacews.num
: the number of this workspacews.visible
: indicates whether this workspace is visiblews.focused
: indicates whether this workspace is focusedws.urgent
: indicates whether there are urgent hints in this workspacews.monitor
: the monitor this workspace is currently onws.windows
: the list of windows in this workspace
Represents a window
Window(wid)
: construct a windowwin.wid
: the Xorg window id
Represents a rectangle on the screen
Rectangle(x, y, w, h)
: construct a rectanglerect.x
: get x positionrect.y
: get y positionrect.width
: get widthrect.height
: get height
A module for the i3 or sway window manager. Communicates using the i3 IPC protocol.
i3Module(events = ["workspace", "output", "mode", "window", "shutdown"], ipc= None)
: construct an i3 module.events
lists the i3 events to subscribe to, ipc is optionally an instance ofi3ipcModule
. Ani3ipcModule
will be created and registered if none is given.
This module emits wm
events and adjusts wm
state.
A module for interacting with the i3 IPC.
i3ipcModule()
: construct an i3 ipc moduleipc.send_cmd(cmd, payload)
: send a message (any fromevdmodule_i3.ipc.MSG
) with an optional payload.payload
can be a string or an object that is serialized as JSON.
This module sends "i3ipc" events, with the second parameter as "reply" or "event", the third parameter as the message type, and the last parameter as the deserialized payload.
Contains a dictionary MSG with all possible message types, REPLY with all possible reply types, and EVENT with all possible event types.