Skip to content

Commit 8f0e6aa

Browse files
author
徐扬斌
committed
Fix potential crash when do DragNDrop in GTK
Explicit disconnect the cursor draw handler in the end of DoDragDrop to fix potential crash cause by dangling pointer. When wxDropSource destruct, the set of icons are gone too, so the draw handler has chances to read dangling icons.
1 parent 0f47eab commit 8f0e6aa

File tree

2 files changed

+9
-14
lines changed

2 files changed

+9
-14
lines changed

include/wx/gtk/dnd.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define _WX_GTK_DND_H_
1111

1212
#include "wx/icon.h"
13+
#include "wx/gtk/private/wrapgtk.h"
1314

1415
// ----------------------------------------------------------------------------
1516
// macros
@@ -107,7 +108,8 @@ class WXDLLIMPEXP_CORE wxDropSource: public wxDropSourceBase
107108
m_iconNone;
108109

109110
bool m_waiting;
110-
111+
gulong m_icon_draw_handler_id = 0;
112+
GtkWidget* m_icon_drawn_widget = nullptr;
111113
private:
112114
// common part of both ctors
113115
void SetIcons(const wxIcon& copy,

src/gtk/dnd.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
#include "wx/scopeguard.h"
2626

27-
#include "wx/gtk/private/wrapgtk.h"
2827
#include "wx/gtk/private/backend.h"
2928

3029
//----------------------------------------------------------------------------
@@ -814,8 +813,8 @@ void wxDropSource::PrepareIcon( int action, GdkDragContext *context )
814813
cairo_region_destroy(region);
815814
}
816815

817-
g_signal_connect(widget, "draw", G_CALLBACK(draw_icon), icon);
818-
816+
m_icon_draw_handler_id = g_signal_connect(widget, "draw", G_CALLBACK(draw_icon), icon);
817+
m_icon_drawn_widget = widget;
819818
#else // !__WXGTK3__
820819

821820
GdkBitmap *mask;
@@ -927,16 +926,10 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
927926

928927
g_signal_handlers_disconnect_by_func (m_iconWindow,
929928
(gpointer) gtk_dnd_window_configure_callback, this);
930-
#ifdef __WXGTK3__
931-
GtkWidget* drawWidget = m_iconWindow;
932-
if (gtk_check_version(3,20,0) == NULL)
933-
drawWidget = gtk_bin_get_child(GTK_BIN(drawWidget));
934-
if (drawWidget)
935-
{
936-
g_signal_handlers_disconnect_matched(
937-
drawWidget, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (void*)draw_icon, NULL);
938-
}
939-
#endif
929+
930+
if (m_icon_draw_handler_id > 0)
931+
g_signal_handler_disconnect(m_icon_drawn_widget, m_icon_draw_handler_id);
932+
940933
g_object_unref(m_iconWindow);
941934
m_iconWindow = NULL;
942935

0 commit comments

Comments
 (0)