mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2026-08-17 16:34:54 -05:00
fix: memory leaks in multiple dialogs due to reference cycles (#855)
This commit is contained in:
@@ -9,7 +9,8 @@ use gtk::{
|
||||
gdk,
|
||||
glib::{subclass::types::ObjectSubclassIsExt, types::StaticType, value::ToValue},
|
||||
prelude::{
|
||||
AdjustmentExt, BoxExt, ButtonExt, CheckButtonExt, OrientableExt, PopoverExt, WidgetExt,
|
||||
AdjustmentExt, BoxExt, ButtonExt, CheckButtonExt, ObjectExt, OrientableExt, PopoverExt,
|
||||
WidgetExt,
|
||||
},
|
||||
};
|
||||
use i18n_embed_fl::fl;
|
||||
@@ -108,17 +109,23 @@ impl relm4::factory::FactoryComponent for PlotComponent {
|
||||
set_actions: gdk::DragAction::MOVE,
|
||||
set_types: &[DynamicIndexValue::static_type()],
|
||||
|
||||
connect_enter[root] => move |_, _, _| {
|
||||
root.set_opacity(0.5);
|
||||
connect_enter[root = root.downgrade()] => move |_, _, _| {
|
||||
if let Some(root) = root.upgrade() {
|
||||
root.set_opacity(0.5);
|
||||
}
|
||||
gdk::DragAction::MOVE
|
||||
},
|
||||
|
||||
connect_leave[root] => move |_| {
|
||||
root.set_opacity(1.0);
|
||||
connect_leave[root = root.downgrade()] => move |_| {
|
||||
if let Some(root) = root.upgrade() {
|
||||
root.set_opacity(1.0);
|
||||
}
|
||||
},
|
||||
|
||||
connect_drop[root, index, sender] => move |_, value, _, _| {
|
||||
root.set_opacity(1.0);
|
||||
connect_drop[root = root.downgrade(), index, sender] => move |_, value, _, _| {
|
||||
if let Some(root) = root.upgrade() {
|
||||
root.set_opacity(1.0);
|
||||
}
|
||||
|
||||
if let Ok(DynamicIndexValue(source_index)) = value.get::<DynamicIndexValue>() {
|
||||
sender.output(GraphsWindowMsg::SwapPlots(index.clone(), source_index)).unwrap();
|
||||
|
||||
@@ -22,8 +22,7 @@ use relm4::{
|
||||
factory::FactoryVecDeque,
|
||||
prelude::DynamicIndex,
|
||||
typed_view::list::{RelmListItem, TypedListView},
|
||||
Component, ComponentController, ComponentParts, ComponentSender, RelmIterChildrenExt,
|
||||
RelmWidgetExt,
|
||||
Component, ComponentParts, ComponentSender, RelmIterChildrenExt, RelmWidgetExt,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use tracing::debug;
|
||||
@@ -35,6 +34,8 @@ pub struct Header {
|
||||
selector_label: String,
|
||||
system_info: SystemInfo,
|
||||
device_flags: Vec<DeviceFlag>,
|
||||
|
||||
new_profile_diag: Option<relm4::Controller<NewProfileDialog>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -302,6 +303,7 @@ impl Component for Header {
|
||||
profiles_info: ProfilesInfo::default(),
|
||||
system_info,
|
||||
device_flags: Vec::new(),
|
||||
new_profile_diag: None,
|
||||
};
|
||||
|
||||
let gpu_selector = &model.gpu_selector.view;
|
||||
@@ -395,12 +397,13 @@ impl Component for Header {
|
||||
HeaderMsg::CreateProfile => {
|
||||
sender.input(HeaderMsg::ClosePopover);
|
||||
|
||||
let mut diag_controller = NewProfileDialog::builder()
|
||||
let diag_controller = NewProfileDialog::builder()
|
||||
.launch(self.custom_profiles())
|
||||
.forward(sender.output_sender(), |(name, base)| {
|
||||
AppMsg::CreateProfile(name, base)
|
||||
});
|
||||
diag_controller.detach_runtime();
|
||||
|
||||
self.new_profile_diag = Some(diag_controller);
|
||||
}
|
||||
HeaderMsg::RenameProfile(index) => {
|
||||
sender.input(HeaderMsg::ClosePopover);
|
||||
|
||||
@@ -67,8 +67,10 @@ impl Component for NewProfileDialog {
|
||||
set_label: &fl!(I18N, "cancel"),
|
||||
set_hexpand: true,
|
||||
|
||||
connect_clicked[root] => move |_| {
|
||||
root.hide();
|
||||
connect_clicked[root = root.downgrade()] => move |_| {
|
||||
if let Some(root) = root.upgrade() {
|
||||
root.close();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -122,7 +124,7 @@ impl Component for NewProfileDialog {
|
||||
.output((self.name_buffer.text().to_string(), base))
|
||||
.unwrap();
|
||||
|
||||
root.hide();
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ pub mod profile_row;
|
||||
|
||||
use crate::app::{msg::AppMsg, APP_BROKER};
|
||||
use crate::I18N;
|
||||
use gtk::prelude::ObjectExt;
|
||||
use gtk::{
|
||||
pango,
|
||||
prelude::{
|
||||
@@ -64,14 +65,16 @@ impl relm4::Component for ProfileRuleWindow {
|
||||
set_default_size: (600, 300),
|
||||
set_title: Some(&fl!(I18N, "profile-rules")),
|
||||
set_transient_for: Some(&root_window),
|
||||
connect_response[root, sender] => move |_, response| {
|
||||
match response {
|
||||
gtk::ResponseType::Accept => {
|
||||
sender.input(ProfileRuleWindowMsg::Save);
|
||||
root.close();
|
||||
connect_response[root = root.downgrade(), sender] => move |_, response| {
|
||||
if let Some(root) = root.upgrade() {
|
||||
match response {
|
||||
gtk::ResponseType::Accept => {
|
||||
sender.input(ProfileRuleWindowMsg::Save);
|
||||
root.close();
|
||||
}
|
||||
gtk::ResponseType::Cancel => root.close(),
|
||||
_ => (),
|
||||
}
|
||||
gtk::ResponseType::Cancel => root.close(),
|
||||
_ => (),
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ pub struct SoftwarePage {
|
||||
|
||||
vulkan_driver_selector: relm4::Controller<SimpleComboBox<String>>,
|
||||
opencl_platform_selector: relm4::Controller<SimpleComboBox<String>>,
|
||||
|
||||
vulkan_window: Option<relm4::Controller<VulkanFeaturesWindow>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -250,6 +252,7 @@ impl relm4::SimpleComponent for SoftwarePage {
|
||||
device_info: None,
|
||||
vulkan_driver_selector,
|
||||
opencl_platform_selector,
|
||||
vulkan_window: None,
|
||||
};
|
||||
|
||||
let mut daemon_version = format!("{}-{}", system_info.version, system_info.profile);
|
||||
@@ -329,12 +332,18 @@ impl relm4::SimpleComponent for SoftwarePage {
|
||||
}
|
||||
SoftwarePageMsg::ShowVulkanFeatures => {
|
||||
if let Some(vulkan_info) = &self.selected_vulkan_info() {
|
||||
show_features_window("Vulkan Features", &vulkan_info.features);
|
||||
self.vulkan_window = Some(show_features_window(
|
||||
"Vulkan Features",
|
||||
&vulkan_info.features,
|
||||
));
|
||||
}
|
||||
}
|
||||
SoftwarePageMsg::ShowVulkanExtensions => {
|
||||
if let Some(vulkan_info) = self.selected_vulkan_info() {
|
||||
show_features_window("Vulkan Extensions", &vulkan_info.extensions);
|
||||
self.vulkan_window = Some(show_features_window(
|
||||
"Vulkan Extensions",
|
||||
&vulkan_info.extensions,
|
||||
));
|
||||
}
|
||||
}
|
||||
SoftwarePageMsg::SelectionChanged => (),
|
||||
@@ -366,7 +375,10 @@ impl SoftwarePage {
|
||||
}
|
||||
}
|
||||
|
||||
fn show_features_window(title: &str, values: &IndexMap<String, bool>) {
|
||||
fn show_features_window(
|
||||
title: &str,
|
||||
values: &IndexMap<String, bool>,
|
||||
) -> relm4::Controller<VulkanFeaturesWindow> {
|
||||
let values = values
|
||||
.into_iter()
|
||||
.map(|(name, &supported)| VulkanFeature {
|
||||
@@ -375,9 +387,9 @@ fn show_features_window(title: &str, values: &IndexMap<String, bool>) {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut window_controller = VulkanFeaturesWindow::builder()
|
||||
let window_controller = VulkanFeaturesWindow::builder()
|
||||
.launch((values, title.to_owned()))
|
||||
.detach();
|
||||
window_controller.detach_runtime();
|
||||
window_controller.widget().present();
|
||||
window_controller
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use gtk::{
|
||||
glib::GString,
|
||||
prelude::{EditableExt, GtkWindowExt, OrientableExt, WidgetExt},
|
||||
prelude::{EditableExt, GtkWindowExt, ObjectExt, OrientableExt, WidgetExt},
|
||||
NoSelection,
|
||||
};
|
||||
use relm4::{
|
||||
@@ -39,8 +39,10 @@ impl SimpleComponent for VulkanFeaturesWindow {
|
||||
sender.input(AppMsg::FilterChanged(entry.text()));
|
||||
},
|
||||
|
||||
connect_stop_search[root] => move |_| {
|
||||
root.close();
|
||||
connect_stop_search[root = root.downgrade()] => move |_| {
|
||||
if let Some(root) = root.upgrade() {
|
||||
root.close();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user