diff --git a/src/clients.rs b/src/clients.rs index 6676d57..be4db9d 100644 --- a/src/clients.rs +++ b/src/clients.rs @@ -2,6 +2,7 @@ use std::{ops::Rem, usize}; use indexmap::IndexMap; use log::error; +use num_traits::Zero; use crate::util::BuildIdentityHasher; use crate::util::{Point, Size}; @@ -457,13 +458,20 @@ impl ClientState { where K: ClientKey, { - self.get_mut(key) - .into_option() - .map(|client| { - client.toggle_fullscreen(); + let fullscreen_size = self.screen_size + - Size::new(self.border_size * 2, self.border_size * 2); + + match self.get_mut(key).into_option() { + Some(client) => { + if client.toggle_fullscreen() { + client.size = fullscreen_size; + client.position = Point::zero(); + } + true - }) - .unwrap_or(false) + } + None => false, + } } /** @@ -491,35 +499,48 @@ impl ClientState { where K: ClientKey, { - let key = key.key(); - let client = self.clients.remove(&key); - let floating_client = self.floating_clients.remove(&key); + // do nothing if either no client matches the key or the client is fullscreen. + // FIXME: this should probably disable fullscreen mode (but that has to + // be handled in the wm state so that the backend can notify the client + // that it is no longer fullscreen) + if !self + .get(key) + .into_option() + .map(|c| c.is_fullscreen()) + .unwrap_or(true) + { + let key = key.key(); + let client = self.clients.remove(&key); + let floating_client = self.floating_clients.remove(&key); - match (client, floating_client) { - (Some(client), None) => { - self.floating_clients.insert(key, client); - self.remove_from_virtual_screens(&key); - } - (None, Some(floating_client)) => { - // transient clients cannot be tiled - match floating_client.is_transient() { - true => { - self.floating_clients.insert(key, floating_client); - } + match (client, floating_client) { + (Some(client), None) => { + self.floating_clients.insert(key, client); + self.remove_from_virtual_screens(&key); + } + (None, Some(floating_client)) => { + // transient clients cannot be tiled + match floating_client.is_transient() { + true => { + self.floating_clients.insert(key, floating_client); + } - false => { - self.clients.insert(key, floating_client); - self.virtual_screens.get_mut_current().insert(&key); + false => { + self.clients.insert(key, floating_client); + self.virtual_screens.get_mut_current().insert(&key); + } } } - } - _ => { - error!("wtf? Client was present in tiled and floating list.") - } - }; + _ => { + error!( + "wtf? Client was present in tiled and floating list." + ) + } + }; - // we added or removed a client from the tiling so the layout changed, rearrange - self.arrange_virtual_screen(); + // we added or removed a client from the tiling so the layout changed, rearrange + self.arrange_virtual_screen(); + } } fn remove_from_virtual_screens(&mut self, key: &K) @@ -1007,3 +1028,25 @@ impl ClientEntry { !self.is_vacant() } } + +impl ClientEntry<&client::Client> { + pub fn is_fullscreen(&self) -> bool { + match self { + ClientEntry::Tiled(c) | ClientEntry::Floating(c) => { + c.is_fullscreen() + } + ClientEntry::Vacant => false, + } + } +} + +impl ClientEntry<&mut client::Client> { + pub fn is_fullscreen(&self) -> bool { + match self { + ClientEntry::Tiled(c) | ClientEntry::Floating(c) => { + c.is_fullscreen() + } + ClientEntry::Vacant => false, + } + } +} diff --git a/src/state.rs b/src/state.rs index 4eadd27..a73cbf3 100644 --- a/src/state.rs +++ b/src/state.rs @@ -758,42 +758,45 @@ where fn start_move_resize_window(&mut self, event: &ButtonEvent) { let window = event.window; // xev.subwindow - match event.keycode { - MouseButton::Left => { - if self.clients.set_floating(&window) { - self.arrange_clients(); + if !self.clients.get(&window).is_fullscreen() { + match event.keycode { + MouseButton::Left => { + if self.clients.set_floating(&window) { + self.arrange_clients(); + } + + self.move_resize_window = + MoveResizeInfo::Move(MoveInfoInner { + window, + starting_cursor_pos: event.cursor_position, + starting_window_pos: self + .clients + .get(&window) + .unwrap() + .position, + }); } + MouseButton::Right => { + if self.clients.set_floating(&window) { + self.arrange_clients(); + } - self.move_resize_window = MoveResizeInfo::Move(MoveInfoInner { - window, - starting_cursor_pos: event.cursor_position, - starting_window_pos: self - .clients - .get(&window) - .unwrap() - .position, - }); - } - MouseButton::Right => { - if self.clients.set_floating(&window) { - self.arrange_clients(); + let client = self.clients.get(&window).unwrap(); + + let corner_pos = client.position + client.size.into(); + + self.backend.move_cursor(None, corner_pos.into()); + self.backend.grab_cursor(); + + self.move_resize_window = + MoveResizeInfo::Resize(ResizeInfoInner { + window, + starting_cursor_pos: corner_pos.into(), + starting_window_size: client.size, + }); } - - let client = self.clients.get(&window).unwrap(); - - let corner_pos = client.position + client.size.into(); - - self.backend.move_cursor(None, corner_pos.into()); - self.backend.grab_cursor(); - - self.move_resize_window = - MoveResizeInfo::Resize(ResizeInfoInner { - window, - starting_cursor_pos: corner_pos.into(), - starting_window_size: client.size, - }); + _ => {} } - _ => {} } }