Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always
RUSTFLAGS: "-Dwarnings"

jobs:
check:
name: Check
runs-on: windows-latest
steps:
- uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2

- name: Format check
run: cargo fmt --check

- name: Clippy
run: cargo clippy --all-targets --all-features -- -D warnings

- name: Build
run: cargo build --verbose

- name: Test
run: cargo test --verbose
5 changes: 1 addition & 4 deletions src/animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use windows::Win32::UI::WindowsAndMessaging::{
SWP_SHOWWINDOW, SetWindowLongPtrW, SetWindowPos, WS_EX_COMPOSITED,
};

use crate::error::AnimationError;
use crate::tracking::WindowBounds;

/// Slide direction
Expand Down Expand Up @@ -106,7 +105,7 @@ pub fn run_animation(
bounds: &WindowBounds,
work_area: &RECT,
slide_in: bool,
) -> Result<(), AnimationError> {
) {
let duration = Duration::from_millis(config.duration_ms as u64);
let start = Instant::now();

Expand Down Expand Up @@ -198,8 +197,6 @@ pub fn run_animation(
let _ = InvalidateRect(Some(hwnd), None, true);
SetWindowLongPtrW(hwnd, GWL_EXSTYLE, original_exstyle);
}

Ok(())
}

#[cfg(test)]
Expand Down
13 changes: 0 additions & 13 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@

use thiserror::Error;

/// Animation errors (graceful degradation)
#[derive(Debug, Error)]
pub enum AnimationError {
#[error("GetMonitorInfo failed")]
MonitorInfo,
}

/// Focus tracking errors (graceful degradation)
#[derive(Debug, Error)]
pub enum FocusError {
Expand All @@ -23,12 +16,6 @@ pub enum FocusError {
mod tests {
use super::*;

#[test]
fn test_animation_error_display() {
let err = AnimationError::MonitorInfo;
assert_eq!(err.to_string(), "GetMonitorInfo failed");
}

#[test]
fn test_focus_error_display() {
let err = FocusError::HookInstall;
Expand Down
12 changes: 3 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,7 @@ fn toggle_window() {
}

// 4. Slide out
if let Err(e) = run_animation(hwnd, &config, direction, &bounds, &work_area, false) {
error!("Animation error: {e}");
}
run_animation(hwnd, &config, direction, &bounds, &work_area, false);
WINDOW_VISIBLE.store(false, Ordering::SeqCst);
info!(direction = ?direction, "Window: focus restored → slide out → hidden");
} else {
Expand All @@ -205,9 +203,7 @@ fn toggle_window() {
focus::save_previous(prev);

// 4. Slide in
if let Err(e) = run_animation(hwnd, &config, direction, &bounds, &work_area, true) {
error!("Animation error: {e}");
}
run_animation(hwnd, &config, direction, &bounds, &work_area, true);
let _ = unsafe { SetForegroundWindow(hwnd) };
focus::set_target(hwnd);
if let Err(e) = focus::install_hook(hwnd) {
Expand Down Expand Up @@ -250,9 +246,7 @@ fn handle_focus_lost() {
let direction = tracking::calc_direction(&bounds, &work_area);

let config = AnimConfig::default();
if let Err(e) = run_animation(target, &config, direction, &bounds, &work_area, false) {
error!("Animation error: {e}");
}
run_animation(target, &config, direction, &bounds, &work_area, false);
WINDOW_VISIBLE.store(false, Ordering::SeqCst);
info!(direction = ?direction, "Window: focus lost → hidden");
}
7 changes: 4 additions & 3 deletions src/tracking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub fn is_tracked_valid() -> bool {
/// Returns captured bounds, or None if GetWindowRect fails
pub fn save_bounds(hwnd: HWND) -> Option<WindowBounds> {
let mut rect = RECT::default();
if !unsafe { GetWindowRect(hwnd, &mut rect) }.is_ok() {
if unsafe { GetWindowRect(hwnd, &mut rect) }.is_err() {
return None;
}

Expand All @@ -82,8 +82,9 @@ pub fn load_bounds() -> Option<WindowBounds> {
}
}

/// Clear stored bounds
pub fn clear_bounds() {
/// Clear stored bounds (test-only)
#[cfg(test)]
fn clear_bounds() {
let ptr = STORED_BOUNDS.swap(null_mut(), Ordering::SeqCst);
if !ptr.is_null() {
// Safety: ptr was created by Box::into_raw
Expand Down