mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-05-08 03:43:25 +02:00
feat(cli): add visible-windows cmd
This commit adds a new komorebic command, "visible-windows", to make tracking down ghost windows easier. The returned JSON structure will try to use the device id to identify a monitor if it is available, or fall back to the monitor index. Thanks to raggi on Discord for suggesting this command!
This commit is contained in:
@@ -147,6 +147,7 @@ pub enum SocketMessage {
|
||||
IdentifyLayeredApplication(ApplicationIdentifier, String),
|
||||
IdentifyBorderOverflowApplication(ApplicationIdentifier, String),
|
||||
State,
|
||||
VisibleWindows,
|
||||
Query(StateQuery),
|
||||
FocusFollowsMouse(FocusFollowsMouseImplementation, bool),
|
||||
ToggleFocusFollowsMouse(FocusFollowsMouseImplementation),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::BufRead;
|
||||
@@ -701,6 +702,32 @@ impl WindowManager {
|
||||
let mut stream = UnixStream::connect(socket)?;
|
||||
stream.write_all(state.as_bytes())?;
|
||||
}
|
||||
SocketMessage::VisibleWindows => {
|
||||
let mut monitor_visible_windows = HashMap::new();
|
||||
|
||||
for (index, monitor) in self.monitors().iter().enumerate() {
|
||||
if let Some(ws) = monitor.focused_workspace() {
|
||||
monitor_visible_windows.insert(
|
||||
monitor
|
||||
.device_id()
|
||||
.clone()
|
||||
.unwrap_or_else(|| format!("{index}")),
|
||||
ws.visible_window_details().clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let visible_windows_state =
|
||||
match serde_json::to_string_pretty(&monitor_visible_windows) {
|
||||
Ok(state) => state,
|
||||
Err(error) => error.to_string(),
|
||||
};
|
||||
|
||||
let socket = DATA_DIR.join("komorebic.sock");
|
||||
let mut stream = UnixStream::connect(socket)?;
|
||||
stream.write_all(visible_windows_state.as_bytes())?;
|
||||
}
|
||||
|
||||
SocketMessage::Query(query) => {
|
||||
let response = match query {
|
||||
StateQuery::FocusedMonitorIndex => self.focused_monitor_idx(),
|
||||
|
||||
@@ -6,6 +6,7 @@ use std::fmt::Formatter;
|
||||
use std::fmt::Write as _;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use color_eyre::eyre;
|
||||
use color_eyre::eyre::anyhow;
|
||||
use color_eyre::Result;
|
||||
use komorebi_core::config_generation::IdWithIdentifier;
|
||||
@@ -46,6 +47,26 @@ pub struct Window {
|
||||
pub(crate) hwnd: isize,
|
||||
}
|
||||
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
#[derive(Debug, Clone, Serialize, JsonSchema)]
|
||||
pub struct WindowDetails {
|
||||
pub title: String,
|
||||
pub exe: String,
|
||||
pub class: String,
|
||||
}
|
||||
|
||||
impl TryFrom<Window> for WindowDetails {
|
||||
type Error = eyre::ErrReport;
|
||||
|
||||
fn try_from(value: Window) -> std::result::Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
title: value.title()?,
|
||||
exe: value.exe()?,
|
||||
class: value.class()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Window {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let mut display = format!("(hwnd: {}", self.hwnd);
|
||||
|
||||
@@ -23,6 +23,7 @@ use crate::container::Container;
|
||||
use crate::ring::Ring;
|
||||
use crate::static_config::WorkspaceConfig;
|
||||
use crate::window::Window;
|
||||
use crate::window::WindowDetails;
|
||||
use crate::windows_api::WindowsApi;
|
||||
use crate::DEFAULT_CONTAINER_PADDING;
|
||||
use crate::DEFAULT_WORKSPACE_PADDING;
|
||||
@@ -1087,6 +1088,20 @@ impl Workspace {
|
||||
vec
|
||||
}
|
||||
|
||||
pub fn visible_window_details(&self) -> Vec<WindowDetails> {
|
||||
let mut vec: Vec<WindowDetails> = vec![];
|
||||
|
||||
for container in self.containers() {
|
||||
if let Some(focused) = container.focused_window() {
|
||||
if let Ok(details) = (*focused).try_into() {
|
||||
vec.push(details);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vec
|
||||
}
|
||||
|
||||
pub fn visible_windows_mut(&mut self) -> Vec<Option<&mut Window>> {
|
||||
let mut vec = vec![];
|
||||
for container in self.containers_mut() {
|
||||
|
||||
@@ -773,6 +773,8 @@ enum SubCommand {
|
||||
Check,
|
||||
/// Show a JSON representation of the current window manager state
|
||||
State,
|
||||
/// Show a JSON representation of visible windows
|
||||
VisibleWindows,
|
||||
/// Query the current window manager state
|
||||
#[clap(arg_required_else_help = true)]
|
||||
Query(Query),
|
||||
@@ -1921,6 +1923,9 @@ Stop-Process -Name:whkd -ErrorAction SilentlyContinue
|
||||
SubCommand::State => {
|
||||
with_komorebic_socket(|| send_message(&SocketMessage::State.as_bytes()?))?;
|
||||
}
|
||||
SubCommand::VisibleWindows => {
|
||||
with_komorebic_socket(|| send_message(&SocketMessage::VisibleWindows.as_bytes()?))?;
|
||||
}
|
||||
SubCommand::Query(arg) => {
|
||||
with_komorebic_socket(|| {
|
||||
send_message(&SocketMessage::Query(arg.state_query).as_bytes()?)
|
||||
|
||||
Reference in New Issue
Block a user