refactoring; Arc -> Rc; basic tiling functionality
This commit is contained in:
parent
86fc396a84
commit
80fdb915ab
|
@ -9,3 +9,4 @@ edition = "2018"
|
|||
[dependencies]
|
||||
nix = "0.19.1"
|
||||
x11 = {version = "2.18.2", features = ["xlib"] }
|
||||
log = "0.4.13"
|
3
rustfmt.toml
Normal file
3
rustfmt.toml
Normal file
|
@ -0,0 +1,3 @@
|
|||
hard_tabs = true
|
||||
imports_granularity = "Crate"
|
||||
wrap_comments = true
|
528
src/wm.rs
528
src/wm.rs
|
@ -1,25 +1,26 @@
|
|||
// asdf
|
||||
use std::{
|
||||
cell::{Cell, RefCell, RefMut},
|
||||
cell::{RefCell, RefMut},
|
||||
collections::{hash_map::Entry, HashMap},
|
||||
ffi::CString,
|
||||
io::{Error, ErrorKind, Result},
|
||||
ptr::{null, null_mut},
|
||||
rc::{Rc, Weak as WeakRc},
|
||||
sync::{Arc, Weak},
|
||||
rc::{Rc, Weak},
|
||||
};
|
||||
|
||||
use x11::{
|
||||
xlib,
|
||||
xlib::{
|
||||
Atom, ButtonPressMask, ButtonReleaseMask, CWEventMask, ControlMask, EnterWindowMask,
|
||||
FocusChangeMask, GrabModeAsync, LeaveWindowMask, LockMask, Mod1Mask, Mod2Mask, Mod3Mask,
|
||||
Mod4Mask, Mod5Mask, PointerMotionMask, PropertyChangeMask, ShiftMask, StructureNotifyMask,
|
||||
FocusChangeMask, GrabModeAsync, LockMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask,
|
||||
PointerMotionMask, PropertyChangeMask, ShiftMask, StructureNotifyMask,
|
||||
SubstructureNotifyMask, SubstructureRedirectMask, Window, XDefaultScreen, XEvent,
|
||||
XInternAtom, XOpenDisplay, XRootWindow,
|
||||
},
|
||||
};
|
||||
|
||||
use log::info;
|
||||
|
||||
use nix::unistd::{close, execvp, fork, setsid, ForkResult};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -91,26 +92,19 @@ impl Default for WMAtoms {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct ClientState {
|
||||
size: (u32, u32),
|
||||
position: (i32, i32),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Client {
|
||||
window: Window,
|
||||
state: Cell<ClientState>,
|
||||
size: (i32, i32),
|
||||
position: (i32, i32),
|
||||
}
|
||||
|
||||
impl Default for Client {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
window: 0,
|
||||
state: Cell::new(ClientState {
|
||||
size: (0, 0),
|
||||
position: (0, 0),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,10 +116,6 @@ impl Client {
|
|||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_state(&self) -> ClientState {
|
||||
self.state.get()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Client {
|
||||
|
@ -312,8 +302,9 @@ pub struct WMStateMut {
|
|||
// u64 : window to move
|
||||
// (i32, i32) : initial window position
|
||||
resize_window: Option<(u64, (i32, i32))>,
|
||||
clients: HashMap<Window, Rc<Client>>,
|
||||
focused_client: WeakRc<Client>,
|
||||
clients: HashMap<Window, Rc<RefCell<Client>>>,
|
||||
focused_client: Weak<RefCell<Client>>,
|
||||
master_stack: Vec<Weak<RefCell<Client>>>,
|
||||
}
|
||||
|
||||
impl Default for WMStateMut {
|
||||
|
@ -322,17 +313,18 @@ impl Default for WMStateMut {
|
|||
move_window: None,
|
||||
resize_window: None,
|
||||
clients: HashMap::new(),
|
||||
focused_client: WeakRc::new(),
|
||||
focused_client: Weak::new(),
|
||||
master_stack: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WMState {
|
||||
xlib_state: XLibState,
|
||||
key_handlers: Vec<(i32, u32, Arc<dyn Fn(&Self, &XEvent)>)>,
|
||||
key_handlers: Vec<(i32, u32, Rc<dyn Fn(&Self, &XEvent)>)>,
|
||||
// (button, mod_mask, button_mask)
|
||||
buttons: Vec<(u32, u32, i64)>,
|
||||
event_handlers: Vec<Arc<dyn Fn(&Self, &XEvent)>>,
|
||||
event_handlers: Vec<Rc<dyn Fn(&Self, &XEvent)>>,
|
||||
mut_state: RefCell<WMStateMut>,
|
||||
}
|
||||
|
||||
|
@ -354,17 +346,33 @@ impl WMState {
|
|||
Mod1Mask,
|
||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
||||
)
|
||||
.add_event_handler(Self::handle_move_window)
|
||||
//.add_event_handler(Self::handle_move_window)
|
||||
.grab_button(
|
||||
3,
|
||||
Mod1Mask,
|
||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
||||
)
|
||||
.add_event_handler(Self::handle_resize_window)
|
||||
//.add_event_handler(Self::handle_resize_window)
|
||||
.add_key_handler("T", Mod1Mask, |state, _| {
|
||||
println!("spawning terminal");
|
||||
let _ = state.spawn("xterm", &[]);
|
||||
})
|
||||
.add_key_handler("M", Mod1Mask, |state, event| {
|
||||
Some(state.mut_state.borrow_mut()).and_then(|mut mstate| {
|
||||
(mstate
|
||||
.clients
|
||||
.iter()
|
||||
.filter(|&(_, c)| c.borrow().window == unsafe { event.button.subwindow })
|
||||
.next()
|
||||
.and_then(|(_, c)| Some(c.clone())))
|
||||
.and_then(|c| {
|
||||
mstate.master_stack.push(Rc::downgrade(&c));
|
||||
Some(())
|
||||
})
|
||||
});
|
||||
|
||||
state.arrange_clients();
|
||||
})
|
||||
.add_key_handler("L", Mod1Mask, |state, _| {
|
||||
println!("{:#?}", state.mut_state.borrow());
|
||||
})
|
||||
|
@ -419,153 +427,22 @@ impl WMState {
|
|||
|
||||
match event.get_type() {
|
||||
xlib::MapRequest => {
|
||||
let event = unsafe { &event.map_request };
|
||||
|
||||
let _ = self
|
||||
.mut_state
|
||||
.try_borrow_mut()
|
||||
.ok()
|
||||
.and_then(|mut m| {
|
||||
if !m.clients.contains_key(&event.window) {
|
||||
Some(
|
||||
m.clients
|
||||
.entry(event.window)
|
||||
.or_insert_with(|| Rc::new(Client::new(event.window)))
|
||||
.clone(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.and_then(|c| {
|
||||
unsafe { xlib::XMapWindow(self.dpy(), c.window) };
|
||||
|
||||
unsafe {
|
||||
xlib::XSelectInput(
|
||||
self.dpy(),
|
||||
event.window,
|
||||
EnterWindowMask
|
||||
| FocusChangeMask
|
||||
| PropertyChangeMask
|
||||
| StructureNotifyMask,
|
||||
);
|
||||
}
|
||||
|
||||
self.buttons
|
||||
.iter()
|
||||
.for_each(|&(button, mod_mask, button_mask)| {
|
||||
self.xlib_state.grab_button(
|
||||
c.window,
|
||||
button,
|
||||
mod_mask,
|
||||
button_mask,
|
||||
);
|
||||
});
|
||||
|
||||
self.arrange_clients();
|
||||
|
||||
self.focus_client(c);
|
||||
|
||||
Some(())
|
||||
});
|
||||
self.map_request(unsafe { &event.map_request });
|
||||
}
|
||||
xlib::UnmapNotify => {
|
||||
let event = unsafe { &event.unmap };
|
||||
|
||||
println!("UnmapNotify: {:?}", event.window);
|
||||
|
||||
if event.send_event == 0 {
|
||||
let _ = self.mut_state.try_borrow_mut().and_then(|mut_state| {
|
||||
if mut_state.clients.contains_key(&event.window) {
|
||||
RefMut::map(mut_state, |t| &mut t.clients).remove(&event.window);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
self.arrange_clients();
|
||||
self.unmap_notify(unsafe { &event.unmap });
|
||||
}
|
||||
xlib::DestroyNotify => {
|
||||
let event = unsafe { &event.destroy_window };
|
||||
|
||||
println!("DestroyNotify: {:?}", event.window);
|
||||
|
||||
let _ = self.mut_state.try_borrow_mut().and_then(|mut_state| {
|
||||
if mut_state.clients.contains_key(&event.window) {
|
||||
RefMut::map(mut_state, |t| &mut t.clients).remove(&event.window);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
self.arrange_clients();
|
||||
self.destroy_notify(unsafe { &event.destroy_window });
|
||||
}
|
||||
xlib::ConfigureRequest => {
|
||||
let event = unsafe { &event.configure_request };
|
||||
|
||||
match self.mut_state.borrow_mut().clients.entry(event.window) {
|
||||
Entry::Occupied(entry) => {
|
||||
self.configure_client(entry.get().clone());
|
||||
}
|
||||
_ => {
|
||||
let mut wc = xlib::XWindowChanges {
|
||||
x: event.x,
|
||||
y: event.y,
|
||||
width: event.width,
|
||||
height: event.height,
|
||||
border_width: event.border_width,
|
||||
sibling: event.above,
|
||||
stack_mode: event.detail,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
xlib::XConfigureWindow(
|
||||
self.dpy(),
|
||||
event.window,
|
||||
event.value_mask as u32,
|
||||
&mut wc,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.configure_request(unsafe { &event.configure_request });
|
||||
}
|
||||
xlib::EnterNotify => {
|
||||
let event = unsafe { &event.crossing };
|
||||
|
||||
println!("EnterNotify: {:?}", event.window);
|
||||
|
||||
match self.mut_state.try_borrow().ok().and_then(|mut_state| {
|
||||
mut_state
|
||||
.clients
|
||||
.get(&event.window)
|
||||
.and_then(|c| Some(c.clone()))
|
||||
}) {
|
||||
Some(client) => {
|
||||
self.focus_client(client);
|
||||
}
|
||||
None => {}
|
||||
};
|
||||
self.enter_notify(unsafe { &event.crossing });
|
||||
}
|
||||
xlib::ButtonPress => {
|
||||
let event = unsafe { &event.button };
|
||||
|
||||
match self.mut_state.try_borrow().ok().and_then(|mut_state| {
|
||||
mut_state
|
||||
.clients
|
||||
.get(&event.subwindow)
|
||||
.and_then(|c| Some(c.clone()))
|
||||
}) {
|
||||
Some(client) => {
|
||||
self.focus_client(client.clone());
|
||||
println!("raising window {:?}", client.window);
|
||||
unsafe {
|
||||
xlib::XRaiseWindow(self.dpy(), client.window);
|
||||
xlib::XSync(self.dpy(), 0);
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
};
|
||||
self.button_press(unsafe { &event.button });
|
||||
}
|
||||
xlib::KeyPress => {
|
||||
let clean_mask = self.xlib_state.clean_mask();
|
||||
|
@ -600,11 +477,12 @@ impl WMState {
|
|||
self
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn add_event_handler<F>(mut self, handler: F) -> Self
|
||||
where
|
||||
F: Fn(&Self, &XEvent) + 'static,
|
||||
{
|
||||
self.event_handlers.push(Arc::new(handler));
|
||||
self.event_handlers.push(Rc::new(handler));
|
||||
|
||||
self
|
||||
}
|
||||
|
@ -616,17 +494,187 @@ impl WMState {
|
|||
{
|
||||
let keycode = self.xlib_state.keycode(key);
|
||||
|
||||
self.key_handlers.push((keycode, mask, Arc::new(handler)));
|
||||
self.key_handlers.push((keycode, mask, Rc::new(handler)));
|
||||
self.xlib_state.grab_key(self.root(), keycode, mask);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn unfocus_client(&self, client: Rc<Client>) {
|
||||
fn map_request(&self, event: &xlib::XMapRequestEvent) {
|
||||
info!("[MapRequest] event: {:#?}", event);
|
||||
|
||||
let _ = Some(self.mut_state.borrow_mut())
|
||||
.and_then(|mut state| {
|
||||
if !state.clients.contains_key(&event.window) {
|
||||
info!("[MapRequest] new client: {:#?}", event.window);
|
||||
Some(
|
||||
state
|
||||
.clients
|
||||
.entry(event.window)
|
||||
.or_insert_with(|| Rc::new(RefCell::new(Client::new(event.window))))
|
||||
.clone(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.and_then(|c| {
|
||||
unsafe {
|
||||
xlib::XMapWindow(self.dpy(), c.borrow().window);
|
||||
|
||||
xlib::XSelectInput(
|
||||
self.dpy(),
|
||||
event.window,
|
||||
EnterWindowMask
|
||||
| FocusChangeMask | PropertyChangeMask
|
||||
| StructureNotifyMask,
|
||||
);
|
||||
}
|
||||
|
||||
self.buttons
|
||||
.iter()
|
||||
.for_each(|&(button, mod_mask, button_mask)| {
|
||||
self.xlib_state.grab_button(
|
||||
c.borrow().window,
|
||||
button,
|
||||
mod_mask,
|
||||
button_mask,
|
||||
);
|
||||
});
|
||||
|
||||
self.arrange_clients();
|
||||
self.focus_client(c.clone());
|
||||
|
||||
Some(())
|
||||
});
|
||||
}
|
||||
|
||||
fn unmap_notify(&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.clients.contains_key(&event.window) {
|
||||
let client = state.clients.remove(&event.window);
|
||||
info!("[UnmapNotify] removing client: {:#?}", client);
|
||||
}
|
||||
|
||||
Some(())
|
||||
});
|
||||
}
|
||||
|
||||
self.arrange_clients();
|
||||
}
|
||||
|
||||
fn destroy_notify(&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);
|
||||
|
||||
info!("[DestroyNotify] removed entry: {:?}", _entry);
|
||||
|
||||
Some(())
|
||||
});
|
||||
|
||||
self.arrange_clients();
|
||||
}
|
||||
|
||||
fn configure_request(&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()
|
||||
);
|
||||
|
||||
self.configure_client(entry.get().clone());
|
||||
}
|
||||
_ => {
|
||||
info!(
|
||||
"[ConfigureRequest] no client found for Window({:?}), calling XConfigureWindow()",
|
||||
event.window);
|
||||
|
||||
let mut wc = xlib::XWindowChanges {
|
||||
x: event.x,
|
||||
y: event.y,
|
||||
width: event.width,
|
||||
height: event.height,
|
||||
border_width: event.border_width,
|
||||
sibling: event.above,
|
||||
stack_mode: event.detail,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
xlib::XConfigureWindow(
|
||||
self.dpy(),
|
||||
event.window,
|
||||
event.value_mask as u32,
|
||||
&mut wc,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_notify(&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(())
|
||||
});
|
||||
}
|
||||
|
||||
fn button_press(&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());
|
||||
|
||||
info!("[ButtonPress] raising Window({:?})", event.window);
|
||||
|
||||
unsafe {
|
||||
xlib::XRaiseWindow(self.dpy(), c.borrow().window);
|
||||
xlib::XSync(self.dpy(), 0);
|
||||
}
|
||||
|
||||
Some(())
|
||||
});
|
||||
}
|
||||
|
||||
fn unfocus_client(&self, client: Rc<RefCell<Client>>) {
|
||||
unsafe {
|
||||
xlib::XSetInputFocus(
|
||||
self.dpy(),
|
||||
client.window,
|
||||
client.borrow().window,
|
||||
xlib::RevertToPointerRoot,
|
||||
xlib::CurrentTime,
|
||||
);
|
||||
|
@ -639,7 +687,7 @@ impl WMState {
|
|||
}
|
||||
}
|
||||
|
||||
fn focus_client(&self, client: Rc<Client>) {
|
||||
fn focus_client(&self, client: Rc<RefCell<Client>>) {
|
||||
let _ = self.mut_state.try_borrow_mut().and_then(|m| {
|
||||
let mut focused_client = RefMut::map(m, |m| &mut m.focused_client);
|
||||
match focused_client.upgrade() {
|
||||
|
@ -657,7 +705,7 @@ impl WMState {
|
|||
unsafe {
|
||||
xlib::XSetInputFocus(
|
||||
self.dpy(),
|
||||
client.window,
|
||||
client.borrow().window,
|
||||
xlib::RevertToPointerRoot,
|
||||
xlib::CurrentTime,
|
||||
);
|
||||
|
@ -669,16 +717,18 @@ impl WMState {
|
|||
xlib::XA_WINDOW,
|
||||
32,
|
||||
xlib::PropModeReplace,
|
||||
&client.window as *const u64 as *const _,
|
||||
&client.borrow().window as *const u64 as *const _,
|
||||
1,
|
||||
);
|
||||
}
|
||||
|
||||
self.xlib_state
|
||||
.send_event(client.window, self.xlib_state.atoms.take_focus);
|
||||
.send_event(client.borrow().window, self.xlib_state.atoms.take_focus);
|
||||
}
|
||||
|
||||
fn arrange_clients(&self) {
|
||||
self.refresh_stack();
|
||||
|
||||
let (screen_w, screen_h) = unsafe {
|
||||
(
|
||||
xlib::XDisplayWidth(self.dpy(), self.xlib_state.screen()),
|
||||
|
@ -686,33 +736,106 @@ impl WMState {
|
|||
)
|
||||
};
|
||||
|
||||
let clients_num = self.mut_state.borrow().clients.len() as i32;
|
||||
Some(self.mut_state.borrow_mut()).and_then(|mut state| {
|
||||
// no need to arrange any clients if there is no clients
|
||||
if !state.clients.is_empty() {
|
||||
// if master stack is empty, populate with first entry in clients list
|
||||
if state.master_stack.is_empty() {
|
||||
let first_client = Rc::downgrade(state.clients.iter().next().unwrap().1);
|
||||
state.master_stack.push(first_client);
|
||||
}
|
||||
|
||||
if clients_num != 0 {
|
||||
let window_w = screen_w / clients_num;
|
||||
let window_w = {
|
||||
let has_aux_stack = state
|
||||
.clients
|
||||
.iter()
|
||||
.filter(|&(_, client)| {
|
||||
state
|
||||
.master_stack
|
||||
.iter()
|
||||
.filter(|weak_client| weak_client.upgrade().unwrap() != *client)
|
||||
.count() != 0
|
||||
})
|
||||
.count() != 0;
|
||||
|
||||
for (i, (_, client)) in self.mut_state.borrow().clients.iter().enumerate() {
|
||||
let client_state = ClientState {
|
||||
size: (window_w as u32, screen_h as u32),
|
||||
position: (window_w * i as i32, 0),
|
||||
if has_aux_stack {
|
||||
screen_w / 2
|
||||
} else {
|
||||
screen_w
|
||||
}
|
||||
};
|
||||
|
||||
client.state.replace(client_state);
|
||||
for (i, weak_client) in state.master_stack.iter().enumerate() {
|
||||
let client = weak_client.upgrade().unwrap();
|
||||
|
||||
let mut wc = xlib::XWindowChanges {
|
||||
x: client_state.position.0,
|
||||
y: client_state.position.1,
|
||||
width: client_state.size.0 as i32,
|
||||
height: client_state.size.1 as i32,
|
||||
let mut wc = {
|
||||
let mut client = client.borrow_mut();
|
||||
let window_h = screen_h / state.master_stack.len() as i32;
|
||||
|
||||
client.size = (window_w, window_h);
|
||||
client.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,
|
||||
border_width: 0,
|
||||
sibling: 0,
|
||||
stack_mode: 0,
|
||||
}
|
||||
};
|
||||
|
||||
unsafe {
|
||||
xlib::XConfigureWindow(
|
||||
self.dpy(),
|
||||
client.window,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// filter only windows that arent inthe master stack, essentially aux stack
|
||||
for (i, (_, client)) in state
|
||||
.clients
|
||||
.iter()
|
||||
.filter(|&(_, c)| {
|
||||
state
|
||||
.master_stack
|
||||
.iter()
|
||||
.filter(|w| w.upgrade().unwrap() == *c)
|
||||
.count() == 0
|
||||
})
|
||||
.enumerate()
|
||||
{
|
||||
let mut wc = {
|
||||
let mut client = client.borrow_mut();
|
||||
let window_h =
|
||||
screen_h / (state.clients.len() - state.master_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,
|
||||
);
|
||||
|
@ -723,31 +846,52 @@ impl WMState {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(())
|
||||
});
|
||||
}
|
||||
|
||||
fn configure_client(&self, client: Rc<Client>) {
|
||||
let client_state = client.get_state();
|
||||
fn refresh_stack(&self) {
|
||||
Some(self.mut_state.borrow_mut()).and_then(|mut state| {
|
||||
state.master_stack = state
|
||||
.master_stack
|
||||
.iter()
|
||||
.filter_map(|weak_client| {
|
||||
weak_client
|
||||
.upgrade()
|
||||
.and_then(|_| Some(weak_client.clone()))
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut event = xlib::XConfigureEvent {
|
||||
Some(())
|
||||
});
|
||||
}
|
||||
|
||||
fn configure_client(&self, client: Rc<RefCell<Client>>) {
|
||||
let mut event = {
|
||||
let client = client.borrow();
|
||||
|
||||
xlib::XConfigureEvent {
|
||||
type_: xlib::ConfigureNotify,
|
||||
display: self.dpy(),
|
||||
event: client.window,
|
||||
window: client.window,
|
||||
x: client_state.position.0,
|
||||
y: client_state.position.1,
|
||||
width: client_state.size.0 as i32,
|
||||
height: client_state.size.1 as i32,
|
||||
x: client.position.0,
|
||||
y: client.position.1,
|
||||
width: client.size.0,
|
||||
height: client.size.1,
|
||||
border_width: 0,
|
||||
override_redirect: 0,
|
||||
send_event: 0,
|
||||
serial: 0,
|
||||
above: 0,
|
||||
}
|
||||
};
|
||||
|
||||
unsafe {
|
||||
xlib::XSendEvent(
|
||||
self.dpy(),
|
||||
client.window,
|
||||
event.window,
|
||||
0,
|
||||
StructureNotifyMask,
|
||||
&mut event as *mut _ as *mut XEvent,
|
||||
|
|
Loading…
Reference in a new issue