use crate::windows::Window;
use crate::ring::{Ring, Selector};
use winapi::shared::windef::HWND;
use winapi::um::winuser::{SetForegroundWindow, GetForegroundWindow, IsIconic};
#[derive(Debug)]
pub struct VirtualDesktop {
pub(crate) name: String,
windows: Ring<Window>,
minimized: Ring<Window>,
}
impl PartialEq for VirtualDesktop {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}
impl VirtualDesktop {
pub fn new(name: impl Into<String>) -> VirtualDesktop {
VirtualDesktop {
name: name.into(),
windows: Ring::new(Vec::new()),
minimized: Ring::new(Vec::new()),
}
}
pub fn push_window(&mut self, window: Window) {
let minimized = unsafe { IsIconic(window.hwnd()) } > 0;
if minimized {
self.minimized.push(window);
} else {
self.windows.push(window)
}
}
pub fn pull_window_by_hwnd(&mut self, hwnd: HWND) -> Option<Window> {
let condition = |window: &Window| window.hwnd() == hwnd;
let selector = Selector::Condition(&condition);
self.windows.remove(&selector).or(self.minimized.remove(&selector))
}
pub fn set_focus_by_hwnd(&mut self, hwnd: HWND) {
let condition = |window: &Window| window.hwnd() == hwnd;
let selector = Selector::Condition(&condition);
self.windows.focus(&selector);
}
pub fn set_minimized(&mut self, hwnd: HWND) {
let condition = |window: &Window| window.hwnd() == hwnd;
let selector = Selector::Condition(&condition);
match self.windows.remove(&selector) {
Some(window) => self.minimized.push(window),
None => {
let i = self.minimized.index(&selector);
if i.is_none() {
println!("Virtual desktop `{}` was requested to set window {:?} minimized, \
but it is not present there!", self.name, hwnd);
}
}
}
}
pub fn set_unminimized(&mut self, hwnd: HWND) {
let condition = |window: &Window| window.hwnd() == hwnd;
let selector = Selector::Condition(&condition);
match self.minimized.remove(&selector) {
Some(window) => self.windows.push(window),
None => {
let i = self.windows.index(&selector);
if i.is_none() {
println!("Virtual desktop `{}` was requested to set window {:?} unminimized, \
but it is not present there!", self.name, hwnd);
}
}
}
}
pub fn grab_focus(&self) {
let maybe_focused = self.windows.focused();
match maybe_focused {
Some(window) => {
let result = unsafe{ SetForegroundWindow(window.hwnd()) };
if result == 0 {
println!("Failed to grab focus on {:?}", window);
}
},
None => {},
}
}
pub(crate) fn update_focus(&mut self) {
self.set_focus_by_hwnd(unsafe{ GetForegroundWindow() });
}
}