From 89b0e9eeb6eb5e1f3d4863431edc3d6335f48df5 Mon Sep 17 00:00:00 2001 From: Holger Rapp Date: Mon, 19 Aug 2019 17:53:34 +0200 Subject: [PATCH] Bug fix of origin calculation and window indices. --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 57 +++++++++++++++++++++++++++++++++++++---------------- watcher.lua | 8 ++++---- 4 files changed, 46 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54af2e3..bb3e053 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,7 +82,7 @@ dependencies = [ [[package]] name = "move_window" -version = "0.2.0" +version = "0.3.0" dependencies = [ "cocoa 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index fe935c8..eebf9bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "move_window" -version = "0.2.0" +version = "0.3.0" authors = ["Holger Rapp "] edition = "2018" diff --git a/src/main.rs b/src/main.rs index 3e2e677..1ccd496 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ use cocoa::foundation::{NSArray, NSDictionary, NSString}; use objc::runtime::Class; use objc::runtime::Object; use osascript::JavaScript; -use serde_derive::Serialize; +use serde_derive::{Deserialize, Serialize}; use std::ffi::CStr; #[derive(Serialize)] @@ -18,7 +18,7 @@ struct MoveWindowParams { r: Rect, } -#[derive(Debug, Serialize)] +#[derive(Debug, Deserialize, Serialize, Clone)] struct Rect { x: i32, y: i32, @@ -45,7 +45,8 @@ struct MoveParameters { #[derive(Debug)] struct Screen { index: u64, - rect: Rect, + visible_frame: Rect, + frame: Rect, } fn next_integer(a: &mut ::std::iter::Peekable>) -> Result { @@ -63,7 +64,7 @@ impl MoveParameters { let screen = { let c = i.next().ok_or_else(|| "No more items".to_string())?; match c { - '0'...'9' => ScreenSelector::Index(c.to_digit(10).unwrap() as usize), + '0'..='9' => ScreenSelector::Index(c.to_digit(10).unwrap() as usize), c => ScreenSelector::Char(c), } }; @@ -123,19 +124,33 @@ fn get_screens() -> Vec { let screens: *mut Object = NSScreen::screens(nil); for index in 0..NSArray::count(screens) { let screen: *mut Object = msg_send![screens, objectAtIndex: index]; - let s = screen.visibleFrame(); + let visible_frame = screen.visibleFrame(); + let frame = screen.frame(); rv.push(Screen { index, - rect: Rect { - x: s.origin.x as i32, - y: s.origin.y as i32, - width: s.size.width as i32, - height: s.size.height as i32, + visible_frame: Rect { + x: visible_frame.origin.x as i32, + y: visible_frame.origin.y as i32, + width: visible_frame.size.width as i32, + height: visible_frame.size.height as i32, + }, + frame: Rect { + x: frame.origin.x as i32, + y: frame.origin.y as i32, + width: frame.size.width as i32, + height: frame.size.height as i32, }, }) } }; - rv.sort_by_key(|s| s.rect.x); + // The window frames have their origins in the bottom left of the screen, y going upwards. + // However, screen bounds have the origin at the top left going down. We need to convert here + // to get them in the screen space. + for idx in 1..rv.len() { + let y = rv[0].frame.height - rv[idx].visible_frame.height - rv[idx].visible_frame.y; + rv[idx].visible_frame.y = y; + } + rv.sort_by_key(|s| s.visible_frame.x); rv } @@ -167,20 +182,28 @@ fn main() { let screens = get_screens(); let screen = match params.screen { - ScreenSelector::Index(index) => &screens[index], + ScreenSelector::Index(index) => { + let mut screen = None; + for s in &screens { + if s.index == index as u64 { + screen = Some(s) + } + } + screen.expect("Unknown screen index.") + } ScreenSelector::Char(c) => match c { 'l' => &screens[0], 'm' | 'c' => &screens[1], 'r' => &screens[screens.len() - 1], _ => panic!("Unknown character for screen selection: {}", c), - } + }, }; - let width = f64::from(screen.rect.width) / f64::from(params.x_ratio); - let height = f64::from(screen.rect.height) / f64::from(params.y_ratio); + let width = f64::from(screen.visible_frame.width) / f64::from(params.x_ratio); + let height = f64::from(screen.visible_frame.height) / f64::from(params.y_ratio); let frame = Rect { - x: (f64::from(screen.rect.x) + width * f64::from(params.x_start)).round() as i32, - y: (f64::from(screen.rect.y) + height * f64::from(params.y_start)).round() as i32, + x: (f64::from(screen.visible_frame.x) + width * f64::from(params.x_start)).round() as i32, + y: (f64::from(screen.visible_frame.y) + height * f64::from(params.y_start)).round() as i32, width: (width * f64::from(params.x_end - params.x_start + 1)).round() as i32, height: (height * f64::from(params.y_end - params.y_start + 1)).round() as i32, }; diff --git a/watcher.lua b/watcher.lua index dcffb7e..41e2161 100644 --- a/watcher.lua +++ b/watcher.lua @@ -12,14 +12,14 @@ return { -- name = "Running cargo check", -- command = "cargo check --release --color=always", -- }, - { - name = "Running cargo clippy", - command = "cargo clippy --release --color=always", - }, { name = "Running cargo build", command = "cargo build --release --color=always", }, + { + name = "Running cargo clippy", + command = "cargo clippy --color=always -- -D warnings", + }, } }, }