The clock is gone

This commit is contained in:
famfo 2022-06-25 00:34:37 +02:00
parent 832d68bfcf
commit 52e24bdedf
5 changed files with 143 additions and 7 deletions

1
run.sh
View file

@ -9,4 +9,3 @@ xinit ./xinitrc -- \
-ac \
-screen 800x600 \
-host-cursor

View file

@ -1,6 +1,7 @@
#![warn(clippy::pedantic)]
use std::collections::HashMap;
//use std::sync::Rc;
use breadx::{
prelude::{AsyncDisplayXprotoExt, MapState, SetMode},
@ -9,8 +10,15 @@ use breadx::{
Event, EventMask, Window,
};
mod x11;
use x11::client::XcrabClient;
const BORDER_WIDTH: u16 = 5;
const GAP_WIDTH: u16 = 10;
#[derive(Debug)] // TODO: actually print good errors on failure
enum XcrabError {
pub enum XcrabError {
Bread(BreadError),
}
@ -43,8 +51,13 @@ async fn main() -> Result<(), XcrabError> {
for &win in top_level_windows.iter() {
let attrs = win.window_attributes_immediate_async(&mut conn).await?;
println!("a");
if !attrs.override_redirect && attrs.map_state == MapState::Viewable {
clients.insert(win, manage_window(&mut conn, win).await?);
clients.insert(
win,
XcrabClient::new(win, &mut conn, clients.len() + 1).await?,
);
x11::client::calculate_geometry(&mut clients, &mut conn).await?;
}
}
@ -57,7 +70,11 @@ async fn main() -> Result<(), XcrabError> {
Event::MapRequest(ev) => {
let win = ev.window;
clients.insert(win, manage_window(&mut conn, win).await?);
clients.insert(
win,
XcrabClient::new(win, &mut conn, clients.len() + 1).await?,
);
x11::client::calculate_geometry(&mut clients, &mut conn).await?;
}
Event::ConfigureRequest(ev) => {
// cope from `ev` to `params`
@ -85,7 +102,7 @@ async fn main() -> Result<(), XcrabError> {
Event::UnmapNotify(ev) => {
if ev.event != root {
if let Some(parent) = clients.get(&ev.window) {
parent.unmap_async(&mut conn).await?;
parent.parent.unmap_async(&mut conn).await?;
ev.window.reparent_async(&mut conn, root, 0, 0).await?;
@ -94,7 +111,7 @@ async fn main() -> Result<(), XcrabError> {
.change_save_set_async(&mut conn, SetMode::Delete)
.await?;
parent.free_async(&mut conn).await?;
parent.parent.free_async(&mut conn).await?;
clients.remove(&ev.window);
}

119
src/x11/client.rs Normal file
View file

@ -0,0 +1,119 @@
use breadx::prelude::{AsyncDisplayXprotoExt, Geometry, SetMode};
use breadx::{AsyncDisplay, ConfigureWindowParameters, Window};
use std::collections::HashMap;
use std::sync::Arc;
pub struct XcrabClient {
geometry: XcrabGeometry,
position: usize,
pub parent: Window,
}
#[derive(Debug)]
struct XcrabGeometry {
x: i16,
y: i16,
width: u16,
height: u16,
}
impl XcrabClient {
pub async fn new<Dpy: AsyncDisplay + ?Sized>(
window: Window,
dpy: &mut Dpy,
position: usize,
) -> Result<Self, crate::XcrabError> {
let geometry = window.geometry_immediate_async(dpy).await?;
let root = dpy.default_root();
let parent = dpy
.create_simple_window_async(
root,
geometry.x,
geometry.y,
geometry.width,
geometry.height,
crate::BORDER_WIDTH,
0xff_00_00,
0x00_00_00,
)
.await?;
Ok(XcrabClient {
geometry: XcrabGeometry {
x: geometry.x,
y: geometry.y,
width: geometry.width,
height: geometry.height,
},
position,
parent,
})
}
pub fn update_geometry(&mut self, geometry: XcrabGeometry) {
self.geometry = geometry;
}
}
pub async fn calculate_geometry<Dpy: AsyncDisplay + ?Sized>(
windows: &mut HashMap<Window, XcrabClient>,
dpy: &mut Dpy,
) -> Result<(), crate::XcrabError> {
let root = dpy.default_root();
let root_geometry = root.geometry_immediate_async(dpy).await?;
let window_count = windows.len();
// let gap_width = crate::GAP_WIDTH as usize * (window_count + 1);
let width_per_window = root_geometry.width as usize / window_count;
let border_width = crate::BORDER_WIDTH as usize * 2;
for (window, xcrab_client) in windows {
let xcrab_geometry = XcrabGeometry {
x: xcrab_client.position as i16 * width_per_window as i16,
y: xcrab_client.geometry.y,
width: (width_per_window - border_width) as u16,
height: xcrab_client.geometry.height,
};
xcrab_client.update_geometry(xcrab_geometry);
window.change_save_set_async(dpy, SetMode::Insert).await?;
xcrab_client
.parent
.configure_async(
dpy,
ConfigureWindowParameters {
x: Some(xcrab_client.geometry.x.into()),
y: Some(xcrab_client.geometry.y.into()),
width: Some(xcrab_client.geometry.width.into()),
height: Some(xcrab_client.geometry.height.into()),
..Default::default()
},
)
.await?;
window
.configure_async(
dpy,
ConfigureWindowParameters {
width: Some(xcrab_client.geometry.width.into()),
height: Some(xcrab_client.geometry.height.into()),
..Default::default()
},
)
.await?;
window
.reparent_async(dpy, xcrab_client.parent, 0, 0)
.await?;
xcrab_client.parent.map_async(dpy).await?;
window.map_async(dpy).await?;
println!("{:#?}", xcrab_client.geometry);
}
Ok(())
}

1
src/x11/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod client;

View file

@ -5,4 +5,4 @@ xterm &
sleep 2;
target/debug/xcrab
target/debug/xcrab