fix: make scrolled_window always scrolled to the end

This commit is contained in:
MeexReay 2025-09-02 20:15:15 +03:00
parent d929a7d8dd
commit eb1c585ecb
4 changed files with 85 additions and 0 deletions

View File

@ -46,6 +46,7 @@ use super::{
mod preferences;
mod page;
mod widgets;
use page::*;
use preferences::*;

View File

@ -35,6 +35,7 @@ use crate::chat::{
on_send_message, parse_message, SERVER_LIST,
};
use super::widgets::CustomLayout;
use super::{add_chat_messages, get_avatar_id, get_message_sign, load_pixbuf, send_notification, try_save_config, update_window_title, UiModel};
pub fn get_message_box(
@ -359,6 +360,21 @@ pub fn build_page_box(ctx: Arc<Context>, app: &Application) -> (GtkBox, GtkBox,
.propagate_natural_height(true)
.build();
let layout = CustomLayout::default();
layout.connect_local("size-changed", false, {
let chat_scrolled = chat_scrolled.downgrade();
move |_| {
if let Some(chat_scrolled) = chat_scrolled.upgrade() {
let value = chat_scrolled.vadjustment().upper() - chat_scrolled.vadjustment().page_size();
chat_scrolled.vadjustment().set_value(value);
}
return None;
}
});
page_box.set_layout_manager(Some(layout));
timeout_add_local_once(Duration::ZERO, clone!(
#[weak] chat_scrolled,
move || {

View File

@ -0,0 +1,53 @@
use libadwaita::{glib, gtk};
use glib::object::ObjectExt;
use gtk::{subclass::prelude::*, prelude::LayoutManagerExt, BoxLayout};
#[derive(Debug)]
pub struct CustomLayout {
box_layout: BoxLayout
}
impl Default for CustomLayout {
fn default() -> Self {
CustomLayout {
box_layout: BoxLayout::builder()
.orientation(gtk::Orientation::Vertical)
.spacing(5)
.build()
}
}
}
#[glib::object_subclass]
impl ObjectSubclass for CustomLayout {
const NAME: &'static str = "CustomLayout";
type Type = super::CustomLayout;
type ParentType = gtk::LayoutManager;
}
impl ObjectImpl for CustomLayout {
fn signals() -> &'static [glib::subclass::Signal] {
use std::sync::OnceLock;
static SIGNALS: OnceLock<Vec<glib::subclass::Signal>> = OnceLock::new();
SIGNALS.get_or_init(|| {
vec![glib::subclass::Signal::builder("size-changed").build()]
})
}
}
impl LayoutManagerImpl for CustomLayout {
fn allocate(&self, widget: &gtk::Widget, width: i32, height: i32, baseline: i32) {
self.obj().emit_by_name::<()>("size-changed", &[]);
self.box_layout.allocate(widget, width, height, baseline)
}
fn measure(
&self,
widget: &gtk::Widget,
orientation: gtk::Orientation,
for_size: i32,
) -> (i32, i32, i32, i32) {
self.box_layout.measure(widget, orientation, for_size)
}
}

View File

@ -0,0 +1,15 @@
mod imp;
use libadwaita::gtk::glib;
use libadwaita::gtk;
glib::wrapper! {
pub struct CustomLayout(ObjectSubclass<imp::CustomLayout>)
@extends gtk::LayoutManager;
}
impl Default for CustomLayout {
fn default() -> Self {
glib::Object::new()
}
}