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.
Этот коммит содержится в:
родитель
db7260e57a
Коммит
64aeddb117
@ -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
|
||||||
|
216
gnome/gdesktop.c
216
gnome/gdesktop.c
@ -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));
|
||||||
}
|
}
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user