Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changes/add-text-scale-factor-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tao": patch
---

feat(windows): add text scale factor support
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
target/
rls/
.vscode/
.idea/
*~
*.ts
*.js
Expand Down
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ unicode-segmentation = "1.11"
windows-version = "0.1"
windows-core = "0.61"

[target."cfg(target_os = \"windows\")".dependencies.windows]
version = "0.61"
features = [
[target."cfg(target_os = \"windows\")".dependencies.windows]
version = "0.61"
features = [
"UI_ViewManagement",
"Win32_Devices_HumanInterfaceDevice",
"Win32_Foundation",
"Win32_Globalization",
Expand Down
8 changes: 8 additions & 0 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,12 @@ pub enum WindowEvent<'a> {
new_inner_size: &'a mut PhysicalSize<u32>,
},

/// The system text scale factor has changed.
///
/// ## Platform-specific
/// - **Linux / Android / iOS:** Unsupported
TextScaleFactorChanged(f64),

/// The system window theme has changed.
///
/// Applications might wish to react to this to change the theme of the content of the window
Expand Down Expand Up @@ -510,6 +516,7 @@ impl Clone for WindowEvent<'static> {
ScaleFactorChanged { .. } => {
unreachable!("Static event can't be about scale factor changing")
}
TextScaleFactorChanged(f) => TextScaleFactorChanged(*f),
DecorationsClick => DecorationsClick,
}
}
Expand Down Expand Up @@ -595,6 +602,7 @@ impl<'a> WindowEvent<'a> {
Touch(touch) => Some(Touch(touch)),
ThemeChanged(theme) => Some(ThemeChanged(theme)),
ScaleFactorChanged { .. } => None,
TextScaleFactorChanged(factor) => Some(TextScaleFactorChanged(factor)),
DecorationsClick => Some(DecorationsClick),
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/platform_impl/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,8 @@ impl Window {
MonitorHandle.scale_factor()
}

pub fn text_scale_factor(&self) -> f64 { 1.0 }

pub fn request_redraw(&self) {
// TODO
}
Expand Down
4 changes: 4 additions & 0 deletions src/platform_impl/ios/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ impl Inner {
}
}

pub fn text_scale_factor(&self) -> f64 {
1.0
}

pub fn set_cursor_icon(&self, _cursor: CursorIcon) {
debug!("`Window::set_cursor_icon` ignored on iOS")
}
Expand Down
3 changes: 3 additions & 0 deletions src/platform_impl/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,9 @@ impl UnownedWindow {
NSWindow::backingScaleFactor(&self.ns_window) as _
}

#[inline]
pub fn text_scale_factor(&self) -> f64 { 1.0 }

#[inline]
pub fn set_cursor_position(&self, cursor_position: Position) -> Result<(), ExternalError> {
let physical_window_position = self.inner_position().unwrap();
Expand Down
32 changes: 32 additions & 0 deletions src/platform_impl/windows/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,12 @@ lazy_static! {
pub static ref CHANGE_THEME_MSG_ID: u32 = unsafe {
RegisterWindowMessageA(s!("Tao::ChangeTheme"))
};
/// Message sent by event loop when TextScaleFactorChanged
/// WPARAM and LPARAM are unused.
pub static ref TEXT_SCALE_FACTOR_CHANGED_MSG_ID: u32 = unsafe {
RegisterWindowMessageA(s!("Tao::TextScaleFactorChanged"))
};

/// When the taskbar is created, it registers a message with the "TaskbarCreated" string and then broadcasts this message to all top-level windows
/// When the application receives this message, it should assume that any taskbar icons it added have been removed and add them again.
pub static ref S_U_TASKBAR_RESTART: u32 = unsafe {
Expand Down Expand Up @@ -2147,6 +2153,7 @@ unsafe fn public_window_callback_inner<T: 'static>(

win32wm::WM_SETTINGCHANGE => {
update_theme(subclass_input, window, true);
update_text_scale_factor(subclass_input, window, true);
}

win32wm::WM_NCCALCSIZE => {
Expand Down Expand Up @@ -2278,6 +2285,9 @@ unsafe fn public_window_callback_inner<T: 'static>(
} else if msg == *S_U_TASKBAR_RESTART {
let window_state = subclass_input.window_state.lock();
let _ = set_skip_taskbar(window, window_state.skip_taskbar);
} else if msg == *TEXT_SCALE_FACTOR_CHANGED_MSG_ID {
update_text_scale_factor(subclass_input, window, false);
result = ProcResult::Value(LRESULT(0));
}
}
};
Expand Down Expand Up @@ -2319,6 +2329,28 @@ fn update_theme<T>(
}
}

fn update_text_scale_factor<T>(
subclass_input: &SubclassInput<T>,
window: HWND,
from_settings_change_event: bool,
) {
let mut window_state = subclass_input.window_state.lock();
if from_settings_change_event {
return;
}
let new_text_scale_factor = util::get_cur_text_scale_factor().unwrap_or(1.0);
if window_state.text_scale_factor != new_text_scale_factor {
window_state.text_scale_factor = new_text_scale_factor;
mem::drop(window_state);
unsafe {
subclass_input.send_event(Event::WindowEvent {
window_id: RootWindowId(WindowId(window.0 as _)),
event: WindowEvent::TextScaleFactorChanged(new_text_scale_factor),
})
};
}
}

fn is_show_window_contents_while_dragging_enabled() -> bool {
let mut is_enabled: BOOL = BOOL(0);
let result = unsafe {
Expand Down
7 changes: 7 additions & 0 deletions src/platform_impl/windows/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{
use once_cell::sync::Lazy;
use windows::{
core::{BOOL, HRESULT, PCSTR, PCWSTR},
UI::ViewManagement::UISettings,
Win32::{
Foundation::{COLORREF, FARPROC, HWND, LPARAM, LRESULT, POINT, RECT, WPARAM},
Globalization::lstrlenW,
Expand Down Expand Up @@ -509,3 +510,9 @@ pub unsafe fn get_system_metrics_for_dpi(nindex: SYSTEM_METRICS_INDEX, dpi: u32)
GetSystemMetrics(nindex)
}
}

// Read text_scale_factor from system settings
pub(crate) fn get_cur_text_scale_factor() -> Result<f64, windows::core::Error> {
let ui_settings = UISettings::new()?;
ui_settings.TextScaleFactor()
}
5 changes: 5 additions & 0 deletions src/platform_impl/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,11 @@ impl Window {
self.window_state.lock().scale_factor
}

#[inline]
pub fn text_scale_factor(&self) -> f64 {
self.window_state.lock().text_scale_factor
}

#[inline]
pub fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError> {
let scale_factor = self.scale_factor();
Expand Down
4 changes: 4 additions & 0 deletions src/platform_impl/windows/window_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub struct WindowState {

pub saved_window: Option<SavedWindow>,
pub scale_factor: f64,
pub text_scale_factor: f64,

pub dragging: bool,

Expand Down Expand Up @@ -132,6 +133,8 @@ impl WindowState {
preferred_theme: Option<Theme>,
background_color: Option<RGBA>,
) -> WindowState {
let text_scale_factor = util::get_cur_text_scale_factor().unwrap_or(1.0);

WindowState {
mouse: MouseProperties {
cursor: CursorIcon::default(),
Expand All @@ -147,6 +150,7 @@ impl WindowState {

saved_window: None,
scale_factor,
text_scale_factor,

dragging: false,

Expand Down
9 changes: 9 additions & 0 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,15 @@ impl Window {
self.window.scale_factor()
}

/// Returns the text scale factor
///
/// ## Platform-specific
/// Android/iOS/Linux: Unsupported, always returns 1.0
#[inline]
pub fn text_scale_factor(&self) -> f64 {
self.window.text_scale_factor()
}

/// Emits a `WindowEvent::RedrawRequested` event in the associated event loop after all OS
/// events have been processed by the event loop.
///
Expand Down