Skip to content

Commit 9f44f18

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 2cc78b1 commit 9f44f18

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)