Skip to content

Commit

Permalink
fix(windows): draw over white line below menu (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
amrbashir authored Sep 20, 2023
1 parent 7bbb000 commit e34040e
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 34 deletions.
5 changes: 5 additions & 0 deletions .changes/windwos-white-line.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"muda": "patch"
---

On Windows, draw over the white line under the menubar in dark mode.
18 changes: 14 additions & 4 deletions examples/wry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,25 @@ fn main() -> wry::Result<()> {
<html>
<body>
<style>
* {{
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
}}
main {{
width: 100vw;
height: 100vh;
width: 100vw;
height: 100vh;
}}
@media (prefers-color-scheme: dark) {{
main {{
color: #fff;
background: #2f2f2f;
}}
}}
</style>
<main>
<h4> WRYYYYYYYYYYYYYYYYYYYYYY! </h4>
<input />
<button> Hi </button>
</main>
<script>
window.addEventListener('contextmenu', (e) => {{
Expand Down
71 changes: 54 additions & 17 deletions src/platform_impl/windows/dark_menu_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@

// this is a port of combination of https://github.com/hrydgard/ppsspp/blob/master/Windows/W32Util/UAHMenuBar.cpp and https://github.com/ysc3839/win32-darkmode/blob/master/win32-darkmode/DarkMode.h

#![allow(non_snake_case)]
#![allow(non_snake_case, clippy::upper_case_acronyms)]

use once_cell::sync::Lazy;
use windows_sys::{
s, w,
Win32::{
Foundation::{HMODULE, HWND, LPARAM, RECT, WPARAM},
Graphics::Gdi::{OffsetRect, DT_CENTER, DT_HIDEPREFIX, DT_SINGLELINE, DT_VCENTER, HDC},
Graphics::Gdi::{
GetWindowDC, MapWindowPoints, OffsetRect, ReleaseDC, DT_CENTER, DT_HIDEPREFIX,
DT_SINGLELINE, DT_VCENTER, HDC,
},
System::LibraryLoader::{GetProcAddress, LoadLibraryA},
UI::{
Accessibility::HIGHCONTRASTA,
Expand All @@ -21,8 +24,9 @@ use windows_sys::{
ODS_GRAYED, ODS_HOTLIGHT, ODS_INACTIVE, ODS_NOACCEL, ODS_SELECTED,
},
WindowsAndMessaging::{
GetMenuBarInfo, GetMenuItemInfoW, GetWindowRect, SystemParametersInfoA, HMENU,
MENUBARINFO, MENUITEMINFOW, MIIM_STRING, OBJID_MENU, SPI_GETHIGHCONTRAST,
GetClientRect, GetMenuBarInfo, GetMenuItemInfoW, GetWindowRect,
SystemParametersInfoA, HMENU, MENUBARINFO, MENUITEMINFOW, MIIM_STRING, OBJID_MENU,
SPI_GETHIGHCONTRAST, WM_NCACTIVATE, WM_NCPAINT,
},
},
},
Expand Down Expand Up @@ -69,12 +73,49 @@ struct UAHDRAWMENUITEM {
}

/// Draws a dark menu bar if needed and returns whether it draws it or not
pub fn draw(hwnd: HWND, msg: u32, _wparam: WPARAM, lparam: LPARAM) -> bool {
if !should_use_dark_mode(hwnd) {
return false;
}

pub fn draw(hwnd: HWND, msg: u32, _wparam: WPARAM, lparam: LPARAM) {
match msg {
// draw over the annoying white line blow menubar
// ref: https://github.com/notepad-plus-plus/notepad-plus-plus/pull/9985
WM_NCACTIVATE | WM_NCPAINT => {
let mut mbi = MENUBARINFO {
cbSize: std::mem::size_of::<MENUBARINFO>() as _,
..unsafe { std::mem::zeroed() }
};
unsafe { GetMenuBarInfo(hwnd, OBJID_MENU, 0, &mut mbi) };

let mut client_rc: RECT = unsafe { std::mem::zeroed() };
unsafe {
GetClientRect(hwnd, &mut client_rc);
MapWindowPoints(hwnd, 0, &mut client_rc as *mut _ as *mut _, 2);
};

let mut window_rc: RECT = unsafe { std::mem::zeroed() };
unsafe { GetWindowRect(hwnd, &mut window_rc) };

unsafe { OffsetRect(&mut client_rc, -window_rc.left, -window_rc.top) };

let mut annoying_rc = client_rc;
annoying_rc.bottom = annoying_rc.top;
annoying_rc.top -= 1;

unsafe {
let theme = OpenThemeData(hwnd, w!("Menu"));
let hdc = GetWindowDC(hwnd);
DrawThemeBackground(
theme,
hdc,
MENU_POPUPITEM,
MPI_NORMAL,
&annoying_rc,
std::ptr::null(),
);
ReleaseDC(hwnd, hdc);
CloseThemeData(theme);
}
}

// draw menu bar background
WM_UAHDRAWMENU => {
let pudm = lparam as *const UAHMENU;

Expand All @@ -86,9 +127,7 @@ pub fn draw(hwnd: HWND, msg: u32, _wparam: WPARAM, lparam: LPARAM) -> bool {
};
unsafe { GetMenuBarInfo(hwnd, OBJID_MENU, 0, &mut mbi) };

let mut window_rc = RECT {
..unsafe { std::mem::zeroed() }
};
let mut window_rc: RECT = unsafe { std::mem::zeroed() };
unsafe { GetWindowRect(hwnd, &mut window_rc) };

let mut rc = mbi.rcBar;
Expand All @@ -100,7 +139,6 @@ pub fn draw(hwnd: HWND, msg: u32, _wparam: WPARAM, lparam: LPARAM) -> bool {

unsafe {
let theme = OpenThemeData(hwnd, w!("Menu"));

DrawThemeBackground(
theme,
(*pudm).hdc,
Expand All @@ -113,6 +151,7 @@ pub fn draw(hwnd: HWND, msg: u32, _wparam: WPARAM, lparam: LPARAM) -> bool {
}
}

// draw menu bar items
WM_UAHDRAWMENUITEM => {
let pudmi = lparam as *const UAHDRAWMENUITEM;

Expand Down Expand Up @@ -194,13 +233,11 @@ pub fn draw(hwnd: HWND, msg: u32, _wparam: WPARAM, lparam: LPARAM) -> bool {
}
}

_ => return false,
_ => {}
};

true
}

fn should_use_dark_mode(hwnd: HWND) -> bool {
pub fn should_use_dark_mode(hwnd: HWND) -> bool {
should_apps_use_dark_mode() && !is_high_contrast() && is_dark_mode_allowed_for_window(hwnd)
}

Expand Down
33 changes: 20 additions & 13 deletions src/platform_impl/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use windows_sys::Win32::{
HMENU, MENUITEMINFOW, MFS_CHECKED, MFS_DISABLED, MF_BYCOMMAND, MF_BYPOSITION,
MF_CHECKED, MF_DISABLED, MF_ENABLED, MF_GRAYED, MF_POPUP, MF_SEPARATOR, MF_STRING,
MF_UNCHECKED, MIIM_BITMAP, MIIM_STATE, MIIM_STRING, SW_HIDE, SW_MAXIMIZE, SW_MINIMIZE,
TPM_LEFTALIGN, WM_CLOSE, WM_COMMAND,
TPM_LEFTALIGN, WM_CLOSE, WM_COMMAND, WM_NCACTIVATE, WM_NCPAINT,
},
},
};
Expand Down Expand Up @@ -1070,7 +1070,6 @@ unsafe extern "system" fn menu_subclass_proc(
uidsubclass: usize,
dwrefdata: usize,
) -> LRESULT {
let mut ret = None;
match msg {
WM_COMMAND => {
let id = util::LOWORD(wparam as _) as u32;
Expand All @@ -1083,8 +1082,6 @@ unsafe extern "system" fn menu_subclass_proc(
};

if let Some(item) = item {
ret = Some(0);

let (mut dispatch, mut menu_id) = (true, None);

{
Expand Down Expand Up @@ -1149,22 +1146,32 @@ unsafe extern "system" fn menu_subclass_proc(
id: menu_id.unwrap(),
});
}

0
} else {
DefSubclassProc(hwnd, msg, wparam, lparam)
}
}

WM_UAHDRAWMENUITEM | WM_UAHDRAWMENU => {
if dark_menu_bar::draw(hwnd, msg, wparam, lparam) {
ret = Some(0);
if dark_menu_bar::should_use_dark_mode(hwnd) {
dark_menu_bar::draw(hwnd, msg, wparam, lparam);
0
} else {
DefSubclassProc(hwnd, msg, wparam, lparam)
}
}
WM_NCACTIVATE | WM_NCPAINT => {
// DefSubclassProc needs to be called before calling the
// custom dark menu redraw
let res = DefSubclassProc(hwnd, msg, wparam, lparam);
if dark_menu_bar::should_use_dark_mode(hwnd) {
dark_menu_bar::draw(hwnd, msg, wparam, lparam);
}
res
}

_ => {}
};

if let Some(ret) = ret {
ret
} else {
DefSubclassProc(hwnd, msg, wparam, lparam)
_ => DefSubclassProc(hwnd, msg, wparam, lparam),
}
}

Expand Down

0 comments on commit e34040e

Please sign in to comment.