swayipc-types-1.3.1/.cargo_vcs_info.json0000644000000001430000000000100136550ustar { "git": { "sha1": "7d04828d14297b7cb1307c4c84abfdb72573b415" }, "path_in_vcs": "types" }swayipc-types-1.3.1/Cargo.toml0000644000000020600000000000100116530ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" name = "swayipc-types" version = "1.3.1" authors = ["Jayce Fayne "] description = "A library containing Type defintions from sway's IPC interface" readme = "README.md" keywords = [ "sway", "swaywm", "swayipc", "ipc", ] categories = ["network-programming"] license = "MIT" repository = "https://github.com/jaycefayne/swayipc-rs" [dependencies.serde] version = "1" features = ["derive"] [dependencies.serde_json] version = "1" [dependencies.thiserror] version = "1" optional = true [features] default = ["error"] error = ["thiserror"] swayipc-types-1.3.1/Cargo.toml.orig000064400000000000000000000010601046102023000153330ustar 00000000000000[package] name = "swayipc-types" version = "1.3.1" authors = ["Jayce Fayne "] edition = "2021" description = "A library containing Type defintions from sway's IPC interface" license = "MIT" repository = "https://github.com/jaycefayne/swayipc-rs" categories = ["network-programming"] keywords = ["sway", "swaywm", "swayipc", "ipc"] readme = "README.md" [dependencies] serde = { version = "1", features = ["derive"] } serde_json = "1" thiserror = { version = "1", optional = true } [features] default = ["error"] error = ["thiserror"] swayipc-types-1.3.1/README.md000064400000000000000000000022341046102023000137270ustar 00000000000000# swayipc-types   [![Action Badge]][actions] [![Version Badge]][crates.io] [![License Badge]][license] [![Docs Badge]][docs] [Version Badge]: https://img.shields.io/crates/v/swayipc-types.svg [crates.io]: https://crates.io/crates/swayipc-types [Action Badge]: https://github.com/JayceFayne/swayipc-rs/workflows/Rust/badge.svg [actions]: https://github.com/JayceFayne/swayipc-rs/actions [License Badge]: https://img.shields.io/crates/l/swayipc-types.svg [license]: https://github.com/JayceFayne/swayipc-rs/blob/master/LICENSE.md [Docs Badge]: https://docs.rs/swayipc-types/badge.svg [docs]: https://docs.rs/swayipc-types A Rust library containing types used to control swaywm through its [IPC interface](https://github.com/swaywm/sway/blob/master/sway/sway-ipc.7.scd). ## i3 compatibility [i3](https://github.com/i3/i3) compatibility is kept if possible even though this library primarily targets sway. ## Versioning This library targets the latest stable release of [sway](https://github.com/swaywm/sway). ## Contributing If you find any errors in swayipc or just want to add a new feature feel free to [submit a PR](https://github.com/jaycefayne/swayipc-rs/pulls). swayipc-types-1.3.1/src/command.rs000064400000000000000000000035521046102023000152270ustar 00000000000000#[repr(u32)] #[non_exhaustive] #[derive(Debug, PartialEq, Copy, Clone)] pub enum CommandType { /// Runs the payload as sway commands. RunCommand = 0, /// Get the list of current workspaces. GetWorkspaces = 1, /// Subscribe the IPC connection to the events listed in the payload. Subscribe = 2, /// Get the list of current outputs. GetOutputs = 3, /// Get the node layout tree. GetTree = 4, /// Get the names of all the marks currently set. GetMarks = 5, /// Get the specified bar config or a list of bar config names. GetBarConfig = 6, /// Get the version of sway that owns the IPC socket. GetVersion = 7, /// Get the list of binding mode names. GetBindingModes = 8, /// Returns the config that was last loaded. GetConfig = 9, /// Sends a tick event with the specified payload. SendTick = 10, /// Replies failure object for i3 compatibility. Sync = 11, /// Request the current binding state, e.g. the currently active binding /// mode name. GetBindingState = 12, /// Get the list of input devices. GetInputs = 100, /// Get the list of seats. GetSeats = 101, } impl CommandType { pub fn encode(self) -> Vec { crate::MAGIC .into_iter() .chain(0_u32.to_ne_bytes().into_iter()) .chain(u32::from(self).to_ne_bytes().into_iter()) .collect() } pub fn encode_with>(self, payload: T) -> Vec { let payload = payload.as_ref(); crate::MAGIC .into_iter() .chain((payload.len() as u32).to_ne_bytes().into_iter()) .chain(u32::from(self).to_ne_bytes().into_iter()) .chain(payload.iter().cloned()) .collect() } } impl From for u32 { fn from(value: CommandType) -> Self { value as u32 } } swayipc-types-1.3.1/src/error/command_outcome.rs000064400000000000000000000006471046102023000201150ustar 00000000000000use crate::{CommandOutcome, Error, Fallible}; impl CommandOutcome { pub fn decode(command_outcome: CommandOutcome) -> Fallible<()> { if let Some(error) = command_outcome.error { Err(if error.parse_error { Error::CommandParse(error.message) } else { Error::CommandFailed(error.message) }) } else { Ok(()) } } } swayipc-types-1.3.1/src/error/command_type.rs000064400000000000000000000007031046102023000174140ustar 00000000000000use crate::{CommandType, Error::InvalidCommandType, Fallible}; use serde::de::DeserializeOwned as Deserialize; impl CommandType { pub fn decode(self, (payload_type, payload): (u32, Vec)) -> Fallible { let command_type = u32::from(self); if payload_type != command_type { return Err(InvalidCommandType(payload_type, command_type)); } Ok(serde_json::from_slice(&payload)?) } } swayipc-types-1.3.1/src/error/event.rs000064400000000000000000000021631046102023000160600ustar 00000000000000use crate::{ Error::UnimplementedEvent, Event::{self, *}, Fallible, }; impl Event { pub fn decode((payload_type, payload): (u32, Vec)) -> Fallible { // strip the highest order bit indicating it's an event // since we dont convert to hex we also dont match on the (hex) values written in the sway-ipc docs! let event_type = (payload_type << 1) >> 1; Ok(match event_type { 0 => Workspace(serde_json::from_slice(&payload)?), 1 => Output(serde_json::from_slice(&payload)?), 2 => Mode(serde_json::from_slice(&payload)?), 3 => Window(serde_json::from_slice(&payload)?), 4 => BarConfigUpdate(serde_json::from_slice(&payload)?), 5 => Binding(serde_json::from_slice(&payload)?), 6 => Shutdown(serde_json::from_slice(&payload)?), 7 => Tick(serde_json::from_slice(&payload)?), 20 => BarStateUpdate(serde_json::from_slice(&payload)?), 21 => Input(serde_json::from_slice(&payload)?), _ => return Err(UnimplementedEvent(event_type, payload)), }) } } swayipc-types-1.3.1/src/error/mod.rs000064400000000000000000000017701046102023000155210ustar 00000000000000mod command_outcome; mod command_type; mod event; use thiserror::Error as ThisError; pub type Fallible = Result; #[non_exhaustive] #[derive(Debug, ThisError)] pub enum Error { #[error(transparent)] Io(#[from] std::io::Error), #[error(transparent)] SerdeJson(#[from] serde_json::Error), #[error("unexpected magic string, expected 'i3-ipc' but got '{}'", String::from_utf8_lossy(.0))] InvalidMagic([u8; 6]), #[error("did receive a reply with type '{0}' but send command with type '{1}'")] InvalidCommandType(u32, u32), #[error("received unimplemented event '{}' with type '{}'", String::from_utf8_lossy(.1), .0)] UnimplementedEvent(u32, Vec), #[error("failed to subscribe to events {0}")] SubscriptionFailed(String), #[error("command failed with '{0}'")] CommandFailed(String), #[error("command could not be parsed '{0}'")] CommandParse(String), #[error("could not find the socket for neither i3 nor sway")] SocketNotFound, } swayipc-types-1.3.1/src/event.rs000064400000000000000000000020751046102023000147310ustar 00000000000000use serde::Serialize; #[non_exhaustive] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize)] #[serde(rename_all = "snake_case")] pub enum EventType { /// Sent whenever an event involving a workspace occurs such as /// initialization of a new workspace or a different workspace gains focus. Workspace, /// Sent whenever an output is added, removed, or its configuration is changed. Output, /// Sent whenever the binding mode changes. Mode, /// Sent whenever an event involving a view occurs such as being reparented, /// focused, or closed. Window, /// Sent whenever a bar config changes. #[serde(rename = "barconfig_update")] BarConfigUpdate, /// Sent when a configured binding is executed. Binding, /// Sent when the ipc shuts down because sway is exiting. Shutdown, /// Sent when an ipc client sends a SEND_TICK message. Tick, /// Sent when the visibility of a bar should change due to a modifier. BarStateUpdate, /// Sent when something related to input devices changes. Input, } swayipc-types-1.3.1/src/lib.rs000064400000000000000000000005051046102023000143520ustar 00000000000000#![deny(unsafe_code)] #![deny(rust_2018_idioms)] mod command; #[cfg(feature = "error")] mod error; mod event; mod reply; mod utils; pub use command::CommandType; #[cfg(feature = "error")] pub use error::{Error, Fallible}; pub use event::EventType; pub use reply::*; pub const MAGIC: [u8; 6] = [105, 51, 45, 105, 112, 99]; swayipc-types-1.3.1/src/reply.rs000064400000000000000000000637511046102023000147530ustar 00000000000000use serde::{Deserialize, Serialize}; #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct CommandOutcome { /// A boolean indicating whether the command was successful. pub success: bool, /// An error object if the command failed, and None otherwise. #[serde(flatten)] pub error: Option, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct CommandError { /// A boolean indicating whether the reason the command failed was because /// the command was unknown or not able to be parsed. pub parse_error: bool, /// A human readable error message. #[serde(rename = "error")] pub message: String, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Workspace { pub id: i64, /// The workspace number or -1 for workspaces that do not start with a /// number. pub num: i32, /// The name of the workspace. pub name: String, #[serde(default)] pub layout: String, /// Whether the workspace is currently visible on any output. pub visible: bool, /// Whether the workspace is currently focused by the default seat (seat0). pub focused: bool, /// Whether a view on the workspace has the urgent flag set. pub urgent: bool, pub representation: Option, #[serde(default)] pub orientation: String, /// The bounds of the workspace. It consists of x, y, width, and height. pub rect: Rect, /// The name of the output that the workspace is on. pub output: String, #[serde(default)] pub focus: Vec, } #[non_exhaustive] #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub struct Success { /// A boolean value indicating whether the operation was successful or not. pub success: bool, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] pub struct Mode { pub width: i32, pub height: i32, pub refresh: i32, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Output { pub id: Option, // Sway doesn't give disabled outputs ids /// The name of the output. On DRM, this is the connector. pub name: String, /// The make of the output. pub make: String, /// The model of the output. pub model: String, /// The output's serial number as a hexa‐ decimal string. pub serial: String, /// Whether this output is active/enabled. pub active: bool, /// Whether this output is on/off (via DPMS). pub dpms: bool, /// For i3 compatibility, this will be false. It does not make sense in /// Wayland. pub primary: bool, /// The scale currently in use on the output or -1 for disabled outputs. pub scale: Option, /// The subpixel hinting current in use on the output. This can be rgb, bgr, /// vrgb, vbgr, or none. pub subpixel_hinting: Option, /// The transform currently in use for the output. This can be normal, 90, /// 180, 270, flipped-90, flipped-180, or flipped-270. pub transform: Option, /// The workspace currently visible on the output or null for disabled /// outputs. pub current_workspace: Option, /// An array of supported mode objects. Each object contains width, height, /// and refresh. #[serde(default)] pub modes: Vec, /// An object representing the current mode containing width, height, and /// refresh. pub current_mode: Option, /// The bounds for the output consisting of x, y, width, and height. pub rect: Rect, #[serde(default)] pub focus: Vec, #[serde(default)] pub focused: bool, } #[non_exhaustive] #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub struct Libinput { /// Whether events are being sent by the device. It can be enabled, /// disabled, or disabled_on_external_mouse. pub send_events: Option, /// Whether tap to click is enabled. It can be enabled or disabled. pub tap: Option, /// The finger to button mapping in use. It can be lmr or lrm. pub tap_button_mapping: Option, /// Whether tap-and-drag is enabled. It can be enabled or disabled. pub tap_drag: Option, /// Whether drag-lock is enabled. It can be enabled or disabled. pub tap_drag_lock: Option, /// The pointer-acceleration in use. pub accel_speed: Option, /// Whether natural scrolling is enabled. It can be enabled or disabled. pub natural_scroll: Option, /// Whether left-handed mode is enabled. It can be enabled or disabled. pub left_handed: Option, /// The click method in use. It can be none, button_areas, or clickfinger. pub click_method: Option, /// Whether middle emulation is enabled. It can be enabled or disabled. pub middle_emulation: Option, /// The scroll method in use. It can be none, two_finger, edge, or /// on_button_down. pub scroll_method: Option, /// The scroll button to use when scroll_method is on_button_down. This /// will be given as an input event code. pub scroll_button: Option, /// Whether disable-while-typing is enabled. It can be enabled or disabled. pub dwt: Option, /// An array of 6 floats representing the calibration matrix for absolute /// devices such as touchscreens. pub calibration_matrix: Option<[f32; 6]>, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum SendEvents { Enabled, Disabled, DisabledOnExternalMouse, } #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum EnabledOrDisabled { Enabled, Disabled, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum ClickMethod { ButtonAreas, Clickfinger, None, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum ScrollMethod { TwoFinger, Edge, OnButtonDown, None, } #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum ButtonMapping { LMR, LRM, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Input { /// The identifier for the input device. pub identifier: String, /// The human readable name for the device. pub name: String, /// The vendor code for the input device. pub vendor: i32, /// The product code for the input device. pub product: i32, /// The device type. Currently this can be keyboard, pointer, touch, /// tablet_tool, tablet_pad, or switch. #[serde(rename = "type")] pub input_type: String, /// (Only keyboards) The name of the active keyboard layout in use. pub xkb_active_layout_name: Option, /// (Only keyboards) A list a layout names configured for the keyboard. #[serde(default)] pub xkb_layout_names: Vec, /// (Only keyboards) The index of the active keyboard layout in use. pub xkb_active_layout_index: Option, /// (Only libinput devices) An object describing the current device /// settings. See below for more information. pub libinput: Option, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Seat { /// The unique name for the seat. pub name: String, /// The number of capabilities that the seat has. pub capabilities: i32, /// The id of the node currently focused by the seat or 0 when the seat is /// not currently focused by a node (i.e. a surface layer or xwayland /// unmanaged has focus). pub focus: i64, /// An array of input devices that are attached to the seat. Currently, this /// is an array of objects that are identical to those returned by /// GET_INPUTS. #[serde(default)] pub devices: Vec, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] pub struct Rect { pub x: i32, pub y: i32, pub width: i32, pub height: i32, } #[non_exhaustive] #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct WindowProperties { pub title: Option, pub instance: Option, pub class: Option, pub window_role: Option, pub window_type: Option, pub transient_for: Option, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum UserIdleInhibitType { Focus, Fullscreen, Open, Visible, None, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum ApplicationIdleInhibitType { Enabled, None, } #[non_exhaustive] #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct IdleInhibitors { pub application: ApplicationIdleInhibitType, pub user: UserIdleInhibitType, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum NodeType { Root, Output, Workspace, Con, FloatingCon, Dockarea, // i3-specific } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum NodeBorder { Normal, Pixel, Csd, None, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum NodeLayout { SplitH, SplitV, Stacked, Tabbed, Output, Dockarea, // i3-specific None, } #[non_exhaustive] #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct Node { /// The internal unique ID for this node. pub id: i64, /// The name of the node such as the output name or window title. For the /// scratchpad, this will be __i3_scratch for compatibility with i3. pub name: Option, /// The node type. It can be root, output, workspace, con, or floating_con. #[serde(rename = "type")] pub node_type: NodeType, /// The border style for the node. It can be normal, none, pixel, or csd. pub border: NodeBorder, /// Number of pixels used for the border width. pub current_border_width: i32, /// The node's layout. It can either be splith, splitv, stacked, tabbed, or /// output. pub layout: NodeLayout, /// The percentage of the node's parent that it takes up or null for the /// root and other special nodes such as the scratchpad. pub percent: Option, /// The absolute geometry of the node. The window decorations are excluded /// from this, but borders are included. pub rect: Rect, /// The geometry of the contents inside the node. The window decorations are /// excluded from this calculation, but borders are included. pub window_rect: Rect, /// The geometry of the decorations for the node relative to the parent /// node. pub deco_rect: Rect, /// The natural geometry of the contents if it were to size itself. pub geometry: Rect, /// Whether the node or any of its descendants has the urgent hint set. /// Note: This may not exist when compiled without xwayland support. pub urgent: bool, /// Whether the node is currently focused by the default seat (seat0). pub focused: bool, /// Array of child node IDs in the current focus order. pub focus: Vec, /// The tiling children nodes for the node. #[serde(default)] pub nodes: Vec, /// The floating children nodes for the node. pub floating_nodes: Vec, /// Whether the node is sticky (shows on all workspaces). pub sticky: bool, /// (Only workspaces) A string representation of the layout of the workspace /// that can be used as an aid in submitting reproduction steps for bug /// reports. pub representation: Option, /// (Only containers and views) The fullscreen mode of the node. 0 means /// none, 1 means full workspace, and 2 means global fullscreen. pub fullscreen_mode: Option, /// (Only views) For an xdg-shell view, the name of the application, if set. /// Otherwise, null. pub app_id: Option, /// (Only views) The PID of the application that owns the view. pub pid: Option, /// (Only xwayland views) The X11 window ID for the xwayland view. pub window: Option, pub num: Option, //workspace number if `node_type` == `NodeType::Workspace` /// (Only xwayland views) An object containing the title, class, instance, /// window_role, window_type, and transient_for for the view. pub window_properties: Option, /// List of marks assigned to the node. #[serde(default)] pub marks: Vec, /// (Only views) Whether the view is inhibiting the idle state. pub inhibit_idle: Option, /// (Only views) An object containing the state of the application and user /// idle inhibitors. application can be enabled or none. user can be /// focus, fullscreen, open, visible or none. pub idle_inhibitors: Option, /// (Only views) The shell of the view, such as xdg_shell or xwayland. pub shell: Option, /// (Only views) Whether the node is visible. pub visible: Option, /// (Only workspaces) Name of the output the node is located on. pub output: Option, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub struct ColorableBarPart { /// The color to use for the bar background on unfocused outputs. pub background: String, /// The color to use for the status line text on unfocused outputs. pub statusline: String, /// The color to use for the separator text on unfocused outputs. pub separator: String, /// The color to use for the background of the bar on the focused output. pub focused_background: String, /// The color to use for the status line text on the focused output. pub focused_statusline: String, /// The color to use for the separator text on the focused output. pub focused_separator: String, /// The color to use for the text of the focused workspace button. pub focused_workspace_text: String, /// The color to use for the background of the focused workspace button. pub focused_workspace_bg: String, /// The color to use for the border of the focused workspace button. pub focused_workspace_border: String, /// The color to use for the text of the workspace buttons for the visible /// workspaces on unfocused outputs. pub active_workspace_text: String, /// The color to use for the background of the workspace buttons for the /// visible workspaces on unfocused outputs. pub active_workspace_bg: String, /// The color to use for the border of the workspace buttons for the visible /// workspaces on unfocused outputs. pub active_workspace_border: String, /// The color to use for the text of the workspace buttons for workspaces /// that are not visible. pub inactive_workspace_text: String, /// The color to use for the background of the workspace buttons for /// workspaces that are not visible. pub inactive_workspace_bg: String, /// The color to use for the border of the workspace buttons for workspaces /// that are not visible. pub inactive_workspace_border: String, /// The color to use for the text of the workspace buttons for workspaces /// that contain an urgent view. pub urgent_workspace_text: String, /// The color to use for the background of the workspace buttons for /// workspaces that contain an urgent view. pub urgent_workspace_bg: String, /// The color to use for the border of the workspace buttons for workspaces /// that contain an urgent view. pub urgent_workspace_border: String, /// The color to use for the text of the binding mode indicator. pub binding_mode_text: String, /// The color to use for the background of the binding mode indicator. pub binding_mode_bg: String, /// The color to use for the border of the binding mode indicator. pub binding_mode_border: String, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct BarConfig { /// The bar ID. pub id: String, /// The mode for the bar. It can be dock, hide, or invisible. pub mode: BarMode, /// The bar's position. It can currently either be bottom or top. pub position: Position, /// The command which should be run to generate the status line. pub status_command: String, /// The font to use for the text on the bar. pub font: String, /// Whether to display the workspace buttons on the bar. pub workspace_buttons: bool, /// Whether to display the current binding mode on the bar. pub binding_mode_indicator: bool, /// For i3 compatibility, this will be the boolean value false. pub verbose: bool, /// An object containing the #RRGGBBAA colors to use for the bar. See below /// for more information. pub colors: ColorableBarPart, /// An object representing the gaps for the bar consisting of top, right, /// bottom, and left. pub gaps: Gaps, /// The absolute height to use for the bar or 0 to automatically size based /// on the font. pub bar_height: usize, /// The vertical padding to use for the status line. pub status_padding: usize, /// The horizontal padding to use for the status line when at the end of an /// output. pub status_edge_padding: usize, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct BindingState { /// The currently active binding mode, as a string. pub name: String, } #[non_exhaustive] #[derive(Clone, Copy, Debug, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum BarMode { Dock, Hide, Invisible, } #[non_exhaustive] #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub struct Gaps { pub top: usize, pub bottom: usize, pub right: usize, pub left: usize, } #[non_exhaustive] #[derive(Clone, Copy, Debug, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum Position { Bottom, Top, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Version { /// The major version of the sway process. pub major: i32, /// The minor version of the sway process. pub minor: i32, /// The patch version of the sway process. pub patch: i32, /// A human readable version string that will likely contain more useful /// information such as the git commit short hash and git branch. pub human_readable: String, /// The path to the loaded config file. pub loaded_config_file_name: String, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Config { /// A single string property containing the contents of the config. pub config: String, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub enum Event { /// Sent whenever an event involving a workspace occurs such as /// initialization of a new workspace or a different workspace gains focus. Workspace(Box), /// Sent whenever an output is added, removed, or its configuration is changed. Output(OutputEvent), /// Sent whenever the binding mode changes. Mode(ModeEvent), /// Sent whenever an event involving a view occurs such as being reparented, /// focused, or closed. Window(Box), /// Sent whenever a bar config changes. BarConfigUpdate(Box), /// Sent when a configured binding is executed. Binding(BindingEvent), /// Sent when the ipc shuts down because sway is exiting. Shutdown(ShutdownEvent), /// Sent when an ipc client sends a SEND_TICK message. Tick(TickEvent), /// Send when the visibility of a bar should change due to a modifier. BarStateUpdate(BarStateUpdateEvent), /// Sent when something related to input devices changes. Input(Box), } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct InputEvent { /// What has changed. pub change: InputChange, /// An object representing the input that is identical the ones GET_INPUTS /// gives. pub input: Input, } #[non_exhaustive] #[derive(Clone, Copy, Debug, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum InputChange { /// The input device became available. Added, /// The input device is no longer available. Removed, /// (Keyboards only) The keymap for the keyboard has changed. XkbKeymap, /// (Keyboards only) The effective layout in the keymap has changed. XkbLayout, /// (libinput device only) A libinput config option for the device changed. LibinputConfig, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct BarStateUpdateEvent { /// The bar ID effected. pub id: String, /// Whether the bar should be made visible due to a modifier being pressed. pub visible_by_modifier: bool, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct TickEvent { /// Whether this event was triggered by subscribing to the tick events. pub first: bool, /// The payload given with a SEND_TICK message, if any. Otherwise, an empty /// string. pub payload: String, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct WorkspaceEvent { /// The type of change that occurred. pub change: WorkspaceChange, /// An object representing the workspace effected or null for reload /// changes. pub current: Option, //Only None if WorkspaceChange::Reload /// For a focus change, this is will be an object representing the workspace /// being switched from. Otherwise, it is null. pub old: Option, //Only None if WorkspaceChange::Reload } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum OutputChange { /// We don't know what exactly changed. Unspecified, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct OutputEvent { /// The type of change that occurred. pub change: OutputChange, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ModeEvent { /// The binding mode that became active. pub change: String, /// Whether the mode should be parsed as pango markup. pub pango_markup: bool, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct WindowEvent { /// The type of change that occurred. pub change: WindowChange, /// An object representing the view effected. pub container: Node, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct BindingEvent { /// The change that occurred for the binding. Currently this will only be /// run. pub change: BindingChange, /// Details about the binding event. pub binding: BindingEventOps, } #[non_exhaustive] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct BindingEventOps { /// The command associated with the binding. pub command: String, /// An array of strings that correspond to each modifier key for the /// binding. #[serde(default)] pub event_state_mask: Vec, /// For keyboard bindcodes, this is the key code for the binding. For mouse /// bindings, this is the X11 button number, if there is an equivalent. In /// all other cases, this will be 0. pub input_code: u8, /// For keyboard bindsyms, this is the bindsym for the binding. Otherwise, /// this will be null. pub symbol: Option, /// The input type that triggered the binding. This is either keyboard or /// mouse. pub input_type: InputType, } #[non_exhaustive] #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub struct ShutdownEvent { /// The reason for the shutdown. pub change: ShutdownChange, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum WorkspaceChange { /// The workspace was created. Init, /// The workspace is empty and is being destroyed since it is not visible. Empty, /// The workspace was focused. See the old property for the previous focus. Focus, /// The workspace was moved to a different output. Move, /// The workspace was renamed. Rename, /// A view on the workspace has had their urgency hint set or all urgency /// hints for views on the workspace have been cleared. Urgent, /// The configuration file has been reloaded. Reload, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum WindowChange { /// The view was created. New, /// The view was closed. Close, /// The view was focused. Focus, /// The view's title has changed. Title, /// The view's fullscreen mode has changed. FullscreenMode, /// The view has been reparented in the tree. Move, /// The view has become floating or is no longer floating. Floating, /// The view's urgency hint has changed status. Urgent, /// A mark has been added or. Mark, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum InputType { Keyboard, Mouse, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum BindingChange { Run, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum ShutdownChange { Exit, } #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum ShellType { XdgShell, Xwayland, Unknown, } swayipc-types-1.3.1/src/utils/mod.rs000064400000000000000000000000121046102023000155140ustar 00000000000000mod node; swayipc-types-1.3.1/src/utils/node.rs000064400000000000000000000133601046102023000156740ustar 00000000000000use crate::reply::Node; impl Node { pub fn find_as_ref(&self, predicate: F) -> Option<&Node> where F: Copy + Fn(&Node) -> bool, { if predicate(self) { return Some(self); } for node in &self.nodes { let node = node.find_as_ref(predicate); if node.is_some() { return node; } } for node in &self.floating_nodes { let node = node.find_as_ref(predicate); if node.is_some() { return node; } } None } pub fn find(self, predicate: F) -> Option where F: Copy + Fn(&Node) -> bool, { if predicate(&self) { return Some(self); } let Node { nodes, floating_nodes, .. } = self; for node in nodes { let node = node.find(predicate); if node.is_some() { return node; } } for node in floating_nodes { let node = node.find(predicate); if node.is_some() { return node; } } None } pub fn find_focused_as_ref(&self, predicate: F) -> Option<&Node> where F: Copy + Fn(&Node) -> bool, { if predicate(self) { return Some(self); } if self.focus.is_empty() { return None; } let first = self.focus[0]; for node in &self.nodes { if node.id == first { return node.find_focused_as_ref(predicate); } } for node in &self.floating_nodes { if node.id == first { return node.find_focused_as_ref(predicate); } } None } pub fn find_focused(self, predicate: F) -> Option where F: Copy + Fn(&Node) -> bool, { if predicate(&self) { return Some(self); } let Node { nodes, floating_nodes, focus, .. } = self; if focus.is_empty() { return None; } let first = focus[0]; for node in nodes { if node.id == first { return node.find_focused(predicate); } } for node in floating_nodes { if node.id == first { return node.find_focused(predicate); } } None } pub fn iter(&self) -> NodeIterator<'_> { NodeIterator { queue: vec![self] } } } pub struct NodeIterator<'a> { queue: Vec<&'a Node>, } impl<'a> Iterator for NodeIterator<'a> { type Item = &'a Node; fn next(&mut self) -> Option<&'a Node> { match self.queue.pop() { None => None, Some(result) => { self.queue.extend(result.nodes.iter()); Some(result) } } } } #[cfg(test)] mod tests { use super::*; use crate::NodeBorder; use crate::NodeLayout; use crate::NodeType; use crate::Rect; fn rect() -> Rect { Rect { x: 0, y: 0, width: 10, height: 10, } } fn mk_node(name: Option, node_type: NodeType, nodes: Vec) -> Node { Node { id: 1, name, node_type, border: NodeBorder::Normal, current_border_width: 0, layout: NodeLayout::Tabbed, percent: None, rect: rect(), window_rect: rect(), deco_rect: rect(), geometry: rect(), urgent: false, focused: false, focus: Vec::new(), nodes, floating_nodes: Vec::new(), sticky: false, representation: None, fullscreen_mode: None, app_id: None, pid: None, window: None, num: None, window_properties: None, marks: Vec::new(), inhibit_idle: None, idle_inhibitors: None, shell: None, visible: None, output: None, } } #[test] fn returns_the_given_root_node_first() { let root = mk_node(Some(String::from("root")), NodeType::Root, vec![]); let mut iterator = root.iter(); assert_eq!(iterator.next().unwrap().name, Some("root".to_string())); } #[test] fn returns_children_of_the_given_node() { let root = mk_node( Some("root".to_string()), NodeType::Root, vec![mk_node(Some("child".to_string()), NodeType::Con, vec![])], ); let mut iterator = root.iter(); iterator.next(); assert_eq!(iterator.next().unwrap().name, Some("child".to_string())); } #[test] fn returns_transitive_children_of_the_given_node() { let root = mk_node( Some("root".to_string()), NodeType::Root, vec![mk_node( Some("child".to_string()), NodeType::Con, vec![mk_node( Some("grandchild".to_string()), NodeType::Con, vec![], )], )], ); let mut iterator = root.iter(); iterator.next(); iterator.next(); assert_eq!( iterator.next().unwrap().name, Some("grandchild".to_string()) ); } #[test] fn returns_none_at_the_end() { let root = mk_node(Some("root".to_string()), NodeType::Root, vec![]); let mut iterator = root.iter(); iterator.next(); assert_eq!(iterator.next(), None); } }