Skip to content

Commit b1f9179

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 69dbef5 commit b1f9179

File tree

2 files changed

+7
-4
lines changed

2 files changed

+7
-4
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: 4 additions & 3 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
//----------------------------------------------------------------------------
@@ -806,8 +805,8 @@ void wxDropSource::PrepareIcon( int action, GdkDragContext *context )
806805
cairo_region_destroy(region);
807806
}
808807

809-
g_signal_connect(widget, "draw", G_CALLBACK(draw_icon), icon);
810-
808+
m_icon_draw_handler_id = g_signal_connect(widget, "draw", G_CALLBACK(draw_icon), icon);
809+
m_icon_drawn_widget = widget;
811810
#else // !__WXGTK3__
812811

813812
GdkBitmap *mask;
@@ -919,6 +918,8 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
919918

920919
g_signal_handlers_disconnect_by_func (m_iconWindow,
921920
(gpointer) gtk_dnd_window_configure_callback, this);
921+
if (m_icon_draw_handler_id > 0)
922+
g_signal_handler_disconnect(m_icon_drawn_widget, m_icon_draw_handler_id);
922923
g_object_unref(m_iconWindow);
923924
m_iconWindow = NULL;
924925

0 commit comments

Comments
 (0)