From b74ecec127137116ed3ed2bcb8b40268abc438b4 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Sat, 11 Oct 2014 15:21:59 +0200 Subject: GTK: Don't create widgets in the ::realize handler Creating a widget may lead to a ::hierarchy-changed signal to be emitted, which itself may lead a tooltip window to be unrealized. This is problematic because it can lead to the ::unrealize handler to be called during the ::realize handler, breaking most of the logic there assuming the widget was properly realized. This fixes adding a Scintilla widget inside a GTK2 tooltip. GTK3 didn't seem to be affected. Also properly destroy the preedit popup window with the widget. --- gtk/ScintillaGTK.cxx | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index 0c45843ec..bc3d00952 100644 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -425,6 +425,7 @@ ScintillaGTK::~ScintillaGTK() { gdk_event_free(reinterpret_cast(evbtn)); evbtn = 0; } + wPreedit.Destroy(); } static void UnRefCursor(GdkCursor *cursor) { @@ -483,20 +484,8 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { gdk_window_show(widget->window); UnRefCursor(cursor); #endif - wPreedit = gtk_window_new(GTK_WINDOW_POPUP); - wPreeditDraw = gtk_drawing_area_new(); - GtkWidget *predrw = PWidget(wPreeditDraw); // No code inside the G_OBJECT macro -#if GTK_CHECK_VERSION(3,0,0) - g_signal_connect(G_OBJECT(predrw), "draw", - G_CALLBACK(DrawPreedit), this); -#else - g_signal_connect(G_OBJECT(predrw), "expose_event", - G_CALLBACK(ExposePreedit), this); -#endif - gtk_container_add(GTK_CONTAINER(PWidget(wPreedit)), predrw); gtk_widget_realize(PWidget(wPreedit)); - gtk_widget_realize(predrw); - gtk_widget_show(predrw); + gtk_widget_realize(PWidget(wPreeditDraw)); im_context = gtk_im_multicontext_new(); g_signal_connect(G_OBJECT(im_context), "commit", @@ -844,6 +833,20 @@ void ScintillaGTK::Initialise() { GTK_DEST_DEFAULT_ALL, clipboardPasteTargets, nClipboardPasteTargets, static_cast(GDK_ACTION_COPY | GDK_ACTION_MOVE)); + /* create pre-edit window */ + wPreedit = gtk_window_new(GTK_WINDOW_POPUP); + wPreeditDraw = gtk_drawing_area_new(); + GtkWidget *predrw = PWidget(wPreeditDraw); // No code inside the G_OBJECT macro +#if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(predrw), "draw", + G_CALLBACK(DrawPreedit), this); +#else + g_signal_connect(G_OBJECT(predrw), "expose_event", + G_CALLBACK(ExposePreedit), this); +#endif + gtk_container_add(GTK_CONTAINER(PWidget(wPreedit)), predrw); + gtk_widget_show(predrw); + // Set caret period based on GTK settings gboolean blinkOn = false; if (g_object_class_find_property(G_OBJECT_GET_CLASS( -- cgit v1.2.3