diff --git a/crates/gpui/src/platform/windows/events.rs b/crates/gpui/src/platform/windows/events.rs index b0a3bf2620f0eb5dcc726a15bc581522d655d820..fad7a55760509569617b51a3de61642e1c021e47 100644 --- a/crates/gpui/src/platform/windows/events.rs +++ b/crates/gpui/src/platform/windows/events.rs @@ -93,6 +93,7 @@ pub(crate) fn handle_msg( WM_IME_COMPOSITION => handle_ime_composition(handle, lparam, state_ptr), WM_SETCURSOR => handle_set_cursor(lparam, state_ptr), WM_SETTINGCHANGE => handle_system_settings_changed(handle, lparam, state_ptr), + WM_INPUTLANGCHANGE => handle_input_language_changed(lparam, state_ptr), WM_GPUI_CURSOR_STYLE_CHANGED => handle_cursor_changed(lparam, state_ptr), _ => None, }; @@ -1279,6 +1280,18 @@ fn handle_system_theme_changed( Some(0) } +fn handle_input_language_changed( + lparam: LPARAM, + state_ptr: Rc, +) -> Option { + let thread = state_ptr.main_thread_id_win32; + let validation = state_ptr.validation_number; + unsafe { + PostThreadMessageW(thread, WM_INPUTLANGCHANGE, WPARAM(validation), lparam).log_err(); + } + Some(0) +} + fn parse_syskeydown_msg_keystroke(wparam: WPARAM) -> Option { let modifiers = current_modifiers(); let vk_code = wparam.loword(); diff --git a/crates/gpui/src/platform/windows/platform.rs b/crates/gpui/src/platform/windows/platform.rs index b76bc887a1db628f21ab3243f0d31f437aa5c6d7..fea3a6184c95318f6014cc0f73f97e17fcb2c013 100644 --- a/crates/gpui/src/platform/windows/platform.rs +++ b/crates/gpui/src/platform/windows/platform.rs @@ -33,8 +33,8 @@ use crate::{platform::blade::BladeContext, *}; pub(crate) struct WindowsPlatform { state: RefCell, raw_window_handles: RwLock>, - gpu_context: BladeContext, // The below members will never change throughout the entire lifecycle of the app. + gpu_context: BladeContext, icon: HICON, main_receiver: flume::Receiver, background_executor: BackgroundExecutor, @@ -62,6 +62,7 @@ struct PlatformCallbacks { app_menu_action: Option>, will_open_app_menu: Option>, validate_app_menu_command: Option bool>>, + keyboard_layout_change: Option>, } impl WindowsPlatformState { @@ -201,6 +202,19 @@ impl WindowsPlatform { } } + fn handle_input_lang_change(&self) { + let mut lock = self.state.borrow_mut(); + if let Some(mut callback) = lock.callbacks.keyboard_layout_change.take() { + drop(lock); + callback(); + self.state + .borrow_mut() + .callbacks + .keyboard_layout_change + .get_or_insert(callback); + } + } + // Returns true if the app should quit. fn handle_events(&self) -> bool { let mut msg = MSG::default(); @@ -208,7 +222,8 @@ impl WindowsPlatform { while PeekMessageW(&mut msg, None, 0, 0, PM_REMOVE).as_bool() { match msg.message { WM_QUIT => return true, - WM_GPUI_CLOSE_ONE_WINDOW + WM_INPUTLANGCHANGE + | WM_GPUI_CLOSE_ONE_WINDOW | WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD | WM_GPUI_DOCK_MENU_ACTION => { if self.handle_gpui_evnets(msg.message, msg.wParam, msg.lParam, &msg) { @@ -247,6 +262,7 @@ impl WindowsPlatform { } WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD => self.run_foreground_task(), WM_GPUI_DOCK_MENU_ACTION => self.handle_dock_action_event(lparam.0 as _), + WM_INPUTLANGCHANGE => self.handle_input_lang_change(), _ => unreachable!(), } false @@ -305,8 +321,8 @@ impl Platform for WindowsPlatform { ) } - fn on_keyboard_layout_change(&self, _callback: Box) { - // todo(windows) + fn on_keyboard_layout_change(&self, callback: Box) { + self.state.borrow_mut().callbacks.keyboard_layout_change = Some(callback); } fn run(&self, on_finish_launching: Box) {