aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorColomban Wendling <ban@herbesfolles.org>2014-10-11 15:21:59 +0200
committerColomban Wendling <ban@herbesfolles.org>2014-10-11 15:21:59 +0200
commit79c82eb3c119c6080302e579d27af8417898d160 (patch)
treec02189c11d6013105a279a315ebd74623f7839e5
parenta8ecdec099ea9a31d9d91cc6ef22bc7deada49fe (diff)
downloadscintilla-mirror-79c82eb3c119c6080302e579d27af8417898d160.tar.gz
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.
-rw-r--r--gtk/ScintillaGTK.cxx29
1 files 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<GdkEvent *>(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<GdkDragAction>(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(