[gnome-builder] terminal: dont spawn terminal from realize
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] terminal: dont spawn terminal from realize
- Date: Tue, 22 Feb 2022 21:45:48 +0000 (UTC)
commit 5db405ac812bd4a793b186bff7234e0425e40d2c
Author: Christian Hergert <chergert redhat com>
Date: Tue Feb 22 13:45:35 2022 -0800
terminal: dont spawn terminal from realize
It can cause us to get into difficult issues with re-entrancy if the
widget is removed during realize by the IdeGrid.
src/libide/terminal/ide-terminal-page.c | 44 ++++++++++++++++++++++++---------
1 file changed, 33 insertions(+), 11 deletions(-)
---
diff --git a/src/libide/terminal/ide-terminal-page.c b/src/libide/terminal/ide-terminal-page.c
index 044f73d3f..27d913c32 100644
--- a/src/libide/terminal/ide-terminal-page.c
+++ b/src/libide/terminal/ide-terminal-page.c
@@ -172,19 +172,15 @@ ide_terminal_page_spawn_cb (GObject *object,
IDE_EXIT;
}
-static void
-ide_terminal_page_realize (GtkWidget *widget)
+static gboolean
+ide_terminal_page_do_spawn_in_idle (IdeTerminalPage *self)
{
- IdeTerminalPage *self = (IdeTerminalPage *)widget;
+ IDE_ENTRY;
g_assert (IDE_IS_TERMINAL_PAGE (self));
- GTK_WIDGET_CLASS (ide_terminal_page_parent_class)->realize (widget);
-
- if (self->did_defered_setup_in_realize)
- return;
-
- self->did_defered_setup_in_realize = TRUE;
+ if (self->destroyed)
+ IDE_RETURN (G_SOURCE_REMOVE);
self->last_respawn = g_get_monotonic_time ();
@@ -195,14 +191,14 @@ ide_terminal_page_realize (GtkWidget *widget)
if (!(self->pty = vte_pty_new_sync (VTE_PTY_DEFAULT, NULL, &error)))
{
g_critical ("Failed to create PTY for terminal: %s", error->message);
- return;
+ IDE_RETURN (G_SOURCE_REMOVE);
}
}
vte_terminal_set_pty (VTE_TERMINAL (self->terminal_top), self->pty);
if (!self->manage_spawn)
- return;
+ IDE_RETURN (G_SOURCE_REMOVE);
/* Spawn our terminal and wait for it to exit */
ide_terminal_launcher_spawn_async (self->launcher,
@@ -210,6 +206,32 @@ ide_terminal_page_realize (GtkWidget *widget)
NULL,
ide_terminal_page_spawn_cb,
g_object_ref (self));
+
+ IDE_RETURN (G_SOURCE_REMOVE);
+}
+
+static void
+ide_terminal_page_realize (GtkWidget *widget)
+{
+ IdeTerminalPage *self = (IdeTerminalPage *)widget;
+
+ g_assert (IDE_IS_TERMINAL_PAGE (self));
+
+ GTK_WIDGET_CLASS (ide_terminal_page_parent_class)->realize (widget);
+
+ if (self->did_defered_setup_in_realize)
+ return;
+
+ self->did_defered_setup_in_realize = TRUE;
+
+ /* We don't want to process this in realize as it could be holding things
+ * up from being mapped. Instead, wait until the GDK backend has finished
+ * reacting to realize/etc and then spawn from idle.
+ */
+ g_idle_add_full (G_PRIORITY_LOW,
+ (GSourceFunc)ide_terminal_page_do_spawn_in_idle,
+ g_object_ref (self),
+ g_object_unref);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]