diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index f5d03415ca..ed7b8041a9 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -375,6 +375,7 @@ protected: virtual void DoFreeze(); virtual void DoThaw(); + void GTKConnectFreezeWidget(GtkWidget* widget); void GTKFreezeWidget(GtkWidget *w); void GTKThawWidget(GtkWidget *w); void GTKDisconnect(void* instance); diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 8c5cbbb78f..5f4f134da5 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -695,6 +695,7 @@ bool wxTextCtrl::Create( wxWindow *parent, gulong sig_id = g_signal_connect(m_buffer, "mark_set", G_CALLBACK(mark_set), &m_anonymousMarkList); // Create view m_text = gtk_text_view_new_with_buffer(m_buffer); + GTKConnectFreezeWidget(m_text); // gtk_text_view_set_buffer adds its own reference g_object_unref(m_buffer); g_signal_handler_disconnect(m_buffer, sig_id); @@ -1968,6 +1969,8 @@ void wxTextCtrl::DoFreeze() wxCHECK_RET(m_text != NULL, wxT("invalid text ctrl")); GTKFreezeWidget(m_text); + if (m_widget != m_text) + GTKFreezeWidget(m_widget); if ( HasFlag(wxTE_MULTILINE) ) { @@ -2014,6 +2017,8 @@ void wxTextCtrl::DoThaw() } GTKThawWidget(m_text); + if (m_widget != m_text) + GTKThawWidget(m_widget); } // ---------------------------------------------------------------------------- diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index e290ad0bd0..743743a5bf 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -2075,9 +2075,6 @@ static void frame_clock_layout(GdkFrameClock*, wxWindow* win) void wxWindowGTK::GTKHandleRealized() { - if (IsFrozen()) - DoFreeze(); - GdkWindow* const window = GTKGetDrawingWindow(); if (m_wxwindow) @@ -2159,11 +2156,6 @@ void wxWindowGTK::GTKHandleRealized() void wxWindowGTK::GTKHandleUnrealize() { - // unrealizing a frozen window seems to have some lingering effect - // preventing updates to the affected area - if (IsFrozen()) - DoThaw(); - if (m_wxwindow) { if (m_imContext) @@ -2525,12 +2517,6 @@ wxWindowGTK::~wxWindowGTK() m_imContext = NULL; } - // avoid problem with GTK+ 2.18 where a frozen window causes the whole - // TLW to be frozen, and if the window is then destroyed, nothing ever - // gets painted again - while (IsFrozen()) - Thaw(); - #ifdef __WXGTK3__ if (m_styleProvider) g_object_unref(m_styleProvider); @@ -2578,6 +2564,10 @@ void wxWindowGTK::PostCreation() { wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") ); + GTKConnectFreezeWidget(m_widget); + if (m_wxwindow && m_wxwindow != m_widget) + GTKConnectFreezeWidget(m_wxwindow); + #if wxGTK_HAS_COMPOSITING_SUPPORT // Set RGBA visual as soon as possible to minimize the possibility that // somebody uses the wrong one. @@ -5070,53 +5060,49 @@ GdkWindow* wxWindowGTK::GTKGetDrawingWindow() const // freeze/thaw // ---------------------------------------------------------------------------- +extern "C" { +static gboolean draw_freeze(GtkWidget*, void*, wxWindow*) +{ + // stop other handlers from being invoked + return true; +} +} + +void wxWindowGTK::GTKConnectFreezeWidget(GtkWidget* widget) +{ +#ifdef __WXGTK3__ + gulong id = g_signal_connect(widget, "draw", G_CALLBACK(draw_freeze), this); +#else + gulong id = g_signal_connect(widget, "expose-event", G_CALLBACK(draw_freeze), this); +#endif + g_signal_handler_block(widget, id); +} + void wxWindowGTK::GTKFreezeWidget(GtkWidget* widget) { - if (widget && gtk_widget_get_has_window(widget)) - { - GdkWindow* window = gtk_widget_get_window(widget); - if (window) - { -#if GTK_CHECK_VERSION(2,18,0) -#ifndef __WXGTK3__ - if (gtk_check_version(2,18,0) == NULL) -#endif - { - // impl_window for a non-native GdkWindow can change if - // gdk_window_ensure_native() is called on it or some other - // GdkWindow in the same TLW. Since the freeze count is on the - // impl_window, we have to make sure impl_window does not change - // after we call gdk_window_freeze_updates(). - gdk_window_ensure_native(window); - } -#endif - gdk_window_freeze_updates(window); - } - } + g_signal_handlers_unblock_by_func(widget, (void*)draw_freeze, this); } void wxWindowGTK::GTKThawWidget(GtkWidget* widget) { - if (widget && gtk_widget_get_has_window(widget)) - { - GdkWindow* window = gtk_widget_get_window(widget); - if (window) - gdk_window_thaw_updates(window); - } + g_signal_handlers_block_by_func(widget, (void*)draw_freeze, this); + gtk_widget_queue_draw(widget); } void wxWindowGTK::DoFreeze() { - GtkWidget* widget = m_wxwindow; - if (widget == NULL) - widget = m_widget; - GTKFreezeWidget(widget); + wxCHECK_RET(m_widget, "invalid window"); + + GTKFreezeWidget(m_widget); + if (m_wxwindow && m_wxwindow != m_widget) + GTKFreezeWidget(m_wxwindow); } void wxWindowGTK::DoThaw() { - GtkWidget* widget = m_wxwindow; - if (widget == NULL) - widget = m_widget; - GTKThawWidget(widget); + wxCHECK_RET(m_widget, "invalid window"); + + GTKThawWidget(m_widget); + if (m_wxwindow && m_wxwindow != m_widget) + GTKThawWidget(m_wxwindow); }