The clock is gone
This commit is contained in:
parent
832d68bfcf
commit
52e24bdedf
27
src/main.rs
27
src/main.rs
|
@ -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
119
src/x11/client.rs
Normal 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
1
src/x11/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod client;
|
Loading…
Reference in a new issue