gtk2/gtk/gtkdndprivate.h
Руслан Ижбулатов 4172138154 DnD: fix setting icon in drag-begin
Commit 1c96b703 changed the way icon
information is given to DnD. Previously an icon helper was kept at
the drag source site. Now an image definition is stored there.
The difference is that icon helper is an object that changes its
state in response to an icon being set, thus the object survived
multiple icon changes. Whereas image definition is destroyed and
re-created from scratch every time a drag icon is changed.
This created a problem where gtk_drag_begin_internal() would receive
the value of site->image_def when a drag just began, then it emits
"drag-begin" signal, in response to which an application can
set drag icon, changing the value of site->image_def. However,
gtk_drag_begin_internal() is unable to know about that change and
continues to use the old value it received from up the stack.

Not only does it prevent drag icon from being set from "drag-begin",
it also can induce a crash, since the old image_def value used
by gtk_drag_begin_internal() points to a freed memory region.

Fix this by only setting a default icon (which is created in-place)
in gtk_drag_begin_internal() if the caller does not care about icons.
Otherwise gtk_drag_begin_internal() will return a boolean that indicates
whether an icon needs to be set. Then the caller can invoke
gtk_drag_set_icon_definition() to set the icon, if needed.

Fixes #1407.
2018-10-16 19:04:54 +00:00

65 lines
2.8 KiB
C

/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
/* GTK - The GIMP Toolkit
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_DND_PRIVATE_H__
#define __GTK_DND_PRIVATE_H__
#include <gtk/gtkwidget.h>
#include <gtk/gtkselection.h>
#include <gtk/gtkdragdest.h>
#include "gtkimagedefinitionprivate.h"
typedef struct _GtkDragDestSite GtkDragDestSite;
struct _GtkDragDestSite
{
GtkDestDefaults flags;
GtkTargetList *target_list;
GdkDragAction actions;
GdkWindow *proxy_window;
GdkDragProtocol proxy_protocol;
guint do_proxy : 1;
guint proxy_coords : 1;
guint have_drag : 1;
guint track_motion : 1;
};
G_BEGIN_DECLS
GdkDragContext * gtk_drag_begin_internal (GtkWidget *widget,
gboolean *out_needs_icon,
GtkTargetList *target_list,
GdkDragAction actions,
gint button,
const GdkEvent *event,
int x,
int y);
void gtk_drag_set_icon_definition (GdkDragContext *context,
GtkImageDefinition *def,
gint hot_x,
gint hot_y);
void _gtk_drag_source_handle_event (GtkWidget *widget,
GdkEvent *event);
void _gtk_drag_dest_handle_event (GtkWidget *toplevel,
GdkEvent *event);
G_END_DECLS
#endif /* __GTK_DND_PRIVATE_H__ */