Open Horbin-Magician opened 3 months ago
could you maybe provide a sample code that one can try that reproduce the problem?
I implemented a simple demo. It is a borderless window, and a button that takes up the entire window, like:
The appwindow.slint file:
import { Button, VerticalBox } from "std-widgets.slint";
export component AppWindow inherits Window {
no-frame: true;
in-out property <int> win_width;
in-out property <int> win_height;
callback clicked <=> btn.clicked;
width: win_width * 1px;
height: win_height * 1px;
VerticalBox {
padding: 0px;
btn := Button {
text: "Click";
}
}
}
The main.rs file:
slint::include_modules!();
use xcap::Monitor;
fn main() -> Result<(), slint::PlatformError> {
let ui = AppWindow::new()?;
// get screens and info
let monitors = Monitor::all().unwrap();
let mut sec_monitor = None;
for monitor in monitors {
if monitor.is_primary() == false {
sec_monitor = Some(monitor);
}
}
let mut default_scale_factor: f32 = 0.0;
if let Some(sec_monitor) = sec_monitor {
ui.window().set_position(slint::PhysicalPosition::new(sec_monitor.x(), sec_monitor.y()));
default_scale_factor = ui.window().scale_factor();
println!("the default scale factor: {default_scale_factor}");
ui.set_win_height( (sec_monitor.height() as f32 / (default_scale_factor * 2.0) ) as i32);
ui.set_win_width( (sec_monitor.width() as f32 / (default_scale_factor * 2.0) ) as i32);
let ui_clone = ui.as_weak();
ui.on_clicked(move || {
let scale_factor = ui_clone.unwrap().window().scale_factor();
println!("the scale factor: {scale_factor}");
});
} else {
eprintln!("No secondary monitor found");
}
ui.run()
}
Abnormal one:the default_scale_factor always be the scale_factor of the primary monitor. But when I click the button, it returns the correct scale_factor. I understand this default behavior, but perhaps it would be better to refresh the scale_factor after setting the window position.
Abnormal two:according to the code below:
ui.set_win_height( (sec_monitor.height() as f32 / (default_scale_factor * 2.0) ) as i32);
ui.set_win_width( (sec_monitor.width() as f32 / (default_scale_factor * 2.0) ) as i32);
My expectation is that the window will take up a quarter of the monitor. But considering the “Abnormal one”, the reality should not be what I expected. But surprisingly, the window takes up exactly a quarter of the monitor, but the buttons don't take up the entire screen, like:
I think it might caused by a mix using of default scale factor and true scale factor in slint. This is my demo project: demo.zip
So the bug is that scale_factor
is not updated right after set_position
?
I think that might be because set_position is asynchronous and so it will take some iteration of the event loop before it actually applies and that the new scale factor is provided to slint.
So the bug is that
scale_factor
is not updated right afterset_position
? I think that might be because set_position is asynchronous and so it will take some iteration of the event loop before it actually applies and that the new scale factor is provided to slint.
Yes, besides, I think the "Abnormal two" is due to the correct scale_factor of winit. Because my window size is right, but the content displayed inside the window is wrong. The scale_factor of slint and winit should be synchronized (if my guess is right).
Slint: 1.7.0; Windows; Rust
When I use two monitors with different scale factors. A new window always return the scale factor of the primary monitor when using
win.window().scale_factor();
. At the same time, if it first appears on the non-primary monitor, its window size is not normal.I'm not quite sure at what stage the scale_factor is set, but I think it needs to be reset after using
win.window().set_position()
or beforewin.show()
.