1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
|
from . import con
from .replies import BarConfigReply, InputReply
from enum import Enum
class IpcBaseEvent:
"""An abstract base event that all events inherit from.
"""
pass
class Event(Enum):
"""An enumeration of events that can be subscribed to with
:func:`Connection.on()`.
"""
WORKSPACE = 'workspace'
OUTPUT = 'output'
MODE = 'mode'
WINDOW = 'window'
BARCONFIG_UPDATE = 'barconfig_update'
BINDING = 'binding'
SHUTDOWN = 'shutdown'
TICK = 'tick'
INPUT = 'input'
WORKSPACE_FOCUS = 'workspace::focus'
WORKSPACE_INIT = 'workspace::init'
WORKSPACE_EMPTY = 'workspace::empty'
WORKSPACE_URGENT = 'workspace::urgent'
WORKSPACE_RELOAD = 'workspace::reload'
WORKSPACE_RENAME = 'workspace::rename'
WORKSPACE_RESTORED = 'workspace::restored'
WORKSPACE_MOVE = 'workspace::move'
WINDOW_NEW = 'window::new'
WINDOW_CLOSE = 'window::close'
WINDOW_FOCUS = 'window::focus'
WINDOW_TITLE = 'window::title'
WINDOW_FULLSCREEN_MODE = 'window::fullscreen_mode'
WINDOW_MOVE = 'window::move'
WINDOW_FLOATING = 'window::floating'
WINDOW_URGENT = 'window::urgent'
WINDOW_MARK = 'window::mark'
SHUTDOWN_RESTART = 'shutdown::restart'
SHUTDOWN_EXIT = 'shutdown::exit'
INPUT_ADDED = 'input::added'
INPUT_REMOVED = 'input::removed'
Event._subscribable_events = [e for e in Event if '::' not in e.value]
class WorkspaceEvent(IpcBaseEvent):
"""Sent when the user switches to a different workspace, when a new
workspace is initialized or when a workspace is removed (because the last
client vanished).
.. seealso:: https://i3wm.org/docs/ipc.html#_workspace_event
:ivar change: The type of change.
:vartype change: str
:ivar current: The affected workspace.
:vartype current: :class:`Con`
:ivar old: When the change is "focus", an old (object) property will be
present with the previous workspace if it exists.
:vartype old: :class:`Con` or :class:`None`
:ivar ipc_data: The raw data from the i3 ipc.
:vartype ipc_data: dict
"""
def __init__(self, data, conn, _Con=con.Con):
self.ipc_data = data
self.change = data['change']
self.current = None
self.old = None
if 'current' in data and data['current']:
self.current = _Con(data['current'], None, conn)
if 'old' in data and data['old']:
self.old = _Con(data['old'], None, conn)
class OutputEvent(IpcBaseEvent):
"""Sent when RandR issues a change notification (of either screens,
outputs, CRTCs or output properties).
.. seealso:: https://i3wm.org/docs/ipc.html#_output_event
:ivar change: The type of change (currently only "unspecified").
:vartype change: str
:ivar ipc_data: The raw data from the i3 ipc.
:vartype ipc_data: dict
"""
def __init__(self, data):
self.ipc_data = data
self.change = data['change']
class ModeEvent(IpcBaseEvent):
"""Sent whenever i3 changes its binding mode.
.. seealso:: https://i3wm.org/docs/ipc.html#_mode_event
:ivar change: The name of the current mode in use.
:vartype change: str
:ivar pango_markup: Whether pango markup should be used for displaying this
mode.
:vartype pango_markup: bool
:ivar ipc_data: The raw data from the i3 ipc.
:vartype ipc_data: dict
"""
def __init__(self, data):
self.ipc_data = data
self.change = data['change']
self.pango_markup = data.get('pango_markup', False)
class WindowEvent(IpcBaseEvent):
"""Sent when a client’s window is successfully reparented (that is when i3
has finished fitting it into a container), when a window received input
focus or when certain properties of the window have changed.
.. seealso:: https://i3wm.org/docs/ipc.html#_window_event
:ivar change: The type of change.
:vartype change: str
:ivar container: The window's parent container.
:ivar ipc_data: The raw data from the i3 ipc.
:vartype ipc_data: dict
"""
def __init__(self, data, conn, _Con=con.Con):
self.ipc_data = data
self.change = data['change']
self.container = _Con(data['container'], None, conn)
class BarconfigUpdateEvent(IpcBaseEvent, BarConfigReply):
"""Sent when the hidden_state or mode field in the barconfig of any bar
instance was updated and when the config is reloaded.
.. seealso:: https://i3wm.org/docs/ipc.html#_barconfig_update_event
:ivar id: The ID for this bar.
:vartype id: str
:ivar mode: Either dock (the bar sets the dock window type) or hide (the
bar does not show unless a specific key is pressed).
:vartype mode: str
:ivar position: Either bottom or top at the moment.
:vartype position: str
:ivar status_command: Command which will be run to generate a statusline.
:vartype status_command: str
:ivar font: The font to use for text on the bar.
:vartype font: str
:ivar workspace_buttons: Display workspace buttons or not.
:vartype workspace_buttons: bool
:ivar binding_mode_indicator: Display the mode indicator or not.
:vartype binding_mode_indicator: bool
:ivar verbose: Should the bar enable verbose output for debugging.
:vartype verbose: bool
:ivar colors: Contains key/value pairs of colors. Each value is a color
code in hex, formatted #rrggbb (like in HTML).
:vartype colors: dict
:ivar ipc_data: The raw data from the i3 ipc.
:vartype ipc_data: dict
"""
pass
class BindingInfo:
"""Info about a binding associated with a :class:`BindingEvent`.
:ivar ~.command: The i3 command that is configured to run for this binding.
:vartype ~.command: str
:ivar event_state_mask: The group and modifier keys that were configured
with this binding.
:vartype event_state_mask: list(str)
:ivar input_code: If the binding was configured with bindcode, this will be
the key code that was given for the binding.
:vartype input_code: int
:ivar symbol: If this is a keyboard binding that was configured with
bindsym, this field will contain the given symbol.
:vartype symbol: str or :class:`None` if this binding was not configured
with a symbol.
:ivar input_type: This will be "keyboard" or "mouse" depending on whether
or not this was a keyboard or a mouse binding.
:vartype input_type: str
:ivar ipc_data: The raw data from the i3 ipc.
:vartype ipc_data: dict
"""
def __init__(self, data):
self.ipc_data = data
self.command = data['command']
self.event_state_mask = data.get('event_state_mask', [])
self.input_code = data['input_code']
self.symbol = data.get('symbol', None)
self.input_type = data['input_type']
# sway only
self.symbols = data.get('symbols', [])
# not included in sway
self.mods = data.get('mods', [])
class BindingEvent(IpcBaseEvent):
"""Sent when a configured command binding is triggered with the keyboard or
mouse.
.. seealso:: https://i3wm.org/docs/ipc.html#_binding_event
:ivar change: The type of change.
:vartype change: str
:ivar binding: Contains details about the binding that was run.
:vartype binding: :class:`BindingInfo <i3ipc.BindingInfo>`
:ivar ipc_data: The raw data from the i3 ipc.
:vartype ipc_data: dict
"""
def __init__(self, data):
self.ipc_data = data
self.change = data['change']
self.binding = BindingInfo(data['binding'])
class ShutdownEvent(IpcBaseEvent):
"""Sent when the ipc shuts down because of a restart or exit by user
command.
.. seealso:: https://i3wm.org/docs/ipc.html#_shutdown_event
:ivar change: The type of change.
:vartype change: str
:ivar ipc_data: The raw data from the i3 ipc.
:vartype ipc_data: dict
"""
def __init__(self, data):
self.ipc_data = data
self.change = data['change']
class TickEvent(IpcBaseEvent):
"""Sent when the ipc client subscribes to the tick event (with "first":
true) or when any ipc client sends a SEND_TICK message (with "first":
false).
.. seealso:: https://i3wm.org/docs/ipc.html#_tick_event
:ivar first: True when the ipc first subscribes to the tick event.
:vartype first: bool or :class:`None` if not supported by this version of
i3 (<=4.15).
:ivar payload: The payload that was sent with the tick.
:vartype payload: str
:ivar ipc_data: The raw data from the i3 ipc.
:vartype ipc_data: dict
"""
def __init__(self, data):
self.ipc_data = data
# i3 didn't include the 'first' field in 4.15. See i3/i3#3271.
self.first = data.get('first', None)
self.payload = data['payload']
class InputEvent(IpcBaseEvent):
"""(sway only) Sent when something related to the input devices changes.
:ivar change: The type of change ("added" or "removed")
:vartype change: str
:ivar input: Information about the input that changed.
:vartype input: :class:`InputReply <i3ipc.InputReply>`
:ivar ipc_data: The raw data from the i3 ipc.
:vartype ipc_data: dict
"""
def __init__(self, data):
self.ipc_data = data
self.change = data['change']
self.input = InputReply(data['input'])
|