lesavka: stabilize diagnostics scrolling
This commit is contained in:
parent
c6f9001323
commit
c24bef1bf2
@ -4,7 +4,7 @@ path = "src/main.rs"
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.11.23"
|
version = "0.11.24"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -1359,7 +1359,12 @@ pub fn run_gui_launcher(server_addr: String) -> Result<()> {
|
|||||||
let widgets = widgets.clone();
|
let widgets = widgets.clone();
|
||||||
let diagnostics_popout = Rc::clone(&diagnostics_popout);
|
let diagnostics_popout = Rc::clone(&diagnostics_popout);
|
||||||
widgets.diagnostics_popout_button.connect_clicked(move |_| {
|
widgets.diagnostics_popout_button.connect_clicked(move |_| {
|
||||||
open_diagnostics_popout(&app, &diagnostics_popout, &widgets.diagnostics_buffer);
|
open_diagnostics_popout(
|
||||||
|
&app,
|
||||||
|
&diagnostics_popout,
|
||||||
|
&widgets.diagnostics_popout_scroll,
|
||||||
|
&widgets.diagnostics_buffer,
|
||||||
|
);
|
||||||
widgets
|
widgets
|
||||||
.status_label
|
.status_label
|
||||||
.set_text("Diagnostics report moved into its own window.");
|
.set_text("Diagnostics report moved into its own window.");
|
||||||
|
|||||||
@ -54,6 +54,7 @@ pub struct LauncherWidgets {
|
|||||||
pub diagnostics_log: Rc<RefCell<DiagnosticsLog>>,
|
pub diagnostics_log: Rc<RefCell<DiagnosticsLog>>,
|
||||||
pub diagnostics_buffer: gtk::TextBuffer,
|
pub diagnostics_buffer: gtk::TextBuffer,
|
||||||
pub diagnostics_scroll: gtk::ScrolledWindow,
|
pub diagnostics_scroll: gtk::ScrolledWindow,
|
||||||
|
pub diagnostics_popout_scroll: Rc<RefCell<Option<gtk::ScrolledWindow>>>,
|
||||||
pub session_log_buffer: gtk::TextBuffer,
|
pub session_log_buffer: gtk::TextBuffer,
|
||||||
pub session_log_view: gtk::TextView,
|
pub session_log_view: gtk::TextView,
|
||||||
pub summary: SummaryWidgets,
|
pub summary: SummaryWidgets,
|
||||||
@ -620,12 +621,14 @@ pub fn build_launcher_view(
|
|||||||
state.breakout_size_options(1),
|
state.breakout_size_options(1),
|
||||||
state.breakout_size_preset(1),
|
state.breakout_size_preset(1),
|
||||||
);
|
);
|
||||||
|
let diagnostics_popout_scroll = Rc::new(RefCell::new(None));
|
||||||
|
|
||||||
let widgets = LauncherWidgets {
|
let widgets = LauncherWidgets {
|
||||||
status_label: status_label.clone(),
|
status_label: status_label.clone(),
|
||||||
diagnostics_log: diagnostics_log.clone(),
|
diagnostics_log: diagnostics_log.clone(),
|
||||||
diagnostics_buffer: diagnostics_buffer.clone(),
|
diagnostics_buffer: diagnostics_buffer.clone(),
|
||||||
diagnostics_scroll: diagnostics_scroll.clone(),
|
diagnostics_scroll: diagnostics_scroll.clone(),
|
||||||
|
diagnostics_popout_scroll: diagnostics_popout_scroll.clone(),
|
||||||
session_log_buffer: session_log_buffer.clone(),
|
session_log_buffer: session_log_buffer.clone(),
|
||||||
session_log_view: session_log_view.clone(),
|
session_log_view: session_log_view.clone(),
|
||||||
summary: SummaryWidgets {
|
summary: SummaryWidgets {
|
||||||
|
|||||||
@ -948,15 +948,21 @@ pub fn refresh_diagnostics_report(
|
|||||||
child_running: bool,
|
child_running: bool,
|
||||||
) {
|
) {
|
||||||
let diagnostics_adjustment = widgets.diagnostics_scroll.vadjustment();
|
let diagnostics_adjustment = widgets.diagnostics_scroll.vadjustment();
|
||||||
|
let previous_value = diagnostics_adjustment.value();
|
||||||
let previous_max =
|
let previous_max =
|
||||||
(diagnostics_adjustment.upper() - diagnostics_adjustment.page_size()).max(0.0);
|
(diagnostics_adjustment.upper() - diagnostics_adjustment.page_size()).max(0.0);
|
||||||
let was_at_bottom =
|
let was_at_bottom = previous_max <= 0.0 || previous_value >= (previous_max - 4.0);
|
||||||
previous_max <= 0.0 || diagnostics_adjustment.value() >= (previous_max - 4.0);
|
let popout_adjustment = widgets
|
||||||
let previous_ratio = if previous_max > 0.0 {
|
.diagnostics_popout_scroll
|
||||||
(diagnostics_adjustment.value() / previous_max).clamp(0.0, 1.0)
|
.borrow()
|
||||||
} else {
|
.as_ref()
|
||||||
0.0
|
.map(|scroll| scroll.vadjustment());
|
||||||
};
|
let popout_state = popout_adjustment.as_ref().map(|adjustment| {
|
||||||
|
let previous_value = adjustment.value();
|
||||||
|
let previous_max = (adjustment.upper() - adjustment.page_size()).max(0.0);
|
||||||
|
let was_at_bottom = previous_max <= 0.0 || previous_value >= (previous_max - 4.0);
|
||||||
|
(adjustment.clone(), previous_value, was_at_bottom)
|
||||||
|
});
|
||||||
let mut snapshot = SnapshotReport::from_state(
|
let mut snapshot = SnapshotReport::from_state(
|
||||||
state,
|
state,
|
||||||
&widgets.diagnostics_log.borrow(),
|
&widgets.diagnostics_log.borrow(),
|
||||||
@ -976,9 +982,18 @@ pub fn refresh_diagnostics_report(
|
|||||||
let target = if was_at_bottom {
|
let target = if was_at_bottom {
|
||||||
max
|
max
|
||||||
} else {
|
} else {
|
||||||
(previous_ratio * max).clamp(0.0, max)
|
previous_value.min(max)
|
||||||
};
|
};
|
||||||
diagnostics_adjustment.set_value(target);
|
diagnostics_adjustment.set_value(target);
|
||||||
|
if let Some((adjustment, previous_value, was_at_bottom)) = popout_state {
|
||||||
|
let max = (adjustment.upper() - adjustment.page_size()).max(0.0);
|
||||||
|
let target = if was_at_bottom {
|
||||||
|
max
|
||||||
|
} else {
|
||||||
|
previous_value.min(max)
|
||||||
|
};
|
||||||
|
adjustment.set_value(target);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -987,20 +1002,29 @@ pub fn open_session_log_popout(
|
|||||||
handle: &Rc<RefCell<Option<gtk::ApplicationWindow>>>,
|
handle: &Rc<RefCell<Option<gtk::ApplicationWindow>>>,
|
||||||
buffer: >k::TextBuffer,
|
buffer: >k::TextBuffer,
|
||||||
) {
|
) {
|
||||||
open_text_buffer_popout(app, handle, buffer, "Lesavka Log", "Copy Log");
|
open_text_buffer_popout(app, handle, None, buffer, "Lesavka Log", "Copy Log");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_diagnostics_popout(
|
pub fn open_diagnostics_popout(
|
||||||
app: >k::Application,
|
app: >k::Application,
|
||||||
handle: &Rc<RefCell<Option<gtk::ApplicationWindow>>>,
|
handle: &Rc<RefCell<Option<gtk::ApplicationWindow>>>,
|
||||||
|
scroll_handle: &Rc<RefCell<Option<gtk::ScrolledWindow>>>,
|
||||||
buffer: >k::TextBuffer,
|
buffer: >k::TextBuffer,
|
||||||
) {
|
) {
|
||||||
open_text_buffer_popout(app, handle, buffer, "Lesavka Diagnostics", "Copy Report");
|
open_text_buffer_popout(
|
||||||
|
app,
|
||||||
|
handle,
|
||||||
|
Some(scroll_handle),
|
||||||
|
buffer,
|
||||||
|
"Lesavka Diagnostics",
|
||||||
|
"Copy Report",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_text_buffer_popout(
|
fn open_text_buffer_popout(
|
||||||
app: >k::Application,
|
app: >k::Application,
|
||||||
handle: &Rc<RefCell<Option<gtk::ApplicationWindow>>>,
|
handle: &Rc<RefCell<Option<gtk::ApplicationWindow>>>,
|
||||||
|
scroll_handle: Option<&Rc<RefCell<Option<gtk::ScrolledWindow>>>>,
|
||||||
buffer: >k::TextBuffer,
|
buffer: >k::TextBuffer,
|
||||||
title: &str,
|
title: &str,
|
||||||
copy_button_label: &str,
|
copy_button_label: &str,
|
||||||
@ -1041,6 +1065,9 @@ fn open_text_buffer_popout(
|
|||||||
.vexpand(true)
|
.vexpand(true)
|
||||||
.child(&view)
|
.child(&view)
|
||||||
.build();
|
.build();
|
||||||
|
if let Some(scroll_handle) = scroll_handle {
|
||||||
|
*scroll_handle.borrow_mut() = Some(scroll.clone());
|
||||||
|
}
|
||||||
root.append(&scroll);
|
root.append(&scroll);
|
||||||
window.set_child(Some(&root));
|
window.set_child(Some(&root));
|
||||||
window.maximize();
|
window.maximize();
|
||||||
@ -1054,8 +1081,12 @@ fn open_text_buffer_popout(
|
|||||||
|
|
||||||
{
|
{
|
||||||
let handle = Rc::clone(handle);
|
let handle = Rc::clone(handle);
|
||||||
|
let scroll_handle = scroll_handle.cloned();
|
||||||
window.connect_close_request(move |_| {
|
window.connect_close_request(move |_| {
|
||||||
handle.borrow_mut().take();
|
handle.borrow_mut().take();
|
||||||
|
if let Some(scroll_handle) = &scroll_handle {
|
||||||
|
scroll_handle.borrow_mut().take();
|
||||||
|
}
|
||||||
glib::Propagation::Proceed
|
glib::Propagation::Proceed
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1115,6 +1146,7 @@ pub fn shutdown_launcher_runtime(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(window) = diagnostics_popout.borrow_mut().take() {
|
if let Some(window) = diagnostics_popout.borrow_mut().take() {
|
||||||
|
widgets.diagnostics_popout_scroll.borrow_mut().take();
|
||||||
window.set_child(Option::<>k::Widget>::None);
|
window.set_child(Option::<>k::Widget>::None);
|
||||||
window.hide();
|
window.hide();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.11.23"
|
version = "0.11.24"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,6 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn banner_includes_version() {
|
fn banner_includes_version() {
|
||||||
assert_eq!(banner("0.11.23"), "lesavka-common CLI (v0.11.23)");
|
assert_eq!(banner("0.11.24"), "lesavka-common CLI (v0.11.24)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ bench = false
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.11.23"
|
version = "0.11.24"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
autobins = false
|
autobins = false
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user