diff --git a/gnome/ChangeLog b/gnome/ChangeLog index 83a86a166..9f65637a3 100644 --- a/gnome/ChangeLog +++ b/gnome/ChangeLog @@ -1,15 +1,47 @@ +1998-12-03 Federico Mena Quintero + + * gdesktop.c (load_desktop_icons): Added arguments that specify + where to place the newly-created icons. This needs some tweaking still. + (reload_desktop_icons): Now takes arguments for the position of + the new icons. + (drag_data_received): Pass in the drop position to reload_desktop_icons(). + + * gscreen.c (panel_tree_drag_motion): Added missing variable declaration. + + * gdesktop.c (load_desktop_icons): Added an incremental flag that + specifies whether icon creation is unconditional regardless of + whether there is an icon for a file or not. + (reload_desktop_icons): Use the incremental flag in load_desktop_icons(). + (drag_data_received): Reload the desktop incrementally, to avoid flicker. + (desktop_icon_info_new): Use mc_lstat(), not mc_stat(). We do + want to read symlinks, even dangling ones, if they exist. + (load_desktop_icons): While we are reading the desktop directory, + first place all the icons that have their metadata icon-position + set, and build a list of the ones that don't. *Then* place + those. This fixes overlapping icons on weird situations. + + * directory.xpm: Removed bogus garbage. There was a stale pixmap here. + + * gdesktop.c (setup_desktop_dnd): Allow for GDK_ACTION_ASK as well. + + * gscreen.c (panel_widget_motion): The action argument to + gtk_drag_begin() is a mask of possible actions, not a single action. + + * gdesktop.c (drag_data_received): Only reload the icons if the + drop was successful. + 1998-12-03 Jonathan Blandford * gdialogs.c (create_op_win): starting the op_win dialog stuff 1998-12-03 Miguel de Icaza + * gscreen.c (panel_create_icon_display, panel_create_file_list): + Hook up to drag_begin and drag_end events. + * gscreen.c (panel_tree_drag_motion): Improve interactivity (x_create_panel): Add a little decorating frame. - - - (panel_create_icon_display, panel_create_file_list): Hook up to drag_begin and drag_end events. diff --git a/gnome/directory.xpm b/gnome/directory.xpm index 2ca38cf35..fdc5e38ef 100644 --- a/gnome/directory.xpm +++ b/gnome/directory.xpm @@ -1,120 +1,4 @@ /* XPM */ -static char * xpm_new[] = { -"24 24 89 1", -" c None", -". c #000000", -"+ c #ADAD9C", -"@ c #959585", -"# c #DCDCC5", -"$ c #DFDFC8", -"% c #242424", -"& c #A7A796", -"* c #D7D7C1", -"= c #D9D9C3", -"- c #DCDCC4", -"; c #DDDDC7", -"> c #E1E1CA", -", c #A6A694", -"' c #D6D6BF", -") c #D8D8C2", -"! c #DBDBC4", -"~ c #DFDFC7", -"{ c #E3E3CB", -"] c #B2B29F", -"^ c #7C7C7C", -"/ c #646464", -"( c #D5D5BD", -"_ c #D5D5BF", -": c #D7D7C0", -"< c #DADAC3", -"[ c #DEDEC6", -"} c #E1E1C9", -"| c #E5E5CD", -"1 c #E9E9D1", -"2 c #343434", -"3 c #E7E7E7", -"4 c #373736", -"5 c #B8B8A6", -"6 c #D3D3BC", -"7 c #D9D9C2", -"8 c #DDDDC5", -"9 c #E0E0C8", -"0 c #E8E8D0", -"a c #ECECD4", -"b c #EEEED5", -"c c #ECECEC", -"d c #EDEDED", -"e c #3D3D37", -"f c #CECEB7", -"g c #E6E6CE", -"h c #EAEAD2", -"i c #F1F1D8", -"j c #A5A594", -"k c #EEEEE5", -"l c #3C3C3C", -"m c #8F8F80", -"n c #D0D0B9", -"o c #E4E4CB", -"p c #EAEAD1", -"q c #ECECD3", -"r c #EFEFD6", -"s c #F2F2D9", -"t c #F3F3DA", -"u c #EEEEE6", -"v c #505050", -"w c #929282", -"x c #D1D1B9", -"y c #E7E7CF", -"z c #EBEBD2", -"A c #F4F4DB", -"B c #F5F5DC", -"C c #969686", -"D c #D2D2BC", -"E c #E0E0C9", -"F c #E9E9D0", -"G c #EDEDD4", -"H c #F0F0D7", -"I c #BEBEAB", -"J c #797973", -"K c #D8D8C1", -"L c #DDDDC6", -"M c #98988F", -"N c #E4E4CC", -"O c #818174", -"P c #E2E2CA", -"Q c #BEBEAE", -"R c #4E4E4E", -"S c #828274", -"T c #EBEBD3", -"U c #BBBBA8", -"V c #CDCDB8", -"W c #4D4D45", -"X c #A6A696", -" ", -" ", -" . ", -" ..+. ", -" ..@#$% ", -" ..&*=-;>. ", -" ..,'**)!~{]. ", -" .^/'(_:<[}|12 ", -" .3456*789|0ab. ", -" .cdef_!9g0hbij. ", -" .kklmn9opqrist. ", -" .uvwx-}yzbittAB. ", -" ..CD!E{FGHtAABBI. ", -" .JK7L>ypbitBBBBB). ", -" .M!#$NyzbitBBBBBO. ", -" .~9P|1qrsABBBB.. ", -" .Q||0hGHtABB<. ", -" R01hGrstAsS. ", -" .TaGriss<. ", -" .rHis1j. ", -" .UstVW. ", -" .tX. ", -" .. ", -" "}; -/* XPM */ static char * directory_xpm[] = { "16 13 5 1", " c None", diff --git a/gnome/gdesktop.c b/gnome/gdesktop.c index ba0bf5d49..503523bb3 100644 --- a/gnome/gdesktop.c +++ b/gnome/gdesktop.c @@ -95,9 +95,9 @@ static GtkTargetEntry dnd_targets[] = { static int dnd_ntargets = sizeof (dnd_targets) / sizeof (dnd_targets[0]); +/* Proxy window for DnD on the root window */ static GtkWidget *dnd_proxy_window; - /* Looks for a free slot in the layout_slots array and returns the coordinates that coorespond to * it. "Free" means it either has zero icons in it, or it has the minimum number of icons of all @@ -492,7 +492,7 @@ desktop_icon_info_new (char *filename, int auto_pos, int xpos, int ypos) full_name = g_concat_dir_and_file (desktop_directory, filename); - if (mc_stat (full_name, &s) != 0) { + if (mc_lstat (full_name, &s) != 0) { g_warning ("Could not stat %s; will not use a desktop icon", full_name); g_free (full_name); return NULL; @@ -598,17 +598,37 @@ create_desktop_dir (void) } } -/* Reads the ~/Desktop directory and creates the initial desktop icons */ +/* Returns TRUE if there is already an icon in the desktop for the specified filename, FALSE otherwise. */ +static int +icon_exists (char *filename) +{ + int i; + GList *l; + struct desktop_icon_info *dii; + + for (i = 0; i < (layout_cols * layout_rows); i++) + for (l = layout_slots[i].icons; l; l = l->next) { + dii = l->data; + if (strcmp (filename, dii->filename) == 0) + return TRUE; + } + + return FALSE; +} + +/* Reads the ~/Desktop directory and creates the desktop icons. If incremental is TRUE, then an + * icon will not be created for a file if there is already an icon for it, and icons will be created + * starting at the specified position. + */ static void -load_desktop_icons (void) +load_desktop_icons (int incremental, int xpos, int ypos) { struct dirent *dirent; DIR *dir; char *full_name; int have_pos, x, y; - int i; - GList *l; struct desktop_icon_info *dii; + GSList *need_position_list, *l; dir = mc_opendir (desktop_directory); if (!dir) { @@ -619,28 +639,48 @@ load_desktop_icons (void) return; } + /* First create the icons for all the files that do have their icon position set. Build a + * list of the icons that do not have their position set. + */ + + need_position_list = NULL; + while ((dirent = mc_readdir (dir)) != NULL) { if (((dirent->d_name[0] == '.') && (dirent->d_name[1] == 0)) || ((dirent->d_name[0] == '.') && (dirent->d_name[1] == '.') && (dirent->d_name[2] == 0))) continue; + if (incremental && icon_exists (dirent->d_name)) + continue; + full_name = g_concat_dir_and_file (desktop_directory, dirent->d_name); have_pos = gmeta_get_icon_pos (full_name, &x, &y); - desktop_icon_info_new (dirent->d_name, !have_pos, x, y); - g_free (full_name); + if (have_pos) { + dii = desktop_icon_info_new (dirent->d_name, FALSE, x, y); + gtk_widget_show (dii->dicon); + + g_free (full_name); + } else + need_position_list = g_slist_prepend (need_position_list, g_strdup (dirent->d_name)); } mc_closedir (dir); - /* Show all the icons */ + /* Now create the icons for all the files that did not have their position set. This makes + * auto-placement work correctly without overlapping icons. + */ - for (i = 0; i < (layout_cols * layout_rows); i++) - for (l = layout_slots[i].icons; l; l = l->next) { - dii = l->data; - gtk_widget_show (dii->dicon); - } + need_position_list = g_slist_reverse (need_position_list); + + for (l = need_position_list; l; l = l->next) { + dii = desktop_icon_info_new (l->data, FALSE, xpos, ypos); + gtk_widget_show (dii->dicon); + g_free (l->data); + } + + g_slist_free (need_position_list); } /* Destroys all the current desktop icons */ @@ -663,12 +703,16 @@ destroy_desktop_icons (void) } } -/* Reloads the desktop icons */ +/* Reloads the desktop icons. If incremental is TRUE, then the existing icons will not be destroyed + * first, and the new icons will be put at the specified position. + */ static void -reload_desktop_icons (void) +reload_desktop_icons (int incremental, int x, int y) { - destroy_desktop_icons (); - load_desktop_icons (); + if (!incremental) + destroy_desktop_icons (); + + load_desktop_icons (incremental, x, y); } /* Sets up a proxy window for DnD on the specified X window. Courtesy of Owen Taylor */ @@ -764,15 +808,25 @@ static void drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *data, guint info, guint time, gpointer user_data) { + int retval; + gint dx, dy; + switch (info) { case TARGET_URI_LIST: - printf ("uri-list dropped on desktop!\n"); + /* Fix the proxy window offsets */ + gdk_window_get_position (widget->window, &dx, &dy); + x += dx; + y += dy; + + /* Drop! */ + + retval = gdnd_drop_on_directory (context, data, desktop_directory); + + if (retval) + reload_desktop_icons (TRUE, x, y); - gdnd_drop_on_directory (context, data, desktop_directory); - reload_desktop_icons (); /* FIXME: this is inefficient and it sucks! */ - /* FIXME: return TRUE for delete if appropriate */ - gtk_drag_finish (context, TRUE, FALSE, time); + gtk_drag_finish (context, retval, FALSE, time); return; default: @@ -793,9 +847,9 @@ setup_desktop_dnd (void) g_warning ("Eeeeek, some moron is already taking drops on the root window!"); gtk_drag_dest_set (dnd_proxy_window, - GTK_DEST_DEFAULT_DROP, + GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, dnd_targets, dnd_ntargets, - GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); + GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK); gtk_signal_connect (GTK_OBJECT (dnd_proxy_window), "drag_data_received", GTK_SIGNAL_FUNC (drag_data_received), NULL); @@ -812,7 +866,7 @@ desktop_init (void) { create_layout_info (); create_desktop_dir (); - load_desktop_icons (); + load_desktop_icons (FALSE, 0, 0); setup_desktop_dnd (); } diff --git a/gnome/gscreen.c b/gnome/gscreen.c index 063d16d8a..729bfd70b 100644 --- a/gnome/gscreen.c +++ b/gnome/gscreen.c @@ -15,8 +15,9 @@ #include "mad.h" #include "x.h" #include "dir.h" -#include "panel.h" #include "command.h" +#include "panel.h" +#define WANT_WIDGETS /* bleah */ #include "main.h" #include "color.h" #include "mouse.h" @@ -60,11 +61,6 @@ static GdkImlibImage *icon_view_regular; static GdkImlibImage *icon_view_core; static GdkImlibImage *icon_view_sock; -#ifdef OLD_DND -static char *drag_types [] = { "text/plain", "file:ALL", "url:ALL" }; -static char *drop_types [] = { "url:ALL" }; -#endif - static GtkTargetEntry drag_types [] = { { "text/uri-list", 0, TARGET_URI_LIST }, { "text/plain", 0, TARGET_TEXT_PLAIN } @@ -1061,36 +1057,27 @@ panel_clist_button_release (GtkWidget *widget, GdkEventButton *event, WPanel *pa return FALSE; } -#define MAX(a,b) ((a > b) ? a : b) - static int panel_widget_motion (GtkWidget *widget, GdkEventMotion *event, WPanel *panel) { GtkTargetList *list; - GdkDragAction action; GdkDragContext *context; - + if (!panel->maybe_start_drag) return FALSE; if (panel->maybe_start_drag == 3) return FALSE; - if ((abs (event->x - panel->click_x) < 4) || + if ((abs (event->x - panel->click_x) < 4) || (abs (event->y - panel->click_y) < 4)) return FALSE; list = gtk_target_list_new (drag_types, ELEMENTS (drag_types)); - /* Control+Shift = LINK */ - if ((event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) == (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) - action = GDK_ACTION_LINK; - else if (event->state & (GDK_SHIFT_MASK)) - action = GDK_ACTION_MOVE; - else - action = GDK_ACTION_COPY; - - context = gtk_drag_begin (widget, list, action, panel->maybe_start_drag, (GdkEvent *) event); + context = gtk_drag_begin (widget, list, + GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK, + panel->maybe_start_drag, (GdkEvent *) event); gtk_drag_set_icon_default (context); return FALSE;