Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: default style memory leak #2

Merged
merged 2 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions winbar/src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use windows::{
core::w,
Win32::{
Foundation::{COLORREF, HWND, LPARAM, LRESULT, WPARAM},
Graphics::Gdi::{BeginPaint, CreateSolidBrush, EndPaint, InvalidateRect, PAINTSTRUCT},
Graphics::Gdi::{
BeginPaint, CreateSolidBrush, DeleteObject, EndPaint, InvalidateRect, SelectObject,
SetBkColor, SetTextColor, PAINTSTRUCT, PS_SOLID,
},
System::{
LibraryLoader::GetModuleHandleW,
Threading::{GetStartupInfoW, STARTUPINFOW},
Expand All @@ -20,7 +23,10 @@ use windows::{
},
};

use crate::{windows_api::WindowsApi, COMPONENT_MANAGER, HEIGHT, TRANSPARENT_COLOR, WIDTH};
use crate::{
styles::Styles, windows_api::WindowsApi, COMPONENT_MANAGER, DEFAULT_BG_COLOR, DEFAULT_FG_COLOR,
DEFAULT_FONT, DEFAULT_FONT_SIZE, HEIGHT, TRANSPARENT_COLOR, WIDTH,
};

pub fn create_window() -> HWND {
unsafe {
Expand Down Expand Up @@ -117,7 +123,29 @@ pub extern "system" fn window_proc(
let mut ps = PAINTSTRUCT::default();
let hdc = BeginPaint(hwnd, &mut ps);

WindowsApi::set_default_styles(hdc);
let default_bg_color = {
let color = DEFAULT_BG_COLOR.lock().unwrap();
color.bgr()
};
let default_fg_color = {
let color = DEFAULT_FG_COLOR.lock().unwrap();
color.bgr()
};
let default_font = {
let font = DEFAULT_FONT.lock().unwrap();
font.to_string()
};
let default_font_size = DEFAULT_FONT_SIZE.load(Ordering::SeqCst);

let pen = Styles::pen(default_bg_color, PS_SOLID);
let brush = Styles::solid_brush(default_bg_color);
let font = Styles::font(default_font_size, &default_font);

SelectObject(hdc, pen);
SelectObject(hdc, brush);
SelectObject(hdc, font);
SetBkColor(hdc, COLORREF(default_bg_color));
SetTextColor(hdc, COLORREF(default_fg_color));

match COMPONENT_MANAGER.lock() {
Ok(mut manager) => {
Expand All @@ -132,6 +160,10 @@ pub extern "system" fn window_proc(
}
}

DeleteObject(pen);
DeleteObject(brush);
DeleteObject(font);

EndPaint(hwnd, &ps);
tracing::trace!("Finished painting");
}
Expand Down
1 change: 1 addition & 0 deletions winbar/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub mod component_impl;
pub mod config;
pub mod container;
pub mod server;
pub mod styles;
pub mod windows_api;

// runtime variables
Expand Down
56 changes: 56 additions & 0 deletions winbar/src/styles.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use windows::{
core::HSTRING,
Win32::{
Foundation::COLORREF,
Graphics::Gdi::{
CreateFontW, CreatePen, CreateSolidBrush, ANSI_CHARSET, CLIP_DEFAULT_PRECIS,
DEFAULT_PITCH, FF_DONTCARE, FW_DONTCARE, HBRUSH, HFONT, HPEN, OUT_TT_PRECIS, PEN_STYLE,
PROOF_QUALITY,
},
},
};

pub struct Styles {}

impl Styles {
/// Creates a new pen.
///
/// Note that it is the caller's responsibility to call SelectObject to use the object, and
/// DeleteObject to cleanup the resource.
pub fn pen(color: u32, style: PEN_STYLE) -> HPEN {
unsafe { CreatePen(style, 0, COLORREF(color)) }
}

/// Creates a new solid brush.
///
/// Note that it is the caller's responsibility to call SelectObject to use the object, and
/// DeleteObject to cleanup the resource.
pub fn solid_brush(color: u32) -> HBRUSH {
unsafe { CreateSolidBrush(COLORREF(color)) }
}

/// Creates a new font.
///
/// Note that it is the caller's responsibility to call SelectObject to use the object, and
/// DeleteObject to cleanup the resource.
pub fn font(size: i32, name: &str) -> HFONT {
unsafe {
CreateFontW(
size,
0,
0,
0,
FW_DONTCARE.0 as i32,
0,
0,
0,
ANSI_CHARSET.0.into(),
OUT_TT_PRECIS.0.into(),
CLIP_DEFAULT_PRECIS.0.into(),
PROOF_QUALITY.0.into(),
DEFAULT_PITCH.0 as u32 | FF_DONTCARE.0 as u32,
&HSTRING::from(name),
)
}
}
}
69 changes: 5 additions & 64 deletions winbar/src/windows_api.rs
Original file line number Diff line number Diff line change
@@ -1,79 +1,20 @@
use std::{mem::MaybeUninit, sync::atomic::Ordering};
use std::mem::MaybeUninit;

use anyhow::{bail, Result};
use tracing::instrument;
use windows::{
core::HSTRING,
Win32::{
Foundation::{COLORREF, HWND, LPARAM, WPARAM},
Graphics::{
Gdi::{
CreateFontW, CreatePen, CreateSolidBrush, SelectObject, SetBkColor, SetTextColor,
ANSI_CHARSET, CLIP_DEFAULT_PRECIS, DEFAULT_PITCH, FF_DONTCARE, FW_DONTCARE, HDC,
OUT_TT_PRECIS, PROOF_QUALITY, PS_SOLID,
},
GdiPlus::{GdiplusShutdown, GdiplusStartup, GdiplusStartupInput, Status},
},
UI::WindowsAndMessaging::{PostMessageW, ShowWindow, SW_HIDE, SW_SHOW, WM_CLOSE},
},
use windows::Win32::{
Foundation::{HWND, LPARAM, WPARAM},
Graphics::GdiPlus::{GdiplusShutdown, GdiplusStartup, GdiplusStartupInput, Status},
UI::WindowsAndMessaging::{PostMessageW, ShowWindow, SW_HIDE, SW_SHOW, WM_CLOSE},
};

use crate::{DEFAULT_BG_COLOR, DEFAULT_FG_COLOR, DEFAULT_FONT, DEFAULT_FONT_SIZE};

pub struct WindowsApi {}

impl WindowsApi {
pub fn str_to_u16_slice(s: &str) -> Vec<u16> {
s.encode_utf16().collect::<Vec<u16>>()
}

pub fn set_default_styles(hdc: HDC) {
let default_bg_color = {
let color = DEFAULT_BG_COLOR.lock().unwrap();
color.bgr()
};
let default_fg_color = {
let color = DEFAULT_FG_COLOR.lock().unwrap();
color.bgr()
};
let default_font = {
let font = DEFAULT_FONT.lock().unwrap();
font.to_string()
};
let default_font_size = DEFAULT_FONT_SIZE.load(Ordering::SeqCst);

unsafe {
let pen = CreatePen(PS_SOLID, 0, COLORREF(default_bg_color));
let brush = CreateSolidBrush(COLORREF(default_bg_color));

SelectObject(hdc, pen);
SelectObject(hdc, brush);
SetBkColor(hdc, COLORREF(default_bg_color));
// SetBkColor(hdc, COLORREF(TRANSPARENT_COLOR));

let font = CreateFontW(
default_font_size,
0,
0,
0,
FW_DONTCARE.0 as i32,
0,
0,
0,
ANSI_CHARSET.0.into(),
OUT_TT_PRECIS.0.into(),
CLIP_DEFAULT_PRECIS.0.into(),
PROOF_QUALITY.0.into(),
DEFAULT_PITCH.0 as u32 | FF_DONTCARE.0 as u32,
&HSTRING::from(default_font),
);

SelectObject(hdc, font);

SetTextColor(hdc, COLORREF(default_fg_color));
}
}

pub fn show_window(hwnd: HWND) {
unsafe {
let _ = ShowWindow(hwnd, SW_SHOW);
Expand Down
Loading