aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs197
1 files changed, 197 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..8f9a8aa
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,197 @@
1use std::thread;
2use std::time::{Duration, Instant};
3
4fn main() {
5 let win_width = 500u16;
6 let win_height = 500u16;
7
8 let (conn, screen_num) = xcb::Connection::connect(None).unwrap();
9 let setup = conn.get_setup();
10 let screen = setup.roots().nth(screen_num as usize).unwrap();
11
12 let depths = screen.allowed_depths();
13 let mut alpha_depths = depths.filter(|d| d.depth() == 32u8);
14
15 let visual = alpha_depths
16 .next()
17 .unwrap()
18 .visuals()
19 .nth(1 as usize)
20 .unwrap();
21
22 let win_start_x = 0;
23 let win_start_y = 0;
24
25 let colormap = conn.generate_id();
26 xcb::create_colormap(
27 &conn,
28 xcb::COLORMAP_ALLOC_NONE as u8,
29 colormap,
30 screen.root(),
31 visual.visual_id(),
32 );
33
34 let win = conn.generate_id();
35 xcb::create_window(
36 &conn,
37 32u8,
38 win,
39 screen.root(),
40 win_start_x,
41 win_start_y,
42 win_width,
43 win_height,
44 2,
45 xcb::WINDOW_CLASS_INPUT_OUTPUT as u16,
46 visual.visual_id(),
47 &[
48 (xcb::CW_BACK_PIXEL, 0x00),
49 (xcb::CW_BORDER_PIXEL, 0x00),
50 //(xcb::CW_OVERRIDE_REDIRECT, 1u32),
51 (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_EXPOSURE),
52 (xcb::CW_COLORMAP, colormap),
53 ],
54 );
55
56 let gfx_ctx = conn.generate_id();
57 xcb::create_gc(
58 &conn,
59 gfx_ctx,
60 win,
61 &[
62 (xcb::GC_FOREGROUND, screen.white_pixel()),
63 (xcb::GC_GRAPHICS_EXPOSURES, 0),
64 (xcb::GC_LINE_WIDTH, 1),
65 ],
66 );
67
68 xcb::free_colormap(&conn, colormap);
69
70 let win_type_atom = xcb::intern_atom(&conn, true, "_NET_WM_WINDOW_TYPE")
71 .get_reply()
72 .unwrap()
73 .atom();
74 let win_menu_atom = xcb::intern_atom(&conn, true, "_NET_WM_WINDOW_TYPE_SPLASH")
75 .get_reply()
76 .unwrap()
77 .atom();
78
79 let win_state_atom = xcb::intern_atom(&conn, true, "_NET_WM_STATE")
80 .get_reply()
81 .unwrap()
82 .atom();
83 let win_on_top_atom = xcb::intern_atom(&conn, true, "_NET_WM_STATE_STAYS_ON_TOP")
84 .get_reply()
85 .unwrap()
86 .atom();
87
88 xcb::change_property(
89 &conn,
90 xcb::PROP_MODE_REPLACE as u8,
91 win,
92 win_type_atom,
93 xcb::ATOM_ATOM,
94 32,
95 &[win_menu_atom],
96 );
97 xcb::change_property(
98 &conn,
99 xcb::PROP_MODE_APPEND as u8,
100 win,
101 win_state_atom,
102 xcb::ATOM_ATOM,
103 32,
104 &[win_on_top_atom],
105 );
106
107 let mut circles = (1u16..10u16)
108 .map(|i| {
109 xcb::Arc::new(
110 win_start_x + 25 * i as i16,
111 win_start_y + 25 * i as i16,
112 win_width - 50 * i,
113 win_height - 50 * i,
114 0,
115 360 << 6,
116 )
117 })
118 .collect::<Vec<xcb::Arc>>()
119 .into_iter();
120
121 xcb::map_window(&conn, win);
122 conn.flush();
123
124 loop {
125 let event = conn.wait_for_event();
126 match event {
127 None => {
128 break;
129 }
130 Some(e) => {
131 let r = e.response_type() & !0x80;
132 match r {
133 xcb::EXPOSE => {
134 xcb::poly_arc(&conn, win, gfx_ctx, &[circles.next().unwrap()]);
135 conn.flush();
136 break;
137 }
138 _ => {
139 break;
140 }
141 }
142 }
143 }
144 }
145
146 let pointer = xcb::query_pointer(&conn, win).get_reply().unwrap();
147 let p_x = pointer.root_x();
148 let p_y = pointer.root_y();
149
150 move_win_to_cursor(&conn, win, win_width, win_height, p_x, p_y);
151
152 let loop_start = Instant::now();
153 let anim_duration = Duration::from_millis(600);
154 let circle_duration = Duration::from_millis(60);
155 loop {
156 match circles.next() {
157 Some(c) => {
158 let _ = xcb::poly_arc(&conn, win, gfx_ctx, &[c]);
159 conn.flush();
160 }
161 None => {}
162 };
163 thread::sleep(circle_duration);
164 let now = Instant::now();
165 if now.duration_since(loop_start) > anim_duration {
166 break;
167 }
168 }
169 thread::sleep(Duration::from_millis(100));
170}
171
172fn move_win_to_cursor(
173 conn: &xcb::Connection,
174 win: u32,
175 win_width: u16,
176 win_height: u16,
177 p_x: i16,
178 p_y: i16,
179) {
180 let win_x = p_x - (win_width as i16) / 2;
181 let win_y = p_y - (win_height as i16) / 2;
182 xcb::configure_window(
183 &conn,
184 win,
185 &[
186 (
187 xcb::CONFIG_WINDOW_X as u16,
188 if win_x < 0 { 0 } else { win_x as u32 },
189 ),
190 (
191 xcb::CONFIG_WINDOW_Y as u16,
192 if win_y < 0 { 0 } else { win_y as u32 },
193 ),
194 ],
195 );
196 conn.flush();
197}