small changes/fixes

This commit is contained in:
noonebtw 2021-04-23 02:54:54 +02:00
parent 08a0c6b089
commit c6fc328702

View file

@ -1,7 +1,7 @@
use std::{borrow::Borrow, cell::RefCell, collections::HashMap, rc::Rc}; use std::{borrow::Borrow, cell::RefCell, collections::HashMap, rc::Rc};
use std::{ use std::{
hash::{Hash, Hasher}, hash::{Hash, Hasher},
rc::Weak, num::NonZeroI32,
}; };
use x11::xlib::Window; use x11::xlib::Window;
@ -89,343 +89,313 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn client_lists_test() {} fn client_lists_test() {
let mut clients = ClientState::default();
clients.insert(Client {
window: 1,
size: (1, 1),
position: (1, 1),
floating: false,
});
clients.insert(Client {
window: 2,
size: (1, 1),
position: (1, 1),
floating: false,
});
clients.stack_unstacked();
clients.refresh_virtual_screen();
clients.arange_virtual_screen(600, 400);
println!("{:#?}", clients);
clients.remove(&1u64);
clients.stack_unstacked();
clients.refresh_virtual_screen();
clients.arange_virtual_screen(600, 400);
println!("{:#?}", clients);
clients.virtual_screens.rotate_right(1);
clients.insert(Client {
window: 3,
size: (1, 1),
position: (1, 1),
floating: false,
});
clients.stack_unstacked();
clients.refresh_virtual_screen();
clients.arange_virtual_screen(600, 400);
println!("{:#?}", clients);
clients.toggle_floating(&2u64);
clients.virtual_screens.rotate_left(1);
clients.stack_unstacked();
clients.refresh_virtual_screen();
clients.arange_virtual_screen(600, 400);
println!("{:#?}", clients);
}
} }
mod no_refcell { use std::{collections::VecDeque, iter::repeat};
use std::{collections::VecDeque, iter::repeat};
use super::*; type Clients = HashMap<Window, Client, BuildIdentityHasher>;
type ClientRef = u64;
type ClientRefs = Vec<ClientRef>;
type ClientsWrapped = Rc<RefCell<Clients>>; #[derive(Debug, Clone)]
type Clients = HashMap<Window, Client, BuildIdentityHasher>; struct ClientState {
type ClientRef = u64; clients: Clients,
type ClientRefs = Vec<ClientRef>; virtual_screens: VecDeque<VirtualScreen>,
}
struct ClientState { #[derive(Debug, Clone)]
clients: Clients, struct VirtualScreen {
virtual_screens: VecDeque<VirtualScreen>, master: ClientRefs,
aux: ClientRefs,
focused: Option<ClientRef>,
}
impl Default for ClientState {
fn default() -> Self {
let mut vss = VecDeque::<VirtualScreen>::new();
vss.resize_with(10, Default::default);
Self {
clients: Default::default(),
virtual_screens: vss,
}
}
}
impl ClientState {
fn insert(&mut self, client: Client) {
let key = client.key();
self.clients.insert(key, client);
} }
struct VirtualScreen { fn remove<K>(&mut self, key: &K)
master: ClientRefs, where
aux: ClientRefs, K: ClientKey,
focused: Option<ClientRef>, {
self.virtual_screens
.iter_mut()
.for_each(|vs| vs.remove(key));
self.clients.remove(&key.key());
} }
impl ClientState { fn get<K>(&self, key: &K) -> Option<&Client>
fn insert(&mut self, client: Client) { where
let key = client.key(); K: ClientKey,
{
self.clients.get(&key.key())
}
self.clients.insert(key, client); fn get_mut<K>(&mut self, key: &K) -> Option<&mut Client>
where
K: ClientKey,
{
self.clients.get_mut(&key.key())
}
fn toggle_floating<K>(&mut self, key: &K) -> Option<bool>
where
K: ClientKey,
{
match self.get_mut(key) {
Some(client) => {
client.floating = !client.floating;
Some(client.floating)
}
None => None,
} }
}
fn get<K>(&self, key: &K) -> Option<&Client> fn get_virtualscreen_for_client<K>(&self, key: &K) -> Option<&VirtualScreen>
where where
K: ClientKey, K: ClientKey,
{ {
self.clients.get(&key.key()) self.virtual_screens
} .iter()
.find_map(|vs| if vs.contains(key) { Some(vs) } else { None })
}
fn get_mut<K>(&mut self, key: &K) -> Option<&mut Client> fn get_mut_virtualscreen_for_client<K>(&mut self, key: &K) -> Option<&mut VirtualScreen>
where where
K: ClientKey, K: ClientKey,
{ {
self.clients.get_mut(&key.key()) self.virtual_screens.iter_mut().find_map(
} |vs| {
if vs.contains(key) {
fn toggle_floating<K>(&mut self, key: &K) -> Option<bool> Some(vs)
where } else {
K: ClientKey, None
{ }
match self.get_mut(key) { },
Some(client) => { )
client.floating = !client.floating; }
Some(client.floating)
/// focuses client `key` on current virtual screen
fn focus_client<K>(&mut self, key: &K)
where
K: ClientKey,
{
match self.virtual_screens.front_mut() {
Some(vs) => vs.focus(key),
None => {}
}
}
fn stack_unstacked(&mut self) {
let unstacked = self
.clients
.iter()
.filter(|&(key, client)| {
!client.floating && self.get_virtualscreen_for_client(key).is_none()
})
.map(|(key, _)| key)
.collect::<Vec<_>>();
if let Some(vs) = self.virtual_screens.front_mut() {
vs.aux.extend(unstacked.into_iter())
}
}
fn switch_stack_for_client<K>(&mut self, key: &K)
where
K: ClientKey,
{
if let Some(vs) = self.get_mut_virtualscreen_for_client(key) {
match vs.master.iter().position(|&key| key == key.key()) {
Some(index) => {
vs.aux.extend(vs.master.drain(index..=index));
}
None => {
let index = vs.aux.iter().position(|&key| key == key.key()).unwrap();
vs.master.extend(vs.aux.drain(index..=index));
} }
None => None,
} }
} }
}
fn get_virtualscreen_for_client<K>(&self, key: &K) -> Option<&VirtualScreen> fn refresh_virtual_screen(&mut self) {
where let clients = &self.clients;
K: ClientKey,
{
self.virtual_screens.iter().find_map(
|vs| {
if vs.contains(key) {
Some(vs)
} else {
None
}
},
)
}
fn get_mut_virtualscreen_for_client<K>(&mut self, key: &K) -> Option<&mut VirtualScreen> if let Some(vs) = self.virtual_screens.front_mut() {
where vs.master.retain(|key| match clients.get(key) {
K: ClientKey, Some(client) => !client.floating,
{ None => false,
self.virtual_screens.iter_mut().find_map( });
|vs| { vs.aux.retain(|key| match clients.get(key) {
if vs.contains(key) { Some(client) => !client.floating,
Some(vs) None => false,
} else { });
None
}
},
)
}
/// focuses client `key` on current virtual screen // if master is empty but aux has at least one client, drain from aux to master
fn focus_client<K>(&mut self, key: &K) if vs.master.is_empty() && !vs.aux.is_empty() {
where vs.master.extend(vs.aux.drain(..1));
K: ClientKey,
{
match self.virtual_screens.front_mut() {
Some(vs) => vs.focus(key),
None => {}
} }
} }
}
fn stack_unstacked(&mut self) { /**
let unstacked = self resizes and moves clients on the current virtual screen with `width` and `height` as
.clients screen width and screen height
*/
fn arange_virtual_screen(&mut self, width: i32, height: i32) {
// should be fine to unwrap since we will always have at least 1 virtual screen
if let Some(vs) = self.virtual_screens.front_mut() {
// if aux is empty -> width : width / 2
let width = width / (1 + i32::from(!vs.aux.is_empty() && !vs.master.is_empty()));
// make sure we dont devide by 0
let master_height = height
/ match NonZeroI32::new(vs.master.len() as i32) {
Some(i) => i.get(),
None => 1,
};
let aux_height = height
/ match NonZeroI32::new(vs.aux.len() as i32) {
Some(i) => i.get(),
None => 1,
};
// chaining master and aux together with `Zip`s for height and x reduces duplicate code
for ((i, key), (height, x)) in vs
.master
.iter() .iter()
.filter(|&(key, client)| { .enumerate()
!client.floating && self.get_virtualscreen_for_client(key).is_some() // add repeating height for each window and x pos for each window
}) .zip(repeat(master_height).zip(repeat(0i32)))
.map(|(key, _)| key) .chain(
.collect::<Vec<_>>(); vs.aux
.iter()
.enumerate()
.zip(repeat(aux_height).zip(repeat(width))),
)
{
let size = (width, height);
let position = (x, height * i as i32);
match self.virtual_screens.front_mut() { if let Some(client) = self.clients.get_mut(key) {
Some(vs) => vs.aux.extend(unstacked.into_iter()), *client = Client {
None => {} size,
} position,
} ..*client
};
fn switch_stack_for_client<K>(&mut self, key: &K)
where
K: ClientKey,
{
if let Some(vs) = self.get_mut_virtualscreen_for_client(key) {
match vs.master.iter().position(|&key| key == key.key()) {
Some(index) => {
vs.aux.extend(vs.master.drain(index..=index));
}
None => {
let index = vs.aux.iter().position(|&key| key == key.key()).unwrap();
vs.master.extend(vs.aux.drain(index..=index));
}
} }
} }
} }
fn refresh_virtual_screen(&mut self) {
let clients = &self.clients;
if let Some(vs) = self.virtual_screens.front_mut() {
vs.master.retain(|key| match clients.get(key) {
Some(client) => !client.floating,
None => false,
});
vs.aux.retain(|key| match clients.get(key) {
Some(client) => !client.floating,
None => false,
});
// if master is empty but aux has at least one client, drain from aux to master
if vs.master.is_empty() && !vs.aux.is_empty() {
vs.master.extend(vs.aux.drain(..1));
}
}
}
/**
resizes and moves clients on the current virtual screen with `width` and `height` as
screen width and screen height
*/
fn arange_virtual_screen(&mut self, width: i32, height: i32) {
// should be fine to unwrap since we will always have at least 1 virtual screen
if let Some(vs) = self.virtual_screens.front_mut() {
// if aux is empty -> width : width / 2
let width = width / 1 + i32::from(!vs.aux.is_empty());
// chaining master and aux together with `Zip`s for height and x reduces duplicate code
for ((i, key), (height, x)) in vs
.master
.iter()
.enumerate()
// add repeating height for each window and x pos for each window
.zip(repeat(height / vs.master.len() as i32).zip(repeat(0i32)))
.chain(
vs.aux
.iter()
.enumerate()
.zip(repeat(height / vs.aux.len() as i32).zip(repeat(width))),
)
{
let size = (width, height);
let position = (x, height * i as i32);
if let Some(client) = self.clients.get_mut(key) {
*client = Client {
size,
position,
..*client
};
}
}
}
}
// Should have xlib send those changes back to the x server after this function
} }
impl VirtualScreen { // Should have xlib send those changes back to the x server after this function
fn contains<K>(&self, key: &K) -> bool }
where
K: ClientKey,
{
self.master.contains(&key.key()) || self.aux.contains(&key.key())
}
fn focus<K>(&mut self, key: &K) impl Default for VirtualScreen {
where fn default() -> Self {
K: ClientKey, Self {
{ master: Default::default(),
self.focused = Some(key.key()); aux: Default::default(),
focused: None,
} }
} }
} }
/* impl VirtualScreen {
mod refcell { fn contains<K>(&self, key: &K) -> bool
use std::collections::VecDeque; where
K: ClientKey,
use super::*; {
self.master.contains(&key.key()) || self.aux.contains(&key.key())
type ClientsWrapped = Rc<RefCell<Clients>>;
type Clients = HashMap<Window, Rc<RefCell<Client>>, BuildIdentityHasher>;
type ClientRef = Weak<RefCell<Client>>;
type ClientRefs = Vec<ClientRef>;
struct ClientState {
clients: Clients,
virtual_screens: VecDeque<VirtualScreen>,
} }
struct VirtualScreen { fn remove<K>(&mut self, key: &K)
master: ClientRefs, where
aux: ClientRefs, K: ClientKey,
focused: Option<ClientRef>, {
let key = key.key();
self.master.retain(|k| *k != key);
self.aux.retain(|k| *k != key);
} }
impl ClientState { fn focus<K>(&mut self, key: &K)
fn insert(&mut self, client: Client) { where
let key = client.key(); K: ClientKey,
{
self.clients.insert(key, Rc::new(RefCell::new(client))); self.focused = Some(key.key());
}
fn get<K>(&self, key: &K) -> Option<&Rc<RefCell<Client>>>
where
K: ClientKey,
{
self.clients.get(&key.key())
}
fn toggle_floating<K>(&mut self, key: &K) -> Option<bool>
where
K: ClientKey,
{
match self.get(key) {
Some(client) => {
let client = client.borrow_mut();
client.floating = !client.floating;
Some(client.floating)
}
None => None,
}
}
fn get_virtualscreen_for_client<K>(&self, key: &K) -> Option<&VirtualScreen>
where
K: ClientKey,
{
self.virtual_screens.iter().find_map(
|vs| {
if vs.contains(key) {
Some(vs)
} else {
None
}
},
)
}
fn get_mut_virtualscreen_for_client<K>(&mut self, key: &K) -> Option<&mut VirtualScreen>
where
K: ClientKey,
{
self.virtual_screens.iter_mut().find_map(
|vs| {
if vs.contains(key) {
Some(vs)
} else {
None
}
},
)
}
/// focuses client `key` on current virtual screen
fn focus_client<K>(&mut self, key: &K)
where
K: ClientKey,
{
match self.virtual_screens.front_mut() {
Some(vs) => vs.focus(key),
None => {}
}
}
fn stack_unstacked(&mut self) {
let unstacked = self
.clients
.iter()
.filter(|&(key, client)| {
!client.as_ref().borrow().floating
&& self.get_virtualscreen_for_client(key).is_some()
})
.map(|(key, _)| key)
.collect::<Vec<_>>();
match self.virtual_screens.front_mut() {
Some(vs) => vs.aux.extend(unstacked.into_iter()),
None => {}
}
}
fn arrange(&mut self) {}
}
impl VirtualScreen {
fn contains<K>(&self, key: &K) -> bool
where
K: ClientKey,
{
self.master.contains(&key.key()) || self.aux.contains(&key.key())
}
fn focus<K>(&mut self, key: &K)
where
K: ClientKey,
{
self.focused = Some(key.key());
}
} }
} }
*/