aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2021-10-13 14:02:32 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2021-10-13 16:32:31 +0300
commit4a59a66d1f7b569313396f0b63127796987f1ca6 (patch)
tree873b63e37b321855e8a37a0888fca3d4ea82e86b /src
parent33a16ae04270647e99dc0741b706061e6468fa3c (diff)
downloadsciteco-4a59a66d1f7b569313396f0b63127796987f1ca6.tar.gz
GTK: fixed teco_view_free() (hopefully)
* The old implementation could apparently result in use-after-free situations that are not related to unstopped watchers in Scintilla. This would result in frequent crashes. Possibly, this only now manifests after upgrading to Scintilla 5. * The old implementation also had the bug that freeing views (e.g. via <EF>) would not release any memory in batch mode since the main loop is not triggered. * I don't pretend to understand why we need gtk_widget_destroy() instead of g_object_unref().
Diffstat (limited to 'src')
-rw-r--r--src/interface-gtk/interface.c27
1 files changed, 7 insertions, 20 deletions
diff --git a/src/interface-gtk/interface.c b/src/interface-gtk/interface.c
index 27c043c..ea9745a 100644
--- a/src/interface-gtk/interface.c
+++ b/src/interface-gtk/interface.c
@@ -146,31 +146,18 @@ teco_view_ssm(teco_view_t *ctx, unsigned int iMessage, uptr_t wParam, sptr_t lPa
return scintilla_send_message(SCINTILLA(ctx), iMessage, wParam, lParam);
}
-static gboolean
-teco_view_free_idle_cb(gpointer user_data)
-{
- /*
- * This does NOT destroy the Scintilla object
- * and GTK widget, if it is the current view
- * (and therefore added to the vbox).
- */
- g_object_unref(user_data);
- return G_SOURCE_REMOVE;
-}
-
void
teco_view_free(teco_view_t *ctx)
{
/*
- * FIXME: The widget is unreffed only in an idle watcher because
- * Scintilla may have idle callbacks activated (see ScintillaGTK.cxx)
- * and we must prevent use-after-frees.
- * A simple g_idle_remove_by_data() does not suffice for some strange reason
- * (perhaps it does not prevent the invocation of already activated watchers).
- * This is a bug should better be fixed by reference counting in
- * ScintillaGTK.cxx itself.
+ * FIXME: It's not entirely clear why g_object_unref() won't do here.
+ * This results in crashes later on because something is still referencing
+ * the widget/GObject.
+ * However, currently displayed views (ctx == teco_interface.current_view_widget)
+ * should have a reference count of 2 and unreffing them should not actually
+ * touch the object until is is removed from the view.
*/
- g_idle_add_full(G_PRIORITY_LOW, teco_view_free_idle_cb, SCINTILLA(ctx), NULL);
+ gtk_widget_destroy(teco_view_get_widget(ctx));
}
static struct {