rewrite of functions for constructing and sending ipc messages to reduce code reuse when deserializing json
This commit is contained in:
parent
f0ccfc3c5a
commit
ae04447488
274
src/lib.rs
274
src/lib.rs
@ -2,7 +2,10 @@ mod types;
|
||||
|
||||
use std::os::unix::net::UnixStream;
|
||||
use std::io::prelude::*;
|
||||
use types::workspace::Workspace;
|
||||
use std::io::{IoSlice, Result, Error, ErrorKind};
|
||||
|
||||
use serde::de::DeserializeOwned;
|
||||
use types::{Success, Workspace, Output, Version , Config, Input};
|
||||
|
||||
pub const IPC_RUN_COMMAND: u32 = 0;
|
||||
pub const IPC_GET_WORKSPACES: u32 = 1;
|
||||
@ -22,140 +25,269 @@ pub const IPC_GET_SEATS: u32 = 101;
|
||||
|
||||
pub struct I3msg {
|
||||
magic_string: &'static str,
|
||||
buffer: Vec<u8>,
|
||||
response: Vec<u8>,
|
||||
stream: UnixStream,
|
||||
}
|
||||
|
||||
impl I3msg {
|
||||
pub fn new() -> I3msg {
|
||||
pub fn new(socket: &str) -> I3msg {
|
||||
let stream = UnixStream::connect(socket).unwrap();
|
||||
return I3msg {
|
||||
magic_string: "i3-ipc",
|
||||
buffer: Vec::new(),
|
||||
response: Vec::new(),
|
||||
stream: stream
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs the payload as sway commands
|
||||
pub fn run_command(&mut self, socket: &mut UnixStream, payload: &str) -> Vec<u8> {
|
||||
self.send_command(socket, payload, IPC_RUN_COMMAND)
|
||||
pub fn run_command(&mut self, payload: &str) -> Result<Vec<Success>> {
|
||||
self.run(payload, IPC_RUN_COMMAND)
|
||||
}
|
||||
|
||||
/// Get the list of current workspaces
|
||||
pub fn get_workspaces(&mut self, socket: &mut UnixStream) -> Vec<Workspace> {
|
||||
let response = self.send_command(socket, "get_workspaces", IPC_GET_WORKSPACES);
|
||||
serde_json::from_slice::<Vec<Workspace>>(&response[14..]).unwrap()
|
||||
pub fn get_workspaces(&mut self) -> Result<Vec<Workspace>> {
|
||||
self.run("get_workspaces", IPC_GET_WORKSPACES)
|
||||
}
|
||||
|
||||
/// Subscribe the IPC connection to the event listed in the payload
|
||||
pub fn subscribe(&mut self, socket: &mut UnixStream, payload: &str) -> Vec<u8> {
|
||||
self.send_command(socket, payload, IPC_SUBSCRIBE);
|
||||
todo!();
|
||||
pub fn subscribe(&mut self, payload: &str) -> Result<Success> {
|
||||
self.run(payload, IPC_SUBSCRIBE)
|
||||
}
|
||||
|
||||
/// Get the list of current outputs
|
||||
pub fn get_outputs(&mut self, socket: &mut UnixStream) -> Vec<u8> {
|
||||
self.send_command(socket, "get_outputs", IPC_GET_OUTPUTS)
|
||||
pub fn get_outputs(&mut self) -> Result<Vec<Output>> {
|
||||
self.run("get_outputs", IPC_GET_OUTPUTS)
|
||||
}
|
||||
|
||||
/// Get the node layout tree
|
||||
pub fn get_tree(&mut self, socket: &mut UnixStream) -> Vec<u8> {
|
||||
self.send_command(socket, "get_tree", IPC_GET_TREE)
|
||||
pub fn get_tree(&mut self) -> Result<Vec<u8>> {
|
||||
self.run("get_tree", IPC_GET_TREE)
|
||||
}
|
||||
|
||||
/// Get the names of all the marks currently set
|
||||
pub fn get_marks(&mut self, socket: &mut UnixStream) -> Vec<u8> {
|
||||
self.send_command(socket, "get_marks", IPC_GET_MARKS)
|
||||
pub fn get_marks(&mut self) -> Result<Vec<String>> {
|
||||
self.run("get_marks", IPC_GET_MARKS)
|
||||
}
|
||||
|
||||
/// Get the specified bar config or a list of bar config names
|
||||
pub fn get_bar_config(&mut self, socket: &mut UnixStream) -> Vec<u8> {
|
||||
self.send_command(socket, "get_bar_config", IPC_GET_BAR_CONFIG)
|
||||
pub fn get_bar_config(&mut self, payload: &str) -> Result<Vec<u8>> {
|
||||
self.run(payload, IPC_GET_BAR_CONFIG)
|
||||
}
|
||||
|
||||
/// Get the version of sway that owns the IPC socket
|
||||
pub fn get_version(&mut self, socket: &mut UnixStream) -> Vec<u8> {
|
||||
self.send_command(socket, "get_version", IPC_GET_VERSION)
|
||||
pub fn get_version(&mut self) -> Result<Version> {
|
||||
self.run("get_version", IPC_GET_VERSION)
|
||||
}
|
||||
|
||||
/// Get the list of binding mode names
|
||||
pub fn get_binding_modes(&mut self, socket: &mut UnixStream) -> Vec<u8> {
|
||||
self.send_command(socket, "get_binding_modes", IPC_GET_BINDING_MODES)
|
||||
pub fn get_binding_modes(&mut self) -> Result<Vec<String>> {
|
||||
self.run("get_binding_modes", IPC_GET_BINDING_MODES)
|
||||
}
|
||||
|
||||
/// Returns the config that was last loaded
|
||||
pub fn get_config(&mut self, socket: &mut UnixStream) -> Vec<u8> {
|
||||
self.send_command(socket, "get_config", IPC_GET_CONFIG)
|
||||
pub fn get_config(&mut self) -> Result<Config> {
|
||||
self.run("get_config", IPC_GET_CONFIG)
|
||||
}
|
||||
|
||||
/// Sends a tick event with specified payload
|
||||
pub fn send_tick(&mut self, socket: &mut UnixStream, payload: &str) -> Vec<u8> {
|
||||
self.send_command(socket, payload, IPC_SEND_TICK);
|
||||
todo!()
|
||||
pub fn send_tick(&mut self, payload: &str) -> Result<Success> {
|
||||
self.run(payload, IPC_SEND_TICK)
|
||||
}
|
||||
|
||||
/// Replies failure object for i3 compatibility
|
||||
pub fn sync(&mut self, socket: &mut UnixStream) -> Vec<u8> {
|
||||
self.send_command(socket, "sync", IPC_SYNC)
|
||||
pub fn sync(&mut self) -> Result<Success> {
|
||||
self.run("sync", IPC_SYNC)
|
||||
}
|
||||
|
||||
/// Request the current binding state, e.g. the currently active binding mode name
|
||||
pub fn get_binding_state(&mut self, socket: &mut UnixStream) -> Vec<u8> {
|
||||
self.send_command(socket, "get_binding_state", IPC_GET_BINDING_STATE)
|
||||
pub fn get_binding_state(&mut self) -> Result<Vec<u8>> {
|
||||
self.run("get_binding_state", IPC_GET_BINDING_STATE)
|
||||
}
|
||||
|
||||
/// Get the list of input devices
|
||||
pub fn get_inputs(&mut self, socket: &mut UnixStream) -> Vec<u8> {
|
||||
self.send_command(socket, "get_inputs", IPC_GET_INPUTS)
|
||||
pub fn get_inputs(&mut self) -> Result<Vec<Input>> {
|
||||
self.run("get_inputs", IPC_GET_INPUTS)
|
||||
}
|
||||
|
||||
/// Get the list of seats
|
||||
pub fn get_seats(&mut self, socket: &mut UnixStream) -> Vec<u8> {
|
||||
self.send_command(socket, "get_seats", IPC_GET_SEATS)
|
||||
pub fn get_seats(&mut self) -> Result<Vec<u8>> {
|
||||
self.run("get_seats", IPC_GET_SEATS)
|
||||
}
|
||||
|
||||
fn send_command(&mut self, socket: &mut UnixStream, payload: &str, payload_type: u32) -> Vec<u8> {
|
||||
self.construct_packet(payload, payload_type);
|
||||
socket.write_all(&self.buffer.as_slice()).unwrap();
|
||||
fn run<T>(&mut self, payload: &str, payload_type: u32) -> Result<T>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
let buffer = match self.construct_packet(payload, payload_type) {
|
||||
Ok(buffer) => buffer,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
match self.stream.write_all(&buffer.as_slice()) {
|
||||
Ok(_) => {},
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
|
||||
let mut buffer = [0; 10000];
|
||||
let n = socket.read(&mut buffer).unwrap();
|
||||
let n = match self.stream.read(&mut buffer) {
|
||||
Ok(n) => n,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
self.response.write(&buffer[..n]).unwrap();
|
||||
self.response.to_owned()
|
||||
match serde_json::from_slice::<T>(&buffer[14..n]) {
|
||||
Ok(result) => return Ok(result),
|
||||
Err(e) => return Err(Error::new(ErrorKind::Other, e.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
fn construct_packet(&mut self, payload: &str, payload_type: u32) {
|
||||
self.buffer.write(self.magic_string.as_bytes()).unwrap();
|
||||
self.buffer.write(&payload.len().to_ne_bytes().as_slice()[..4]).unwrap();
|
||||
self.buffer.write(&payload_type.to_ne_bytes().as_slice()).unwrap();
|
||||
self.buffer.write(payload.as_bytes()).unwrap();
|
||||
fn construct_packet(&mut self, payload: &str, payload_type: u32) -> Result<Vec<u8>> {
|
||||
let mut buffer = Vec::new();
|
||||
let length = payload.len().to_ne_bytes();
|
||||
let payload_type = payload_type.to_ne_bytes();
|
||||
|
||||
let bufs = &mut [
|
||||
IoSlice::new(self.magic_string.as_bytes()),
|
||||
IoSlice::new(&length.as_slice()[..4]),
|
||||
IoSlice::new(payload_type.as_slice()),
|
||||
IoSlice::new(payload.as_bytes()),
|
||||
];
|
||||
|
||||
match buffer.write_vectored(bufs) {
|
||||
Ok(_) => return Ok(buffer),
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn send_command() {
|
||||
let mut socket = UnixStream::connect(env!("SWAYSOCK")).unwrap();
|
||||
let response = I3msg::new().run_command(&mut socket, "reload");
|
||||
assert_eq!(response, vec![
|
||||
0x69u8, 0x33u8 ,0x2Du8, 0x69u8, 0x70u8, 0x63u8,
|
||||
0x17u8, 0x00u8 ,0x00u8, 0x00u8, 0x00u8, 0x00u8,
|
||||
0x00u8, 0x00u8 ,0x5Bu8, 0x20u8, 0x7Bu8, 0x20u8,
|
||||
0x22u8, 0x73u8 ,0x75u8, 0x63u8, 0x63u8, 0x65u8,
|
||||
0x73u8, 0x73u8 ,0x22u8, 0x3Au8, 0x20u8, 0x74u8,
|
||||
0x72u8, 0x75u8 ,0x65u8, 0x20u8, 0x7Du8, 0x20u8,
|
||||
0x5Du8,
|
||||
]);
|
||||
fn run_command() {
|
||||
match I3msg::new(env!("SWAYSOCK")).run_command("reload") {
|
||||
Ok(response) => assert_eq!(response.into_iter().nth(0).unwrap().success, true),
|
||||
Err(e) => panic!("{}", e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_workspaces() {
|
||||
match I3msg::new(env!("SWAYSOCK")).get_workspaces() {
|
||||
Ok(response) => {
|
||||
for workspace in response {
|
||||
assert_eq!(workspace._type, "workspace");
|
||||
}
|
||||
},
|
||||
Err(e) => panic!("{}", e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subscribe() {
|
||||
match I3msg::new(env!("SWAYSOCK")).subscribe("") {
|
||||
Ok(response) => assert_eq!(response.success, false),
|
||||
Err(e) => panic!("{}", e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_outputs() {
|
||||
match I3msg::new(env!("SWAYSOCK")).get_outputs() {
|
||||
Ok(response) => {
|
||||
for output in response {
|
||||
assert_eq!(output._type, "output");
|
||||
}
|
||||
},
|
||||
Err(e) => panic!("{}", e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_tree() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_marks() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_bar_config() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_version() {
|
||||
match I3msg::new(env!("SWAYSOCK")).get_version() {
|
||||
Ok(response) => assert_eq!(response.major, 1),
|
||||
Err(e) => panic!("{}", e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_binding_modes() {
|
||||
match I3msg::new(env!("SWAYSOCK")).get_binding_modes() {
|
||||
Ok(response) => {
|
||||
assert_eq!(response.into_iter().nth(0).unwrap(), "default")
|
||||
},
|
||||
Err(e) => panic!("{}", e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_config() {
|
||||
match I3msg::new(env!("SWAYSOCK")).get_config() {
|
||||
Ok(_) => {},
|
||||
Err(e) => panic!("{}", e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn send_tick() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sync() {
|
||||
match I3msg::new(env!("SWAYSOCK")).sync() {
|
||||
Ok(response) => assert_eq!(response.success, false),
|
||||
Err(e) => panic!("{}", e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_binding_state() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_inputs() {
|
||||
match I3msg::new(env!("SWAYSOCK")).get_inputs() {
|
||||
Ok(response) => {
|
||||
for input in response {
|
||||
if !(input._type.eq("keyboard") | input._type.eq("pointer")) {
|
||||
panic!("invalid input: {}", input._type);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => panic!("{}", e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_seats() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn construct_packet() {
|
||||
let mut i3 = I3msg::new();
|
||||
i3.construct_packet("reload", IPC_RUN_COMMAND);
|
||||
assert_eq!(i3.buffer, vec![
|
||||
0x69u8, 0x33u8, 0x2Du8, 0x69u8,
|
||||
0x70u8, 0x63u8, 0x06u8, 0x00u8,
|
||||
0x00u8, 0x00u8, 0x00u8, 0x00u8,
|
||||
0x00u8, 0x00u8, 0x72u8, 0x65u8,
|
||||
0x6Cu8, 0x6Fu8, 0x61u8, 0x64u8,
|
||||
]);
|
||||
let mut i3 = I3msg::new(env!("SWAYSOCK"));
|
||||
match i3.construct_packet("reload", IPC_RUN_COMMAND) {
|
||||
Ok(buffer) => {
|
||||
assert_eq!(buffer, vec![
|
||||
0x69, 0x33, 0x2D, 0x69,
|
||||
0x70, 0x63, 0x06, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x72, 0x65,
|
||||
0x6C, 0x6F, 0x61, 0x64,
|
||||
]);
|
||||
},
|
||||
Err(e) => panic!("{}", e.to_string()),
|
||||
}
|
||||
}
|
23
src/main.rs
23
src/main.rs
@ -1,11 +1,10 @@
|
||||
use std::os::unix::net::UnixStream;
|
||||
use std::env;
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
match UnixStream::connect(env!("SWAYSOCK")) {
|
||||
Ok(mut sock) => {
|
||||
let mut i3 = sway_ipc::I3msg::new();
|
||||
for ws in i3.get_workspaces(&mut sock) {
|
||||
let mut i3 = sway_ipc::I3msg::new(env!("SWAYSOCK"));
|
||||
match i3.get_workspaces() {
|
||||
Ok(workspaces) => {
|
||||
for ws in workspaces {
|
||||
for float in ws.floating_nodes {
|
||||
match float.app_id {
|
||||
Some(app_id) => println!("{}", app_id),
|
||||
@ -15,8 +14,18 @@ fn main() -> std::io::Result<()> {
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Couldn't connect: {e:?}");
|
||||
eprintln!("error: {e:?}");
|
||||
}
|
||||
};
|
||||
}
|
||||
match i3.get_outputs() {
|
||||
Ok(outputs) => {
|
||||
for output in outputs {
|
||||
println!("output: {}", output.name);
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("error: {e:?}");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
256
src/types.rs
256
src/types.rs
@ -1,87 +1,173 @@
|
||||
pub mod workspace {
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Workspace {
|
||||
pub id: i32,
|
||||
#[serde(rename = "type")]
|
||||
pub _type: String,
|
||||
pub orientation: String,
|
||||
pub percent: Option<f32>,
|
||||
pub urgent: bool,
|
||||
// todo marks
|
||||
pub layout: String,
|
||||
pub border: String,
|
||||
pub current_border_width: i32,
|
||||
pub rect: Rect,
|
||||
pub deco_rect: Rect,
|
||||
pub window_rect: Rect,
|
||||
pub geometry: Rect,
|
||||
pub name: String,
|
||||
// todo window
|
||||
// todo nodes
|
||||
pub floating_nodes: Vec<FloatingNodes>,
|
||||
pub focus: Vec<i32>,
|
||||
pub fullscreen_mode: i32,
|
||||
pub sticky: bool,
|
||||
pub num: i32,
|
||||
pub output: String,
|
||||
pub representation: String,
|
||||
pub focused: bool,
|
||||
pub visible: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct FloatingNodes {
|
||||
pub id: i32,
|
||||
#[serde(rename = "type")]
|
||||
pub _type: String,
|
||||
pub orientation: String,
|
||||
pub percent: f32,
|
||||
pub urgent: bool,
|
||||
// todo marks
|
||||
pub focused: bool,
|
||||
pub layout: String,
|
||||
pub border: String,
|
||||
pub current_border_width: i32,
|
||||
pub rect: Rect,
|
||||
pub deco_rect: Rect,
|
||||
pub window_rect: Rect,
|
||||
pub geometry: Rect,
|
||||
pub name: String,
|
||||
// todo nodes
|
||||
pub focus: Vec<i32>,
|
||||
pub fullscreen_mode: i32,
|
||||
pub sticky: bool,
|
||||
pub pid: i32,
|
||||
pub app_id: Option<String>,
|
||||
pub visible: bool,
|
||||
pub max_render_time: i32,
|
||||
pub shell: String,
|
||||
pub inhibit_idle: bool,
|
||||
pub idle_inhibitors: IdleInhibitors,
|
||||
pub window_properties: Option<WindowProperties>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct IdleInhibitors {
|
||||
user: String,
|
||||
application: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct WindowProperties {
|
||||
class: String,
|
||||
instance: String,
|
||||
title: String,
|
||||
//todo transient_for
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Rect {
|
||||
x: i32,
|
||||
y: i32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
pub struct Success {
|
||||
pub success: bool,
|
||||
pub parse_error: Option<bool>,
|
||||
pub error: Option<String>
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Workspace {
|
||||
pub id: i32,
|
||||
#[serde(rename = "type")]
|
||||
pub _type: String,
|
||||
pub orientation: String,
|
||||
pub percent: Option<f32>,
|
||||
pub urgent: bool,
|
||||
pub layout: String,
|
||||
pub border: String,
|
||||
pub current_border_width: i32,
|
||||
pub rect: Rect,
|
||||
pub deco_rect: Rect,
|
||||
pub window_rect: Rect,
|
||||
pub geometry: Rect,
|
||||
pub name: String,
|
||||
pub floating_nodes: Vec<FloatingNodes>,
|
||||
pub focus: Vec<i32>,
|
||||
pub fullscreen_mode: i32,
|
||||
pub sticky: bool,
|
||||
pub num: i32,
|
||||
pub output: String,
|
||||
pub representation: String,
|
||||
pub focused: bool,
|
||||
pub visible: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Output {
|
||||
pub id: i32,
|
||||
#[serde(rename = "type")]
|
||||
pub _type: String,
|
||||
pub orientation: String,
|
||||
pub percent: Option<f32>,
|
||||
pub urgent: bool,
|
||||
pub layout: String,
|
||||
pub border: String,
|
||||
pub current_border_width: i32,
|
||||
pub rect: Rect,
|
||||
pub deco_rect: Rect,
|
||||
pub window_rect: Rect,
|
||||
pub geometry: Rect,
|
||||
pub name: String,
|
||||
pub floating_nodes: Vec<FloatingNodes>,
|
||||
pub focus: Vec<i32>,
|
||||
pub fullscreen_mode: i32,
|
||||
pub sticky: bool,
|
||||
pub active: bool,
|
||||
pub dpms: bool,
|
||||
pub primary: bool,
|
||||
pub make: String,
|
||||
pub model: String,
|
||||
pub serial: String,
|
||||
pub scale: f32,
|
||||
pub scale_filter: String,
|
||||
pub transform: String,
|
||||
pub adaptive_sync_status: String,
|
||||
pub current_workspace: String,
|
||||
pub modes: Vec<Mode>,
|
||||
pub current_mode: Mode,
|
||||
pub max_render_time: i32,
|
||||
pub focused: bool,
|
||||
pub subpixel_hinting: String
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Config {
|
||||
pub config: String
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Mode {
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
pub refresh: i32
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Version {
|
||||
pub human_readable: String,
|
||||
pub variant: String,
|
||||
pub major: i32,
|
||||
pub minor: i32,
|
||||
pub patch: i32,
|
||||
pub loaded_config_file_name: String
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Input {
|
||||
pub identifier: String,
|
||||
pub name: String,
|
||||
pub vendor: i32,
|
||||
pub product: i32,
|
||||
#[serde(rename = "type")]
|
||||
pub _type: String,
|
||||
pub xkb_layout_names: Option<Vec<String>>,
|
||||
pub xkb_active_layout_index: Option<i32>,
|
||||
pub xkb_active_layout_name: Option<String>,
|
||||
pub scroll_factor: Option<f32>,
|
||||
pub libinput: LibInput,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct LibInput {
|
||||
pub send_events: String,
|
||||
pub accel_speed: Option<f32>,
|
||||
pub accel_profile: Option<String>,
|
||||
pub natural_scroll: Option<String>,
|
||||
pub left_handed: Option<String>,
|
||||
pub middle_emulation: Option<String>,
|
||||
pub scroll_method: Option<String>,
|
||||
pub scroll_button: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct FloatingNodes {
|
||||
pub id: i32,
|
||||
#[serde(rename = "type")]
|
||||
pub _type: String,
|
||||
pub orientation: String,
|
||||
pub percent: f32,
|
||||
pub urgent: bool,
|
||||
pub focused: bool,
|
||||
pub layout: String,
|
||||
pub border: String,
|
||||
pub current_border_width: i32,
|
||||
pub rect: Rect,
|
||||
pub deco_rect: Rect,
|
||||
pub window_rect: Rect,
|
||||
pub geometry: Rect,
|
||||
pub name: String,
|
||||
pub focus: Vec<i32>,
|
||||
pub fullscreen_mode: i32,
|
||||
pub sticky: bool,
|
||||
pub pid: i32,
|
||||
pub app_id: Option<String>,
|
||||
pub visible: bool,
|
||||
pub max_render_time: i32,
|
||||
pub shell: String,
|
||||
pub inhibit_idle: bool,
|
||||
pub idle_inhibitors: IdleInhibitors,
|
||||
pub window_properties: Option<WindowProperties>
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct IdleInhibitors {
|
||||
user: String,
|
||||
application: String
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct WindowProperties {
|
||||
class: String,
|
||||
instance: String,
|
||||
title: String
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Rect {
|
||||
x: i32,
|
||||
y: i32,
|
||||
width: i32,
|
||||
height: i32
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user