oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git

Rust is memory safe.

Commit
8e7c5c62ef1d2d4ff41c24bca96fff773e99f6b1
Parent
fa421d2
Author
tonybanters <tonybanters@gmail.com>
Date
2025-12-20 00:53:57

Diff

diff --git a/src/bar/bar.rs b/src/bar/bar.rs
index 4b6e1c8..f6b3555 100644
--- a/src/bar/bar.rs
+++ b/src/bar/bar.rs
@@ -1,5 +1,5 @@
 use super::blocks::Block;
-use super::font::{Font, FontDraw};
+use super::font::{DrawingSurface, Font};
 use crate::Config;
 use crate::errors::X11Error;
 use std::time::Instant;
@@ -13,10 +13,7 @@ pub struct Bar {
     width: u16,
     height: u16,
     graphics_context: Gcontext,
-    pixmap: x11::xlib::Pixmap,
-    display: *mut x11::xlib::Display,
-
-    font_draw: FontDraw,
+    surface: DrawingSurface,
 
     tag_widths: Vec<u16>,
     needs_redraw: bool,
@@ -80,19 +77,15 @@ impl Bar {
 
         let visual = unsafe { x11::xlib::XDefaultVisual(display, screen_num as i32) };
         let colormap = unsafe { x11::xlib::XDefaultColormap(display, screen_num as i32) };
-        let depth = unsafe { x11::xlib::XDefaultDepth(display, screen_num as i32) };
-
-        let pixmap = unsafe {
-            x11::xlib::XCreatePixmap(
-                display,
-                window as x11::xlib::Drawable,
-                width as u32,
-                height as u32,
-                depth as u32,
-            )
-        };
 
-        let font_draw = FontDraw::new(display, pixmap, visual, colormap)?;
+        let surface = DrawingSurface::new(
+            display,
+            window as x11::xlib::Drawable,
+            width as u32,
+            height as u32,
+            visual,
+            colormap,
+        )?;
 
         let horizontal_padding = (font.height() as f32 * 0.4) as u16;
 
@@ -124,9 +117,7 @@ impl Bar {
             width,
             height,
             graphics_context,
-            pixmap,
-            display,
-            font_draw,
+            surface,
             tag_widths,
             needs_redraw: true,
             blocks,
@@ -201,11 +192,11 @@ impl Bar {
         connection.flush()?;
 
         unsafe {
-            let gc = x11::xlib::XCreateGC(display, self.pixmap, 0, std::ptr::null_mut());
+            let gc = x11::xlib::XCreateGC(display, self.surface.pixmap(), 0, std::ptr::null_mut());
             x11::xlib::XSetForeground(display, gc, self.scheme_normal.background as u64);
             x11::xlib::XFillRectangle(
                 display,
-                self.pixmap,
+                self.surface.pixmap(),
                 gc,
                 0,
                 0,
@@ -241,7 +232,8 @@ impl Bar {
             let top_padding = 4;
             let text_y = top_padding + font.ascent();
 
-            self.font_draw
+            self.surface
+                .font_draw()
                 .draw_text(font, scheme.foreground, text_x, text_y, tag);
 
             if is_selected || is_urgent {
@@ -255,11 +247,11 @@ impl Bar {
                 let underline_x = x_position + (underline_padding / 2) as i16;
 
                 unsafe {
-                    let gc = x11::xlib::XCreateGC(display, self.pixmap, 0, std::ptr::null_mut());
+                    let gc = x11::xlib::XCreateGC(display, self.surface.pixmap(), 0, std::ptr::null_mut());
                     x11::xlib::XSetForeground(display, gc, scheme.underline as u64);
                     x11::xlib::XFillRectangle(
                         display,
-                        self.pixmap,
+                        self.surface.pixmap(),
                         gc,
                         underline_x as i32,
                         underline_y as i32,
@@ -279,7 +271,7 @@ impl Bar {
         let top_padding = 4;
         let text_y = top_padding + font.ascent();
 
-        self.font_draw.draw_text(
+        self.surface.font_draw().draw_text(
             font,
             self.scheme_normal.foreground,
             text_x,
@@ -295,7 +287,7 @@ impl Bar {
             let text_x = x_position;
             let text_y = top_padding + font.ascent();
 
-            self.font_draw.draw_text(
+            self.surface.font_draw().draw_text(
                 font,
                 self.scheme_selected.foreground,
                 text_x,
@@ -316,7 +308,8 @@ impl Bar {
                     let top_padding = 4;
                     let text_y = top_padding + font.ascent();
 
-                    self.font_draw
+                    self.surface
+                        .font_draw()
                         .draw_text(font, block.color(), x_position, text_y, &text);
 
                     if self.block_underlines[i] {
@@ -331,11 +324,11 @@ impl Bar {
 
                         unsafe {
                             let gc =
-                                x11::xlib::XCreateGC(display, self.pixmap, 0, std::ptr::null_mut());
+                                x11::xlib::XCreateGC(display, self.surface.pixmap(), 0, std::ptr::null_mut());
                             x11::xlib::XSetForeground(display, gc, block.color() as u64);
                             x11::xlib::XFillRectangle(
                                 display,
-                                self.pixmap,
+                                self.surface.pixmap(),
                                 gc,
                                 underline_x as i32,
                                 underline_y as i32,
@@ -358,7 +351,7 @@ impl Bar {
             );
             x11::xlib::XCopyArea(
                 display,
-                self.pixmap,
+                self.surface.pixmap(),
                 self.window as x11::xlib::Drawable,
                 gc,
                 0,
@@ -418,11 +411,3 @@ impl Bar {
         self.needs_redraw = true;
     }
 }
-
-impl Drop for Bar {
-    fn drop(&mut self) {
-        unsafe {
-            x11::xlib::XFreePixmap(self.display, self.pixmap);
-        }
-    }
-}
diff --git a/src/bar/font.rs b/src/bar/font.rs
index 1292d8d..ad846c3 100644
--- a/src/bar/font.rs
+++ b/src/bar/font.rs
@@ -149,3 +149,51 @@ impl Drop for FontDraw {
         }
     }
 }
+
+pub struct DrawingSurface {
+    font_draw: FontDraw,
+    pixmap: x11::xlib::Pixmap,
+    display: *mut Display,
+}
+
+impl DrawingSurface {
+    pub fn new(
+        display: *mut Display,
+        window: x11::xlib::Drawable,
+        width: u32,
+        height: u32,
+        visual: *mut Visual,
+        colormap: Colormap,
+    ) -> Result<Self, crate::errors::X11Error> {
+        let depth = unsafe { x11::xlib::XDefaultDepth(display, 0) };
+        let pixmap = unsafe {
+            x11::xlib::XCreatePixmap(display, window, width, height, depth as u32)
+        };
+
+        let font_draw = FontDraw::new(display, pixmap, visual, colormap)?;
+
+        Ok(Self {
+            font_draw,
+            pixmap,
+            display,
+        })
+    }
+
+    pub fn pixmap(&self) -> x11::xlib::Pixmap {
+        self.pixmap
+    }
+
+    pub fn font_draw(&self) -> &FontDraw {
+        &self.font_draw
+    }
+}
+
+impl Drop for DrawingSurface {
+    fn drop(&mut self) {
+        unsafe {
+            x11::xft::XftDrawDestroy(self.font_draw.xft_draw);
+            self.font_draw.xft_draw = std::ptr::null_mut();
+            x11::xlib::XFreePixmap(self.display, self.pixmap);
+        }
+    }
+}
diff --git a/src/tab_bar.rs b/src/tab_bar.rs
index a6dd278..cb0f35e 100644
--- a/src/tab_bar.rs
+++ b/src/tab_bar.rs
@@ -1,5 +1,5 @@
 use crate::ColorScheme;
-use crate::bar::font::{Font, FontDraw};
+use crate::bar::font::{DrawingSurface, Font};
 use crate::errors::X11Error;
 use crate::layout::tabbed::TAB_BAR_HEIGHT;
 use x11rb::COPY_DEPTH_FROM_PARENT;
@@ -14,9 +14,8 @@ pub struct TabBar {
     x_offset: i16,
     y_offset: i16,
     graphics_context: Gcontext,
-    pixmap: x11::xlib::Pixmap,
     display: *mut x11::xlib::Display,
-    font_draw: FontDraw,
+    surface: DrawingSurface,
     scheme_normal: ColorScheme,
     scheme_selected: ColorScheme,
 }
@@ -69,19 +68,15 @@ impl TabBar {
 
         let visual = unsafe { x11::xlib::XDefaultVisual(display, screen_num as i32) };
         let colormap = unsafe { x11::xlib::XDefaultColormap(display, screen_num as i32) };
-        let depth = unsafe { x11::xlib::XDefaultDepth(display, screen_num as i32) };
 
-        let pixmap = unsafe {
-            x11::xlib::XCreatePixmap(
-                display,
-                window as x11::xlib::Drawable,
-                width as u32,
-                height as u32,
-                depth as u32,
-            )
-        };
-
-        let font_draw = FontDraw::new(display, pixmap, visual, colormap)?;
+        let surface = DrawingSurface::new(
+            display,
+            window as x11::xlib::Drawable,
+            width as u32,
+            height as u32,
+            visual,
+            colormap,
+        )?;
 
         Ok(Self {
             window,
@@ -90,9 +85,8 @@ impl TabBar {
             x_offset: x,
             y_offset: y,
             graphics_context,
-            pixmap,
             display,
-            font_draw,
+            surface,
             scheme_normal,
             scheme_selected,
         })
@@ -116,11 +110,11 @@ impl TabBar {
         connection.flush()?;
 
         unsafe {
-            let gc = x11::xlib::XCreateGC(self.display, self.pixmap, 0, std::ptr::null_mut());
+            let gc = x11::xlib::XCreateGC(self.display, self.surface.pixmap(), 0, std::ptr::null_mut());
             x11::xlib::XSetForeground(self.display, gc, self.scheme_normal.background as u64);
             x11::xlib::XFillRectangle(
                 self.display,
-                self.pixmap,
+                self.surface.pixmap(),
                 gc,
                 0,
                 0,
@@ -158,7 +152,8 @@ impl TabBar {
             let top_padding = 6;
             let text_y = top_padding + font.ascent();
 
-            self.font_draw
+            self.surface
+                .font_draw()
                 .draw_text(font, scheme.foreground, text_x, text_y, &display_title);
 
             if is_focused {
@@ -167,11 +162,11 @@ impl TabBar {
 
                 unsafe {
                     let gc =
-                        x11::xlib::XCreateGC(self.display, self.pixmap, 0, std::ptr::null_mut());
+                        x11::xlib::XCreateGC(self.display, self.surface.pixmap(), 0, std::ptr::null_mut());
                     x11::xlib::XSetForeground(self.display, gc, scheme.underline as u64);
                     x11::xlib::XFillRectangle(
                         self.display,
-                        self.pixmap,
+                        self.surface.pixmap(),
                         gc,
                         x_position as i32,
                         underline_y as i32,
@@ -195,7 +190,7 @@ impl TabBar {
                 x11::xlib::XCreateGC(self.display, self.window as u64, 0, std::ptr::null_mut());
             x11::xlib::XCopyArea(
                 self.display,
-                self.pixmap,
+                self.surface.pixmap(),
                 self.window as u64,
                 gc,
                 0,
@@ -239,24 +234,17 @@ impl TabBar {
                 .width(width as u32),
         )?;
 
-        unsafe {
-            x11::xlib::XFreePixmap(self.display, self.pixmap);
-        }
-
-        let depth = unsafe { x11::xlib::XDefaultDepth(self.display, 0) };
-        self.pixmap = unsafe {
-            x11::xlib::XCreatePixmap(
-                self.display,
-                self.window as x11::xlib::Drawable,
-                width as u32,
-                self.height as u32,
-                depth as u32,
-            )
-        };
-
         let visual = unsafe { x11::xlib::XDefaultVisual(self.display, 0) };
         let colormap = unsafe { x11::xlib::XDefaultColormap(self.display, 0) };
-        self.font_draw = FontDraw::new(self.display, self.pixmap, visual, colormap)?;
+
+        self.surface = DrawingSurface::new(
+            self.display,
+            self.window as x11::xlib::Drawable,
+            width as u32,
+            self.height as u32,
+            visual,
+            colormap,
+        )?;
 
         connection.flush()?;
         Ok(())
@@ -274,11 +262,3 @@ impl TabBar {
         Ok(())
     }
 }
-
-impl Drop for TabBar {
-    fn drop(&mut self) {
-        unsafe {
-            x11::xlib::XFreePixmap(self.display, self.pixmap);
-        }
-    }
-}