Skip to content

Commit

Permalink
feat(wm): allow direct querying of focused objects
Browse files Browse the repository at this point in the history
This commit adds a new query command to komorebic, which allows for the
current focused monitor, workspace, container and window indices to be
queried directly without having to use jq run lookups on the entire
output of the state command.

resolve #24
  • Loading branch information
LGUG2Z committed Sep 2, 2021
1 parent a9a0ecd commit 2d19109
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -178,6 +178,7 @@ each command.
start Start komorebi.exe as a background process
stop Stop the komorebi.exe process and restore all hidden windows
state Show a JSON representation of the current window manager state
query Query the current window manager state
log Tail komorebi.exe's process logs (cancel with Ctrl-C)
focus Change focus to the window in the specified direction
move Move the focused window in the specified direction
Expand Down Expand Up @@ -270,6 +271,7 @@ used [is available here](komorebi.sample.with.lib.ahk).
- [x] Watch configuration for changes
- [x] Helper library for AutoHotKey
- [x] View window manager state
- [x] Query window manager state

## Development

Expand Down
10 changes: 10 additions & 0 deletions komorebi-core/src/lib.rs
Expand Up @@ -67,6 +67,7 @@ pub enum SocketMessage {
ManageRule(ApplicationIdentifier, String),
IdentifyTrayApplication(ApplicationIdentifier, String),
State,
Query(StateQuery),
FocusFollowsMouse(bool),
ToggleFocusFollowsMouse,
}
Expand All @@ -89,6 +90,15 @@ impl FromStr for SocketMessage {
}
}

#[derive(Clone, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
#[strum(serialize_all = "snake_case")]
pub enum StateQuery {
FocusedMonitorIndex,
FocusedWorkspaceIndex,
FocusedContainerIndex,
FocusedWindowIndex,
}

#[derive(Clone, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
#[strum(serialize_all = "snake_case")]
pub enum ApplicationIdentifier {
Expand Down
25 changes: 25 additions & 0 deletions komorebi/src/process_command.rs
Expand Up @@ -12,6 +12,7 @@ use uds_windows::UnixStream;

use komorebi_core::ApplicationIdentifier;
use komorebi_core::SocketMessage;
use komorebi_core::StateQuery;

use crate::window_manager;
use crate::window_manager::WindowManager;
Expand Down Expand Up @@ -175,6 +176,30 @@ impl WindowManager {
let mut stream = UnixStream::connect(&socket)?;
stream.write_all(state.as_bytes())?;
}
SocketMessage::Query(query) => {
let response = match query {
StateQuery::FocusedMonitorIndex => self.focused_monitor_idx(),
StateQuery::FocusedWorkspaceIndex => self
.focused_monitor()
.ok_or_else(|| anyhow!("there is no monitor"))?
.focused_workspace_idx(),
StateQuery::FocusedContainerIndex => {
self.focused_workspace()?.focused_container_idx()
}
StateQuery::FocusedWindowIndex => {
self.focused_container()?.focused_window_idx()
}
}
.to_string();

let mut socket =
dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?;
socket.push("komorebic.sock");
let socket = socket.as_path();

let mut stream = UnixStream::connect(&socket)?;
stream.write_all(response.as_bytes())?;
}
SocketMessage::ResizeWindow(direction, sizing) => {
self.resize_window(direction, sizing, Option::from(50))?;
}
Expand Down
4 changes: 4 additions & 0 deletions komorebic.lib.sample.ahk
Expand Up @@ -12,6 +12,10 @@ State() {
Run, komorebic.exe state, , Hide
}

Query(state_query) {
Run, komorebic.exe query %state_query%, , Hide
}

Log() {
Run, komorebic.exe log, , Hide
}
Expand Down
39 changes: 39 additions & 0 deletions komorebic/src/main.rs
Expand Up @@ -34,6 +34,7 @@ use komorebi_core::Layout;
use komorebi_core::OperationDirection;
use komorebi_core::Sizing;
use komorebi_core::SocketMessage;
use komorebi_core::StateQuery;

trait AhkLibrary {
fn generate_ahk_library() -> String;
Expand Down Expand Up @@ -82,6 +83,7 @@ gen_enum_subcommand_args! {
ChangeLayout: Layout,
WatchConfiguration: BooleanState,
FocusFollowsMouse: BooleanState,
Query: StateQuery,
}

macro_rules! gen_target_subcommand_args {
Expand Down Expand Up @@ -246,6 +248,9 @@ enum SubCommand {
Stop,
/// Show a JSON representation of the current window manager state
State,
/// Query the current window manager state
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
Query(Query),
/// Tail komorebi.exe's process logs (cancel with Ctrl-C)
Log,
/// Change focus to the window in the specified direction
Expand Down Expand Up @@ -607,6 +612,40 @@ fn main() -> Result<()> {
}
}
}
SubCommand::Query(arg) => {
let home = dirs::home_dir().context("there is no home directory")?;
let mut socket = home;
socket.push("komorebic.sock");
let socket = socket.as_path();

match std::fs::remove_file(&socket) {
Ok(_) => {}
Err(error) => match error.kind() {
// Doing this because ::exists() doesn't work reliably on Windows via IntelliJ
ErrorKind::NotFound => {}
_ => {
return Err(error.into());
}
},
};

send_message(&*SocketMessage::Query(arg.state_query).as_bytes()?)?;

let listener = UnixListener::bind(&socket)?;
match listener.accept() {
Ok(incoming) => {
let stream = BufReader::new(incoming.0);
for line in stream.lines() {
println!("{}", line?);
}

return Ok(());
}
Err(error) => {
panic!("{}", error);
}
}
}
SubCommand::RestoreWindows => {
let mut hwnd_json = dirs::home_dir().context("there is no home directory")?;
hwnd_json.push("komorebi.hwnd.json");
Expand Down

0 comments on commit 2d19109

Please sign in to comment.