Skip to content

Commit f83bb0a

Browse files
committed
added optional snowflakes on root window
1 parent 28dd4ea commit f83bb0a

File tree

6 files changed

+203
-4
lines changed

6 files changed

+203
-4
lines changed

Cargo.lock

Lines changed: 93 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ libc = "0.2.177"
1616
chrono = "0.4.42"
1717
dirs = "6.0.0"
1818
sysinfo = "0.37"
19-
battery = "0.7"
19+
battery = "0.7"
20+
rand = "0.9"

gridwm.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ exec = []
33

44
[general]
55
update_ms = "auto"
6+
snowflakes = false
67

78
[window]
89
scale_steps = 20

src/gridwm/config.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@ impl Default for Window {
4949
#[serde(default)]
5050
pub struct General {
5151
pub update_ms: String,
52+
pub snowflakes: bool,
5253
}
5354

5455
impl Default for General {
5556
fn default() -> Self {
5657
Self {
57-
update_ms: "5".to_string(),
58+
update_ms: "auto".to_string(),
59+
snowflakes: false,
5860
}
5961
}
6062
}

src/gridwm/mod.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ mod config;
33
mod error;
44
mod keybinds;
55
mod signals;
6+
mod winter;
67

78
use bar::*;
89
use config::Config;
910
use error::*;
1011
use keybinds::*;
1112
use signals::*;
13+
use winter::*;
1214

1315
use log::*;
1416
use std::{
@@ -56,6 +58,7 @@ pub struct GridWM {
5658
win_bar_windows: HashMap<Window, Window>,
5759
refresh_rate: i16,
5860
trigger_redraw: bool,
61+
snowflakes: Vec<Snowflake>,
5962
}
6063

6164
pub type Window = u64;
@@ -177,6 +180,12 @@ impl GridWM {
177180
}
178181
};
179182

183+
let mut snowflakes: Vec<Snowflake> = Vec::new();
184+
185+
if config.general.snowflakes {
186+
snowflakes = generate_snowflakes(screen_width, screen_height);
187+
}
188+
180189
Ok(GridWM {
181190
display,
182191
config,
@@ -194,6 +203,7 @@ impl GridWM {
194203
win_bar_windows: HashMap::new(),
195204
refresh_rate,
196205
trigger_redraw: true,
206+
snowflakes,
197207
})
198208
}
199209

@@ -548,6 +558,18 @@ impl GridWM {
548558
self.trigger_redraw = true;
549559
}
550560

561+
// snowflakes
562+
if self.config.general.snowflakes {
563+
draw_snowflakes(
564+
self.display,
565+
&mut self.snowflakes,
566+
self.screen_width,
567+
self.screen_height,
568+
self.bar_gc,
569+
);
570+
self.trigger_redraw = true;
571+
}
572+
551573
if self.config.bar.enable && self.trigger_redraw {
552574
self.draw_bar(None);
553575
}
@@ -1046,7 +1068,15 @@ impl GridWM {
10461068
}
10471069
};
10481070

1049-
xlib::XClearArea(self.display, root, 0, 0, self.screen_width as u32, 50, 0);
1071+
xlib::XClearArea(
1072+
self.display,
1073+
root,
1074+
0,
1075+
0,
1076+
self.screen_width as u32,
1077+
self.config.bar.height,
1078+
0,
1079+
);
10501080
xlib::XFillRectangle(
10511081
self.display,
10521082
root,

src/gridwm/winter.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use std::ffi::CString;
2+
3+
use rand::Rng;
4+
use x11::xlib::{Display, GC, XClearArea, XDefaultRootWindow, XDrawString};
5+
6+
#[derive(Debug)]
7+
pub struct Snowflake {
8+
pub x: f32,
9+
pub y: f32,
10+
pub speed: f32,
11+
pub drift: f32,
12+
}
13+
14+
pub fn draw_snowflakes(
15+
display: *mut Display,
16+
snowflakes: &mut Vec<Snowflake>,
17+
screen_width: i16,
18+
screen_height: i16,
19+
flake_gc: GC,
20+
) {
21+
unsafe {
22+
let root = XDefaultRootWindow(display);
23+
24+
for flake in snowflakes {
25+
XClearArea(
26+
display,
27+
root,
28+
flake.x as i32 - 2,
29+
flake.y as i32 - 14,
30+
18,
31+
20,
32+
0,
33+
);
34+
35+
flake.y += flake.speed;
36+
flake.x += flake.drift;
37+
38+
if flake.y > screen_height as f32 {
39+
flake.y = 0.0;
40+
}
41+
if flake.x < 0.0 {
42+
flake.x = screen_width as f32
43+
} else if flake.x > screen_width as f32 {
44+
flake.x = 0.0
45+
}
46+
47+
let flake_str = CString::new("*").unwrap_or_default();
48+
XDrawString(
49+
display,
50+
root,
51+
flake_gc,
52+
flake.x as i32,
53+
flake.y as i32,
54+
flake_str.as_ptr(),
55+
flake_str.to_bytes().len() as i32,
56+
);
57+
}
58+
}
59+
}
60+
61+
// snowflake generation
62+
pub fn generate_snowflakes(screen_width: i16, screen_height: i16) -> Vec<Snowflake> {
63+
let mut rng = rand::rng();
64+
65+
(0..40)
66+
.map(|_| Snowflake {
67+
x: rng.random_range(0.0..=screen_width as f32),
68+
y: rng.random_range(0.0..=screen_height as f32),
69+
speed: rng.random_range(0.5..=1.8),
70+
drift: rng.random_range(-0.3..=0.3),
71+
})
72+
.collect()
73+
}

0 commit comments

Comments
 (0)