clients iteration 1, probably wont work tho

This commit is contained in:
noonebtw 2021-04-22 18:47:05 +02:00
parent 81536fb52c
commit 5608f1d9da
4 changed files with 547 additions and 472 deletions

View file

@ -10,5 +10,5 @@ edition = "2018"
nix = "0.19.1"
x11 = {version = "2.18.2", features = ["xlib"] }
log = "0.4.13"
weak-table = "0.3.0"
weak-table = {path = "/mnt/storage/rust/weak-table-rs"}
simple_logger = "1.11.0"

218
src/clients.rs Normal file
View file

@ -0,0 +1,218 @@
use std::{
borrow::{Borrow, BorrowMut},
collections::HashSet,
ops::{Deref, DerefMut},
rc::Rc,
};
use std::{
hash::{Hash, Hasher},
rc::Weak,
};
use weak_table::WeakHashSet;
use x11::xlib::Window;
use crate::util::BuildIdentityHasher;
#[derive(Clone, Debug)]
struct Client {
window: Window,
floating: bool,
size: (i32, i32),
position: (i32, i32),
}
impl Hash for Client {
fn hash<H: Hasher>(&self, state: &mut H) {
self.window.hash(state);
}
}
impl PartialEq for Client {
fn eq(&self, other: &Self) -> bool {
self.window == other.window
}
}
impl Eq for Client {}
trait ClientKey {
fn key(&self) -> u64;
}
impl<'a> PartialEq for (dyn ClientKey + 'a) {
fn eq(&self, other: &Self) -> bool {
self.key() == other.key()
}
}
impl<'a> Eq for (dyn ClientKey + 'a) {}
impl<'a> Hash for (dyn ClientKey + 'a) {
fn hash<H: Hasher>(&self, state: &mut H) {
self.key().hash(state);
}
}
impl ClientKey for Client {
fn key(&self) -> u64 {
self.window
}
}
impl ClientKey for Rc<Client> {
fn key(&self) -> u64 {
self.window
}
}
impl ClientKey for Window {
fn key(&self) -> u64 {
self.to_owned()
}
}
impl<'a> Borrow<dyn ClientKey + 'a> for Client {
fn borrow(&self) -> &(dyn ClientKey + 'a) {
self
}
}
impl<'a> Borrow<dyn ClientKey + 'a> for Rc<Client> {
fn borrow(&self) -> &(dyn ClientKey + 'a) {
self
}
}
trait ClientList {
fn contains_key<T>(&self, key: &T) -> bool
where
T: ClientKey;
fn get_with_key<T>(&self, key: &T) -> Option<Rc<Client>>
where
T: ClientKey;
fn remove_key<T>(&mut self, key: &T) -> bool
where
T: ClientKey;
}
struct Clients(HashSet<Rc<Client>, BuildIdentityHasher>);
impl Default for Clients {
fn default() -> Self {
Self(Default::default())
}
}
impl Deref for Clients {
type Target = HashSet<Rc<Client>, BuildIdentityHasher>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Clients {
fn deref_mut(&mut self) -> &mut HashSet<Rc<Client>, BuildIdentityHasher> {
&mut self.0
}
}
impl ClientList for Clients {
fn contains_key<T>(&self, key: &T) -> bool
where
T: ClientKey,
{
self.0.contains(key as &dyn ClientKey)
}
fn get_with_key<T>(&self, key: &T) -> Option<Rc<Client>>
where
T: ClientKey,
{
self.0.get(key as &dyn ClientKey).cloned()
}
fn remove_key<T>(&mut self, key: &T) -> bool
where
T: ClientKey,
{
self.0.remove(key as &dyn ClientKey)
}
}
struct ClientRefs(WeakHashSet<Weak<Client>, BuildIdentityHasher>);
impl Default for ClientRefs {
fn default() -> Self {
Self(Default::default())
}
}
impl Deref for ClientRefs {
type Target = WeakHashSet<Weak<Client>, BuildIdentityHasher>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for ClientRefs {
fn deref_mut(&mut self) -> &mut WeakHashSet<Weak<Client>, BuildIdentityHasher> {
&mut self.0
}
}
impl ClientList for ClientRefs {
fn contains_key<T>(&self, key: &T) -> bool
where
T: ClientKey,
{
self.0.contains(key as &dyn ClientKey)
}
fn get_with_key<T>(&self, key: &T) -> Option<Rc<Client>>
where
T: ClientKey,
{
self.0.get(key as &dyn ClientKey)
}
fn remove_key<T>(&mut self, key: &T) -> bool
where
T: ClientKey,
{
self.0.remove(key as &dyn ClientKey)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn client_lists_test() {
let mut clients: Clients = Default::default();
clients.insert(Rc::new(Client {
window: 1,
floating: false,
position: (1, 1),
size: (1, 1),
}));
assert!(clients.contains_key(&1u64));
let mut client_refs = ClientRefs::default();
client_refs.insert(clients.get_with_key(&1u64).unwrap());
assert!(client_refs.contains_key(&1u64));
clients.remove_key(&1u64);
assert!(!client_refs.contains_key(&1u64));
}
}

View file

@ -2,6 +2,7 @@ use log::info;
use std::io::Result;
//mod state;
mod clients;
mod util;
mod wm;
@ -31,7 +32,7 @@ fn main() -> Result<()> {
simple_logger::SimpleLogger::new().init().unwrap();
info!("Hello, World!");
wm::WMState::init().run();
//wm::WMState::init().run();
Ok(())
}

674
src/wm.rs
View file

@ -1,9 +1,12 @@
/*
use std::{
borrow::Borrow,
cell::RefCell,
collections::{hash_map::Entry, HashMap, HashSet},
collections::HashSet,
ffi::CString,
hash::{Hash, Hasher},
io::{Error, ErrorKind, Result},
ops::Deref,
ptr::{null, null_mut},
rc::{Rc, Weak},
};
@ -70,48 +73,6 @@ impl WMAtoms {
}
}
#[derive(Clone, Debug)]
pub struct Client {
window: Window,
floating: bool,
size: (i32, i32),
position: (i32, i32),
}
impl Default for Client {
fn default() -> Self {
Self {
window: 0,
floating: false,
size: (0, 0),
position: (0, 0),
}
}
}
impl Hash for Client {
fn hash<H: Hasher>(&self, state: &mut H) {
self.window.hash(state);
}
}
impl Client {
pub fn new(window: xlib::Window) -> Self {
Self {
window,
..Default::default()
}
}
}
impl PartialEq for Client {
fn eq(&self, other: &Self) -> bool {
self.window == other.window
}
}
impl Eq for Client {}
use crate::util::BuildIdentityHasher;
use weak_table::WeakHashSet;
@ -132,7 +93,7 @@ impl VirtualScreen {
}
fn contains_client(&self, client: &Rc<Client>) -> bool {
self.master_stack.contains(client) || self.aux_stack.contains(client)
self.master_stack.contains(client.as_ref()) || self.aux_stack.contains(client.as_ref())
}
}
@ -299,125 +260,6 @@ impl XLibState {
}
}
#[derive(Clone, Debug)]
pub struct WMStateMut {
//move_window:
// u64 : window to move
// (i32, i32) : initial cursor position
// (i32, i32) : initial window position
move_window: Option<(u64, (i32, i32), (i32, i32))>,
//resize_window:
// u64 : window to move
// (i32, i32) : initial window position
resize_window: Option<(u64, (i32, i32))>,
clients: HashSet<Rc<Client>, BuildIdentityHasher>,
focused_client: Weak<Client>,
current_vscreen: usize,
virtual_screens: Vec<VirtualScreen>,
}
impl Default for WMStateMut {
fn default() -> Self {
Self {
move_window: None,
resize_window: None,
clients: Default::default(),
focused_client: Weak::new(),
current_vscreen: 0,
virtual_screens: vec![VirtualScreen::new()],
}
}
}
impl WMStateMut {
fn stack_unstacked_clients(&mut self) {
info!("[stack_unstacked_clients] ");
self.clients
.iter()
.filter(|&c| !c.floating && self.is_client_stacked(c))
.for_each(|c| {
info!(
"[stack_unstacked_clients] inserting Client({:?}) into aux_stack",
c
);
self.virtual_screens[self.current_vscreen]
.aux_stack
.insert(c.clone());
});
}
fn is_client_stacked(&self, client: &Rc<Client>) -> bool {
self.virtual_screens
.iter()
.any(|vs| vs.contains_client(client))
}
fn client_for_window(&self, window: &Window) -> Option<Rc<Client>> {
self.clients
.iter()
.filter(|&c| c.window == *window)
.next()
.map(|c| c.clone())
}
fn switch_stack_for_client(&mut self, window: &Window) {
if let Some(client) = self.client_for_window(window) {
info!("[switch_stack_for_client] client: {:#?}", client);
if self.virtual_screens[self.current_vscreen]
.master_stack
.contains(&client)
{
self.virtual_screens[self.current_vscreen]
.master_stack
.remove(&client);
self.virtual_screens[self.current_vscreen]
.aux_stack
.insert(client.clone());
info!("[switch_stack_for_client] moved to aux stack");
} else {
self.virtual_screens[self.current_vscreen]
.aux_stack
.remove(&client);
self.virtual_screens[self.current_vscreen]
.master_stack
.insert(client.clone());
info!("[switch_stack_for_client] moved to master stack");
}
self.clients.replace(Rc::new(Client {
floating: false,
..*client
}));
}
}
fn refresh_screen(&mut self) {
let current_vscreen = self.current_vscreen;
self.stack_unstacked_clients();
if let Some(vs) = self.virtual_screens.get_mut(self.current_vscreen) {
vs.master_stack.retain(|c| !c.floating);
vs.aux_stack.retain(|c| !c.floating);
if vs.master_stack.is_empty() {
info!("[refresh_screen] master stack was empty, pushing first client if exists:");
vs.aux_stack.iter().filter(|c| !c.floating).next().map(|c| {
info!("[arrange_clients] Client({:#?})", c);
self.virtual_screens[current_vscreen]
.master_stack
.insert(c.clone());
self.virtual_screens[current_vscreen].aux_stack.remove(&c);
});
}
}
}
}
struct Key {
keycode: i32,
mod_mask: u32,
@ -436,21 +278,41 @@ enum KeyOrButton {
pub struct WMState {
xlib_state: XLibState,
key_handlers: Vec<(i32, u32, Rc<dyn Fn(&Self, &XEvent)>)>,
key_handlers: Vec<(i32, u32, Rc<dyn Fn(&mut Self, &XEvent)>)>,
// (button, mod_mask, button_mask)
buttons: Vec<(u32, u32, i64)>,
event_handlers: Vec<Rc<dyn Fn(&Self, &XEvent)>>,
mut_state: RefCell<WMStateMut>,
event_handlers: Vec<Rc<dyn Fn(&mut Self, &XEvent)>>,
// MutState:
//move_window:
// u64 : window to move
// (i32, i32) : initial cursor position
// (i32, i32) : initial window position
move_window: Option<(u64, (i32, i32), (i32, i32))>,
//resize_window:
// u64 : window to move
// (i32, i32) : initial window position
resize_window: Option<(u64, (i32, i32))>,
clients: HashSet<Rc<Client>, BuildIdentityHasher>,
focused_client: Weak<Client>,
current_vscreen: usize,
virtual_screens: Vec<VirtualScreen>,
}
impl WMState {
pub fn new() -> Self {
Self {
xlib_state: XLibState::new(),
mut_state: RefCell::new(WMStateMut::default()),
key_handlers: vec![],
event_handlers: vec![],
buttons: vec![],
move_window: None,
resize_window: None,
clients: Default::default(),
focused_client: Weak::new(),
current_vscreen: 0,
virtual_screens: vec![VirtualScreen::new()],
}
}
@ -520,7 +382,103 @@ impl WMState {
state
}
pub fn run(self) -> Self {
// MutState Functions:
fn stack_unstacked_clients(&mut self) {
info!("[stack_unstacked_clients] ");
let unstacked_clients = self
.clients
.iter()
.filter(|&c| !c.floating && !self.is_client_stacked(c))
.cloned()
.collect::<Vec<_>>();
unstacked_clients.iter().for_each(|c| {
info!(
"[stack_unstacked_clients] inserting Client({:?}) into aux_stack",
c
);
self.virtual_screens[self.current_vscreen]
.aux_stack
.insert(c.clone());
});
}
fn is_client_stacked(&self, client: &Rc<Client>) -> bool {
self.virtual_screens
.iter()
.any(|vs| vs.contains_client(client))
}
fn client_for_window(&self, window: Window) -> Option<Rc<Client>> {
self.clients
.iter()
.filter(|&c| c.window == window)
.next()
.cloned()
}
fn switch_stack_for_client(&mut self, client: Rc<Client>) {
info!("[switch_stack_for_client] client: {:#?}", client);
if self.virtual_screens[self.current_vscreen]
.master_stack
.contains(client.as_ref())
{
self.virtual_screens[self.current_vscreen]
.master_stack
.remove(client.as_ref());
self.virtual_screens[self.current_vscreen]
.aux_stack
.insert(client.clone());
info!("[switch_stack_for_client] moved to aux stack");
} else {
self.virtual_screens[self.current_vscreen]
.aux_stack
.remove(client.as_ref());
self.virtual_screens[self.current_vscreen]
.master_stack
.insert(client.clone());
info!("[switch_stack_for_client] moved to master stack");
}
self.clients.replace(Client::new_rc(InnerClient {
floating: false,
..**client.as_ref()
}));
}
fn refresh_screen(&mut self) {
let current_vscreen = self.current_vscreen;
self.stack_unstacked_clients();
if let Some(vs) = self.virtual_screens.get_mut(self.current_vscreen) {
vs.master_stack.retain(|c| !c.0.borrow().floating);
vs.aux_stack.retain(|c| !c.floating);
if vs.master_stack.is_empty() {
info!("[refresh_screen] master stack was empty, pushing first client if exists:");
vs.aux_stack.iter().filter(|c| !c.floating).next().map(|c| {
info!("[arrange_clients] Client({:#?})", c);
self.virtual_screens[current_vscreen]
.master_stack
.insert(c.clone());
self.virtual_screens[current_vscreen]
.aux_stack
.remove(c.as_ref());
});
}
}
}
pub fn run(mut self) -> Self {
let event_handlers = self.event_handlers.clone();
let key_handlers = self.key_handlers.clone();
loop {
let event = unsafe {
let mut event: xlib::XEvent = std::mem::MaybeUninit::zeroed().assume_init();
@ -529,9 +487,9 @@ impl WMState {
event
};
self.event_handlers.iter().for_each(|handler| {
handler(&self, &event);
});
for handler in event_handlers.iter() {
handler(&mut self, &event);
}
match event.get_type() {
xlib::MapRequest => {
@ -555,12 +513,12 @@ impl WMState {
xlib::KeyPress => {
let clean_mask = self.xlib_state.clean_mask();
self.key_handlers.iter().for_each(|(key, mask, handler)| {
key_handlers.iter().for_each(|(key, mask, handler)| {
if unsafe {
event.key.keycode == *key as u32
&& event.key.state & clean_mask == *mask & clean_mask
} {
handler(&self, &event);
handler(&mut self, &event);
}
})
}
@ -588,7 +546,7 @@ impl WMState {
#[allow(dead_code)]
pub fn add_event_handler<F>(mut self, handler: F) -> Self
where
F: Fn(&Self, &XEvent) + 'static,
F: Fn(&mut Self, &XEvent) + 'static,
{
self.event_handlers.push(Rc::new(handler));
@ -598,7 +556,7 @@ impl WMState {
pub fn add_key_handler<S, F>(mut self, key: S, mask: u32, handler: F) -> Self
where
S: Into<String>,
F: Fn(&Self, &XEvent) + 'static,
F: Fn(&mut Self, &XEvent) + 'static,
{
let keycode = self.xlib_state.keycode(key);
@ -608,32 +566,21 @@ impl WMState {
self
}
fn map_request(&self, event: &xlib::XMapRequestEvent) {
fn map_request(&mut self, event: &xlib::XMapRequestEvent) {
info!("[MapRequest] event: {:#?}", event);
let _ = Some(self.mut_state.borrow_mut())
.and_then(|mut state| {
if state.client_for_window(&event.window).is_none() {
if self.client_for_window(event.window).is_none() {
info!("[MapRequest] new client: {:#?}", event.window);
let client = Rc::new(Client::new(event.window));
state.clients.insert(client.clone());
self.clients.insert(client.clone());
Some(client)
} else {
None
}
})
.and_then(|c| {
unsafe {
xlib::XMapWindow(self.dpy(), c.window);
xlib::XMapWindow(self.dpy(), client.window);
xlib::XSelectInput(
self.dpy(),
event.window,
EnterWindowMask
| FocusChangeMask
| PropertyChangeMask
| StructureNotifyMask,
EnterWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask,
);
}
@ -641,59 +588,47 @@ impl WMState {
.iter()
.for_each(|&(button, mod_mask, button_mask)| {
self.xlib_state
.grab_button(c.window, button, mod_mask, button_mask);
.grab_button(client.window, button, mod_mask, button_mask);
});
self.arrange_clients();
self.focus_client(c.clone());
Some(())
});
self.focus_client(&client);
}
}
fn unmap_notify(&self, event: &xlib::XUnmapEvent) {
fn unmap_notify(&mut self, event: &xlib::XUnmapEvent) {
info!("[UnmapNotify] event: {:#?}", event);
if event.send_event == 0 {
let _ = Some(self.mut_state.borrow_mut()).and_then(|mut state| {
if state.client_for_window(&event.window).is_none() {
let client = state.clients.remove(&event.window);
if let Some(client) = self.client_for_window(event.window) {
self.clients.remove(&client);
info!("[UnmapNotify] removing client: {:#?}", client);
}
Some(())
});
}
self.arrange_clients();
}
fn destroy_notify(&self, event: &xlib::XDestroyWindowEvent) {
fn destroy_notify(&mut self, event: &xlib::XDestroyWindowEvent) {
info!("[DestroyNotify] event: {:?}", event);
let _ = Some(self.mut_state.borrow_mut()).and_then(|mut state| {
let _entry = state.clients.remove(&event.window);
if let Some(client) = self.client_for_window(event.window) {
self.clients.remove(&client);
info!("[DestroyNotify] removed entry: {:?}", _entry);
Some(())
});
info!("[DestroyNotify] removed entry: {:?}", client);
}
self.arrange_clients();
}
fn configure_request(&self, event: &xlib::XConfigureRequestEvent) {
fn configure_request(&mut self, event: &xlib::XConfigureRequestEvent) {
info!("[ConfigureRequest] event: {:?}", event);
match self.mut_state.borrow_mut().clients.entry(event.window) {
Entry::Occupied(entry) => {
info!(
"[ConfigureRequest] found Client for Window({:?}): {:#?}",
event.window,
entry.get()
);
match self.client_for_window(event.window) {
Some(client) => {
info!("[ConfigureRequest] found Client {:#?}", client,);
self.configure_client(entry.get().clone());
self.configure_client(&client);
}
_ => {
info!(
@ -722,61 +657,36 @@ impl WMState {
}
}
fn enter_notify(&self, event: &xlib::XCrossingEvent) {
fn enter_notify(&mut self, event: &xlib::XCrossingEvent) {
info!("[EnterNotify] event: {:?}", event);
Some(self.mut_state.borrow())
.and_then(|state| {
state
.clients
.get(&event.window)
.and_then(|c| Some(c.clone()))
})
.and_then(|c| {
info!(
"[EnterNotify] focusing Client for Window({:?})",
event.window
);
self.focus_client(c);
Some(())
});
if let Some(client) = self.client_for_window(event.window) {
info!("[EnterNotify] focusing Client ({:?})", client);
self.focus_client(&client);
}
}
fn button_press(&self, event: &xlib::XButtonEvent) {
fn button_press(&mut self, event: &xlib::XButtonEvent) {
info!("[ButtonPress] event: {:?}", event);
Some(self.mut_state.borrow())
.and_then(|state| {
state
.clients
.get(&event.subwindow)
.and_then(|c| Some(c.clone()))
})
.and_then(|c| {
info!(
"[ButtonPress] focusing Client for Window({:?})",
event.window
);
self.focus_client(c.clone());
if let Some(client) = self.client_for_window(event.subwindow) {
info!("[ButtonPress] focusing Client ({:?})", client);
self.focus_client(&client);
info!("[ButtonPress] raising Window({:?})", event.window);
unsafe {
xlib::XRaiseWindow(self.dpy(), c.borrow().window);
xlib::XRaiseWindow(self.dpy(), client.window);
xlib::XSync(self.dpy(), 0);
}
Some(())
});
}
}
fn unfocus_client(&self, client: Rc<RefCell<Client>>) {
fn unfocus_client(&self, client: &Rc<Client>) {
unsafe {
xlib::XSetInputFocus(
self.dpy(),
client.borrow().window,
client.window,
xlib::RevertToPointerRoot,
xlib::CurrentTime,
);
@ -785,26 +695,19 @@ impl WMState {
}
}
fn focus_client(&self, client: Rc<Client>) {
Some(self.mut_state.borrow_mut()).and_then(|mut state| {
let current_vscreen = state.current_vscreen;
fn focus_client(&mut self, client: &Rc<Client>) {
if let Some(focused_client) = self.focused_client.upgrade() {
self.unfocus_client(&focused_client);
}
state
.focused_client
.upgrade()
.and_then(|c| Some(self.unfocus_client(c)));
self.focused_client = Rc::downgrade(client);
state.focused_client = Rc::downgrade(&client);
state.virtual_screens[current_vscreen].focused_client = state.focused_client.clone();
Some(())
});
self.virtual_screens[self.current_vscreen].focused_client = self.focused_client.clone();
unsafe {
xlib::XSetInputFocus(
self.dpy(),
client.borrow().window,
client.window,
xlib::RevertToPointerRoot,
xlib::CurrentTime,
);
@ -816,13 +719,13 @@ impl WMState {
xlib::XA_WINDOW,
32,
xlib::PropModeReplace,
&client.borrow().window as *const u64 as *const _,
&client.window as *const u64 as *const _,
1,
);
}
self.xlib_state
.send_event(client.borrow().window, self.xlib_state.atoms.take_focus);
.send_event(client.window, self.xlib_state.atoms.take_focus);
}
fn arrange_clients(&self) {
@ -833,13 +736,12 @@ impl WMState {
)
};
Some(self.mut_state.borrow_mut()).and_then(|mut state| {
if !state.clients.is_empty() {
if !self.clients.is_empty() {
info!("[arrange_clients] refreshing screen");
state.refresh_screen();
self.refresh_screen();
let window_w = {
if state.virtual_screens[state.current_vscreen]
if self.virtual_screens[self.current_vscreen]
.aux_stack
.is_empty()
{
@ -849,97 +751,64 @@ impl WMState {
}
};
for (i, (_, weak_client)) in state.virtual_screens[state.current_vscreen]
.master_stack
if let Some(vc) = self.virtual_screens.get_mut(self.current_vscreen) {
vc.master_stack
.iter()
.zip(std::iter::repeat(vc.master_stack.len()))
.enumerate()
{
let client = weak_client.upgrade().unwrap();
.chain(
vc.aux_stack
.iter()
.zip(std::iter::repeat(vc.aux_stack.len()))
.enumerate(),
)
.for_each(|(i, (client, length))| {
let (mut wc, size, position) = {
let window_h = screen_h / length as i32;
let mut wc = {
let mut client = client.borrow_mut();
let window_h = screen_h
/ state.virtual_screens[state.current_vscreen]
.master_stack
.len() as i32;
client.size = (window_w, window_h);
client.position = (0, window_h * i as i32);
let size = (window_w, window_h);
let position = (0, window_h * i as i32);
(
xlib::XWindowChanges {
x: client.position.0,
y: client.position.1,
width: client.size.0,
height: client.size.1,
x: position.0,
y: position.1,
width: size.0,
height: size.1,
border_width: 0,
sibling: 0,
stack_mode: 0,
}
},
size,
position,
)
};
unsafe {
xlib::XConfigureWindow(
self.dpy(),
client.borrow().window,
client.window,
(xlib::CWY | xlib::CWX | xlib::CWHeight | xlib::CWWidth) as u32,
&mut wc,
);
self.configure_client(client.clone());
self.clients.replace(Client::new_rc(InnerClient {
size,
position,
..**client
}));
self.configure_client(&client);
xlib::XSync(self.dpy(), 0);
}
}
for (i, (_, weak_client)) in state.virtual_screens[state.current_vscreen]
.aux_stack
.iter()
.enumerate()
{
let client = weak_client.upgrade().unwrap();
let mut wc = {
let mut client = client.borrow_mut();
let window_h = screen_h
/ state.virtual_screens[state.current_vscreen].aux_stack.len() as i32;
client.size = (window_w, window_h);
client.position = (window_w, window_h * i as i32);
xlib::XWindowChanges {
x: client.position.0,
y: client.position.1,
width: client.size.0,
height: client.size.1,
border_width: 0,
sibling: 0,
stack_mode: 0,
}
};
unsafe {
xlib::XConfigureWindow(
self.dpy(),
client.borrow().window,
(xlib::CWY | xlib::CWX | xlib::CWHeight | xlib::CWWidth) as u32,
&mut wc,
);
self.configure_client(client.clone());
xlib::XSync(self.dpy(), 0);
}
}
}
Some(())
});
}
}
}
fn configure_client(&self, client: Rc<RefCell<Client>>) {
fn configure_client(&self, client: &Rc<Client>) {
let mut event = {
let client = client.borrow();
xlib::XConfigureEvent {
type_: xlib::ConfigureNotify,
display: self.dpy(),
@ -968,61 +837,49 @@ impl WMState {
}
}
fn handle_change_virtual_screen(&self, direction: i32) {
fn handle_change_virtual_screen(&mut self, direction: i32) {
assert!(direction == 1 || direction == -1);
Some(self.mut_state.borrow_mut()).and_then(|mut state| {
// hide all windows from current virtual screen
state.virtual_screens[state.current_vscreen]
self.virtual_screens[self.current_vscreen]
.master_stack
.iter()
.chain(
state.virtual_screens[state.current_vscreen]
.aux_stack
.iter(),
)
.for_each(|(_, c)| {
if let Some(c) = c.upgrade() {
let c = c.borrow();
unsafe {
.chain(self.virtual_screens[self.current_vscreen].aux_stack.iter())
.for_each(|c| unsafe {
xlib::XMoveWindow(self.dpy(), c.window, c.size.0 * -2, c.position.1);
}
}
});
// change current_vscreen variable
let mut new_vscreen = state.current_vscreen as isize + direction as isize;
let mut new_vscreen = self.current_vscreen as isize + direction as isize;
if new_vscreen >= state.virtual_screens.len() as isize {
state.virtual_screens.push(VirtualScreen::new());
if new_vscreen >= self.virtual_screens.len() as isize {
self.virtual_screens.push(VirtualScreen::new());
} else if new_vscreen < 0 {
new_vscreen = state.virtual_screens.len() as isize - 1;
new_vscreen = self.virtual_screens.len() as isize - 1;
}
state.current_vscreen = new_vscreen as usize;
Some(())
});
self.current_vscreen = new_vscreen as usize;
self.arrange_clients();
// focus the focused cliend of the new virtual screen
let client = self.mut_state.borrow().virtual_screens
[self.mut_state.borrow().current_vscreen]
if let Some(client) = self.virtual_screens[self.current_vscreen]
.focused_client
.to_owned();
client.upgrade().and_then(|c| Some(self.focus_client(c)));
.upgrade()
{
self.focus_client(&client);
}
}
fn handle_switch_stack(&self, event: &XEvent) {
self.mut_state
.borrow_mut()
.switch_stack_for_client(unsafe { &event.button.subwindow });
fn handle_switch_stack(&mut self, event: &XEvent) {
if let Some(client) = self.client_for_window(event.button.subwindow) {
self.switch_stack_for_client(client);
}
self.arrange_clients();
}
fn handle_toggle_floating(&self, event: &XEvent) {
fn handle_toggle_floating(&mut self, event: &XEvent) {
if event.get_type() == xlib::ButtonPress {
let event = unsafe { event.button };
let clean_mask = self.xlib_state.clean_mask();
@ -1031,31 +888,28 @@ impl WMState {
&& event.state & clean_mask == Mod1Mask & clean_mask
&& event.subwindow != 0
{
self.mut_state
.borrow_mut()
.clients
.entry(event.subwindow)
.and_modify(|c| {
let mut c = c.borrow_mut();
if let Some(client) = self.client_for_window(event.subwindow) {
info!(
"[handle_toggle_floating] {:#?} floating -> {:?}",
c, !c.floating
client, !client.floating
);
c.floating = !c.floating;
});
self.clients.replace(Client::new_rc(InnerClient {
floating: !client.floating,
..**client
}));
}
self.arrange_clients();
}
}
}
fn handle_move_window(&self, event: &XEvent) {
fn handle_move_window(&mut self, event: &XEvent) {
let clean_mask = self.xlib_state.clean_mask();
let move_window = self.mut_state.borrow_mut().move_window;
if unsafe {
move_window.is_none()
self.move_window.is_none()
&& event.get_type() == xlib::ButtonPress
&& event.button.button == 1
&& event.button.state & clean_mask == Mod1Mask & clean_mask
@ -1069,7 +923,7 @@ impl WMState {
(attr.x, attr.y)
};
self.mut_state.borrow_mut().move_window = Some(unsafe {
self.move_window = Some(unsafe {
(
event.button.subwindow,
(event.button.x, event.button.y),
@ -1077,21 +931,22 @@ impl WMState {
)
});
self.mut_state
.borrow_mut()
.clients
.entry(unsafe { event.button.subwindow })
.and_modify(|c| c.borrow_mut().floating = true);
if let Some(client) = self.client_for_window(event.button.subwindow) {
self.clients.replace(Client::new_rc(InnerClient {
floating: true,
..**client
}));
}
self.arrange_clients();
} else if unsafe {
move_window.is_some()
self.move_window.is_some()
&& event.get_type() == xlib::ButtonRelease
&& event.button.button == 1
} {
self.mut_state.borrow_mut().move_window = None;
} else if move_window.is_some() && event.get_type() == xlib::MotionNotify {
let move_window = move_window.unwrap();
self.move_window = None;
} else if self.move_window.is_some() && event.get_type() == xlib::MotionNotify {
let move_window = self.move_window.unwrap();
let attr = unsafe {
let mut attr: xlib::XWindowAttributes =
@ -1131,10 +986,10 @@ impl WMState {
}
}
fn handle_resize_window(&self, event: &XEvent) {
fn handle_resize_window(&mut self, event: &XEvent) {
let clean_mask = self.xlib_state.clean_mask();
let resize_window = self.mut_state.borrow().resize_window;
let resize_window = self.resize_window;
if unsafe {
resize_window.is_none()
@ -1149,8 +1004,7 @@ impl WMState {
xlib::XGetWindowAttributes(self.dpy(), event.button.subwindow, &mut attr);
self.mut_state.borrow_mut().resize_window =
Some((event.button.subwindow, (attr.x, attr.y)));
self.resize_window = Some((event.button.subwindow, (attr.x, attr.y)));
xlib::XWarpPointer(
self.dpy(),
@ -1165,11 +1019,12 @@ impl WMState {
);
};
self.mut_state
.borrow_mut()
.clients
.entry(unsafe { event.button.subwindow })
.and_modify(|c| c.borrow_mut().floating = true);
if let Some(client) = self.client_for_window(unsafe { event.button.subwindow }) {
self.clients.replace(Client::new_rc(InnerClient {
floating: true,
..**client
}));
}
self.arrange_clients();
} else if unsafe {
@ -1177,7 +1032,7 @@ impl WMState {
&& event.get_type() == xlib::ButtonRelease
&& event.button.button == 3
} {
self.mut_state.borrow_mut().resize_window = None;
self.resize_window = None;
} else if resize_window.is_some() && event.get_type() == xlib::MotionNotify {
let resize_window = resize_window.unwrap();
@ -1261,3 +1116,4 @@ impl WMState {
}
}
}
*/