1
1

1999-02-01 Federico Mena Quintero <federico@nuclecu.unam.mx>

* gdesktop.c (desktop_drag_motion): If the user is dragging a
	Netscape url, allow ACTION_LINK.
	(setup_desktop_dnd): Now we use a single GtkInvisible widget to
	proxy both DnD and clicks on the desktop.
	(setup_motif_dnd_proxy): New function to set up a widow as a Motif
	DnD proxy (to allow drops from Netscape, for example).
	(setup_desktop_click_proxy_window): Use the proxy_invisible widget.
	(drop_url): Reload desktop icons after creating the url entry.
	(desktop_icon_info_place): Allow a drop from something other than
	a desktop icon to be placed where the user wants.
	(desktop_drag_motion): Unconditionally specify ACTION_MOVE if we
	are dragging a desktop icon.
	(desktop_icon_info_place): Remove the icon from its slot before
	calling the smart-positioning routines.
Этот коммит содержится в:
Miguel de Icaza 1999-02-02 02:34:46 +00:00
родитель db7260e57a
Коммит 64aeddb117
2 изменённых файлов: 160 добавлений и 111 удалений

Просмотреть файл

@ -1,3 +1,20 @@
1999-02-01 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gdesktop.c (desktop_drag_motion): If the user is dragging a
Netscape url, allow ACTION_LINK.
(setup_desktop_dnd): Now we use a single GtkInvisible widget to
proxy both DnD and clicks on the desktop.
(setup_motif_dnd_proxy): New function to set up a widow as a Motif
DnD proxy (to allow drops from Netscape, for example).
(setup_desktop_click_proxy_window): Use the proxy_invisible widget.
(drop_url): Reload desktop icons after creating the url entry.
(desktop_icon_info_place): Allow a drop from something other than
a desktop icon to be placed where the user wants.
(desktop_drag_motion): Unconditionally specify ACTION_MOVE if we
are dragging a desktop icon.
(desktop_icon_info_place): Remove the icon from its slot before
calling the smart-positioning routines.
1999-01-31 Federico Mena Quintero <federico@nuclecu.unam.mx> 1999-01-31 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gdesktop.c (reload_desktop_icons): Reload the icon image for a * gdesktop.c (reload_desktop_icons): Reload the icon image for a

Просмотреть файл

@ -6,13 +6,6 @@
* Miguel de Icaza <miguel@nuclecu.unam.mx> * Miguel de Icaza <miguel@nuclecu.unam.mx>
*/ */
/*
* TO-DO list for the desktop;
*
* - Put an InputOnly window over icons to be able to select them even if the user clicks on
* the transparent area.
*/
#include <config.h> #include <config.h>
#include "global.h" #include "global.h"
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
@ -83,17 +76,17 @@ static GtkTargetEntry dnd_icon_targets[] = {
}; };
static GtkTargetEntry dnd_desktop_targets[] = { static GtkTargetEntry dnd_desktop_targets[] = {
{ "_NETSCAPE_URL", 0, TARGET_URL },
{ TARGET_MC_DESKTOP_ICON_TYPE, 0, TARGET_MC_DESKTOP_ICON }, { TARGET_MC_DESKTOP_ICON_TYPE, 0, TARGET_MC_DESKTOP_ICON },
{ TARGET_URI_LIST_TYPE, 0, TARGET_URI_LIST } { TARGET_URI_LIST_TYPE, 0, TARGET_URI_LIST },
{ TARGET_URL_TYPE, 0, TARGET_URL }
}; };
static int dnd_icon_nsources = sizeof (dnd_icon_sources) / sizeof (dnd_icon_sources[0]); static int dnd_icon_nsources = sizeof (dnd_icon_sources) / sizeof (dnd_icon_sources[0]);
static int dnd_icon_ntargets = sizeof (dnd_icon_targets) / sizeof (dnd_icon_targets[0]); static int dnd_icon_ntargets = sizeof (dnd_icon_targets) / sizeof (dnd_icon_targets[0]);
static int dnd_desktop_ntargets = sizeof (dnd_desktop_targets) / sizeof (dnd_desktop_targets[0]); static int dnd_desktop_ntargets = sizeof (dnd_desktop_targets) / sizeof (dnd_desktop_targets[0]);
/* Proxy window for DnD on the root window */ /* Proxy window for DnD and clicks on the desktop */
static GtkWidget *dnd_proxy_window; static GtkWidget *proxy_invisible;
/* Offsets for the DnD cursor hotspot */ /* Offsets for the DnD cursor hotspot */
static int dnd_press_x, dnd_press_y; static int dnd_press_x, dnd_press_y;
@ -112,7 +105,6 @@ static int icon_select_on_text;
/* Proxy window for clicks on the root window */ /* Proxy window for clicks on the root window */
static GdkWindow *click_proxy_gdk_window; static GdkWindow *click_proxy_gdk_window;
static GtkWidget *click_proxy_invisible;
/* GC for drawing the rubberband rectangle */ /* GC for drawing the rubberband rectangle */
static GdkGC *click_gc; static GdkGC *click_gc;
@ -130,7 +122,7 @@ static int click_dragging;
static DesktopIconInfo *desktop_icon_info_new (char *filename, char *url, static DesktopIconInfo *desktop_icon_info_new (char *filename, char *url,
int auto_pos, int xpos, int ypos); int user_pos, int auto_pos, int xpos, int ypos);
/* Looks for a free slot in the layout_slots array and returns the coordinates that coorespond to /* Looks for a free slot in the layout_slots array and returns the coordinates that coorespond to
@ -218,23 +210,24 @@ remove_from_slot (DesktopIconInfo *dii)
layout_slots[dii->slot].icons = g_list_remove (layout_slots[dii->slot].icons, dii); layout_slots[dii->slot].icons = g_list_remove (layout_slots[dii->slot].icons, dii);
} }
/* /* Places a desktop icon. If auto_pos is true, then the function will look for
* Places a desktop icon. If auto_pos is true, then the function will * a place to position the icon automatically, else it will use the specified
* look for a place to position the icon automatically, else it will * coordinates, snapped to the grid if the global desktop_snap_icons flag is
* use the specified coordinates, snapped to the grid if the global * set.
* desktop_snap_icons flag is set.
*/ */
static void static void
desktop_icon_info_place (DesktopIconInfo *dii, int auto_pos, int xpos, int ypos) desktop_icon_info_place (DesktopIconInfo *dii, int user_pos, int auto_pos, int xpos, int ypos)
{ {
int u, v; int u, v;
char *filename; char *filename;
if (auto_pos) { remove_from_slot (dii);
if (desktop_auto_placement || !desktop_snap_icons)
get_icon_auto_pos (&xpos, &ypos); if (!user_pos && auto_pos) {
else if (desktop_snap_icons) if (desktop_snap_icons)
get_icon_snap_pos (&xpos, &ypos); get_icon_snap_pos (&xpos, &ypos);
else
get_icon_auto_pos (&xpos, &ypos);
} }
if (xpos < 0) if (xpos < 0)
@ -249,8 +242,6 @@ desktop_icon_info_place (DesktopIconInfo *dii, int auto_pos, int xpos, int ypos)
/* Increase the number of icons in the corresponding slot */ /* Increase the number of icons in the corresponding slot */
remove_from_slot (dii);
u = xpos / DESKTOP_SNAP_X; u = xpos / DESKTOP_SNAP_X;
v = ypos / DESKTOP_SNAP_Y; v = ypos / DESKTOP_SNAP_Y;
@ -332,13 +323,13 @@ typedef struct {
} file_and_url_t; } file_and_url_t;
/* /*
* Reloads the desktop icons efficiently. If there are "new" files * Reloads the desktop icons efficiently. If there are "new" files for which no
* for which no icons have been created, then icons for them will be * icons have been created, then icons for them will be created started at the
* created started at the specified position -- this is used when * specified position if user_pos is TRUE. If it is FALSE, the icons will be
* dragging new icons to the desktop. * auto-placed.
*/ */
static void static void
reload_desktop_icons (int xpos, int ypos) reload_desktop_icons (int user_pos, int xpos, int ypos)
{ {
struct dirent *dirent; struct dirent *dirent;
DIR *dir; DIR *dir;
@ -391,7 +382,7 @@ reload_desktop_icons (int xpos, int ypos)
g_free (full_name); g_free (full_name);
dii = l->data; dii = l->data;
desktop_icon_set_icon (dii->dicon, im); desktop_icon_set_icon (DESKTOP_ICON (dii->dicon), im);
/* Leave the icon in the desktop by removing it from the list */ /* Leave the icon in the desktop by removing it from the list */
@ -406,7 +397,7 @@ reload_desktop_icons (int xpos, int ypos)
desktop_url = NULL; desktop_url = NULL;
if (have_pos) { if (have_pos) {
dii = desktop_icon_info_new (dirent->d_name, desktop_url, FALSE, x, y); dii = desktop_icon_info_new (dirent->d_name, desktop_url, FALSE, FALSE, x, y);
gtk_widget_show (dii->dicon); gtk_widget_show (dii->dicon);
g_free (full_name); g_free (full_name);
@ -452,7 +443,7 @@ reload_desktop_icons (int xpos, int ypos)
for (sl = need_position_list; sl; sl = sl->next) { for (sl = need_position_list; sl; sl = sl->next) {
file_and_url_t *fau = sl->data; file_and_url_t *fau = sl->data;
dii = desktop_icon_info_new (fau->filename, fau->url, TRUE, xpos, ypos); dii = desktop_icon_info_new (fau->filename, fau->url, user_pos, TRUE, xpos, ypos);
gtk_widget_show (dii->dicon); gtk_widget_show (dii->dicon);
g_free (fau->url); g_free (fau->url);
@ -858,7 +849,7 @@ do_popup_menu (DesktopIconInfo *dii, GdkEventButton *event)
filename = g_concat_dir_and_file (desktop_directory, dii->filename); filename = g_concat_dir_and_file (desktop_directory, dii->filename);
if (gpopup_do_popup (event, NULL, dii, 0, filename) != -1) if (gpopup_do_popup (event, NULL, dii, 0, filename) != -1)
reload_desktop_icons (0, 0); reload_desktop_icons (FALSE, 0, 0);
g_free (filename); g_free (filename);
} }
@ -1290,7 +1281,10 @@ drop_desktop_icons (GdkDragContext *context, GtkSelectionData *data, int x, int
for (sl = sel_icons; sl; sl = sl->next) { for (sl = sel_icons; sl; sl = sl->next) {
dii = sl->data; dii = sl->data;
desktop_icon_info_place (dii, FALSE, dii->x + dx, dii->y + dy); desktop_icon_info_place (dii,
!desktop_auto_placement,
desktop_auto_placement,
dii->x + dx, dii->y + dy);
} }
/* Clean up */ /* Clean up */
@ -1316,26 +1310,23 @@ desktop_icon_drop_uri_list (DesktopIconInfo *dii, GdkDragContext *context, GtkSe
if (!fe) if (!fe)
return; /* eek */ return; /* eek */
/* /* 1. If it is a directory, drop the files there */
* 1. If it is directory, drop the files there
*/
if (fe->f.link_to_dir) { if (fe->f.link_to_dir) {
gdnd_drop_on_directory (context, data, filename); gdnd_drop_on_directory (context, data, filename);
goto out; goto out;
} }
/* /* 2. Try to use a metadata-based drop action */
* 2. Try to use a metadata-based drop action
*/
if (gnome_metadata_get (filename, "drop-action", &size, &buf) == 0) { if (gnome_metadata_get (filename, "drop-action", &size, &buf) == 0) {
/*action_drop (filename, buf, context, data);*/ /* Fixme: i'm undefined */ /*action_drop (filename, buf, context, data);*/ /* Fixme: i'm undefined */
g_free (buf); g_free (buf);
goto out; goto out;
} }
/* /* 3. Try a drop action from the mime-type */
* 3. Try a drop action from the mime-type
*/
mime_type = gnome_mime_type_or_default (filename, NULL); mime_type = gnome_mime_type_or_default (filename, NULL);
if (mime_type) { if (mime_type) {
char *action; char *action;
@ -1348,15 +1339,15 @@ desktop_icon_drop_uri_list (DesktopIconInfo *dii, GdkDragContext *context, GtkSe
} }
} }
/* /* 4. Executable. Try metadata keys for "open" */
* 4. Executable. Try metadata keys for "open".
*/
if (is_exe (fe->buf.st_mode) && if_link_is_exe (fe)) { if (is_exe (fe->buf.st_mode) && if_link_is_exe (fe)) {
GList *names, *l; GList *names, *l;
int len, i; int len, i;
char **drops; char **drops;
/* Convert the list of filenames into an array of char */ /* Convert the list of filenames into an array of char */
names = gnome_uri_list_extract_uris (data->data); names = gnome_uri_list_extract_uris (data->data);
len = g_list_length (names); len = g_list_length (names);
drops = (char **) g_malloc (sizeof (char *) * (len+1)); drops = (char **) g_malloc (sizeof (char *) * (len+1));
@ -1375,6 +1366,7 @@ desktop_icon_drop_uri_list (DesktopIconInfo *dii, GdkDragContext *context, GtkSe
exec_extension (filename, buf, drops, NULL, 0); exec_extension (filename, buf, drops, NULL, 0);
goto out2; goto out2;
} }
exec_extension (filename, "%f %q", drops, NULL, 0); exec_extension (filename, "%f %q", drops, NULL, 0);
g_free (drops); g_free (drops);
@ -1433,15 +1425,11 @@ setup_icon_dnd_dest (DesktopIconInfo *dii)
dii); dii);
} }
/* /* Creates a new desktop icon. The filename is the pruned filename inside the
* Creates a new desktop icon. The filename is the pruned filename * desktop directory. It does not show the icon.
* inside the desktop directory. If auto_pos is false, it will use
* the specified coordinates for the icon. Else, it will use auto-
* positioning trying to start at the specified coordinates. It does
* not show the icon.
*/ */
static DesktopIconInfo * static DesktopIconInfo *
desktop_icon_info_new (char *filename, char *url, int auto_pos, int xpos, int ypos) desktop_icon_info_new (char *filename, char *url, int user_pos, int auto_pos, int xpos, int ypos)
{ {
DesktopIconInfo *dii; DesktopIconInfo *dii;
file_entry *fe; file_entry *fe;
@ -1518,7 +1506,7 @@ desktop_icon_info_new (char *filename, char *url, int auto_pos, int xpos, int yp
/* Place the icon and append it to the list */ /* Place the icon and append it to the list */
desktop_icon_info_place (dii, auto_pos, xpos, ypos); desktop_icon_info_place (dii, user_pos, auto_pos, xpos, ypos);
return dii; return dii;
} }
@ -1600,6 +1588,18 @@ create_desktop_dir (void)
/* setup_trashcan (desktop_directory); */ /* setup_trashcan (desktop_directory); */
} }
/* Property placed on target windows */
typedef struct {
guint8 byte_order;
guint8 protocol_version;
guint8 protocol_style;
guint8 pad;
guint32 proxy_window;
guint16 num_drop_sites;
guint16 padding;
guint32 total_size;
} MotifDragReceiverInfo;
/* Sets up a proxy window for DnD on the specified X window. Courtesy of Owen Taylor */ /* Sets up a proxy window for DnD on the specified X window. Courtesy of Owen Taylor */
static gboolean static gboolean
setup_xdnd_proxy (guint32 xid, GdkWindow *proxy_window) setup_xdnd_proxy (guint32 xid, GdkWindow *proxy_window)
@ -1689,6 +1689,34 @@ setup_xdnd_proxy (guint32 xid, GdkWindow *proxy_window)
return FALSE; return FALSE;
} }
/* Sets up a window as a Motif DnD proxy */
static void
setup_motif_dnd_proxy (guint32 xid, GdkWindow *proxy_window)
{
guint32 proxy_xid;
MotifDragReceiverInfo info;
Atom receiver_info_atom;
guint32 myint;
myint = 0x01020304;
proxy_xid = GDK_WINDOW_XWINDOW (proxy_window);
receiver_info_atom = gdk_atom_intern ("_MOTIF_DRAG_RECEIVER_INFO", FALSE);
info.byte_order = (*((gchar *) &myint) == 1) ? 'B' : 'l';
info.protocol_version = 0;
info.protocol_style = 5; /* XmDRAG_DYNAMIC */
info.proxy_window = proxy_xid;
info.num_drop_sites = 0;
info.total_size = sizeof(info);
XChangeProperty (gdk_display, xid,
receiver_info_atom,
receiver_info_atom,
8, PropModeReplace,
(guchar *)&info,
sizeof (info));
}
/* Callback used when we get a drag_motion event from the desktop. We must /* Callback used when we get a drag_motion event from the desktop. We must
* decide what kind of operation can be performed with what the user is * decide what kind of operation can be performed with what the user is
* dragging. * dragging.
@ -1702,25 +1730,27 @@ desktop_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y,
action = context->suggested_action; /* this is the default */ action = context->suggested_action; /* this is the default */
if (gdnd_drag_context_has_target (context, TARGET_MC_DESKTOP_ICON)) { if (gdnd_drag_context_has_target (context, TARGET_MC_DESKTOP_ICON))
if (context->actions & GDK_ACTION_MOVE)
action = GDK_ACTION_MOVE; action = GDK_ACTION_MOVE;
} else if (gdnd_drag_context_has_target (context, TARGET_URI_LIST)) { else if (gdnd_drag_context_has_target (context, TARGET_URI_LIST)) {
source_widget = gtk_drag_get_source_widget (context); source_widget = gtk_drag_get_source_widget (context);
/* If it comes from ourselves, make move the default unless the /* If it comes from ourselves, make move the default unless the
* user is explicitly asking for ASK. * user is explicitly asking for ASK.
*/ */
printf ("%s\t%s\t%s\t%s\n",
(context->actions & GDK_ACTION_COPY) ? "copy" : "",
(context->actions & GDK_ACTION_MOVE) ? "move" : "",
(context->actions & GDK_ACTION_LINK) ? "link" : "",
(context->actions & GDK_ACTION_ASK) ? "ask" : "");
if (source_widget if (source_widget
&& context->suggested_action != GDK_ACTION_ASK && context->suggested_action != GDK_ACTION_ASK
&& (context->actions & GDK_ACTION_MOVE)) && (context->actions & GDK_ACTION_MOVE))
action = GDK_ACTION_MOVE; action = GDK_ACTION_MOVE;
} else if (gdnd_drag_context_has_target (context, TARGET_URL)) {
/* FIXME: right now we only allow links. We should see if we
* can move or copy stuff instead (for ftp instead of http
* sites, for example).
*/
if (context->actions & GDK_ACTION_LINK)
action = GDK_ACTION_LINK;
else
action = 0;
} else } else
action = 0; /* we cannot handle that type of data */ action = 0; /* we cannot handle that type of data */
@ -1748,7 +1778,10 @@ drop_url (GdkDragContext *context, GtkSelectionData *data, gint x, gint y)
fclose (f); fclose (f);
gnome_metadata_set (template, "desktop-url", gnome_metadata_set (template, "desktop-url",
strlen (data->data)+1, data->data); strlen (data->data) + 1,
data->data);
reload_desktop_icons (TRUE, x, y);
} }
} }
@ -1769,7 +1802,6 @@ desktop_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x,
x += dx; x += dx;
y += dy; y += dy;
printf ("Drag!!\n");
switch (info) { switch (info) {
case TARGET_MC_DESKTOP_ICON: case TARGET_MC_DESKTOP_ICON:
drop_desktop_icons (context, data, x, y); drop_desktop_icons (context, data, x, y);
@ -1778,11 +1810,10 @@ desktop_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x,
case TARGET_URI_LIST: case TARGET_URI_LIST:
retval = gdnd_drop_on_directory (context, data, desktop_directory); retval = gdnd_drop_on_directory (context, data, desktop_directory);
if (retval) if (retval)
reload_desktop_icons (x, y); reload_desktop_icons (TRUE, x, y);
break; break;
case TARGET_URL: case TARGET_URL:
printf ("Aqui!\n");
drop_url (context, data, x, y); drop_url (context, data, x, y);
break; break;
@ -1795,22 +1826,21 @@ desktop_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x,
static void static void
setup_desktop_dnd (void) setup_desktop_dnd (void)
{ {
dnd_proxy_window = gtk_invisible_new (); if (!setup_xdnd_proxy (GDK_ROOT_WINDOW (), proxy_invisible->window))
gtk_widget_show (dnd_proxy_window); g_warning ("There is already a process taking drops on the desktop!\n");
if (!setup_xdnd_proxy (GDK_ROOT_WINDOW (), dnd_proxy_window->window)) setup_motif_dnd_proxy (GDK_ROOT_WINDOW (), proxy_invisible->window);
g_warning ("There is already a process taking drop windows on the desktop\n");
gtk_drag_dest_set (dnd_proxy_window, gtk_drag_dest_set (proxy_invisible,
GTK_DEST_DEFAULT_DROP, GTK_DEST_DEFAULT_DROP,
dnd_desktop_targets, dnd_desktop_targets,
dnd_desktop_ntargets, dnd_desktop_ntargets,
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK); GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK);
gtk_signal_connect (GTK_OBJECT (dnd_proxy_window), "drag_motion", gtk_signal_connect (GTK_OBJECT (proxy_invisible), "drag_motion",
(GtkSignalFunc) desktop_drag_motion, (GtkSignalFunc) desktop_drag_motion,
NULL); NULL);
gtk_signal_connect (GTK_OBJECT (dnd_proxy_window), "drag_data_received", gtk_signal_connect (GTK_OBJECT (proxy_invisible), "drag_data_received",
(GtkSignalFunc) desktop_drag_data_received, (GtkSignalFunc) desktop_drag_data_received,
NULL); NULL);
} }
@ -2122,7 +2152,7 @@ click_proxy_motion (GtkWidget *widget, GdkEventMotion *event, gpointer data)
/* /*
* Filter that translates proxied events from virtual root windows into normal * Filter that translates proxied events from virtual root windows into normal
* Gdk events for the click_proxy_invisible widget. * Gdk events for the proxy_invisible widget.
*/ */
static GdkFilterReturn static GdkFilterReturn
click_proxy_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) click_proxy_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
@ -2187,7 +2217,7 @@ setup_desktop_click_proxy_window (void)
} }
/* Make the proxy window send events to the invisible proxy widget */ /* Make the proxy window send events to the invisible proxy widget */
gdk_window_set_user_data (click_proxy_gdk_window, click_proxy_invisible); gdk_window_set_user_data (click_proxy_gdk_window, proxy_invisible);
/* Add our filter to get events */ /* Add our filter to get events */
gdk_window_add_filter (click_proxy_gdk_window, click_proxy_filter, NULL); gdk_window_add_filter (click_proxy_gdk_window, click_proxy_filter, NULL);
@ -2239,11 +2269,8 @@ setup_desktop_clicks (void)
GdkColor color; GdkColor color;
GdkBitmap *stipple; GdkBitmap *stipple;
click_proxy_invisible = gtk_invisible_new ();
gtk_widget_show (click_proxy_invisible);
/* Make the root window send events to the invisible proxy widget */ /* Make the root window send events to the invisible proxy widget */
gdk_window_set_user_data (GDK_ROOT_PARENT (), click_proxy_invisible); gdk_window_set_user_data (GDK_ROOT_PARENT (), proxy_invisible);
/* Add our filter to get button press/release events (they are sent by /* Add our filter to get button press/release events (they are sent by
* the WM * with the window set to the root). Our filter will translate * the WM * with the window set to the root). Our filter will translate
@ -2260,17 +2287,17 @@ setup_desktop_clicks (void)
/* Connect the signals */ /* Connect the signals */
gtk_signal_connect (GTK_OBJECT (click_proxy_invisible), "button_press_event", gtk_signal_connect (GTK_OBJECT (proxy_invisible), "button_press_event",
(GtkSignalFunc) click_proxy_button_press, (GtkSignalFunc) click_proxy_button_press,
NULL); NULL);
gtk_signal_connect (GTK_OBJECT (click_proxy_invisible), "button_release_event", gtk_signal_connect (GTK_OBJECT (proxy_invisible), "button_release_event",
(GtkSignalFunc) click_proxy_button_release, (GtkSignalFunc) click_proxy_button_release,
NULL); NULL);
gtk_signal_connect (GTK_OBJECT (click_proxy_invisible), "motion_notify_event", gtk_signal_connect (GTK_OBJECT (proxy_invisible), "motion_notify_event",
(GtkSignalFunc) click_proxy_motion, (GtkSignalFunc) click_proxy_motion,
NULL); NULL);
gtk_signal_connect (GTK_OBJECT (click_proxy_invisible), "property_notify_event", gtk_signal_connect (GTK_OBJECT (proxy_invisible), "property_notify_event",
(GtkSignalFunc) click_proxy_property_notify, (GtkSignalFunc) click_proxy_property_notify,
NULL); NULL);
@ -2306,7 +2333,13 @@ desktop_init (void)
gdnd_init (); gdnd_init ();
create_layout_info (); create_layout_info ();
create_desktop_dir (); create_desktop_dir ();
reload_desktop_icons (0, 0); reload_desktop_icons (FALSE, 0, 0);
/* Create the proxy window and initialize all proxying stuff */
proxy_invisible = gtk_invisible_new ();
gtk_widget_show (proxy_invisible);
setup_desktop_dnd (); setup_desktop_dnd ();
setup_desktop_clicks (); setup_desktop_clicks ();
} }
@ -2333,13 +2366,12 @@ desktop_destroy (void)
g_free (desktop_directory); g_free (desktop_directory);
desktop_directory = NULL; desktop_directory = NULL;
/* Remove DnD crap */
gtk_widget_destroy (dnd_proxy_window);
XDeleteProperty (GDK_DISPLAY (), GDK_ROOT_WINDOW (), gdk_atom_intern ("XdndProxy", FALSE));
/* Remove click-on-desktop crap */ /* Remove click-on-desktop crap */
gdk_window_unref (click_proxy_gdk_window); gdk_window_unref (click_proxy_gdk_window);
gtk_widget_destroy (click_proxy_invisible);
/* Remove DnD crap */
gtk_widget_destroy (proxy_invisible);
XDeleteProperty (GDK_DISPLAY (), GDK_ROOT_WINDOW (), gdk_atom_intern ("XdndProxy", FALSE));
} }