Skip to content

Commit

Permalink
support fonts for widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
laudominik committed Sep 14, 2024
1 parent b02c4a0 commit b70b4a1
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 10 deletions.
5 changes: 3 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::state::WIDGETS;
use crate::state::{self, Keybinding, Mousemotion, KEYBINDINGS, MOUSEMOTIONS};
use crate::style::Paddings;
use crate::style::{ColorScheme, ColorSchemes, Style};
use crate::widgets::TopBar;
use crate::widgets::{TopBar, Widget};
use crate::wm::WindowExt;
use crate::{active_workspace, active_workspace_wins, set_keybinding, set_mousemotion, set_spaces, spawn_with_shell, wm};

Expand Down Expand Up @@ -58,7 +58,7 @@ const MODKEY_CTRL: u32 = MODKEY | xlib::ControlMask;
pub fn make(state: &mut state::State){
/* widgets */
{
add_widget!(TopBar {});
add_widget!(TopBar {}, "Noto Sans CJK JP-12");
}

/* mouse motion */
Expand Down Expand Up @@ -109,6 +109,7 @@ pub fn make(state: &mut state::State){
/* default workspaces config */
{
set_spaces!(state, ["一", "二", "三", "四"]);
//set_spaces!(state, ["1", "2", "3", "4"]);
let screen_width = unsafe{xlib::XDisplayWidth(state.dpy, state.screen) as u32};

for space in state.workspaces.iter_mut() {
Expand Down
2 changes: 1 addition & 1 deletion src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub struct Active {
pub focus_locked: bool,
}

pub static mut WIDGETS: Vec<Box<dyn widgets::Widget>> = Vec::new();
pub static mut WIDGETS: Vec<Box<widgets::Widget>> = Vec::new();
pub static mut KEYBINDINGS : Vec<Keybinding> = Vec::new();

macro_rules! mousemotion_type_decl {
Expand Down
23 changes: 22 additions & 1 deletion src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,28 @@ macro_rules! add_widget {
($widget: expr) => {
{
unsafe {
WIDGETS.push(Box::new($widget));
WIDGETS.push(
Box::new(
Widget {
wspec: Box::new($widget),
font: ""
}
)
)
}
}
};
($widget: expr, $font: expr) => {
{
unsafe {
WIDGETS.push(
Box::new(
Widget {
wspec: Box::new($widget),
font: $font
}
)
)
}
}
};
Expand Down
57 changes: 51 additions & 6 deletions src/widgets.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,62 @@
use std::ffi::CString;
use std::mem;

use x11::xlib::{self, XSetWindowAttributes};
use x11::xft;
use x11::{xft, xrender};

use crate::state;
use crate::config::STYLE;


pub trait Widget {
fn draw(&self, state: &mut state::State);
pub struct Widget<'a> {
pub font: &'a str,
pub wspec: Box<dyn WidgetSpec>
}

impl Widget<'_> {
pub fn draw(&self, state: &mut state::State){
self.wspec.draw(state, self);
}
}

pub trait WidgetSpec {
fn draw(&self, state: &mut state::State, widget: &Widget);
}

pub struct TopBar {}
pub struct TaskList {}

impl Widget for TopBar {
fn draw(&self, state: &mut state::State) {
impl WidgetSpec for TopBar {
fn draw(&self, state: &mut state::State, widget: &Widget) {
unsafe {
let screen_width: u32 = xlib::XDisplayWidth(state.dpy, state.screen) as u32;
let box_wh = STYLE.paddings.top;
xft::XftDrawRect(state.xft_draw, &state.colors.normal.bg, 0, 0, screen_width, STYLE.paddings.top);

let font: *mut xft::XftFont = xft::XftFontOpenName(state.dpy, state.screen, widget.font.as_ptr() as *const i8);
let pad = text_width_px(state, font, state.workspaces[0].tag) / 4;

for i in 0..state.workspaces.len() {
let offset = i as u32 * box_wh;
let mut bgcol = &state.colors.normal.bg;
if i == state.active.workspace { bgcol = &state.colors.normal.fg };
let mut fgcol = &state.colors.normal.fg;
if i == state.active.workspace {
bgcol = &state.colors.normal.fg;
fgcol = &state.colors.normal.bg;
};
let utf8_string = CString::new(state.workspaces[i].tag).unwrap();
xft::XftDrawRect(state.xft_draw, bgcol, offset as i32, 0, box_wh, box_wh);
/* TODO: remove hardcore */
xft::XftDrawStringUtf8(state.xft_draw, fgcol, font, offset as i32 + pad, box_wh as i32 - pad, utf8_string.as_ptr() as *const u8, utf8_string.to_bytes().len() as i32);
}
}
}
}

impl WidgetSpec for TaskList {
fn draw(&self, _: &mut state::State, __: &Widget) {}
}

pub fn widget_window(dpy: &mut xlib::Display ) -> (xlib::Window, *mut xft::XftDraw) {
unsafe {
let screen = xlib::XDefaultScreen(dpy);
Expand All @@ -51,4 +78,22 @@ pub fn widget_window(dpy: &mut xlib::Display ) -> (xlib::Window, *mut xft::XftDr
let xft_draw = xft::XftDrawCreate(dpy, win, xlib::XDefaultVisual(dpy, screen), xlib::XDefaultColormap(dpy, screen));
return (win, xft_draw)
}
}

fn text_width_px(state: &mut state::State, font: *mut xft::XftFont, string: &str) -> i32 {
unsafe {
let mut extents: xrender::XGlyphInfo = std::mem::zeroed();
let utf8_string = CString::new(string).unwrap();
// Calculate the text extents
xft::XftTextExtentsUtf8(
state.dpy,
font,
utf8_string.as_ptr() as *const u8,
utf8_string.to_bytes().len() as i32,
&mut extents,
);

return extents.width as i32;
}

}

0 comments on commit b70b4a1

Please sign in to comment.