commit adfc50b5dbdeed4e78f6cde59d88648e56bb2236
parent 11dbf5e86aacfb637429ac3d5796701a4524e299
Author: deurzen <m.deurzen@tum.de>
Date: Wed, 24 Mar 2021 21:32:03 +0100
switches to Cell for Copy fields
Diffstat:
8 files changed, 320 insertions(+), 324 deletions(-)
diff --git a/src/core/client.rs b/src/core/client.rs
@@ -13,7 +13,7 @@ use winsys::hints::SizeHints;
use winsys::window::Window;
use winsys::window::WindowType;
-use std::cell::Ref;
+use std::cell::Cell;
use std::cell::RefCell;
use std::time::SystemTime;
@@ -24,49 +24,49 @@ pub struct Client {
name: RefCell<String>,
class: RefCell<String>,
instance: RefCell<String>,
- context: RefCell<usize>,
- workspace: RefCell<usize>,
+ context: Cell<usize>,
+ workspace: Cell<usize>,
window_type: WindowType,
- active_region: RefCell<Region>,
- previous_region: RefCell<Region>,
- inner_region: RefCell<Region>,
- free_region: RefCell<Region>,
- tile_region: RefCell<Region>,
- decoration: RefCell<Decoration>,
- size_hints: RefCell<Option<SizeHints>>,
- warp_pos: RefCell<Option<Pos>>,
+ active_region: Cell<Region>,
+ previous_region: Cell<Region>,
+ inner_region: Cell<Region>,
+ free_region: Cell<Region>,
+ tile_region: Cell<Region>,
+ decoration: Cell<Decoration>,
+ size_hints: Cell<Option<SizeHints>>,
+ warp_pos: Cell<Option<Pos>>,
parent: Option<Window>,
children: RefCell<Vec<Window>>,
leader: Option<Window>,
producer: Option<Window>,
consumers: RefCell<Vec<Window>>,
- focused: RefCell<bool>,
- mapped: RefCell<bool>,
- managed: RefCell<bool>,
- in_window: RefCell<bool>,
- floating: RefCell<bool>,
- fullscreen: RefCell<bool>,
- iconified: RefCell<bool>,
- disowned: RefCell<bool>,
- sticky: RefCell<bool>,
- invincible: RefCell<bool>,
- urgent: RefCell<bool>,
- consuming: RefCell<bool>,
- producing: RefCell<bool>,
+ focused: Cell<bool>,
+ mapped: Cell<bool>,
+ managed: Cell<bool>,
+ in_window: Cell<bool>,
+ floating: Cell<bool>,
+ fullscreen: Cell<bool>,
+ iconified: Cell<bool>,
+ disowned: Cell<bool>,
+ sticky: Cell<bool>,
+ invincible: Cell<bool>,
+ urgent: Cell<bool>,
+ consuming: Cell<bool>,
+ producing: Cell<bool>,
pid: Option<Pid>,
ppid: Option<Pid>,
- last_focused: RefCell<SystemTime>,
+ last_focused: Cell<SystemTime>,
managed_since: SystemTime,
- expected_unmap_count: RefCell<u8>,
+ expected_unmap_count: Cell<u8>,
}
-impl<'client> Identify for Client {
+impl Identify for Client {
fn id(&self) -> Ident {
self.window as Ident
}
}
-impl<'client> Client {
+impl Client {
pub fn new(
zone: ZoneId,
window: Window,
@@ -85,40 +85,40 @@ impl<'client> Client {
name: RefCell::new(name.into()),
class: RefCell::new(class.into()),
instance: RefCell::new(instance.into()),
- context: RefCell::new(0),
- workspace: RefCell::new(0),
+ context: Cell::new(0),
+ workspace: Cell::new(0),
window_type,
- active_region: RefCell::new(Default::default()),
- previous_region: RefCell::new(Default::default()),
- inner_region: RefCell::new(Default::default()),
- free_region: RefCell::new(Default::default()),
- tile_region: RefCell::new(Default::default()),
- decoration: RefCell::new(Default::default()),
- size_hints: RefCell::new(None),
- warp_pos: RefCell::new(None),
+ active_region: Cell::new(Default::default()),
+ previous_region: Cell::new(Default::default()),
+ inner_region: Cell::new(Default::default()),
+ free_region: Cell::new(Default::default()),
+ tile_region: Cell::new(Default::default()),
+ decoration: Cell::new(Default::default()),
+ size_hints: Cell::new(None),
+ warp_pos: Cell::new(None),
parent: None,
children: RefCell::new(Vec::new()),
leader: None,
producer: None,
consumers: RefCell::new(Vec::new()),
- focused: RefCell::new(false),
- mapped: RefCell::new(false),
- managed: RefCell::new(true),
- in_window: RefCell::new(false),
- floating: RefCell::new(false),
- fullscreen: RefCell::new(false),
- iconified: RefCell::new(false),
- disowned: RefCell::new(false),
- sticky: RefCell::new(false),
- invincible: RefCell::new(false),
- urgent: RefCell::new(false),
- consuming: RefCell::new(false),
- producing: RefCell::new(true),
+ focused: Cell::new(false),
+ mapped: Cell::new(false),
+ managed: Cell::new(true),
+ in_window: Cell::new(false),
+ floating: Cell::new(false),
+ fullscreen: Cell::new(false),
+ iconified: Cell::new(false),
+ disowned: Cell::new(false),
+ sticky: Cell::new(false),
+ invincible: Cell::new(false),
+ urgent: Cell::new(false),
+ consuming: Cell::new(false),
+ producing: Cell::new(true),
pid,
ppid,
- last_focused: RefCell::new(SystemTime::now()),
+ last_focused: Cell::new(SystemTime::now()),
managed_since: SystemTime::now(),
- expected_unmap_count: RefCell::new(0),
+ expected_unmap_count: Cell::new(0),
}
}
@@ -143,8 +143,16 @@ impl<'client> Client {
}
#[inline]
- pub fn name(&'client self) -> Ref<'client, String> {
- self.name.borrow()
+ pub fn set_name(
+ &self,
+ name: impl Into<String>,
+ ) {
+ self.name.replace(name.into());
+ }
+
+ #[inline]
+ pub fn name(&self) -> String {
+ self.name.borrow().to_owned()
}
#[inline]
@@ -159,16 +167,16 @@ impl<'client> Client {
}
#[inline]
- pub fn set_name(
+ pub fn set_class(
&self,
- name: impl Into<String>,
+ class: impl Into<String>,
) {
- self.name.replace(name.into());
+ self.class.replace(class.into());
}
#[inline]
- pub fn class(&'client self) -> Ref<'client, String> {
- self.class.borrow()
+ pub fn class(&self) -> String {
+ self.class.borrow().to_owned()
}
#[inline]
@@ -183,16 +191,16 @@ impl<'client> Client {
}
#[inline]
- pub fn set_class(
+ pub fn set_instance(
&self,
- class: impl Into<String>,
+ instance: impl Into<String>,
) {
- self.class.replace(class.into());
+ self.instance.replace(instance.into());
}
#[inline]
- pub fn instance(&'client self) -> Ref<'client, String> {
- self.instance.borrow()
+ pub fn instance(&self) -> String {
+ self.instance.borrow().to_owned()
}
#[inline]
@@ -207,19 +215,6 @@ impl<'client> Client {
}
#[inline]
- pub fn set_instance(
- &self,
- instance: impl Into<String>,
- ) {
- self.instance.replace(instance.into());
- }
-
- #[inline]
- pub fn context(&self) -> usize {
- self.context.borrow().clone()
- }
-
- #[inline]
pub fn set_context(
&self,
context: usize,
@@ -228,8 +223,8 @@ impl<'client> Client {
}
#[inline]
- pub fn workspace(&self) -> usize {
- self.workspace.borrow().clone()
+ pub fn context(&self) -> usize {
+ self.context.get()
}
#[inline]
@@ -241,44 +236,33 @@ impl<'client> Client {
}
#[inline]
- pub fn window_type(&self) -> WindowType {
- self.window_type
+ pub fn workspace(&self) -> usize {
+ self.workspace.get()
}
#[inline]
- pub fn free_region(&self) -> Region {
- self.free_region.borrow().clone()
+ pub fn window_type(&self) -> WindowType {
+ self.window_type
}
#[inline]
- pub fn tile_region(&self) -> Region {
- self.tile_region.borrow().clone()
+ fn set_active_region(
+ &self,
+ active_region: Region,
+ ) {
+ self.set_inner_region(active_region);
+ let active_region = self.active_region.replace(active_region);
+ self.previous_region.replace(active_region);
}
#[inline]
pub fn active_region(&self) -> Region {
- self.active_region.borrow().clone()
+ self.active_region.get()
}
#[inline]
pub fn previous_region(&self) -> Region {
- self.previous_region.borrow().clone()
- }
-
- #[inline]
- pub fn inner_region(&self) -> Region {
- self.inner_region.borrow().clone()
- }
-
- #[inline]
- fn set_active_region(
- &self,
- active_region: Region,
- ) {
- self.previous_region
- .replace(self.active_region.borrow().clone());
- self.active_region.replace(active_region);
- self.set_inner_region(active_region);
+ self.previous_region.get()
}
#[inline]
@@ -286,8 +270,8 @@ impl<'client> Client {
&self,
active_region: Region,
) {
- self.inner_region.replace(
- if let Some(frame) = self.decoration.borrow().clone().frame {
+ self.inner_region
+ .replace(if let Some(frame) = self.decoration.get().frame {
let mut inner_region = active_region - frame.extents;
inner_region.pos.x = frame.extents.left;
@@ -304,8 +288,7 @@ impl<'client> Client {
inner_region.pos.y = 0;
inner_region
- },
- );
+ });
}
#[inline]
@@ -326,18 +309,18 @@ impl<'client> Client {
}
#[inline]
- pub fn decoration(&self) -> Decoration {
- self.decoration.borrow().clone()
+ pub fn free_region(&self) -> Region {
+ self.free_region.get()
}
#[inline]
- pub fn frame_extents(&self) -> Extents {
- Extents {
- left: 0,
- right: 0,
- top: 0,
- bottom: 0,
- } + self.decoration.borrow().clone()
+ pub fn tile_region(&self) -> Region {
+ self.tile_region.get()
+ }
+
+ #[inline]
+ pub fn inner_region(&self) -> Region {
+ self.inner_region.get()
}
#[inline]
@@ -349,8 +332,18 @@ impl<'client> Client {
}
#[inline]
- pub fn size_hints(&self) -> Option<SizeHints> {
- self.size_hints.borrow().clone()
+ pub fn decoration(&self) -> Decoration {
+ self.decoration.get().to_owned()
+ }
+
+ #[inline]
+ pub fn frame_extents(&self) -> Extents {
+ Extents {
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0,
+ } + self.decoration.get().to_owned()
}
#[inline]
@@ -358,12 +351,12 @@ impl<'client> Client {
&self,
size_hints: Option<SizeHints>,
) {
- self.size_hints.replace(size_hints);
+ self.size_hints.set(size_hints);
}
#[inline]
- pub fn warp_pos(&self) -> Option<Pos> {
- self.warp_pos.borrow().clone()
+ pub fn size_hints(&self) -> Option<SizeHints> {
+ self.size_hints.get()
}
#[inline]
@@ -380,6 +373,11 @@ impl<'client> Client {
}
#[inline]
+ pub fn warp_pos(&self) -> Option<Pos> {
+ self.warp_pos.get().to_owned()
+ }
+
+ #[inline]
pub fn set_parent(
&mut self,
parent: Window,
@@ -406,7 +404,6 @@ impl<'client> Client {
child: Window,
) {
let mut children = self.children.borrow_mut();
-
if let Some(index) = children.iter().rposition(|&c| c == child) {
children.remove(index);
}
@@ -444,11 +441,6 @@ impl<'client> Client {
}
#[inline]
- pub fn consumer_len(&self) -> usize {
- self.consumers.borrow().len()
- }
-
- #[inline]
pub fn add_consumer(
&self,
consumer: Window,
@@ -462,22 +454,19 @@ impl<'client> Client {
consumer: Window,
) {
let mut consumers = self.consumers.borrow_mut();
-
if let Some(index) = consumers.iter().rposition(|&c| c == consumer) {
consumers.remove(index);
}
}
#[inline]
- pub fn is_free(&self) -> bool {
- self.floating.borrow().clone()
- || self.disowned.borrow().clone()
- || !self.managed.borrow().clone()
+ pub fn consumer_len(&self) -> usize {
+ self.consumers.borrow().len()
}
#[inline]
- pub fn is_focused(&self) -> bool {
- self.focused.borrow().clone()
+ pub fn is_free(&self) -> bool {
+ self.floating.get() || self.disowned.get() || !self.managed.get()
}
#[inline]
@@ -485,12 +474,12 @@ impl<'client> Client {
&self,
focused: bool,
) {
- self.focused.replace(focused);
+ self.focused.set(focused);
}
#[inline]
- pub fn is_mapped(&self) -> bool {
- self.mapped.borrow().clone()
+ pub fn is_focused(&self) -> bool {
+ self.focused.get()
}
#[inline]
@@ -498,12 +487,12 @@ impl<'client> Client {
&self,
mapped: bool,
) {
- self.mapped.replace(mapped);
+ self.mapped.set(mapped);
}
#[inline]
- pub fn is_managed(&self) -> bool {
- self.managed.borrow().clone()
+ pub fn is_mapped(&self) -> bool {
+ self.mapped.get()
}
#[inline]
@@ -511,12 +500,12 @@ impl<'client> Client {
&self,
managed: bool,
) {
- self.managed.replace(managed);
+ self.managed.set(managed);
}
#[inline]
- pub fn is_in_window(&self) -> bool {
- self.in_window.borrow().clone()
+ pub fn is_managed(&self) -> bool {
+ self.managed.get()
}
#[inline]
@@ -524,12 +513,12 @@ impl<'client> Client {
&self,
in_window: bool,
) {
- self.in_window.replace(in_window);
+ self.in_window.set(in_window);
}
#[inline]
- pub fn is_floating(&self) -> bool {
- self.floating.borrow().clone()
+ pub fn is_in_window(&self) -> bool {
+ self.in_window.get()
}
#[inline]
@@ -541,8 +530,8 @@ impl<'client> Client {
}
#[inline]
- pub fn is_fullscreen(&self) -> bool {
- self.fullscreen.borrow().clone()
+ pub fn is_floating(&self) -> bool {
+ self.floating.get()
}
#[inline]
@@ -554,8 +543,8 @@ impl<'client> Client {
}
#[inline]
- pub fn is_iconified(&self) -> bool {
- self.iconified.borrow().clone()
+ pub fn is_fullscreen(&self) -> bool {
+ self.fullscreen.get()
}
#[inline]
@@ -567,8 +556,8 @@ impl<'client> Client {
}
#[inline]
- pub fn is_disowned(&self) -> bool {
- self.disowned.borrow().clone()
+ pub fn is_iconified(&self) -> bool {
+ self.iconified.get()
}
#[inline]
@@ -580,8 +569,8 @@ impl<'client> Client {
}
#[inline]
- pub fn is_sticky(&self) -> bool {
- self.sticky.borrow().clone()
+ pub fn is_disowned(&self) -> bool {
+ self.disowned.get()
}
#[inline]
@@ -593,8 +582,8 @@ impl<'client> Client {
}
#[inline]
- pub fn is_invincible(&self) -> bool {
- self.invincible.borrow().clone()
+ pub fn is_sticky(&self) -> bool {
+ self.sticky.get()
}
#[inline]
@@ -606,8 +595,8 @@ impl<'client> Client {
}
#[inline]
- pub fn is_urgent(&self) -> bool {
- self.urgent.borrow().clone()
+ pub fn is_invincible(&self) -> bool {
+ self.invincible.get()
}
#[inline]
@@ -619,8 +608,8 @@ impl<'client> Client {
}
#[inline]
- pub fn is_consuming(&self) -> bool {
- self.consuming.borrow().clone()
+ pub fn is_urgent(&self) -> bool {
+ self.urgent.get()
}
#[inline]
@@ -632,8 +621,8 @@ impl<'client> Client {
}
#[inline]
- pub fn is_producing(&self) -> bool {
- self.producing.borrow().clone()
+ pub fn is_consuming(&self) -> bool {
+ self.consuming.get()
}
#[inline]
@@ -645,6 +634,11 @@ impl<'client> Client {
}
#[inline]
+ pub fn is_producing(&self) -> bool {
+ self.producing.get()
+ }
+
+ #[inline]
pub fn pid(&self) -> Option<Pid> {
self.pid
}
@@ -656,7 +650,7 @@ impl<'client> Client {
#[inline]
pub fn last_focused(&self) -> SystemTime {
- self.last_focused.borrow().clone()
+ self.last_focused.get()
}
#[inline]
@@ -667,17 +661,12 @@ impl<'client> Client {
#[inline]
pub fn expect_unmap(&self) {
self.expected_unmap_count
- .replace(self.expected_unmap_count.borrow().clone() + 1);
- }
-
- #[inline]
- pub fn is_expecting_unmap(&self) -> bool {
- self.expected_unmap_count.borrow().clone() > 0
+ .replace(self.expected_unmap_count.get() + 1);
}
#[inline]
pub fn consume_unmap_if_expecting(&self) -> bool {
- let expected_unmap_count = self.expected_unmap_count.borrow().clone();
+ let expected_unmap_count = self.expected_unmap_count.get();
let expecting = expected_unmap_count > 0;
if expecting {
@@ -686,9 +675,14 @@ impl<'client> Client {
expecting
}
+
+ #[inline]
+ pub fn is_expecting_unmap(&self) -> bool {
+ self.expected_unmap_count.get() > 0
+ }
}
-impl<'client> PartialEq for Client {
+impl PartialEq for Client {
fn eq(
&self,
other: &Self,
@@ -708,7 +702,7 @@ impl std::fmt::Debug for Hex32 {
}
}
-impl<'client> std::fmt::Debug for Client {
+impl std::fmt::Debug for Client {
fn fmt(
&self,
f: &mut std::fmt::Formatter<'_>,
diff --git a/src/core/consume.rs b/src/core/consume.rs
@@ -1,4 +1,5 @@
use crate::client::Client;
+use crate::util::BuildIdHasher;
use winsys::connection::Pid;
use winsys::window::Window;
@@ -19,7 +20,7 @@ pub fn get_spawner_pid(
pid: Pid,
wm_pid: Pid,
pid_map: &HashMap<Pid, Window>,
- client_map: &HashMap<Window, Client>,
+ client_map: &HashMap<Window, Client, BuildIdHasher>,
) -> Option<Pid> {
let mut ppid = get_parent_pid(pid);
diff --git a/src/core/defaults.rs b/src/core/defaults.rs
@@ -14,6 +14,8 @@ macro_rules! WM_NAME (
() => { "wzrd" };
);
+pub const WORKSPACE_NAMES: [&str; 10] = ["main", "web", "term", "4", "5", "6", "7", "8", "9", "10"];
+
impl Client {
pub const MIN_CLIENT_DIM: Dim = Dim {
w: 75,
diff --git a/src/core/model.rs b/src/core/model.rs
@@ -1,3 +1,6 @@
+#[allow(unused_imports)]
+use crate::util::Util;
+
use crate::binding::KeyBindings;
use crate::binding::MouseBindings;
use crate::change::Change;
@@ -8,6 +11,7 @@ use crate::cycle::Cycle;
use crate::cycle::InsertPos;
use crate::cycle::Selector;
use crate::decoration::Decoration;
+use crate::defaults;
use crate::error::StateChangeError;
use crate::identify::Index;
use crate::jump::JumpCriterium;
@@ -22,15 +26,13 @@ use crate::placement::PlacementTarget;
use crate::rule::Rules;
use crate::stack::StackLayer;
use crate::stack::StackManager;
+use crate::util::BuildIdHasher;
use crate::workspace::Buffer;
use crate::workspace::BufferKind;
use crate::workspace::Workspace;
use crate::zone::ZoneContent;
use crate::zone::ZoneManager;
-#[allow(unused_imports)]
-use crate::util::Util;
-
use winsys::connection::Connection;
use winsys::connection::Pid;
use winsys::event::Event;
@@ -56,19 +58,20 @@ use winsys::window::WindowState;
use winsys::window::WindowType;
use std::collections::HashMap;
+use std::collections::HashSet;
-pub struct Model<'a> {
- conn: &'a mut dyn Connection,
- stack: StackManager,
- stacking_order: Vec<Window>,
+pub struct Model<'model> {
+ conn: &'model mut dyn Connection,
zone_manager: ZoneManager,
+ stack_manager: StackManager,
+ stacking_order: Vec<Window>,
pid_map: HashMap<Pid, Window>,
- client_map: HashMap<Window, Client>,
- window_map: HashMap<Window, Window>,
- frame_map: HashMap<Window, Window>,
- sticky_clients: Vec<Window>,
- unmanaged_windows: Vec<Window>,
- fullscreen_regions: HashMap<Window, Region>,
+ client_map: HashMap<Window, Client, BuildIdHasher>,
+ window_map: HashMap<Window, Window, BuildIdHasher>,
+ frame_map: HashMap<Window, Window, BuildIdHasher>,
+ sticky_clients: HashSet<Window, BuildIdHasher>,
+ unmanaged_windows: HashSet<Window, BuildIdHasher>,
+ fullscreen_regions: HashMap<Window, Region, BuildIdHasher>,
partitions: Cycle<Partition>,
workspaces: Cycle<Workspace>,
move_buffer: Buffer,
@@ -80,37 +83,34 @@ pub struct Model<'a> {
jumped_from: Option<Window>,
}
-impl<'a> Model<'a> {
+impl<'model> Model<'model> {
pub fn new(
- conn: &'a mut dyn Connection,
+ conn: &'model mut dyn Connection,
key_bindings: &KeyBindings,
mouse_bindings: &MouseBindings,
) -> Self {
- let move_handle = conn.create_handle();
- let resize_handle = conn.create_handle();
-
Self::init(
Self {
- conn,
- stack: StackManager::new(),
- stacking_order: Vec::new(),
zone_manager: ZoneManager::new(),
+ stack_manager: StackManager::new(),
+ stacking_order: Vec::with_capacity(100),
pid_map: HashMap::new(),
- client_map: HashMap::new(),
- window_map: HashMap::new(),
- frame_map: HashMap::new(),
- sticky_clients: Vec::new(),
- unmanaged_windows: Vec::new(),
- fullscreen_regions: HashMap::new(),
+ client_map: HashMap::with_hasher(BuildIdHasher),
+ window_map: HashMap::with_hasher(BuildIdHasher),
+ frame_map: HashMap::with_hasher(BuildIdHasher),
+ sticky_clients: HashSet::with_hasher(BuildIdHasher),
+ unmanaged_windows: HashSet::with_hasher(BuildIdHasher),
+ fullscreen_regions: HashMap::with_hasher(BuildIdHasher),
partitions: Cycle::new(Vec::new(), false),
- workspaces: Cycle::new(Vec::with_capacity(10), false),
- move_buffer: Buffer::new(BufferKind::Move, move_handle),
- resize_buffer: Buffer::new(BufferKind::Resize, resize_handle),
+ workspaces: Cycle::new(Vec::with_capacity(defaults::WORKSPACE_NAMES.len()), false),
+ move_buffer: Buffer::new(BufferKind::Move, conn.create_handle()),
+ resize_buffer: Buffer::new(BufferKind::Resize, conn.create_handle()),
prev_partition: 0,
prev_workspace: 0,
running: true,
focus: None,
jumped_from: None,
+ conn,
},
key_bindings,
mouse_bindings,
@@ -125,13 +125,11 @@ impl<'a> Model<'a> {
info!("initializing window manager");
model.acquire_partitions();
- let workspaces = ["main", "web", "term", "4", "5", "6", "7", "8", "9", "10"];
-
- for (i, &workspace_name) in workspaces.iter().enumerate() {
+ for (i, &workspace_name) in defaults::WORKSPACE_NAMES.iter().enumerate() {
let region = model
.partitions
.active_element()
- .unwrap()
+ .expect("no screen region found")
.screen()
.placeable_region();
@@ -148,15 +146,17 @@ impl<'a> Model<'a> {
}
model.workspaces.activate_for(&Selector::AtIndex(0));
-
- model.conn.init_wm_properties(WM_NAME!(), &workspaces);
model.conn.set_current_desktop(0);
+ model
+ .conn
+ .init_wm_properties(WM_NAME!(), &defaults::WORKSPACE_NAMES);
+
model.conn.grab_bindings(
&key_bindings
.keys()
- .cloned()
- .collect::<Vec<winsys::input::KeyCode>>(),
+ .into_iter()
+ .collect::<Vec<&winsys::input::KeyCode>>(),
&mouse_bindings
.keys()
.into_iter()
@@ -292,6 +292,79 @@ impl<'a> Model<'a> {
}
}
+ fn window(
+ &self,
+ window: Window,
+ ) -> Option<Window> {
+ if self.window_map.contains_key(&window) {
+ return Some(window);
+ }
+
+ Some(self.frame_map.get(&window)?.to_owned())
+ }
+
+ fn frame(
+ &self,
+ window: Window,
+ ) -> Option<Window> {
+ if self.frame_map.contains_key(&window) {
+ return Some(window);
+ }
+
+ Some(self.window_map.get(&window)?.to_owned())
+ }
+
+ fn client_any(
+ &self,
+ mut window: Window,
+ ) -> Option<&Client> {
+ if let Some(&inside) = self.frame_map.get(&window) {
+ window = inside;
+ }
+
+ self.client_map.get(&window)
+ }
+
+ fn client(
+ &self,
+ window: Window,
+ ) -> Option<&Client> {
+ self.client_any(window).filter(|client| client.is_managed())
+ }
+
+ fn client_any_mut(
+ &mut self,
+ mut window: Window,
+ ) -> Option<&mut Client> {
+ if let Some(inside) = self.frame_map.get(&window) {
+ window = *inside;
+ }
+
+ self.client_map.get_mut(&window)
+ }
+
+ fn client_mut(
+ &mut self,
+ window: Window,
+ ) -> Option<&mut Client> {
+ self.client_any_mut(window)
+ .filter(|client| client.is_managed())
+ }
+
+ fn workspace(
+ &self,
+ index: Index,
+ ) -> &Workspace {
+ self.workspaces.get(index).unwrap()
+ }
+
+ fn workspace_mut(
+ &mut self,
+ index: Index,
+ ) -> &mut Workspace {
+ self.workspaces.get_mut(index).unwrap()
+ }
+
fn acquire_partitions(&mut self) {
let partitions: Vec<Partition> = self
.conn
@@ -381,9 +454,9 @@ impl<'a> Model<'a> {
None => return,
};
- let desktop = self.stack.layer_windows(StackLayer::Desktop);
- let below = self.stack.layer_windows(StackLayer::Below);
- let dock = self.stack.layer_windows(StackLayer::Dock);
+ let desktop = self.stack_manager.layer_windows(StackLayer::Desktop);
+ let below = self.stack_manager.layer_windows(StackLayer::Below);
+ let dock = self.stack_manager.layer_windows(StackLayer::Dock);
let stack: Vec<Window> = workspace
.stack_after_focus()
@@ -404,8 +477,8 @@ impl<'a> Model<'a> {
.map_or(true, |client| self.is_free(client))
});
- let above = self.stack.layer_windows(StackLayer::Above);
- let notification = self.stack.layer_windows(StackLayer::Notification);
+ let above = self.stack_manager.layer_windows(StackLayer::Above);
+ let notification = self.stack_manager.layer_windows(StackLayer::Notification);
let mut windows: Vec<Window> = desktop
.into_iter()
@@ -421,7 +494,7 @@ impl<'a> Model<'a> {
{
// handle above-other relationships
- for &window in self.stack.above_other().keys() {
+ for &window in self.stack_manager.above_other().keys() {
let index = windows.iter().position(|&w| w == window);
if let Some(index) = index {
@@ -429,7 +502,7 @@ impl<'a> Model<'a> {
}
}
- for (&window, &sibling) in self.stack.above_other() {
+ for (&window, &sibling) in self.stack_manager.above_other() {
let index = windows.iter().position(|&w| w == sibling);
if let Some(index) = index {
@@ -442,7 +515,7 @@ impl<'a> Model<'a> {
{
// handle below-other relationships
- for &window in self.stack.below_other().keys() {
+ for &window in self.stack_manager.below_other().keys() {
let index = windows.iter().position(|&w| w == window);
if let Some(index) = index {
@@ -450,7 +523,7 @@ impl<'a> Model<'a> {
}
}
- for (&window, &sibling) in self.stack.below_other() {
+ for (&window, &sibling) in self.stack_manager.below_other() {
let index = windows.iter().position(|&w| w == sibling);
if let Some(index) = index {
@@ -479,6 +552,7 @@ impl<'a> Model<'a> {
return;
}
+ // TODO: keep separate client Vec, open-ended hash iteration not efficient
let mut client_list: Vec<&Client> = self.client_map.values().collect::<Vec<&Client>>();
client_list.sort_by_key(|&a| a.managed_since());
@@ -504,90 +578,6 @@ impl<'a> Model<'a> {
self.conn.update_client_list_stacking(&client_list_stacking);
}
- fn window(
- &self,
- window: Window,
- ) -> Option<Window> {
- if self.window_map.contains_key(&window) {
- return Some(window);
- }
-
- Some(*self.frame_map.get(&window)?)
- }
-
- fn frame(
- &self,
- window: Window,
- ) -> Option<Window> {
- if self.frame_map.contains_key(&window) {
- return Some(window);
- }
-
- Some(*self.window_map.get(&window)?)
- }
-
- fn client_any(
- &self,
- mut window: Window,
- ) -> Option<&Client> {
- if let Some(inside) = self.frame_map.get(&window) {
- window = *inside;
- }
-
- self.client_map.get(&window)
- }
-
- fn client(
- &self,
- window: Window,
- ) -> Option<&Client> {
- self.client_any(window).and_then(|client| {
- if client.is_managed() {
- Some(client)
- } else {
- None
- }
- })
- }
-
- fn client_any_mut(
- &mut self,
- mut window: Window,
- ) -> Option<&mut Client> {
- if let Some(inside) = self.frame_map.get(&window) {
- window = *inside;
- }
-
- self.client_map.get_mut(&window)
- }
-
- fn client_mut(
- &mut self,
- window: Window,
- ) -> Option<&mut Client> {
- self.client_any_mut(window).and_then(|client| {
- if client.is_managed() {
- Some(client)
- } else {
- None
- }
- })
- }
-
- fn workspace(
- &self,
- index: Index,
- ) -> &Workspace {
- self.workspaces.get(index).unwrap()
- }
-
- fn workspace_mut(
- &mut self,
- index: Index,
- ) -> &mut Workspace {
- self.workspaces.get_mut(index).unwrap()
- }
-
fn detect_rules(
&self,
instance: &str,
@@ -636,7 +626,7 @@ impl<'a> Model<'a> {
}
self.conn.init_unmanaged(window);
- self.unmanaged_windows.push(window);
+ self.unmanaged_windows.insert(window);
return;
}
@@ -789,7 +779,7 @@ impl<'a> Model<'a> {
if let Some(parent) = self.client_any_mut(parent) {
let parent_frame = parent.frame();
parent.add_child(window);
- self.stack.add_above_other(frame, parent_frame);
+ self.stack_manager.add_above_other(frame, parent_frame);
}
}
@@ -1055,7 +1045,7 @@ impl<'a> Model<'a> {
w.remove_icon(window);
});
- self.stack.remove_window(window);
+ self.stack_manager.remove_window(window);
self.frame_map.remove(&frame);
self.window_map.remove(&window);
self.client_map.remove(&window);
@@ -2195,7 +2185,7 @@ impl<'a> Model<'a> {
client.set_sticky(true);
self.conn
.set_window_state(window, WindowState::Sticky, true);
- self.sticky_clients.push(window);
+ self.sticky_clients.insert(window);
for workspace in self.workspaces.iter_mut() {
if workspace.number() as Index != workspace_index {
@@ -2226,9 +2216,7 @@ impl<'a> Model<'a> {
self.conn
.set_window_state(window, WindowState::Sticky, false);
- if let Some(index) = self.sticky_clients.iter().position(|&s| s == window) {
- self.sticky_clients.remove(index);
- }
+ self.sticky_clients.remove(&window);
for workspace in self.workspaces.iter_mut() {
if workspace.number() as Index != workspace_index {
@@ -2944,7 +2932,7 @@ impl<'a> Model<'a> {
(Some(WindowState::Above), _) => Some(StackLayer::Above),
(..) => None,
}
- .map(|layer| self.stack.add_window(window, layer));
+ .map(|layer| self.stack_manager.add_window(window, layer));
self.apply_stack(self.active_workspace());
}
@@ -3008,9 +2996,7 @@ impl<'a> Model<'a> {
self.apply_layout(active_workspace, true);
}
- if let Some(index) = self.unmanaged_windows.iter().position(|&s| s == window) {
- self.unmanaged_windows.remove(index);
- }
+ self.unmanaged_windows.remove(&window);
let client = self.client_any(window);
@@ -3338,8 +3324,8 @@ impl<'a> Model<'a> {
);
match mode {
- StackMode::Above => self.stack.add_above_other(window, sibling),
- StackMode::Below => self.stack.add_below_other(window, sibling),
+ StackMode::Above => self.stack_manager.add_above_other(window, sibling),
+ StackMode::Below => self.stack_manager.add_below_other(window, sibling),
}
self.apply_stack(self.active_workspace());
diff --git a/src/core/util.rs b/src/core/util.rs
@@ -8,7 +8,7 @@ use winsys::input::Modifier;
use winsys::input::MouseShortcut;
use std::cmp::Ord;
-use std::hash::BuildHasherDefault;
+use std::hash::BuildHasher;
use std::hash::Hasher;
use std::ops::Add;
use std::ops::AddAssign;
@@ -43,7 +43,19 @@ impl Hasher for IdHasher {
}
}
-pub type BuildIdHasher = BuildHasherDefault<IdHasher>;
+#[derive(Default, Clone)]
+pub struct BuildIdHasher;
+
+impl BuildHasher for BuildIdHasher {
+ type Hasher = IdHasher;
+
+ #[inline]
+ fn build_hasher(&self) -> Self::Hasher {
+ Self::Hasher {
+ state: 0,
+ }
+ }
+}
pub struct Util {}
diff --git a/src/core/workspace.rs b/src/core/workspace.rs
@@ -14,6 +14,7 @@ use crate::placement::Placement;
use crate::placement::PlacementMethod;
use crate::placement::PlacementRegion;
use crate::placement::PlacementTarget;
+use crate::util::BuildIdHasher;
use crate::zone::ZoneId;
use crate::zone::ZoneManager;
@@ -336,7 +337,7 @@ impl Workspace {
pub fn arrange<F>(
&self,
zone_manager: &mut ZoneManager,
- client_map: &HashMap<Window, Client>,
+ client_map: &HashMap<Window, Client, BuildIdHasher>,
screen_region: Region,
ignore_filter: F,
) -> Vec<Placement>
@@ -419,7 +420,7 @@ impl Workspace {
pub fn cycle_focus(
&mut self,
dir: Direction,
- client_map: &HashMap<Window, Client>,
+ client_map: &HashMap<Window, Client, BuildIdHasher>,
zone_manager: &ZoneManager,
) -> Option<(Window, Window)> {
if self.clients.len() < 2 {
diff --git a/src/winsys/connection.rs b/src/winsys/connection.rs
@@ -139,7 +139,7 @@ pub trait Connection {
);
fn grab_bindings(
&self,
- key_codes: &[KeyCode],
+ key_codes: &[&KeyCode],
mouse_bindings: &[&(MouseEventKey, MouseShortcut)],
);
fn regrab_buttons(
diff --git a/src/winsys/xdata/xconnection.rs b/src/winsys/xdata/xconnection.rs
@@ -1513,7 +1513,7 @@ impl<'conn, Conn: connection::Connection> Connection for XConnection<'conn, Conn
fn grab_bindings(
&self,
- key_codes: &[KeyCode],
+ key_codes: &[&KeyCode],
mouse_bindings: &[&(MouseEventKey, MouseShortcut)],
) {
for &m in &[0, u16::from(ModMask::M2)] {