gui: be smart with window size at launch

This commit is contained in:
pythcoiner 2025-05-05 11:37:45 +02:00
parent 089992b947
commit 2dc838f85c
2 changed files with 112 additions and 4 deletions

View File

@ -394,7 +394,6 @@ pub mod global {
#[derive(Debug, Deserialize, Serialize, Default)]
pub struct GlobalSettings {
#[serde(skip)]
pub bitbox: Option<BitboxSettings>,
pub window_config: Option<WindowConfig>,
}

View File

@ -2,8 +2,9 @@ use iced::{
event::{self, Event},
keyboard,
widget::{focus_next, focus_previous, pane_grid},
Length, Subscription, Task,
Length, Size, Subscription, Task,
};
use iced_runtime::window;
use tracing::{error, info};
use tracing_subscriber::filter::LevelFilter;
extern crate serde;
@ -15,12 +16,23 @@ use liana_ui::widget::{Column, Container, Element};
pub mod pane;
pub mod tab;
use crate::{dir::LianaDirectory, launcher, logger::setup_logger, VERSION};
use crate::{
app::settings::global::{GlobalSettings, WindowConfig},
dir::LianaDirectory,
launcher,
logger::setup_logger,
VERSION,
};
use iced::window::Id;
pub struct GUI {
panes: pane_grid::State<pane::Pane>,
focus: Option<pane_grid::Pane>,
config: Config,
window_id: Option<Id>,
window_init: Option<bool>,
window_config: Option<WindowConfig>,
}
#[derive(Debug)]
@ -39,6 +51,8 @@ pub enum Message {
Clicked(pane_grid::Pane),
Dragged(pane_grid::DragEvent),
Resized(pane_grid::ResizeEvent),
Window(Option<Id>),
WindowSize(Size),
}
impl From<Result<(), iced::font::Error>> for Message {
@ -65,15 +79,24 @@ impl GUI {
if let Err(e) = setup_logger(log_level, config.liana_directory.clone()) {
tracing::warn!("Error while setting error: {}", e);
}
let mut cmds = vec![Task::perform(ctrl_c(), |_| Message::CtrlC)];
let mut cmds = vec![
window::get_oldest().map(Message::Window),
Task::perform(ctrl_c(), |_| Message::CtrlC),
];
let (pane, cmd) = pane::Pane::new(&config);
let (panes, focused_pane) = pane_grid::State::new(pane);
cmds.push(cmd.map(move |msg| Message::Pane(focused_pane, msg)));
let window_config =
GlobalSettings::load_window_config(&GlobalSettings::path(&config.liana_directory));
let window_init = window_config.is_some().then_some(true);
(
Self {
panes,
focus: Some(focused_pane),
config,
window_id: None,
window_init,
window_config,
},
Task::batch(cmds),
)
@ -81,6 +104,89 @@ impl GUI {
pub fn update(&mut self, message: Message) -> Task<Message> {
match message {
// we get this message only once at startup
Message::Window(id) => {
self.window_id = id;
// Common case: if there is an already saved screen size we reuse it
if let (Some(id), Some(WindowConfig { width, height })) = (id, &self.window_config)
{
window::resize(
id,
Size {
width: *width,
height: *height,
},
)
// Initial startup: we maximize the screen in order to know the max usable screen area
} else if let Some(id) = &self.window_id {
window::maximize(*id, true)
} else {
Task::none()
}
}
Message::WindowSize(monitor_size) => {
match (
self.window_config.as_mut(),
&self.window_init,
&self.window_id,
) {
// no previous screen size recorded && window maximized
(None, Some(false), Some(id)) => {
self.window_init = Some(true);
let mut batch = vec![window::maximize(*id, false)];
let new_size = if monitor_size.height >= 1200.0 {
let size = Size {
width: 1200.0,
height: 950.0,
};
batch.push(window::resize(*id, size));
size
} else {
batch.push(window::resize(*id, iced::window::Settings::default().size));
iced::window::Settings::default().size
};
let path = GlobalSettings::path(&self.config.liana_directory);
let mut settings = GlobalSettings::load(&path)
.ok()
.flatten()
.unwrap_or_default();
settings.window_config = Some(WindowConfig {
width: new_size.width,
height: new_size.height,
});
settings.to_file(&path).unwrap();
Task::batch(batch)
}
// we already have a record of the last window size and we update it
(Some(WindowConfig { width, height }), _, _) => {
if *width != monitor_size.width || *height != monitor_size.height {
*width = monitor_size.width;
*height = monitor_size.height;
let path = GlobalSettings::path(&self.config.liana_directory);
let mut settings = GlobalSettings::load(&path)
.ok()
.flatten()
.unwrap_or_default();
settings.window_config = Some(WindowConfig {
width: *width,
height: *height,
});
if let Err(e) = settings.to_file(&path) {
tracing::error!("Fail to write window config to file: {e}");
}
}
Task::none()
}
// we ignore the first notification about initial window size it will always be
// the default one
_ => {
if self.window_init.is_none() {
self.window_init = Some(false);
}
Task::none()
}
}
}
Message::CtrlC
| Message::Event(iced::Event::Window(iced::window::Event::CloseRequested)) => {
for (_, pane) in self.panes.iter_mut() {
@ -250,6 +356,9 @@ impl GUI {
iced::Event::Window(iced::window::Event::CloseRequested),
event::Status::Ignored,
) => Some(Message::Event(event)),
(iced::Event::Window(iced::window::Event::Resized(size)), _) => {
Some(Message::WindowSize(*size))
}
_ => None,
}
})];