windows: Improve handling of the `WM_SETTINGCHANGE` (#11738)

张小白 created

This event is broadcast to all windows, so we can handle this message in
the `WindowsWindow` ranther than in `WindowsPlatform`.

Release Notes:

- N/A

Change summary

crates/gpui/src/platform/windows/events.rs          | 38 +++-----------
crates/gpui/src/platform/windows/platform.rs        | 34 +-----------
crates/gpui/src/platform/windows/system_settings.rs | 24 +++------
crates/gpui/src/platform/windows/window.rs          | 10 +--
4 files changed, 25 insertions(+), 81 deletions(-)

Detailed changes

crates/gpui/src/platform/windows/events.rs 🔗

@@ -16,10 +16,8 @@ use windows::Win32::{
 use crate::*;
 
 pub(crate) const CURSOR_STYLE_CHANGED: u32 = WM_USER + 1;
-pub(crate) const MOUSE_WHEEL_SETTINGS_CHANGED: u32 = WM_USER + 2;
-pub(crate) const MOUSE_WHEEL_SETTINGS_SCROLL_CHARS_CHANGED: isize = 1;
-pub(crate) const MOUSE_WHEEL_SETTINGS_SCROLL_LINES_CHANGED: isize = 2;
-pub(crate) const CLOSE_ONE_WINDOW: u32 = WM_USER + 3;
+pub(crate) const CLOSE_ONE_WINDOW: u32 = WM_USER + 2;
+
 const SIZE_MOVE_LOOP_TIMER_ID: usize = 1;
 
 pub(crate) fn handle_msg(
@@ -82,8 +80,8 @@ pub(crate) fn handle_msg(
         WM_IME_STARTCOMPOSITION => handle_ime_position(handle, state_ptr),
         WM_IME_COMPOSITION => handle_ime_composition(handle, lparam, state_ptr),
         WM_SETCURSOR => handle_set_cursor(lparam, state_ptr),
+        WM_SETTINGCHANGE => handle_system_settings_changed(state_ptr),
         CURSOR_STYLE_CHANGED => handle_cursor_changed(lparam, state_ptr),
-        MOUSE_WHEEL_SETTINGS_CHANGED => handle_mouse_wheel_settings_msg(wparam, lparam, state_ptr),
         _ => None,
     };
     if let Some(n) = handled {
@@ -504,7 +502,7 @@ fn handle_mouse_wheel_msg(
     let mut lock = state_ptr.state.borrow_mut();
     if let Some(mut callback) = lock.callbacks.input.take() {
         let scale_factor = lock.scale_factor;
-        let wheel_scroll_lines = lock.mouse_wheel_settings.wheel_scroll_lines;
+        let wheel_scroll_lines = lock.system_settings.mouse_wheel_settings.wheel_scroll_lines;
         drop(lock);
         let wheel_distance =
             (wparam.signed_hiword() as f32 / WHEEL_DELTA as f32) * wheel_scroll_lines as f32;
@@ -544,7 +542,7 @@ fn handle_mouse_horizontal_wheel_msg(
     let mut lock = state_ptr.state.borrow_mut();
     if let Some(mut callback) = lock.callbacks.input.take() {
         let scale_factor = lock.scale_factor;
-        let wheel_scroll_chars = lock.mouse_wheel_settings.wheel_scroll_chars;
+        let wheel_scroll_chars = lock.system_settings.mouse_wheel_settings.wheel_scroll_chars;
         drop(lock);
         let wheel_distance =
             (-wparam.signed_hiword() as f32 / WHEEL_DELTA as f32) * wheel_scroll_chars as f32;
@@ -1037,28 +1035,10 @@ fn handle_set_cursor(lparam: LPARAM, state_ptr: Rc<WindowsWindowStatePtr>) -> Op
     Some(1)
 }
 
-fn handle_mouse_wheel_settings_msg(
-    wparam: WPARAM,
-    lparam: LPARAM,
-    state_ptr: Rc<WindowsWindowStatePtr>,
-) -> Option<isize> {
-    match lparam.0 {
-        1 => {
-            state_ptr
-                .state
-                .borrow_mut()
-                .mouse_wheel_settings
-                .wheel_scroll_chars = wparam.0 as u32
-        }
-        2 => {
-            state_ptr
-                .state
-                .borrow_mut()
-                .mouse_wheel_settings
-                .wheel_scroll_lines = wparam.0 as u32
-        }
-        _ => unreachable!(),
-    }
+fn handle_system_settings_changed(state_ptr: Rc<WindowsWindowStatePtr>) -> Option<isize> {
+    let mut lock = state_ptr.state.borrow_mut();
+    // mouse wheel
+    lock.system_settings.mouse_wheel_settings.update();
     Some(0)
 }
 

crates/gpui/src/platform/windows/platform.rs 🔗

@@ -48,7 +48,6 @@ pub(crate) struct WindowsPlatform {
 
 pub(crate) struct WindowsPlatformState {
     callbacks: PlatformCallbacks,
-    pub(crate) settings: WindowsPlatformSystemSettings,
     // NOTE: standard cursor handles don't need to close.
     pub(crate) current_cursor: HCURSOR,
 }
@@ -66,12 +65,10 @@ struct PlatformCallbacks {
 impl WindowsPlatformState {
     fn new() -> Self {
         let callbacks = PlatformCallbacks::default();
-        let settings = WindowsPlatformSystemSettings::new();
         let current_cursor = load_cursor(CursorStyle::Arrow);
 
         Self {
             callbacks,
-            settings,
             current_cursor,
         }
     }
@@ -149,28 +146,6 @@ impl WindowsPlatform {
 
         lock.is_empty()
     }
-
-    fn update_system_settings(&self) {
-        let mut lock = self.state.borrow_mut();
-        // mouse wheel
-        {
-            let (scroll_chars, scroll_lines) = lock.settings.mouse_wheel_settings.update();
-            if let Some(scroll_chars) = scroll_chars {
-                self.post_message(
-                    MOUSE_WHEEL_SETTINGS_CHANGED,
-                    WPARAM(scroll_chars as usize),
-                    LPARAM(MOUSE_WHEEL_SETTINGS_SCROLL_CHARS_CHANGED),
-                );
-            }
-            if let Some(scroll_lines) = scroll_lines {
-                self.post_message(
-                    MOUSE_WHEEL_SETTINGS_CHANGED,
-                    WPARAM(scroll_lines as usize),
-                    LPARAM(MOUSE_WHEEL_SETTINGS_SCROLL_LINES_CHANGED),
-                );
-            }
-        }
-    }
 }
 
 impl Platform for WindowsPlatform {
@@ -219,7 +194,6 @@ impl Platform for WindowsPlatform {
                                         break 'a;
                                     }
                                 }
-                                WM_SETTINGCHANGE => self.update_system_settings(),
                                 _ => {
                                     // todo(windows)
                                     // crate `windows 0.56` reports true as Err
@@ -325,7 +299,6 @@ impl Platform for WindowsPlatform {
             options,
             self.icon,
             self.foreground_executor.clone(),
-            lock.settings.mouse_wheel_settings,
             lock.current_cursor,
         );
         drop(lock);
@@ -640,8 +613,11 @@ impl Platform for WindowsPlatform {
 
     fn set_cursor_style(&self, style: CursorStyle) {
         let hcursor = load_cursor(style);
-        self.post_message(CURSOR_STYLE_CHANGED, WPARAM(0), LPARAM(hcursor.0));
-        self.state.borrow_mut().current_cursor = hcursor;
+        let mut lock = self.state.borrow_mut();
+        if lock.current_cursor.0 != hcursor.0 {
+            self.post_message(CURSOR_STYLE_CHANGED, WPARAM(0), LPARAM(hcursor.0));
+            lock.current_cursor = hcursor;
+        }
     }
 
     // todo(windows)

crates/gpui/src/platform/windows/system_settings.rs 🔗

@@ -8,8 +8,8 @@ use windows::Win32::UI::WindowsAndMessaging::{
 
 /// Windows settings pulled from SystemParametersInfo
 /// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfow
-#[derive(Default, Debug)]
-pub(crate) struct WindowsPlatformSystemSettings {
+#[derive(Default, Debug, Clone, Copy)]
+pub(crate) struct WindowsSystemSettings {
     pub(crate) mouse_wheel_settings: MouseWheelSettings,
 }
 
@@ -21,7 +21,7 @@ pub(crate) struct MouseWheelSettings {
     pub(crate) wheel_scroll_lines: u32,
 }
 
-impl WindowsPlatformSystemSettings {
+impl WindowsSystemSettings {
     pub(crate) fn new() -> Self {
         let mut settings = Self::default();
         settings.init();
@@ -34,14 +34,12 @@ impl WindowsPlatformSystemSettings {
 }
 
 impl MouseWheelSettings {
-    pub(crate) fn update(&mut self) -> (Option<u32>, Option<u32>) {
-        (
-            self.update_wheel_scroll_chars(),
-            self.update_wheel_scroll_lines(),
-        )
+    pub(crate) fn update(&mut self) {
+        self.update_wheel_scroll_chars();
+        self.update_wheel_scroll_lines();
     }
 
-    fn update_wheel_scroll_chars(&mut self) -> Option<u32> {
+    fn update_wheel_scroll_chars(&mut self) {
         let mut value = c_uint::default();
         let result = unsafe {
             SystemParametersInfoW(
@@ -54,13 +52,10 @@ impl MouseWheelSettings {
 
         if result.log_err() != None && self.wheel_scroll_chars != value {
             self.wheel_scroll_chars = value;
-            Some(value)
-        } else {
-            None
         }
     }
 
-    fn update_wheel_scroll_lines(&mut self) -> Option<u32> {
+    fn update_wheel_scroll_lines(&mut self) {
         let mut value = c_uint::default();
         let result = unsafe {
             SystemParametersInfoW(
@@ -73,9 +68,6 @@ impl MouseWheelSettings {
 
         if result.log_err() != None && self.wheel_scroll_lines != value {
             self.wheel_scroll_lines = value;
-            Some(value)
-        } else {
-            None
         }
     }
 }

crates/gpui/src/platform/windows/window.rs 🔗

@@ -43,7 +43,7 @@ pub struct WindowsWindowState {
     pub renderer: BladeRenderer,
 
     pub click_state: ClickState,
-    pub mouse_wheel_settings: MouseWheelSettings,
+    pub system_settings: WindowsSystemSettings,
     pub current_cursor: HCURSOR,
 
     pub display: WindowsDisplay,
@@ -64,7 +64,6 @@ impl WindowsWindowState {
         hwnd: HWND,
         transparent: bool,
         cs: &CREATESTRUCTW,
-        mouse_wheel_settings: MouseWheelSettings,
         current_cursor: HCURSOR,
         display: WindowsDisplay,
     ) -> Self {
@@ -82,6 +81,7 @@ impl WindowsWindowState {
         let callbacks = Callbacks::default();
         let input_handler = None;
         let click_state = ClickState::new();
+        let system_settings = WindowsSystemSettings::new();
         let fullscreen = None;
 
         Self {
@@ -93,7 +93,7 @@ impl WindowsWindowState {
             input_handler,
             renderer,
             click_state,
-            mouse_wheel_settings,
+            system_settings,
             current_cursor,
             display,
             fullscreen,
@@ -195,7 +195,6 @@ impl WindowsWindowStatePtr {
             hwnd,
             context.transparent,
             cs,
-            context.mouse_wheel_settings,
             context.current_cursor,
             context.display,
         ));
@@ -229,7 +228,6 @@ struct WindowCreateContext {
     display: WindowsDisplay,
     transparent: bool,
     executor: ForegroundExecutor,
-    mouse_wheel_settings: MouseWheelSettings,
     current_cursor: HCURSOR,
 }
 
@@ -239,7 +237,6 @@ impl WindowsWindow {
         params: WindowParams,
         icon: HICON,
         executor: ForegroundExecutor,
-        mouse_wheel_settings: MouseWheelSettings,
         current_cursor: HCURSOR,
     ) -> Self {
         let classname = register_wnd_class(icon);
@@ -271,7 +268,6 @@ impl WindowsWindow {
             display,
             transparent: params.window_background != WindowBackgroundAppearance::Opaque,
             executor,
-            mouse_wheel_settings,
             current_cursor,
         };
         let lpparam = Some(&context as *const _ as *const _);