diff options
| author | Irene Knapp <ireneista@irenes.space> | 2026-11-12 00:36:19 -0700 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2026-11-12 14:23:50 -0700 |
| commit | 7c457902864fd3e54832dd22bf33f324b6ec3cdb (patch) | |
| tree | 6991a0dc8f0eb832e8b60f094789e15a2b59f737 /src/main.rs | |
| parent | 6480f84e8ee9839fb486916d708712daf34a0aff (diff) | |
draw text
this uses Xft, which unfortunately has a lot of parallel tooling it needs some refactoring into its own files, but it works :) Change-Id: I0e78ea69167b1d91af2e9f494d757564d8cb7cdb Force-Push: yes
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 169 |
1 files changed, 121 insertions, 48 deletions
diff --git a/src/main.rs b/src/main.rs index 5b2f853..523ec45 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,15 @@ use crate::geometry::*; use crate::x::*; -use std::ops::Sub; use std::sync::Arc; +use x11::xrender::XRenderColor; +use x11::xft::{ + XftFontOpenName, + XftDrawCreate, XftDrawDestroy, + XftColor, + XftDrawStringUtf8 +}; use xcb::{ Xid }; use xcb::x::{ ClientMessageData, @@ -24,6 +30,8 @@ struct DockConfiguration { thickness: u16, side: Side, background_pixel: u32, + foreground_pixel: u32, + foreground_render_color: XRenderColor, use_rounded_inside_corners: bool, use_rounded_outside_corners: bool, } @@ -32,6 +40,7 @@ struct Dock { configuration: DockConfiguration, window: Window, bounds: Arc<Rectangle<u16>>, + font: *mut x11::xft::XftFont, } impl HasWindow for Dock { @@ -45,10 +54,17 @@ fn main() -> xcb::Result<()> { // #d4ffcc let background_pixel = display.allocate_color(54484, 65535, 52428)?; + // #5c01be + let foreground_pixel = display.allocate_color(23644, 257, 48830)?; + let foreground_render_color = XRenderColor { + red: 23644, green: 257, blue: 48830, alpha: 65535, + }; + let dock = Dock::new(Arc::clone(&display), DockConfiguration { - thickness: 50, + thickness: 34, side: Side::Bottom, background_pixel, + foreground_pixel, foreground_render_color, use_rounded_inside_corners: false, use_rounded_outside_corners: true, })?; @@ -103,7 +119,21 @@ impl Dock { Cw::EventMask(EventMask::EXPOSURE | EventMask::BUTTON_PRESS), ], })?; - let dock = Dock { window, configuration, bounds: Arc::new(dock_bounds) }; + + let xlib_display = display.connection().get_xlib_display(); + let screen_index = display.screen_index(); + + let font = unsafe { + XftFontOpenName(xlib_display, screen_index, + c"FantasqueSansM Nerd Font Mono:style=Regular:size=18" + .as_ptr().cast()) + }; + + let dock = Dock { + window, configuration, + bounds: Arc::new(dock_bounds), + font + }; dock.set_string_property(&xcb::x::ATOM_WM_NAME, b"sandbar")?; @@ -205,61 +235,73 @@ impl Dock { if self.configuration.use_rounded_inside_corners || self.configuration.use_rounded_outside_corners { - let black_pixel = self.screen().black_pixel(); + self.draw_corners(drawable, &context)?; + } - let mut corner_squares = Vec::new(); - let mut corner_arcs = Vec::new(); - if self.configuration.use_rounded_outside_corners { - for corner in self.configuration.side.corners_on_side() { - let (corner_square, corner_arc) = self.compute_corner_regions(*corner); + self.draw_text()?; - corner_squares.push(corner_square); - corner_arcs.push(corner_arc); - } - } - if self.configuration.use_rounded_inside_corners { - for corner in self.configuration.side.opposite().corners_on_side() { - let (corner_square, corner_arc) = self.compute_corner_regions(*corner); + Ok(()) + } - corner_squares.push(corner_square); - corner_arcs.push(corner_arc); - } + + fn draw_corners(&self, drawable: Drawable, context: &GraphicContext) + -> xcb::Result<()> + { + let black_pixel = self.screen().black_pixel(); + + let mut corner_squares = Vec::new(); + let mut corner_arcs = Vec::new(); + if self.configuration.use_rounded_outside_corners { + for corner in self.configuration.side.corners_on_side() { + let (corner_square, corner_arc) = self.compute_corner_regions(*corner); + + corner_squares.push(corner_square); + corner_arcs.push(corner_arc); } + } + if self.configuration.use_rounded_inside_corners { + for corner in self.configuration.side.opposite().corners_on_side() { + let (corner_square, corner_arc) = self.compute_corner_regions(*corner); - let cookie = self.send_request_checked(&ChangeGc { - gc: context.graphic_context_id(), - value_list: &[ - Gc::Foreground(black_pixel), - ], - }); - self.check_request(cookie)?; - - let cookie = self.send_request_checked(&PolyFillRectangle { - drawable: drawable, - gc: context.graphic_context_id(), - rectangles: &corner_squares, - }); - self.check_request(cookie)?; - - let cookie = self.send_request_checked(&ChangeGc { - gc: context.graphic_context_id(), - value_list: &[ - Gc::Foreground(self.configuration.background_pixel), - ], - }); - self.check_request(cookie)?; - - let cookie = self.send_request_checked(&PolyFillArc { - drawable: drawable, - gc: context.graphic_context_id(), - arcs: &corner_arcs, - }); - self.check_request(cookie)?; + corner_squares.push(corner_square); + corner_arcs.push(corner_arc); + } } + let cookie = self.send_request_checked(&ChangeGc { + gc: context.graphic_context_id(), + value_list: &[ + Gc::Foreground(black_pixel), + ], + }); + self.check_request(cookie)?; + + let cookie = self.send_request_checked(&PolyFillRectangle { + drawable: drawable, + gc: context.graphic_context_id(), + rectangles: &corner_squares, + }); + self.check_request(cookie)?; + + let cookie = self.send_request_checked(&ChangeGc { + gc: context.graphic_context_id(), + value_list: &[ + Gc::Foreground(self.configuration.background_pixel), + ], + }); + self.check_request(cookie)?; + + let cookie = self.send_request_checked(&PolyFillArc { + drawable: drawable, + gc: context.graphic_context_id(), + arcs: &corner_arcs, + }); + self.check_request(cookie)?; + Ok(()) } + fn compute_corner_regions(&self, corner: Corner) -> (xcb::x::Rectangle, xcb::x::Arc) { @@ -277,6 +319,37 @@ impl Dock { (corner_square, corner_arc) } + + + fn draw_text(&self) -> xcb::Result<()> { + let xlib_display = self.connection().get_xlib_display(); + let x_visual = unsafe { + x11::xlib::XDefaultVisual(xlib_display, + self.display().screen_index()) + }; + + let xft_context = unsafe { + XftDrawCreate(xlib_display, + self.window().window_id().resource_id() as u64, + x_visual, + self.screen().default_colormap().resource_id() as u64) + }; + + let xft_color = XftColor { + pixel: self.configuration.foreground_pixel as u64, + color: self.configuration.foreground_render_color, + }; + let text = c"amazing cool fiction technically reads playful unknown telephonic works from-post"; + unsafe { + XftDrawStringUtf8(xft_context, &xft_color, self.font, 12, 25, + text.as_ptr().cast(), + text.count_bytes() as i32) + }; + + unsafe { XftDrawDestroy(xft_context) }; + + Ok(()) + } } impl HasDisplay for Dock { |