Skip to content
This repository has been archived by the owner on Sep 15, 2024. It is now read-only.

Commit

Permalink
Update 0.3.1 - Added GWM3 compatibility, general refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
ParasiteDelta authored Jul 29, 2024
1 parent 2f12080 commit 399cf52
Showing 1 changed file with 90 additions and 51 deletions.
141 changes: 90 additions & 51 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#![windows_subsystem = "windows"]
#![cfg_attr(feature = "no_console", windows_subsystem = "windows")]

use std::net::TcpStream;

use semver::Version;
use serde_json::Value;
use tray_item::{IconSource, TrayItem};
use tungstenite::{connect, stream::MaybeTlsStream, Message, WebSocket};
Expand All @@ -27,16 +28,12 @@ use url::Url;
#[tokio::main]
async fn main() {
//Create tray icon using `tray-item-rs`
let mut tray: TrayItem;

//TrayItem data init - add program name, icon, append to raw TrayItem object.
match TrayItem::new(
let mut tray: TrayItem = {
if let Ok(ti) = TrayItem::new(
"GAT - GlazeWM Alternating Tiler",
IconSource::Resource("main-icon"),
) {
Ok(ti) => tray = ti,
Err(tierr) => {
eprintln!("\nERR: Could not init System Tray!\nRaw Error: {tierr}\n");
IconSource::Resource("main-icon")
) { ti } else {
eprintln!("\nERR: Could not init System Tray!\n");
panic!("\nMOR: Cannot continue runtime, please double-check your computer configuration!\n");
}
};
Expand All @@ -52,79 +49,121 @@ async fn main() {
}

//Create menu item for exiting program.
let menu_item_function = || {
std::process::exit(0);
};
match tray.add_menu_item("Quit GAT", menu_item_function) {
Ok(()) => {}
Err(e) => {
eprintln!(
"\nERR: Failed to add menu item! How did this even compile?\nRaw Error: {e}\n"
);
panic!("\nMOR: Cannot continue runtime, please double-check your computer configuration!\n");
}
let menu_item_function = || { std::process::exit(0) };

if let Err(e) = tray.add_menu_item("Quit GAT", menu_item_function) {
eprintln!("\nERR: Failed to add menu item! How did this even compile?\nRaw Error: {e}\n");
panic!("\nMOR: Cannot continue runtime, please double-check your computer configuration!\n");
}

//Initial WS connection
let (mut socket, response) = connect(
match Url::parse("ws://localhost:6123") {
Ok(u) => u,
Err(e) => {
eprintln!("\nERR: Could not parse registered string to URL, was this mistyped or something?\n{e}\n");
panic!("\nMOR: Cannot continue runtime, please double-check your computer configuration!\n");
}
let (mut socket, _response) = connect(
if let Ok(url) = Url::parse("ws://localhost:6123") {
url
} else {
eprintln!("\nERR: Could not parse internal string to URL, was this mistyped or something?\n");
panic!("\nMOR: Cannot continue runtime, please double-check your computer configuration!\n");
}

).expect("\nERR: Can't connect to GWM WS\n");

//Successful connection, print debug info.
println!("Connected to GWM\nResCode - {}", response.status());
println!("Response Headers:\n");
for (header, _value) in response.headers() {
println!("* {}", &header);
}
let version = get_version(&mut socket);
let subscription: String = match version.major {
3u64 => String::from("sub -e focus_changed"),
_ => String::from("subscribe -e focus_changed"),
};

//If we error out attempting to subscribe to GWM, kill the process.
if let Err(e) = socket.send(Message::Text("subscribe -e focus_changed".into())) {
if let Err(e) = socket.send(Message::Text(subscription)) {
eprintln!("\nERR: Could not parse raw message data from initial GWM subscription! Raw error:\n{e}\n");
} else {
loop {
let json_msg: Value = match serde_json::from_str(
socket
.read()
.expect("ERR: Could not read message!\n")
.to_text()
.unwrap_or_default(),
) {
Ok(v) => v,
Err(e) => {
eprintln!("\nERR: GWM WS MSG could not be parsed to Value! Raw error:\n{e}\n");
continue;
}
let focus_msg = {
let test = Value::default();
let result = get_value(&mut socket);
if result == test { continue } else { result }
};

if let Some((x, y)) = get_window_height_width(&json_msg["data"]["focusedContainer"]) {
println!("=-=-=-=-=-=-=\n{:#?}\n", focus_msg["data"]);

if version.major == 3u64 {
let tiling_direction = {
let _ = socket.send(Message::Text("query tiling-direction".into()));
get_value(&mut socket)
};

if let Some((x, y)) = get_window_height_width(&focus_msg["data"]["focusedContainer"]) {
println!("\nWindow dimension conversion to coordinate pair successful!");
size_tile_v3(
&mut socket, x, y,
tiling_direction["data"]["directionContainer"]["tilingDirection"].to_string()
).unwrap();
}
} else if let Some((x, y)) = get_window_height_width(&focus_msg["data"]["focusedContainer"]) {
size_tile(&mut socket, x, y).unwrap();
}
}
}
}

fn get_value(socket: &mut WebSocket<MaybeTlsStream<TcpStream>>) -> Value {
match serde_json::from_str(
socket
.read()
.expect("ERR: Could not read message!\n")
.to_text()
.unwrap_or_default()
) {
Ok(v) => v,
Err(e) => {
eprintln!("\nERR: GWM WS MSG could not be parsed to Value!\nRaw error:\n{e}\n");
Value::default()
}
}
}

fn get_version(socket: &mut WebSocket<MaybeTlsStream<TcpStream>>) -> Version {
let _query = socket.send(Message::Text("query app-metadata".into()));
let reading = {
let test = Value::default();
let result = get_value(socket);

if result == test { panic!("ERR: Could not retrieve version info! Aborting..."); } else { result }
};

if let Ok(v) = Version::parse(reading["data"]["version"].as_str().unwrap_or_default()) { v }
else { Version::new(0, 0, 0) }
}

fn size_tile(
socket: &mut WebSocket<MaybeTlsStream<TcpStream>>,
x: f64,
y: f64,
) -> Result<(), tungstenite::Error> {
if x < y {
socket.send(Message::Text(String::from(
"command \"tiling direction vertical\"",
"command \"tiling direction vertical\""
)))
} else {
socket.send(Message::Text(String::from(
"command \"tiling direction horizontal\"",
"command \"tiling direction horizontal\""
)))
}
}

fn size_tile_v3(
socket: &mut WebSocket<MaybeTlsStream<TcpStream>>,
x: f64,
y: f64,
tiling_direction: String
) -> Result<(), tungstenite::Error> {
if (x < y && tiling_direction != "\"vertical\"")
|| (x > y && tiling_direction != "\"horizontal\"") {
socket.send(Message::Text(String::from(
"command toggle-tiling-direction"
)))
} else { Ok(()) }
}

fn get_window_height_width(v: &Value) -> Option<(f64, f64)> {
v["width"]
.as_f64()
Expand Down

0 comments on commit 399cf52

Please sign in to comment.