From 5a7c76f307b17067a215f2f3357d4eaaeba19491 Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Tue, 10 Mar 2026 23:05:34 +0000 Subject: [PATCH 01/17] Add separator / grayed flag support --- src/os/windows/mod.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index 86932bb..0c752f5 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -3,8 +3,8 @@ use crate::{ check_buffer_size, error::Error, icon::Icon, key_handler::KeyHandler, rate::UpdateRate, CursorStyle, InputCallback, Key, KeyRepeat, MenuHandle, MenuItem, MenuItemHandle, MouseButton, - MouseMode, Result, Scale, ScaleMode, WindowOptions, MENU_KEY_ALT, MENU_KEY_CTRL, - MENU_KEY_SHIFT, MENU_KEY_WIN, + MouseMode, Result, Scale, ScaleMode, WindowOptions, MENU_ID_SEPARATOR, MENU_KEY_ALT, + MENU_KEY_CTRL, MENU_KEY_SHIFT, MENU_KEY_WIN, }; use raw_window_handle::{ DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, @@ -14,6 +14,7 @@ use std::{ ffi::{c_int, c_void, OsStr}, num::NonZeroIsize, os::windows::ffi::OsStrExt, + ptr::null, time::Duration, }; use winapi::{ @@ -28,7 +29,7 @@ use winapi::{ libloaderapi, wingdi, winuser::{ self, GET_XBUTTON_WPARAM, ICON_BIG, ICON_SMALL, IMAGE_ICON, LR_DEFAULTSIZE, - LR_LOADFROMFILE, WM_SETICON, + MF_ENABLED, MF_GRAYED, MF_SEPARATOR, LR_LOADFROMFILE, WM_SETICON, }, }, }; @@ -1380,19 +1381,28 @@ impl Menu { match vk_accel.0 { 0 => { let item_name = to_wstring(&menu_item.label); - winuser::AppendMenuW( - self.menu_handle, - 0x10, - menu_item.id as basetsd::UINT_PTR, - item_name.as_ptr(), - ); + if menu_item.id == MENU_ID_SEPARATOR { +                        winuser::AppendMenuW( +                            self.menu_handle, +                            MF_SEPARATOR, +                            0 as basetsd::UINT_PTR, +                            null(), +                        ); +                    } else { +                        winuser::AppendMenuW( +                            self.menu_handle, +                            0x10 | if menu_item.enabled { MF_ENABLED } else { MF_GRAYED }, +                            menu_item.id as basetsd::UINT_PTR, +                            item_name.as_ptr(), +                        ); + } } _ => { let menu_name = Self::format_name(menu_item, vk_accel.1); let w_name = to_wstring(&menu_name); winuser::AppendMenuW( self.menu_handle, - 0x10, + 0x10 | if menu_item.enabled { MF_ENABLED } else { MF_GRAYED }, menu_item.id as basetsd::UINT_PTR, w_name.as_ptr(), ); From 97cfc907d8469014690803ad1ffb9e2fd863afc0 Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Tue, 10 Mar 2026 23:11:14 +0000 Subject: [PATCH 02/17] Remove non-breaking space --- src/os/windows/mod.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index 0c752f5..6aaea2e 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -1382,19 +1382,19 @@ impl Menu { 0 => { let item_name = to_wstring(&menu_item.label); if menu_item.id == MENU_ID_SEPARATOR { -                        winuser::AppendMenuW( -                            self.menu_handle, -                            MF_SEPARATOR, -                            0 as basetsd::UINT_PTR, -                            null(), -                        ); -                    } else { -                        winuser::AppendMenuW( -                            self.menu_handle, -                            0x10 | if menu_item.enabled { MF_ENABLED } else { MF_GRAYED }, -                            menu_item.id as basetsd::UINT_PTR, -                            item_name.as_ptr(), -                        ); + winuser::AppendMenuW( + self.menu_handle, + MF_SEPARATOR, + 0 as basetsd::UINT_PTR, + null(), + ); + } else { + winuser::AppendMenuW( + self.menu_handle, + 0x10 | if menu_item.enabled { MF_ENABLED } else { MF_GRAYED }, + menu_item.id as basetsd::UINT_PTR, + item_name.as_ptr(), + ); } } _ => { From 84338df45571a4493c45394ea6f6ea81de465748 Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Tue, 10 Mar 2026 23:20:12 +0000 Subject: [PATCH 03/17] Use constant --- src/os/windows/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index 6aaea2e..3349c95 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -29,7 +29,7 @@ use winapi::{ libloaderapi, wingdi, winuser::{ self, GET_XBUTTON_WPARAM, ICON_BIG, ICON_SMALL, IMAGE_ICON, LR_DEFAULTSIZE, - MF_ENABLED, MF_GRAYED, MF_SEPARATOR, LR_LOADFROMFILE, WM_SETICON, + MF_ENABLED, MF_GRAYED, MF_POPUP, MF_SEPARATOR, LR_LOADFROMFILE, WM_SETICON, }, }, }; @@ -1109,7 +1109,7 @@ impl Window { winuser::AppendMenuW( main_menu, - 0x10, + MF_POPUP, menu.menu_handle as basetsd::UINT_PTR, menu.name.as_ptr(), ); @@ -1295,7 +1295,7 @@ impl Menu { let menu_name = to_wstring(name); winuser::AppendMenuW( self.menu_handle, - 0x10, + MF_POPUP, menu.menu_handle as basetsd::UINT_PTR, menu_name.as_ptr(), ); @@ -1391,7 +1391,7 @@ impl Menu { } else { winuser::AppendMenuW( self.menu_handle, - 0x10 | if menu_item.enabled { MF_ENABLED } else { MF_GRAYED }, + MF_POPUP | if menu_item.enabled { MF_ENABLED } else { MF_GRAYED }, menu_item.id as basetsd::UINT_PTR, item_name.as_ptr(), ); @@ -1402,7 +1402,7 @@ impl Menu { let w_name = to_wstring(&menu_name); winuser::AppendMenuW( self.menu_handle, - 0x10 | if menu_item.enabled { MF_ENABLED } else { MF_GRAYED }, + MF_POPUP | if menu_item.enabled { MF_ENABLED } else { MF_GRAYED }, menu_item.id as basetsd::UINT_PTR, w_name.as_ptr(), ); From c5fdc27ea4fb1856f6c34db714f93cd2b59c97b8 Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Tue, 10 Mar 2026 23:34:23 +0000 Subject: [PATCH 04/17] Test MF_GRAYED --- src/os/windows/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index 3349c95..7c5b6c6 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -1109,7 +1109,7 @@ impl Window { winuser::AppendMenuW( main_menu, - MF_POPUP, + MF_POPUP | MF_GRAYED, menu.menu_handle as basetsd::UINT_PTR, menu.name.as_ptr(), ); @@ -1295,7 +1295,7 @@ impl Menu { let menu_name = to_wstring(name); winuser::AppendMenuW( self.menu_handle, - MF_POPUP, + MF_POPUP | MF_GRAYED, menu.menu_handle as basetsd::UINT_PTR, menu_name.as_ptr(), ); From 7819c7dd090c90631213b72de2c47007d267fc3c Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Tue, 10 Mar 2026 23:35:04 +0000 Subject: [PATCH 05/17] Update mod.rs --- src/os/windows/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index 7c5b6c6..ceca833 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -1109,7 +1109,7 @@ impl Window { winuser::AppendMenuW( main_menu, - MF_POPUP | MF_GRAYED, + MF_POPUP, menu.menu_handle as basetsd::UINT_PTR, menu.name.as_ptr(), ); From fab049ccda896e35f496ecac4c2787444c52956e Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Wed, 11 Mar 2026 02:09:17 +0000 Subject: [PATCH 06/17] Add enable --- src/os/windows/mod.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index ceca833..5ee911c 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -1295,7 +1295,7 @@ impl Menu { let menu_name = to_wstring(name); winuser::AppendMenuW( self.menu_handle, - MF_POPUP | MF_GRAYED, + MF_POPUP, menu.menu_handle as basetsd::UINT_PTR, menu_name.as_ptr(), ); @@ -1422,6 +1422,16 @@ impl Menu { pub fn remove_item(&mut self, _item: &MenuItemHandle) { unimplemented!(); } + + pub fn enable_menu(&mut self, menu_item: &MenuItem, enabled: bool) { + unsafe { + winuser::EnableMenuItem( + self.menu_handle, + menu_item.id as basetsd::UINT_PTR, + if enabled { MF_ENABLED } else { MF_GRAYED }, + ); + } + } } impl Drop for Window { From 975d7e67a5a214741d46f5c9decc9db935df8b8e Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Wed, 11 Mar 2026 02:12:01 +0000 Subject: [PATCH 07/17] Add enable --- src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index f0feb08..53cfa0d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1076,6 +1076,12 @@ impl Menu { pub fn remove_item(&mut self, item: &MenuItemHandle) { self.0.remove_item(item) } + + /// Enables or disables an item from the menu + #[inline] + pub fn enable_menu(&mut self, item: &MenuItem, enabled: bool) { + self.0.enable_menu(item, enabled) + } } /// Holds info about each item in a menu From 766a0dc7d6c21094579d5f5a488410ec5eec528c Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Wed, 11 Mar 2026 02:30:32 +0000 Subject: [PATCH 08/17] add enable --- src/os/windows/mod.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index 5ee911c..36076a2 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -1147,6 +1147,23 @@ impl Window { } } + pub fn enable_menu(&mut self, handle: MenuHandle, index: usize, enabled: bool) { +        let window = self.hwnd; +        let main_menu = unsafe { winuser::GetMenu(window) }; +        for i in 0..self.menus.len() { +            if self.menus[i].menu_handle == handle.0 as windef::HMENU { +                unsafe { +                    winuser::EnableMenuItem( +                        main_menu, +                        index as basetsd::UINT32, +                        winuser::MF_BYPOSITION | if enabled { MF_ENABLED } else { MF_GRAYED }, +                    ); +                } +                return; +            } +        } + } + #[inline] pub fn is_menu_pressed(&mut self) -> Option { if self.accel_key == INVALID_ACCEL { From 206b43092233d8035ffd139ad18d0803822d0e25 Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Wed, 11 Mar 2026 02:31:25 +0000 Subject: [PATCH 09/17] add enable --- src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 53cfa0d..9fcd5cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -915,6 +915,13 @@ impl Window { self.0.remove_menu(handle) } + + /// Enable or disable a menu item +    #[inline] +    pub fn enable_menu(&mut self, handle: MenuHandle, index: usize, enabled: bool) { +        self.0.enable_menu(handle, index, enabled) + } + /// Get POSIX menus. Will only return menus on POSIX-like OSes like Linux or BSD /// otherwise ```None``` #[cfg(any(target_os = "macos", target_os = "windows", target_arch = "wasm32"))] From e1f703dd4380c75e363a0b3518da9eed03b6095f Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Wed, 11 Mar 2026 02:56:29 +0000 Subject: [PATCH 10/17] Update mod.rs --- src/os/windows/mod.rs | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index 36076a2..b714b24 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -1147,21 +1147,21 @@ impl Window { } } - pub fn enable_menu(&mut self, handle: MenuHandle, index: usize, enabled: bool) { -        let window = self.hwnd; -        let main_menu = unsafe { winuser::GetMenu(window) }; -        for i in 0..self.menus.len() { -            if self.menus[i].menu_handle == handle.0 as windef::HMENU { -                unsafe { -                    winuser::EnableMenuItem( -                        main_menu, -                        index as basetsd::UINT32, -                        winuser::MF_BYPOSITION | if enabled { MF_ENABLED } else { MF_GRAYED }, -                    ); -                } -                return; -            } -        } + pub fn enable_menu(&mut self, handle: Option, index: usize, enabled: bool) { + let window = self.hwnd; + let main_menu = unsafe { winuser::GetMenu(window) }; + for i in 0..self.menus.len() { + if self.menus[i].menu_handle == handle.0 as windef::HMENU { + unsafe { + winuser::EnableMenuItem( + handle.map_or(main_menu, |raw| raw.0), + index as basetsd::UINT32, + winuser::MF_BYPOSITION | if enabled { MF_ENABLED } else { MF_GRAYED }, + ); + } + return; + } + } } #[inline] @@ -1439,16 +1439,6 @@ impl Menu { pub fn remove_item(&mut self, _item: &MenuItemHandle) { unimplemented!(); } - - pub fn enable_menu(&mut self, menu_item: &MenuItem, enabled: bool) { - unsafe { - winuser::EnableMenuItem( - self.menu_handle, - menu_item.id as basetsd::UINT_PTR, - if enabled { MF_ENABLED } else { MF_GRAYED }, - ); - } - } } impl Drop for Window { From 60af16ccf696e6c42d174ade9c1a4efb22e230a3 Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Wed, 11 Mar 2026 02:57:20 +0000 Subject: [PATCH 11/17] Update lib.rs --- src/lib.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9fcd5cb..e498031 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -917,9 +917,9 @@ impl Window { /// Enable or disable a menu item -    #[inline] -    pub fn enable_menu(&mut self, handle: MenuHandle, index: usize, enabled: bool) { -        self.0.enable_menu(handle, index, enabled) + #[inline] + pub fn enable_menu(&mut self, handle: Option, index: usize, enabled: bool) { + self.0.enable_menu(handle, index, enabled) } /// Get POSIX menus. Will only return menus on POSIX-like OSes like Linux or BSD @@ -1083,12 +1083,6 @@ impl Menu { pub fn remove_item(&mut self, item: &MenuItemHandle) { self.0.remove_item(item) } - - /// Enables or disables an item from the menu - #[inline] - pub fn enable_menu(&mut self, item: &MenuItem, enabled: bool) { - self.0.enable_menu(item, enabled) - } } /// Holds info about each item in a menu From 46b7bc566012d134bd5201652c1c7f8692fc8e40 Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Wed, 11 Mar 2026 03:06:42 +0000 Subject: [PATCH 12/17] Update mod.rs --- src/os/windows/mod.rs | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index b714b24..1178d24 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -1147,19 +1147,34 @@ impl Window { } } - pub fn enable_menu(&mut self, handle: Option, index: usize, enabled: bool) { + /// Enables or disables a menu item. + /// + /// If handle is None the main menu bar is used + pub fn enable_menu(&mut self, handle: Option, position: usize, enabled: bool) { let window = self.hwnd; let main_menu = unsafe { winuser::GetMenu(window) }; - for i in 0..self.menus.len() { - if self.menus[i].menu_handle == handle.0 as windef::HMENU { - unsafe { - winuser::EnableMenuItem( - handle.map_or(main_menu, |raw| raw.0), - index as basetsd::UINT32, - winuser::MF_BYPOSITION | if enabled { MF_ENABLED } else { MF_GRAYED }, - ); + match handle { + None => unsafe { + winuser::EnableMenuItem( + main_menu, + index as basetsd::UINT32, + winuser::MF_BYPOSITION | if enabled { MF_ENABLED } else { MF_GRAYED }, + ); + }, + Some(menuhandle) => { + for i in 0..self.menus.len() { + if self.menus[i].menu_handle == menuhandle.0 as windef::HMENU { + unsafe { + winuser::EnableMenuItem( + menuhandle.0 as windef::HMENU, + position as basetsd::UINT32, + winuser::MF_BYPOSITION + | if enabled { MF_ENABLED } else { MF_GRAYED }, + ); + } + return; + } } - return; } } } From 92cf6507d3773a4348d81899b60dd765590ae4f8 Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Wed, 11 Mar 2026 03:18:45 +0000 Subject: [PATCH 13/17] Gate enable_menu --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index e498031..c123095 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -917,6 +917,7 @@ impl Window { /// Enable or disable a menu item + #[cfg(target_os = "windows")] #[inline] pub fn enable_menu(&mut self, handle: Option, index: usize, enabled: bool) { self.0.enable_menu(handle, index, enabled) From 66b9f5fc43b7a7810be5333afaba4ef253f59dc9 Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Wed, 11 Mar 2026 03:20:10 +0000 Subject: [PATCH 14/17] Fix build --- src/os/windows/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index 1178d24..43cb99a 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -1157,7 +1157,7 @@ impl Window { None => unsafe { winuser::EnableMenuItem( main_menu, - index as basetsd::UINT32, + position as basetsd::UINT32, winuser::MF_BYPOSITION | if enabled { MF_ENABLED } else { MF_GRAYED }, ); }, From 19c639495dd2ae706499b50d5f92477a6b1f0e45 Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Wed, 11 Mar 2026 21:39:01 +0000 Subject: [PATCH 15/17] formatting --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index c123095..6f4739c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -915,7 +915,6 @@ impl Window { self.0.remove_menu(handle) } - /// Enable or disable a menu item #[cfg(target_os = "windows")] #[inline] From 6437321b4a28a51f5b72a3280833a0a1ba069147 Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Wed, 11 Mar 2026 21:40:34 +0000 Subject: [PATCH 16/17] formatting --- src/os/windows/mod.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index 43cb99a..1bf5f99 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -1423,7 +1423,12 @@ impl Menu { } else { winuser::AppendMenuW( self.menu_handle, - MF_POPUP | if menu_item.enabled { MF_ENABLED } else { MF_GRAYED }, + MF_POPUP + | if menu_item.enabled { + MF_ENABLED + } else { + MF_GRAYED + }, menu_item.id as basetsd::UINT_PTR, item_name.as_ptr(), ); @@ -1434,7 +1439,12 @@ impl Menu { let w_name = to_wstring(&menu_name); winuser::AppendMenuW( self.menu_handle, - MF_POPUP | if menu_item.enabled { MF_ENABLED } else { MF_GRAYED }, + MF_POPUP + | if menu_item.enabled { + MF_ENABLED + } else { + MF_GRAYED + }, menu_item.id as basetsd::UINT_PTR, w_name.as_ptr(), ); From ee36085640b4eb4e934192c9684c148db04542dc Mon Sep 17 00:00:00 2001 From: Jefferson <44975876+ZX-80@users.noreply.github.com> Date: Sat, 14 Mar 2026 12:34:48 +0000 Subject: [PATCH 17/17] Formatting --- src/os/windows/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index 1bf5f99..e2291f4 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -29,7 +29,7 @@ use winapi::{ libloaderapi, wingdi, winuser::{ self, GET_XBUTTON_WPARAM, ICON_BIG, ICON_SMALL, IMAGE_ICON, LR_DEFAULTSIZE, - MF_ENABLED, MF_GRAYED, MF_POPUP, MF_SEPARATOR, LR_LOADFROMFILE, WM_SETICON, + LR_LOADFROMFILE, MF_ENABLED, MF_GRAYED, MF_POPUP, MF_SEPARATOR, WM_SETICON, }, }, };