oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git
4,268 bytes raw
1
use crate::bar::font::{Font, FontDraw};
2
use crate::errors::X11Error;
3
use x11rb::COPY_DEPTH_FROM_PARENT;
4
use x11rb::connection::Connection;
5
use x11rb::protocol::xproto::*;
6
use x11rb::rust_connection::RustConnection;
7
8
pub mod error;
9
pub mod keybind;
10
11
pub use error::ErrorOverlay;
12
pub use keybind::KeybindOverlay;
13
14
pub trait Overlay {
15
    fn window(&self) -> Window;
16
    fn is_visible(&self) -> bool;
17
    fn hide(&mut self, connection: &RustConnection) -> Result<(), X11Error>;
18
    fn draw(&self, connection: &RustConnection, font: &Font) -> Result<(), X11Error>;
19
}
20
21
pub struct OverlayBase {
22
    pub window: Window,
23
    pub width: u16,
24
    pub height: u16,
25
    pub graphics_context: Gcontext,
26
    pub font_draw: FontDraw,
27
    pub is_visible: bool,
28
    pub background_color: u32,
29
    pub foreground_color: u32,
30
}
31
32
impl OverlayBase {
33
    pub fn new(
34
        connection: &RustConnection,
35
        screen: &Screen,
36
        screen_num: usize,
37
        display: *mut x11::xlib::Display,
38
        width: u16,
39
        height: u16,
40
        border_width: u16,
41
        border_color: u32,
42
        background_color: u32,
43
        foreground_color: u32,
44
    ) -> Result<Self, X11Error> {
45
        let window = connection.generate_id()?;
46
        let graphics_context = connection.generate_id()?;
47
48
        connection.create_window(
49
            COPY_DEPTH_FROM_PARENT,
50
            window,
51
            screen.root,
52
            0,
53
            0,
54
            width,
55
            height,
56
            border_width,
57
            WindowClass::INPUT_OUTPUT,
58
            screen.root_visual,
59
            &CreateWindowAux::new()
60
                .background_pixel(background_color)
61
                .border_pixel(border_color)
62
                .event_mask(EventMask::EXPOSURE | EventMask::BUTTON_PRESS | EventMask::KEY_PRESS)
63
                .override_redirect(1),
64
        )?;
65
66
        connection.create_gc(
67
            graphics_context,
68
            window,
69
            &CreateGCAux::new()
70
                .foreground(foreground_color)
71
                .background(background_color),
72
        )?;
73
74
        connection.flush()?;
75
76
        let visual = unsafe { x11::xlib::XDefaultVisual(display, screen_num as i32) };
77
        let colormap = unsafe { x11::xlib::XDefaultColormap(display, screen_num as i32) };
78
79
        let font_draw = FontDraw::new(display, window as x11::xlib::Drawable, visual, colormap)?;
80
81
        Ok(OverlayBase {
82
            window,
83
            width,
84
            height,
85
            graphics_context,
86
            font_draw,
87
            is_visible: false,
88
            background_color,
89
            foreground_color,
90
        })
91
    }
92
93
    pub fn configure(
94
        &mut self,
95
        connection: &RustConnection,
96
        x: i16,
97
        y: i16,
98
        width: u16,
99
        height: u16,
100
    ) -> Result<(), X11Error> {
101
        self.width = width;
102
        self.height = height;
103
104
        connection.configure_window(
105
            self.window,
106
            &ConfigureWindowAux::new()
107
                .x(x as i32)
108
                .y(y as i32)
109
                .width(width as u32)
110
                .height(height as u32),
111
        )?;
112
113
        Ok(())
114
    }
115
116
    pub fn show(&mut self, connection: &RustConnection) -> Result<(), X11Error> {
117
        connection.configure_window(
118
            self.window,
119
            &ConfigureWindowAux::new().stack_mode(StackMode::ABOVE),
120
        )?;
121
122
        connection.map_window(self.window)?;
123
        connection.flush()?;
124
125
        self.is_visible = true;
126
127
        Ok(())
128
    }
129
130
    pub fn hide(&mut self, connection: &RustConnection) -> Result<(), X11Error> {
131
        if self.is_visible {
132
            connection.unmap_window(self.window)?;
133
            connection.flush()?;
134
            self.is_visible = false;
135
        }
136
        Ok(())
137
    }
138
139
    pub fn draw_background(&self, connection: &RustConnection) -> Result<(), X11Error> {
140
        connection.change_gc(
141
            self.graphics_context,
142
            &ChangeGCAux::new().foreground(self.background_color),
143
        )?;
144
        connection.poly_fill_rectangle(
145
            self.window,
146
            self.graphics_context,
147
            &[Rectangle {
148
                x: 0,
149
                y: 0,
150
                width: self.width,
151
                height: self.height,
152
            }],
153
        )?;
154
        Ok(())
155
    }
156
}