diff options
Diffstat (limited to 'main')
29 files changed, 125 insertions, 0 deletions
diff --git a/main/meson.build b/main/meson.build index 3f5701bc..b91ddcd9 100644 --- a/main/meson.build +++ b/main/meson.build @@ -79,6 +79,7 @@ sources = files( 'src/ui/util/data_forms.vala', 'src/ui/util/file_metadata_providers.vala', 'src/ui/util/helper.vala', + 'src/ui/util/leak.vala', 'src/ui/util/preference_group.vala', 'src/ui/util/size_request_box.vala', 'src/ui/util/sizing_bin.vala', diff --git a/main/src/ui/call_window/audio_settings_popover.vala b/main/src/ui/call_window/audio_settings_popover.vala index f66c5eee..b00d94c9 100644 --- a/main/src/ui/call_window/audio_settings_popover.vala +++ b/main/src/ui/call_window/audio_settings_popover.vala @@ -13,6 +13,10 @@ public class Dino.Ui.AudioSettingsPopover : Gtk.Popover { private HashMap<ListBoxRow, Plugins.MediaDevice> row_microphone_device = new HashMap<ListBoxRow, Plugins.MediaDevice>(); private HashMap<ListBoxRow, Plugins.MediaDevice> row_speaker_device = new HashMap<ListBoxRow, Plugins.MediaDevice>(); + construct { + check_widget_leak(this); + } + public AudioSettingsPopover() { Box box = new Box(Orientation.VERTICAL, 15); box.append(create_microphone_box()); diff --git a/main/src/ui/call_window/call_bottom_bar.vala b/main/src/ui/call_window/call_bottom_bar.vala index 515fdb38..dcb869c7 100644 --- a/main/src/ui/call_window/call_bottom_bar.vala +++ b/main/src/ui/call_window/call_bottom_bar.vala @@ -26,6 +26,10 @@ public class Dino.Ui.CallBottomBar : Gtk.Box { private Label label = new Label("") { halign=Align.CENTER, valign=Align.CENTER, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true }; private Stack stack = new Stack(); + construct { + check_widget_leak(this); + } + public CallBottomBar() { Object(orientation:Orientation.HORIZONTAL, spacing:0); diff --git a/main/src/ui/call_window/call_connection_details_window.vala b/main/src/ui/call_window/call_connection_details_window.vala index 9e9e1b3a..578d95ed 100644 --- a/main/src/ui/call_window/call_connection_details_window.vala +++ b/main/src/ui/call_window/call_connection_details_window.vala @@ -10,6 +10,10 @@ namespace Dino.Ui { private CallContentDetails audio_details = new CallContentDetails("Audio"); private CallContentDetails video_details = new CallContentDetails("Video"); + construct { + check_widget_leak(this); + } + public CallConnectionDetailsWindow() { box.append(audio_details); box.append(video_details); @@ -52,6 +56,10 @@ namespace Dino.Ui { private PeerContentInfo? prev_info = null; private int row_at = 0; + construct { + check_widget_leak(this); + } + public CallContentDetails(string headline) { attach(new Label("<b>%s</b>".printf(headline)) { use_markup=true, xalign=0 }, 0, row_at++, 1, 1); attach(rtp_title, 0, row_at, 1, 1); diff --git a/main/src/ui/call_window/call_window.vala b/main/src/ui/call_window/call_window.vala index 54e290a7..4a804755 100644 --- a/main/src/ui/call_window/call_window.vala +++ b/main/src/ui/call_window/call_window.vala @@ -52,6 +52,8 @@ namespace Dino.Ui { overlay.get_child_position.connect(on_get_child_position); set_child(overlay); + + check_widget_leak(this); } public CallWindow() { diff --git a/main/src/ui/call_window/participant_widget.vala b/main/src/ui/call_window/participant_widget.vala index 045040df..fbcd9eab 100644 --- a/main/src/ui/call_window/participant_widget.vala +++ b/main/src/ui/call_window/participant_widget.vala @@ -34,6 +34,10 @@ namespace Dino.Ui { install_action("menu.debuginfo", null, (widget, action_name) => { ((ParticipantWidget) widget).debug_information_clicked(); }); } + construct { + check_widget_leak(this); + } + public ParticipantWidget(string participant_name) { encryption_button_controller = new CallEncryptionButtonController(encryption_button); diff --git a/main/src/ui/call_window/video_settings_popover.vala b/main/src/ui/call_window/video_settings_popover.vala index 58967bd2..26728d0c 100644 --- a/main/src/ui/call_window/video_settings_popover.vala +++ b/main/src/ui/call_window/video_settings_popover.vala @@ -10,6 +10,10 @@ public class Dino.Ui.VideoSettingsPopover : Gtk.Popover { private HashMap<ListBoxRow, Plugins.MediaDevice> row_device = new HashMap<ListBoxRow, Plugins.MediaDevice>(); + construct { + check_widget_leak(this); + } + public VideoSettingsPopover() { Box box = new Box(Orientation.VERTICAL, 15); box.append(create_camera_box()); diff --git a/main/src/ui/conversation_content_view/call_widget.vala b/main/src/ui/conversation_content_view/call_widget.vala index 3d6b250b..9e8a5dac 100644 --- a/main/src/ui/conversation_content_view/call_widget.vala +++ b/main/src/ui/conversation_content_view/call_widget.vala @@ -50,6 +50,7 @@ namespace Dino.Ui { construct { margin_top = 4; size_request_mode = SizeRequestMode.HEIGHT_FOR_WIDTH; + check_widget_leak(this); } /** @param call_state Null if it's an old call and we can't interact with it anymore */ diff --git a/main/src/ui/conversation_content_view/file_default_widget.vala b/main/src/ui/conversation_content_view/file_default_widget.vala index b731c9df..f211e3fe 100644 --- a/main/src/ui/conversation_content_view/file_default_widget.vala +++ b/main/src/ui/conversation_content_view/file_default_widget.vala @@ -20,6 +20,10 @@ public class FileDefaultWidget : Box { private FileTransfer.State state; + construct { + check_widget_leak(this); + } + public void init_updating_file_info() { EventControllerMotion this_motion_events = new EventControllerMotion(); this.add_controller(this_motion_events); diff --git a/main/src/ui/conversation_content_view/file_image_widget.vala b/main/src/ui/conversation_content_view/file_image_widget.vala index 2015d9dc..e936ca25 100644 --- a/main/src/ui/conversation_content_view/file_image_widget.vala +++ b/main/src/ui/conversation_content_view/file_image_widget.vala @@ -28,6 +28,7 @@ public class FileImageWidget : Widget { construct { layout_manager = new BinLayout(); + check_widget_leak(this); } public FileImageWidget(int MAX_WIDTH=600, int MAX_HEIGHT=300) { diff --git a/main/src/ui/conversation_content_view/file_transmission_progress.vala b/main/src/ui/conversation_content_view/file_transmission_progress.vala index 92833ea9..e3f33448 100644 --- a/main/src/ui/conversation_content_view/file_transmission_progress.vala +++ b/main/src/ui/conversation_content_view/file_transmission_progress.vala @@ -41,6 +41,8 @@ namespace Dino.Ui { on_state_changed(); setup_animation(); + + check_widget_leak(this); } private void setup_animation() { diff --git a/main/src/ui/conversation_content_view/file_widget.vala b/main/src/ui/conversation_content_view/file_widget.vala index 45972e1c..ecc2d3e9 100644 --- a/main/src/ui/conversation_content_view/file_widget.vala +++ b/main/src/ui/conversation_content_view/file_widget.vala @@ -72,6 +72,7 @@ public class FileWidget : SizeRequestBin { construct { margin_top = 4; size_request_mode = SizeRequestMode.HEIGHT_FOR_WIDTH; + check_widget_leak(this); } public FileWidget(FileTransfer file_transfer) { diff --git a/main/src/ui/conversation_content_view/message_widget.vala b/main/src/ui/conversation_content_view/message_widget.vala index cead6332..7d441657 100644 --- a/main/src/ui/conversation_content_view/message_widget.vala +++ b/main/src/ui/conversation_content_view/message_widget.vala @@ -351,6 +351,8 @@ public class MessageItemEditMode : Box { send_button.clicked.connect(() => send()); chat_text_view.cancel_input.connect(() => cancelled()); chat_text_view.send_text.connect(() => send()); + + check_widget_leak(this); } private void on_text_view_changed() { diff --git a/main/src/ui/conversation_content_view/quote_widget.vala b/main/src/ui/conversation_content_view/quote_widget.vala index aedce687..ce0011e1 100644 --- a/main/src/ui/conversation_content_view/quote_widget.vala +++ b/main/src/ui/conversation_content_view/quote_widget.vala @@ -83,6 +83,7 @@ namespace Dino.Ui.Quote { }); Widget outer = builder.get_object("outer") as Widget; + check_widget_leak(outer); GestureClick gesture_click_controller = new GestureClick(); outer.add_controller(gesture_click_controller); diff --git a/main/src/ui/conversation_content_view/reactions_widget.vala b/main/src/ui/conversation_content_view/reactions_widget.vala index fe465676..04d71256 100644 --- a/main/src/ui/conversation_content_view/reactions_widget.vala +++ b/main/src/ui/conversation_content_view/reactions_widget.vala @@ -120,12 +120,17 @@ public class ReactionsWidget : Grid { private HashMap<string, Button> reaction_buttons = new HashMap<string, Button>(); private MenuButton add_button; + construct { + check_widget_leak(this); + } + public ReactionsWidget() { this.row_spacing = this.column_spacing = 5; this.margin_top = 2; this.add_css_class("reaction-grid"); add_button = new MenuButton() { tooltip_text= _("Add reaction") }; + check_widget_leak(add_button); add_button.add_css_class("pill"); Util.menu_button_set_icon_with_size(add_button, "dino-emoticon-add-symbolic", 14); @@ -141,6 +146,7 @@ public class ReactionsWidget : Grid { Label reaction_label = new Label("<span size='small'>" + reaction + "</span>") { use_markup=true }; Label count_label = new Label("") { use_markup=true }; Button button = new Button(); + check_widget_leak(button); button.add_css_class("pill"); Box reaction_box = new Box(Orientation.HORIZONTAL, 4) { halign=Align.CENTER }; reaction_box.append(reaction_label); diff --git a/main/src/ui/conversation_content_view/unread_indicator_populator.vala b/main/src/ui/conversation_content_view/unread_indicator_populator.vala index 79aa7576..f52408ba 100644 --- a/main/src/ui/conversation_content_view/unread_indicator_populator.vala +++ b/main/src/ui/conversation_content_view/unread_indicator_populator.vala @@ -68,6 +68,7 @@ namespace Dino.Ui.ConversationSummary { public override Object? get_widget(Plugins.ConversationItemWidgetInterface outer, Plugins.WidgetType type) { Box box = new Box(Orientation.HORIZONTAL, 10) { hexpand=true }; + check_widget_leak(box); box.get_style_context().add_class("dino-unread-line"); Separator sep = new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true }; diff --git a/main/src/ui/conversation_selector/conversation_selector.vala b/main/src/ui/conversation_selector/conversation_selector.vala index 3b3caf5a..5d88c540 100644 --- a/main/src/ui/conversation_selector/conversation_selector.vala +++ b/main/src/ui/conversation_selector/conversation_selector.vala @@ -48,6 +48,8 @@ public class ConversationSelector : Widget { }); list_box.row_activated.connect(row_activated); + + check_widget_leak(this); } public void row_activated(ListBoxRow r) { diff --git a/main/src/ui/conversation_selector/conversation_selector_row.vala b/main/src/ui/conversation_selector/conversation_selector_row.vala index 566406f9..38132c5b 100644 --- a/main/src/ui/conversation_selector/conversation_selector_row.vala +++ b/main/src/ui/conversation_selector/conversation_selector_row.vala @@ -33,6 +33,7 @@ public class ConversationSelectorRow : ListBoxRow { construct { name_label.attributes = new AttrList(); + check_widget_leak(this); } public ConversationSelectorRow(StreamInteractor stream_interactor, Conversation conversation) { diff --git a/main/src/ui/file_send_overlay.vala b/main/src/ui/file_send_overlay.vala index 0067e09d..907cea00 100644 --- a/main/src/ui/file_send_overlay.vala +++ b/main/src/ui/file_send_overlay.vala @@ -18,6 +18,10 @@ public class FileSendOverlay : Adw.Dialog { private File file; private bool can_send = true; + construct { + check_widget_leak(this); + } + public FileSendOverlay(File file, FileInfo file_info) { this.file = file; load_file_widget.begin(file, file_info); diff --git a/main/src/ui/occupant_menu/list.vala b/main/src/ui/occupant_menu/list.vala index ce5a1981..6f303ab2 100644 --- a/main/src/ui/occupant_menu/list.vala +++ b/main/src/ui/occupant_menu/list.vala @@ -20,6 +20,10 @@ public class List : Box { private HashMap<Jid, Widget> rows = new HashMap<Jid, Widget>(Jid.hash_func, Jid.equals_func); public HashMap<Widget, ListRow> row_wrappers = new HashMap<Widget, ListRow>(); + construct { + check_widget_leak(this); + } + public List(StreamInteractor stream_interactor, Conversation conversation) { this.stream_interactor = stream_interactor; list_box.set_header_func(header); diff --git a/main/src/ui/occupant_menu/view.vala b/main/src/ui/occupant_menu/view.vala index 08e1e9ed..4196e452 100644 --- a/main/src/ui/occupant_menu/view.vala +++ b/main/src/ui/occupant_menu/view.vala @@ -18,6 +18,10 @@ public class View : Popover { private Jid? selected_jid; + construct { + check_widget_leak(this); + } + public View(StreamInteractor stream_interactor, Conversation conversation) { this.stream_interactor = stream_interactor; this.conversation = conversation; diff --git a/main/src/ui/util/leak.vala b/main/src/ui/util/leak.vala new file mode 100644 index 00000000..07eb1e46 --- /dev/null +++ b/main/src/ui/util/leak.vala @@ -0,0 +1,48 @@ +namespace Dino { + private const string CHECK_WIDGET_LEAK_ID = "dino_check_widget_leak_id"; + private const string CHECK_WIDGET_LEAK_NAME = "dino_check_widget_leak_name"; + private const string CHECK_WIDGET_LEAK_ACTIVE = "dino_check_widget_leak_active"; + private static void check_widget_leak_timeout_reached(Gtk.Widget widget) { + string name = widget.get_data(CHECK_WIDGET_LEAK_NAME) ?? widget.get_type().name(); + warning("%s likely leaked", name); + widget.set_data(CHECK_WIDGET_LEAK_ID, 0); + } + private static void check_widget_leak_disposed(Object widget) { + uint timeout_id = widget.get_data(CHECK_WIDGET_LEAK_ID); + if (timeout_id != 0) Source.remove(timeout_id); + widget.set_data(CHECK_WIDGET_LEAK_ID, 0); + } + private static void check_widget_leak_unrealized(Gtk.Widget widget) { + widget.set_data(CHECK_WIDGET_LEAK_ID, WeakTimeout.add_seconds_once(1, widget, check_widget_leak_timeout_reached)); + widget.weak_ref(check_widget_leak_disposed); + } + private static void check_widget_leak_realized(Gtk.Widget widget) { + uint timeout_id = widget.get_data(CHECK_WIDGET_LEAK_ID); + if (timeout_id != 0) Source.remove(timeout_id); + widget.set_data(CHECK_WIDGET_LEAK_ID, 0); + string name = widget.get_type().name(); + Gtk.Widget parent = widget.parent; + while (parent != null) { + name = parent.get_type().name() + " > " + name; + if (name.has_prefix("Dino")) break; + parent = parent.parent; + } + widget.set_data(CHECK_WIDGET_LEAK_NAME, name); + } + public static Gtk.Widget check_widget_leak(Gtk.Widget widget) { + if (is_leak_check_enabled() && !widget.get_data<bool>(CHECK_WIDGET_LEAK_ACTIVE)) { + widget.set_data(CHECK_WIDGET_LEAK_ACTIVE, true); + widget.set_data(CHECK_WIDGET_LEAK_ID, 0); + widget.realize.connect(check_widget_leak_realized); + widget.unrealize.connect(check_widget_leak_unrealized); + if (widget.get_realized()) { + check_widget_leak_realized(widget); + } + } + return widget; + } + + public static bool is_leak_check_enabled() { + return Environment.get_variable("DINO_CHECK_LEAK") == "1"; + } +}
\ No newline at end of file diff --git a/main/src/ui/util/size_request_box.vala b/main/src/ui/util/size_request_box.vala index 98f1a20a..f479e14e 100644 --- a/main/src/ui/util/size_request_box.vala +++ b/main/src/ui/util/size_request_box.vala @@ -2,6 +2,10 @@ using Gtk; namespace Dino.Ui { public class SizeRequestBox : Box { + construct { + check_widget_leak(this); + } + public SizeRequestMode size_request_mode { get; set; default = SizeRequestMode.CONSTANT_SIZE; } public override Gtk.SizeRequestMode get_request_mode() { @@ -14,6 +18,7 @@ public class SizeRequestBin : Widget { construct { this.layout_manager = new BinLayout(); + check_widget_leak(this); } public override void compute_expand_internal(out bool hexpand, out bool vexpand) { diff --git a/main/src/ui/util/sizing_bin.vala b/main/src/ui/util/sizing_bin.vala index 7401ddbf..0f5b9035 100644 --- a/main/src/ui/util/sizing_bin.vala +++ b/main/src/ui/util/sizing_bin.vala @@ -9,6 +9,10 @@ public class SizingBin : Widget { public int target_height { get; set; default = -1; } public int max_height { get; set; default = -1; } + construct { + check_widget_leak(this); + } + public override void compute_expand_internal(out bool hexpand, out bool vexpand) { hexpand = false; vexpand = false; diff --git a/main/src/ui/widgets/avatar_picture.vala b/main/src/ui/widgets/avatar_picture.vala index ef1462ae..6765364c 100644 --- a/main/src/ui/widgets/avatar_picture.vala +++ b/main/src/ui/widgets/avatar_picture.vala @@ -345,6 +345,7 @@ public class Dino.Ui.AvatarPicture : Gtk.Widget { add_css_class("avatar"); notify["radius-percent"].connect(queue_draw); notify["model"].connect(on_model_changed); + check_widget_leak(this); } private void on_model_changed() { @@ -461,6 +462,7 @@ public class Dino.Ui.AvatarPicture : Gtk.Widget { #endif picture.insert_after(this, label); this.notify["model"].connect(on_model_changed); + check_widget_leak(this); } private void on_model_changed() { diff --git a/main/src/ui/widgets/date_separator.vala b/main/src/ui/widgets/date_separator.vala index 589bc9a6..716e7fec 100644 --- a/main/src/ui/widgets/date_separator.vala +++ b/main/src/ui/widgets/date_separator.vala @@ -87,6 +87,7 @@ public class Dino.Ui.DateSeparator : Gtk.Widget { clamp.insert_after(this, null); notify["model"].connect(on_model_changed); + check_widget_leak(this); } private void on_model_changed() { diff --git a/main/src/ui/widgets/fixed_ratio_picture.vala b/main/src/ui/widgets/fixed_ratio_picture.vala index db0e0afe..6b04ea61 100644 --- a/main/src/ui/widgets/fixed_ratio_picture.vala +++ b/main/src/ui/widgets/fixed_ratio_picture.vala @@ -18,6 +18,7 @@ class Dino.Ui.FixedRatioPicture : Gtk.Widget { add_css_class("fixed-ratio"); inner.insert_after(this, null); this.notify.connect(queue_resize); + check_widget_leak(this); } private void measure_target_size(out int width, out int height) { diff --git a/main/src/ui/widgets/natural_size_increase.vala b/main/src/ui/widgets/natural_size_increase.vala index 3aad486a..d786e2b5 100644 --- a/main/src/ui/widgets/natural_size_increase.vala +++ b/main/src/ui/widgets/natural_size_increase.vala @@ -6,6 +6,7 @@ public class Dino.Ui.NaturalSizeIncrease : Gtk.Widget { construct { this.notify.connect(queue_resize); + check_widget_leak(this); } public override void compute_expand_internal(out bool hexpand, out bool vexpand) { diff --git a/main/src/windows/conversation_details.vala b/main/src/windows/conversation_details.vala index a8d0e430..e1f3061f 100644 --- a/main/src/windows/conversation_details.vala +++ b/main/src/windows/conversation_details.vala @@ -86,6 +86,8 @@ namespace Dino.Ui.ConversationDetails { notification_button_menu_content.can_shrink = true; update_blocked_button(); + + check_widget_leak(this); } private void update_pinned_button() { |
