Implement support for Windows
This commit is contained in:
21
Cargo.toml
21
Cargo.toml
@@ -1,9 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "antidrift"
|
name = "antidrift"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
ratatui = "0.27.0"
|
ratatui = "0.27.0"
|
||||||
regex = "1.10.5"
|
regex = "1.10.5"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winapi = { version = "0.3", features = ["winuser", "processthreadsapi"] }
|
||||||
@@ -9,5 +9,5 @@ window was and calculates a session score from that.
|
|||||||
To use AntiDrift, run `cargo run --release` directly, or `cargo build --release`
|
To use AntiDrift, run `cargo run --release` directly, or `cargo build --release`
|
||||||
and copy the binary into your `PATH`.
|
and copy the binary into your `PATH`.
|
||||||
|
|
||||||
Uses `xdotool` to get window titles and minimize windows. Currently Linux with
|
Under Linux, we use `xdotool` to get window titles and minimize windows. Under
|
||||||
X11 is the only supported platform.
|
Windows, we use the package `winapi` for the same functionality.
|
||||||
|
|||||||
@@ -1,70 +1,70 @@
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::{process::Command, process::Output, str};
|
use std::{process::Command, process::Output, str};
|
||||||
|
|
||||||
pub fn get_title_clean() -> String {
|
pub fn get_title_clean() -> String {
|
||||||
let title = get_window_info().title;
|
let title = get_window_info().title;
|
||||||
let re = Regex::new(r"-?\d+([:.]\d+)+%?").unwrap();
|
let re = Regex::new(r"-?\d+([:.]\d+)+%?").unwrap();
|
||||||
re.replace_all(&title, "").to_string()
|
re.replace_all(&title, "").to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn minimize_other(title: &str) {
|
pub fn minimize_other(title: &str) {
|
||||||
let window_info = get_window_info();
|
let window_info = get_window_info();
|
||||||
if &window_info.title != title {
|
if &window_info.title != title {
|
||||||
run(&format!("xdotool windowminimize {}", window_info.wid));
|
run(&format!("xdotool windowminimize {}", window_info.wid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WindowInfo {
|
struct WindowInfo {
|
||||||
title: String,
|
title: String,
|
||||||
_class: String,
|
_class: String,
|
||||||
wid: String,
|
wid: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(cmd: &str) -> Option<String> {
|
fn run(cmd: &str) -> Option<String> {
|
||||||
let output = Command::new("sh").arg("-c").arg(cmd).output();
|
let output = Command::new("sh").arg("-c").arg(cmd).output();
|
||||||
|
|
||||||
let Ok(Output {
|
let Ok(Output {
|
||||||
status,
|
status,
|
||||||
stdout,
|
stdout,
|
||||||
stderr: _,
|
stderr: _,
|
||||||
}) = output
|
}) = output
|
||||||
else {
|
else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
if status.code() != Some(0) {
|
if status.code() != Some(0) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Ok(output_str) = str::from_utf8(&stdout) else {
|
let Ok(output_str) = str::from_utf8(&stdout) else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(output_str.trim().to_string())
|
Some(output_str.trim().to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_window_info() -> WindowInfo {
|
fn get_window_info() -> WindowInfo {
|
||||||
let none = WindowInfo {
|
let none = WindowInfo {
|
||||||
title: "none".to_string(),
|
title: "none".to_string(),
|
||||||
_class: "none".to_string(),
|
_class: "none".to_string(),
|
||||||
wid: "".to_string(),
|
wid: "".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(wid) = run("xdotool getactivewindow") else {
|
let Some(wid) = run("xdotool getactivewindow") else {
|
||||||
return none;
|
return none;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(class) = run(&format!("xdotool getwindowclassname {wid}")) else {
|
let Some(class) = run(&format!("xdotool getwindowclassname {wid}")) else {
|
||||||
return none;
|
return none;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(title) = run(&format!("xdotool getwindowname {wid}")) else {
|
let Some(title) = run(&format!("xdotool getwindowname {wid}")) else {
|
||||||
return none;
|
return none;
|
||||||
};
|
};
|
||||||
|
|
||||||
WindowInfo {
|
WindowInfo {
|
||||||
title,
|
title,
|
||||||
_class: class,
|
_class: class,
|
||||||
wid,
|
wid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
9
src/window/mod.rs
Normal file
9
src/window/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
mod windows;
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub use windows::*;
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
mod linux;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub use linux::*;
|
||||||
38
src/window/windows.rs
Normal file
38
src/window/windows.rs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
use regex::Regex;
|
||||||
|
use std::{ffi::OsString, os::windows::ffi::OsStringExt};
|
||||||
|
use winapi::shared::windef::HWND;
|
||||||
|
use winapi::um::winuser::{ShowWindow, SW_MINIMIZE, GetForegroundWindow, GetWindowTextW};
|
||||||
|
|
||||||
|
|
||||||
|
pub fn get_title_clean() -> String {
|
||||||
|
let title = get_window_info().title;
|
||||||
|
let re = Regex::new(r"-?\d+([:.]\d+)+%?").unwrap();
|
||||||
|
re.replace_all(&title, "").to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minimize_other(title: &str) {
|
||||||
|
let window_info = get_window_info();
|
||||||
|
if window_info.title != title {
|
||||||
|
unsafe {
|
||||||
|
ShowWindow(window_info.hwnd, SW_MINIMIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WindowInfo {
|
||||||
|
title: String,
|
||||||
|
hwnd: HWND,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_window_info() -> WindowInfo {
|
||||||
|
unsafe {
|
||||||
|
let hwnd = GetForegroundWindow();
|
||||||
|
let mut text: [u16; 512] = [0; 512];
|
||||||
|
let len = GetWindowTextW(hwnd, text.as_mut_ptr(), text.len() as i32) as usize;
|
||||||
|
let title = OsString::from_wide(&text[..len]).to_string_lossy().into_owned();
|
||||||
|
WindowInfo {
|
||||||
|
title,
|
||||||
|
hwnd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user