fixed a bug that caused active window to crash on empty workspaces (window_address not set and query active window invalid), also added openwindow and closewindow to workspace subscription to update workspace windows

This commit is contained in:
2025-03-07 05:05:46 +01:00
parent 5f4eaa031d
commit d830d7c6b7

View File

@@ -755,28 +755,18 @@ fn run_client(config: &Config, subscription: &str) {
/// Prints the active window as json /// Prints the active window as json
fn run_activewindow_client(config: &Config) { fn run_activewindow_client(config: &Config) {
let subscription_line = "activewindowv2,fullscreen,closewindow,movewindow,changefloatingmode,moveintogroup,moveoutofgroup,togglegroup,pin,windowtitle\n"; let subscription_line = String::from(
"activewindowv2,fullscreen,closewindow,movewindow,changefloatingmode,moveintogroup,moveoutofgroup,togglegroup,pin,windowtitle\n",
);
info!("Using subscription line: {}", subscription_line); info!("Using subscription line: {}", subscription_line);
let event_reader = match UnixStream::connect(&config.client_socket_path) { let event_reader = connect_unix_socket(config, subscription_line);
Ok(mut stream) => {
if let Err(e) = stream.write_all(subscription_line.as_bytes()) {
eprintln!("Failed to send subscription: {}", e);
std::process::exit(1);
}
println!("Successfully connected to daemon.");
BufReader::new(stream)
}
Err(e) => {
eprintln!("Failed to connect to daemon. Is it running? Error: {}", e);
std::process::exit(1);
}
};
let mut clients = query_clients(); let mut clients = query_clients();
for event_line in event_reader.lines() { for event_line in event_reader.lines() {
let event: HyprlandEvent = let event: HyprlandEvent =
serde_json::from_str(&event_line.unwrap()).expect("Failed to parse event"); serde_json::from_str(&event_line.unwrap()).expect("Failed to parse event");
match event { match event {
HyprlandEvent::ActiveWindowV2 { window_address } => { HyprlandEvent::ActiveWindowV2 { window_address } => {
if window_address != "" {
if let Some(client) = clients.get(&format!("0x{}", window_address)) { if let Some(client) = clients.get(&format!("0x{}", window_address)) {
println!("{}", serde_json::to_string(&client).unwrap()); println!("{}", serde_json::to_string(&client).unwrap());
} else { } else {
@@ -788,6 +778,45 @@ fn run_activewindow_client(config: &Config) {
std::process::exit(1); std::process::exit(1);
} }
} }
} else {
info!("No active window.");
let client = Client {
address: "".to_string(),
mapped: false,
hidden: false,
at: (0, 0),
size: (0, 0),
workspace: Workspace {
id: 0,
name: "".to_string(),
active: None,
monitor: None,
monitor_id: None,
windows: None,
has_fullscreen: None,
last_window: None,
last_window_title: None,
},
floating: false,
pseudo: false,
monitor: 0,
class: "".to_string(),
title: "".to_string(),
initial_class: "".to_string(),
initial_title: "".to_string(),
pid: 0,
xwayland: false,
pinned: false,
fullscreen: 0,
fullscreen_client: 0,
grouped: vec![],
tags: vec![],
swallowing: "".to_string(),
focus_history_id: 0,
inhibiting_idle: false,
};
println!("{}", serde_json::to_string(&client).unwrap());
}
} }
_ => { _ => {
clients = query_clients(); clients = query_clients();
@@ -801,23 +830,14 @@ fn run_activewindow_client(config: &Config) {
/// Prints the workspaces as json highlighting the active one /// Prints the workspaces as json highlighting the active one
fn run_workspaces_client(config: &Config) { fn run_workspaces_client(config: &Config) {
let subscription_line = "workspacev2,focusedmonv2,createworkspacev2,destoryworkspacev2,moveworkspacev2,renameworkspace,activespecial\n"; let subscription_line = String::from(
"workspacev2,focusedmonv2,createworkspacev2,destoryworkspacev2,moveworkspacev2,renameworkspace,activespecial,openwindow,closewindow\n",
);
info!("Using subscription line: {}", subscription_line); info!("Using subscription line: {}", subscription_line);
let event_reader = match UnixStream::connect(&config.client_socket_path) { let event_reader = connect_unix_socket(config, subscription_line);
Ok(mut stream) => {
if let Err(e) = stream.write_all(subscription_line.as_bytes()) {
eprintln!("Failed to send subscription: {}", e);
std::process::exit(1);
}
println!("Successfully connected to daemon.");
BufReader::new(stream)
}
Err(e) => {
eprintln!("Failed to connect to daemon. Is it running? Error: {}", e);
std::process::exit(1);
}
};
let mut workspaces = query_workspaces(); let mut workspaces = query_workspaces();
let serialized = serde_json::to_string(&workspaces).expect("Failed to serialize workspaces");
println!("{}", serialized);
for event_line in event_reader.lines() { for event_line in event_reader.lines() {
let event: HyprlandEvent = let event: HyprlandEvent =
serde_json::from_str(&event_line.unwrap()).expect("Failed to parse event"); serde_json::from_str(&event_line.unwrap()).expect("Failed to parse event");
@@ -847,6 +867,23 @@ fn run_workspaces_client(config: &Config) {
} }
} }
/// === Helper functions for clients that also query socket1 === /// === Helper functions for clients that also query socket1 ===
fn connect_unix_socket(config: &Config, subscription_line: String) -> BufReader<UnixStream> {
match UnixStream::connect(&config.client_socket_path) {
Ok(mut stream) => {
if let Err(e) = stream.write_all(subscription_line.as_bytes()) {
eprintln!("Failed to send subscription: {}", e);
std::process::exit(1);
}
println!("Successfully connected to daemon.");
BufReader::new(stream)
}
Err(e) => {
eprintln!("Failed to connect to daemon. Is it running? Error: {}", e);
std::process::exit(1);
}
}
}
fn query_socket(query: &str) -> String { fn query_socket(query: &str) -> String {
info!("Using query: {}", query); info!("Using query: {}", query);
let hypr_rundir_path = get_hypr_rundir_path(); let hypr_rundir_path = get_hypr_rundir_path();
@@ -927,7 +964,9 @@ fn print_help() {
println!(" -w, --workspaces Run client mode to track workspace events."); println!(" -w, --workspaces Run client mode to track workspace events.");
println!(" -h, --help Show this help message."); println!(" -h, --help Show this help message.");
println!(); println!();
println!("If no options are provided, Hyprman runs in client mode with the 'all' subscription."); println!(
"If no options are provided, Hyprman runs in client mode with the 'all' subscription."
);
} }
/// === Main Entry Point: Mode Selection Based on CommandLine Arguments === /// === Main Entry Point: Mode Selection Based on CommandLine Arguments ===