This is another update to my patch to add per-window histories to the filer. As before holding down the control key when clicking the up button in the toolbar opens the previous directory, or beeps if there isn't one. Additionally there are three new menu entries, all in the Window sub-menu: Previous, New Window Opens previous directory in a new window Previous, Same Window Opens previous directory in the current window Re-open Leads to a sub-menu of the directories in the history list, either from the current window or a global history. New for ROX-Filer 1.2.0 This patch now saves the window history on exit and re-loads it at program start. The history file can also specify the display type and style to display. Use the menu option "Set default for this". Index:rox-1.2.0-history/ROX-Filer/src/filer.c *** rox-1.2.0/ROX-Filer/src/filer.c Tue Feb 12 15:54:08 2002 --- rox-1.2.0-history/ROX-Filer/src/filer.c Wed Feb 20 12:12:26 2002 *************** *** 31,36 **** --- 31,37 ---- #include #include #include + #include #include #include *************** *** 71,81 **** --- 72,96 ---- static FilerWindow *window_with_primary = NULL; + /* Stored history of a visited directory */ + #define RECORDED_STYLE 1u + #define RECORDED_TYPE 2u + #define RECORDED_WIDTH 4u + #define RECORDED_HEIGHT 8u + struct dir_record { + time_t last_visit; + DisplayStyle style; + DetailsType type; + gint width, height; + guint flags; + }; + /* Item we are about to display a tooltip for */ static DirItem *tip_item = NULL; static GtkWidget *tip_widget = NULL; static gint tip_timeout = 0; static time_t tip_time = 0; /* Time tip widget last closed */ + static GHashTable *all_visited=NULL; /* Static prototypes */ static void attach(FilerWindow *filer_window); *************** *** 114,119 **** --- 129,139 ---- static void start_thumb_scanning(FilerWindow *filer_window); + static void visit_directory(FilerWindow *filer_window); + static void load_dir_history(void); + static void save_dir_history(void); + static gint purge_dir_history(gpointer data); + static GdkCursor *busy_cursor = NULL; static GdkCursor *crosshair = NULL; *************** *** 161,166 **** --- 181,191 ---- } g_free(dpyhost); + + all_visited=g_hash_table_new(g_str_hash, g_str_equal); + load_dir_history(); + atexit(save_dir_history); + gtk_timeout_add(15*60*1000, purge_dir_history, NULL); } static void set_unique(guchar *unique) *************** *** 529,534 **** --- 554,563 ---- filer_tooltip_prime(NULL, NULL); + if(filer_window->history_menu) + gtk_widget_unref(filer_window->history_menu); + g_slist_foreach(filer_window->history, (GFunc) g_free, NULL); + g_slist_free(filer_window->history); g_free(filer_window->auto_select); g_free(filer_window->path); g_free(filer_window); *************** *** 1186,1193 **** from_dup = from && *from ? g_strdup(from) : NULL; detach(filer_window); ! g_free(filer_window->path); filer_window->path = real_path; filer_window->directory = new_dir; --- 1215,1231 ---- from_dup = from && *from ? g_strdup(from) : NULL; detach(filer_window); ! if(filer_window->history && filer_window->history->data==path) { ! /* We are going one back in the history, do not push this onto ! the stack */ ! g_free(filer_window->path); ! } else { ! filer_window->history=g_slist_prepend(filer_window->history, ! filer_window->path); ! } ! filer_window->history_menu_ok=FALSE; filer_window->path = real_path; + visit_directory(filer_window); filer_window->directory = new_dir; *************** *** 1233,1238 **** --- 1271,1309 ---- g_free(copy); } + void filer_go_back(FilerWindow *filer_window) + { + GSList *tmp; + + g_return_if_fail(filer_window != NULL); + + if(!filer_window->history) { + gdk_beep(); + return; + } + + filer_change_to(filer_window, (gchar *) filer_window->history->data, + NULL); + + tmp=filer_window->history; + filer_window->history=g_slist_remove_link(filer_window->history, tmp); + filer_window->history_menu_ok=FALSE; + g_free(tmp->data); + g_slist_free(tmp); + } + + FilerWindow *filer_open_back(FilerWindow *filer_window) + { + g_return_val_if_fail(filer_window != NULL, NULL); + + if(!filer_window->history) { + gdk_beep(); + return NULL; + } + + return filer_opendir((gchar *) filer_window->history->data, NULL); + } + /* Returns a list containing the full pathname of every selected item. * You must g_free() each item in the list. */ *************** *** 1357,1362 **** --- 1428,1436 ---- filer_window->target_cb = NULL; filer_window->mini_type = MINI_NONE; filer_window->selection_state = GTK_STATE_INSENSITIVE; + filer_window->history = NULL; + filer_window->history_menu=NULL; + filer_window->history_menu_ok=FALSE; /* Finds the entry for this directory in the dir cache, creating * a new one if needed. This does not cause a scan to start, *************** *** 1414,1419 **** --- 1488,1495 ---- display_set_layout(filer_window, dstyle, dtype); + visit_directory(filer_window); + /* Open the window after a timeout, or when scanning stops. * Do this before attaching, because attach() might tell us to * stop scanning (if a scan isn't needed). *************** *** 2429,2434 **** --- 2505,2760 ---- start_thumb_scanning(filer_window); } + /* We have just started viewing a new directory. Either add it to the + list of directories viewed, or if it is already recorded restore the + settings it had last time */ + static void visit_directory(FilerWindow *filer_window) + { + struct dir_record *dr; + + dr=(struct dir_record *) + g_hash_table_lookup(all_visited, filer_window->path); + if(!dr) { + gchar *kv=g_strdup(filer_window->path); + dr=g_new(struct dir_record, 1); + + time(&dr->last_visit); + dr->flags=0; + + g_hash_table_insert(all_visited, kv, dr); + + } else { + time(&dr->last_visit); + if(dr->flags & RECORDED_STYLE) + filer_window->display_style=dr->style; + if(dr->flags & RECORDED_TYPE) + filer_window->details_type=dr->type; + } + } + + /* Load list of directories and their prefered settings */ + static void load_dir_history(void) + { + gchar *path; + + path=choices_find_path_load("dir_settings", "ROX-Filer"); + if(path) { + XMLwrapper *dirs; + + dirs=xml_cache_load(path); + if(dirs) { + xmlNode *node; + + node = xmlDocGetRootElement(dirs->doc); + + for(node = node->xmlChildrenNode; node; node = node->next) { + struct dir_record *dr; + xmlNode *subnode; + char *str, *name; + + if(strcmp(node->name, "Directory")!=0) + continue; + + dr=g_new(struct dir_record, 1); + dr->flags=0; + name=NULL; + + subnode = get_subnode(node, NULL, "Path"); + if(subnode) { + str=xmlNodeListGetString(dirs->doc, subnode->xmlChildrenNode, 1); + if(str) { + name=g_strdup(str); + g_free(str); + } + } + + subnode = get_subnode(node, NULL, "Visited"); + if(subnode) { + str=xmlNodeListGetString(dirs->doc, subnode->xmlChildrenNode, 1); + if(str) { + dr->last_visit=atol(str); + g_free(str); + } + } + + subnode = get_subnode(node, NULL, "DisplayStyle"); + if(subnode) { + str=xmlNodeListGetString(dirs->doc, subnode->xmlChildrenNode, 1); + if(str) { + dr->style=atoi(str); + dr->flags|=RECORDED_STYLE; + g_free(str); + } + } + + subnode = get_subnode(node, NULL, "DetailsType"); + if(subnode) { + str=xmlNodeListGetString(dirs->doc, subnode->xmlChildrenNode, 1); + if(str) { + dr->type=atoi(str); + dr->flags|=RECORDED_TYPE; + g_free(str); + } + } + + subnode = get_subnode(node, NULL, "Width"); + if(subnode) { + str=xmlNodeListGetString(dirs->doc, subnode->xmlChildrenNode, 1); + if(str) { + dr->width=atoi(str); + dr->flags|=RECORDED_WIDTH; + g_free(str); + } + } + + subnode = get_subnode(node, NULL, "Height"); + if(subnode) { + str=xmlNodeListGetString(dirs->doc, subnode->xmlChildrenNode, 1); + if(str) { + dr->height=atoi(str); + dr->flags|=RECORDED_HEIGHT; + g_free(str); + } + } + + if(name) { + /* Check the target still exists */ + if(access(name, R_OK)==0) { + g_hash_table_insert(all_visited, name, dr); + } else { + g_free(name); + g_free(dr); + } + } else { + g_free(dr); + } + + } + xml_cache_unref(dirs); + } + g_free(path); + } + } + + static void add_dir_record(const char *path, const struct dir_record *dr, + xmlNodePtr root) + { + xmlNodePtr node; + char buf[80]; + + node=xmlNewChild(root, NULL, "Directory", NULL); + + (void) xmlNewChild(node, NULL, "Path", path); + sprintf(buf, "%ld", dr->last_visit); + (void) xmlNewChild(node, NULL, "Visited", buf); + if(dr->flags & RECORDED_STYLE) { + sprintf(buf, "%d", dr->style); + (void) xmlNewChild(node, NULL, "DisplayStyle", buf); + } + if(dr->flags & RECORDED_TYPE) { + sprintf(buf, "%d", dr->type); + (void) xmlNewChild(node, NULL, "DetailsType", buf); + } + if(dr->flags & RECORDED_WIDTH) { + sprintf(buf, "%d", dr->width); + (void) xmlNewChild(node, NULL, "Width", buf); + } + if(dr->flags & RECORDED_HEIGHT) { + sprintf(buf, "%d", dr->height); + (void) xmlNewChild(node, NULL, "Height", buf); + } + } + + /* Save list of directories and their prefered settings */ + static void save_dir_history(void) + { + gchar *path; + + path=choices_find_path_save("dir_settings", "ROX-Filer", TRUE); + if(path) { + xmlDocPtr doc; + xmlNodePtr root; + + doc=xmlNewDoc("1.0"); + root=xmlNewDocNode(doc, NULL, "DirSettings", NULL); + xmlDocSetRootElement(doc, root); + + g_hash_table_foreach(all_visited, (GHFunc) add_dir_record, root); + + save_xml_file(doc, path); + xmlFreeDoc(doc); + + g_free(path); + } + } + + struct purge_data { + time_t oldest; + GSList *to_remove; + }; + + static void check_for_purge(const char *path, const struct dir_record *dr, + struct purge_data *data) + { + if(dr->last_visitoldest && !dr->flags) + data->to_remove=g_slist_prepend(data->to_remove, path); + } + + static gint purge_dir_history(gpointer unused) + { + time_t now; + struct purge_data data; + GSList *rover; + + time(&now); + data.oldest=now-60*60; + data.to_remove=NULL; + + g_hash_table_foreach(all_visited, (GHFunc) check_for_purge, &data); + + for(rover=data.to_remove; rover; rover=g_slist_next(rover)) { + struct dir_record *dr; + + dr=(struct dir_record *) + g_hash_table_lookup(all_visited, (char *) rover->data); + if(dr) + g_free(dr); + g_hash_table_remove(all_visited, (char *) rover->data); + g_free(rover->data); + } + g_slist_free(data.to_remove); + } + + static void build_list(gpointer key, gpointer value, gpointer data) + { + GList **list=(GList **) data; + + *list=g_list_append(*list, value); + } + + void filer_window_save(FilerWindow *filer_window) + { + struct dir_record *dr; + + dr=(struct dir_record *) + g_hash_table_lookup(all_visited, filer_window->path); + if(dr) { + dr->style=filer_window->display_style; + dr->type=filer_window->details_type; + dr->flags|=(RECORDED_STYLE|RECORDED_TYPE); + } + } + + GList *filer_full_history(void) + { + GList *list=NULL; + + g_hash_table_foreach(all_visited, build_list, &list); + + return list; + } + + /* If thumbnail display is on, look through all the items in this directory * and start creating or updating the thumbnails as needed. */ Index:rox-1.2.0-history/ROX-Filer/src/filer.h *** rox-1.2.0/ROX-Filer/src/filer.h Mon Jan 28 18:03:21 2002 --- rox-1.2.0-history/ROX-Filer/src/filer.h Wed Feb 20 11:27:25 2002 *************** *** 80,85 **** --- 80,89 ---- GList *thumb_queue; /* paths to thumbnail */ GtkWidget *thumb_bar, *thumb_progress; int max_thumbs; /* total for this batch */ + + GSList *history; + GtkWidget *history_menu; + gboolean history_menu_ok; }; extern FilerWindow *window_with_focus; *************** *** 114,118 **** --- 118,126 ---- void filer_cancel_thumbnails(FilerWindow *filer_window); void filer_set_title(FilerWindow *filer_window); void filer_create_thumbs(FilerWindow *filer_window); + extern void filer_go_back(FilerWindow *filer_window); + extern FilerWindow *filer_open_back(FilerWindow *filer_window); + extern GList *filer_full_history(void); + extern void filer_window_save(FilerWindow *filer_window); #endif /* _FILER_H */ Index:rox-1.2.0-history/ROX-Filer/src/menu.c *** rox-1.2.0/ROX-Filer/src/menu.c Thu Jan 31 10:46:57 2002 --- rox-1.2.0-history/ROX-Filer/src/menu.c Wed Feb 20 09:49:38 2002 *************** *** 102,107 **** --- 102,112 ---- static gint updating_menu = 0; /* Non-zero => ignore activations */ static GList *send_to_paths = NULL; + struct reopen_data { + FilerWindow *filer; + gchar *path; + }; + /* Static prototypes */ static void save_menus(void); *************** *** 116,121 **** --- 121,127 ---- static void new_file_type(gchar *templ); static void do_send_to(gchar *templ); static void show_send_to_menu(GList *paths, GdkEvent *event); + static void update_reopen_menu(FilerWindow *filer, GtkWidget *menu); /* Note that for most of these callbacks none of the arguments are used. */ *************** *** 144,153 **** --- 150,163 ---- static void open_parent_same(gpointer data, guint action, GtkWidget *widget); static void open_parent(gpointer data, guint action, GtkWidget *widget); + static void open_previous_same(gpointer data, guint action, GtkWidget *widget); + static void open_previous(gpointer data, guint action, GtkWidget *widget); static void home_directory(gpointer data, guint action, GtkWidget *widget); static void new_window(gpointer data, guint action, GtkWidget *widget); /* static void new_user(gpointer data, guint action, GtkWidget *widget); */ static void close_window(gpointer data, guint action, GtkWidget *widget); + static void show_all_previous(gpointer data, guint action, GtkWidget *widget); + static void set_default(gpointer data, guint action, GtkWidget *widget); /* (action used in this - MiniType) */ static void mini_buffer(gpointer data, guint action, GtkWidget *widget); *************** *** 174,179 **** --- 184,190 ---- static GtkWidget *filer_thumb_menu; /* The Show Thumbs item */ static GtkWidget *filer_new_window; /* The New Window item */ static GtkWidget *filer_new_menu; /* The New submenu */ + static GtkWidget *window_reopen; /* Window->Re-open->this */ /* Used for Copy, etc */ static GtkWidget *savebox = NULL; *************** *** 216,221 **** --- 227,233 ---- {">" N_("Show Hidden"), NULL, hidden, 0, ""}, {">" N_("Show Thumbnails"), NULL, show_thumbs, 0, ""}, {">" N_("Refresh"), NULL, refresh, 0, NULL}, + {">" N_("Set default for this"), NULL, set_default, 0, NULL}, {N_("File"), NULL, NULL, 0, ""}, {">" N_("Copy..."), NULL, file_op, FILE_COPY_ITEM, NULL}, {">" N_("Rename..."), NULL, file_op, FILE_RENAME_ITEM, NULL}, *************** *** 253,258 **** --- 265,272 ---- {N_("Window"), NULL, NULL, 0, ""}, {">" N_("Parent, New Window"), NULL, open_parent, 0, NULL}, {">" N_("Parent, Same Window"), NULL, open_parent_same, 0, NULL}, + {">" N_("Previous, New Window"), NULL, open_previous, 0, NULL}, + {">" N_("Previous, Same Window"), NULL, open_previous_same, 0, NULL}, {">" N_("New Window"), NULL, new_window, 0, NULL}, {">" N_("Home Directory"), NULL, home_directory, 0, NULL}, {">" N_("Resize Window"), NULL, resize, 0, NULL}, *************** *** 259,264 **** --- 273,281 ---- /* {">" N_("New, As User..."), NULL, new_user, 0, NULL}, */ {">" N_("Close Window"), NULL, close_window, 0, NULL}, + {">" N_("Re-open"), NULL, NULL, 0, ""}, + {">>" N_("From This Window"), NULL, NULL, 0, NULL}, + {">>" N_("Any Window"), NULL, show_all_previous, 0, NULL}, {">", NULL, NULL, 0, ""}, {">" N_("Enter Path..."), "slash", mini_buffer, MINI_PATH, NULL}, {">" N_("Shell Command..."), NULL, mini_buffer, MINI_SHELL, NULL}, *************** *** 313,318 **** --- 330,338 ---- "Display", "Small, With..."); GET_SMENU_ITEM(filer_new_menu, "filer", "New"); + + GET_SSMENU_ITEM(window_reopen, "filer", + "Window", "Re-open/From This Window"); /* File '' label... */ items = gtk_container_children(GTK_CONTAINER(filer_menu)); *************** *** 830,835 **** --- 850,856 ---- } update_new_files_menu(get_menu_icon_style()); + update_reopen_menu(filer_window, window_reopen); gtk_widget_set_sensitive(filer_new_window, !o_unique_filer_windows); *************** *** 1477,1482 **** --- 1498,1621 ---- change_to_parent(window_with_focus); } + static void open_previous(gpointer data, guint action, GtkWidget *widget) + { + g_return_if_fail(window_with_focus != NULL); + + filer_open_back(window_with_focus); + } + + static void open_previous_same(gpointer data, guint action, GtkWidget *widget) + { + g_return_if_fail(window_with_focus != NULL); + + filer_go_back(window_with_focus); + } + + static void do_reopen(struct reopen_data *data) + { + filer_change_to(data->filer, data->path, NULL); + } + + static void show_all_previous(gpointer data, guint action, GtkWidget *widget) + { + GList *paths; + GdkEvent *event; + GtkWidget *menu; + GtkWidget *item; + GList *dirs; + MenuIconStyle style; + struct reopen_data *redata; + int nitem; + + paths = filer_full_history(); + event = gtk_get_current_event(); + + menu=gtk_menu_new(); + style=get_menu_icon_style(); + + nitem=0; + for(dirs=paths; dirs; dirs=g_list_next(dirs)) { + DirItem *ditem=NULL; + + redata=g_new(struct reopen_data, 1); + redata->filer=window_with_focus; + redata->path=(gchar *) dirs->data; /* Don't copy, use history list */ + + if(style!=MIS_NONE) { + ditem=diritem_new(redata->path); + if(ditem) + diritem_restat(redata->path, ditem); + } + if(style==MIS_NONE || !ditem || !ditem->image) { + item=gtk_menu_item_new_with_label(redata->path); + } else { + GdkPixmap *icon; + GdkBitmap *mask; + GtkWidget *hbox; + GtkWidget *img; + GtkWidget *label; + + switch (style) { + case MIS_HUGE: + if (!ditem->image->huge_pixmap) + pixmap_make_huge(ditem->image); + icon = ditem->image->huge_pixmap; + mask = ditem->image->huge_mask; + break; + + case MIS_LARGE: + icon = ditem->image->pixmap; + mask = ditem->image->mask; + break; + + case MIS_SMALL: + default: + if (!ditem->image->sm_pixmap) + pixmap_make_small(ditem->image); + icon = ditem->image->sm_pixmap; + mask = ditem->image->sm_mask; + break; + } + item = gtk_menu_item_new(); + hbox = gtk_hbox_new(FALSE, 2); + gtk_container_add(GTK_CONTAINER(item), hbox); + + img = gtk_pixmap_new(icon, mask); + gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 2); + + label = gtk_label_new(redata->path); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 2); + + diritem_free(ditem); + } + + gtk_widget_lock_accelerators(item); + gtk_signal_connect_object(GTK_OBJECT(item), "activate", + GTK_SIGNAL_FUNC(do_reopen), (GtkObject *) redata); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + gtk_signal_connect_object(GTK_OBJECT(item), "destroy", + GTK_SIGNAL_FUNC(g_free), (GtkObject *) redata); + + nitem++; + } + + show_popup_menu(menu, event, 0); + + gtk_widget_unref(menu); + + g_list_free(paths); + gdk_event_free(event); + } + + static void set_default(gpointer data, guint action, GtkWidget *widget) + { + g_return_if_fail(window_with_focus != NULL); + + filer_window_save(window_with_focus); + } + static void resize(gpointer data, guint action, GtkWidget *widget) { g_return_if_fail(window_with_focus != NULL); *************** *** 1606,1611 **** --- 1745,1855 ---- filer_opendir(make_path(app_dir, "Help")->str, NULL); } + static void update_reopen_menu(FilerWindow *filer, GtkWidget *menu) + { + GtkWidget *submenu; + GtkWidget *item; + MenuIconStyle style; + GSList *dirs; + struct reopen_data *data; + int nitem; + + if(filer->history_menu_ok) { + /*printf("re-use %p\n", filer->history_menu);*/ + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu), filer->history_menu); + return; + } + + submenu=gtk_menu_new(); + style=get_menu_icon_style(); + + nitem=0; + for(dirs=filer->history; dirs; dirs=g_slist_next(dirs)) { + DirItem *ditem=NULL; + + data=g_new(struct reopen_data, 1); + data->filer=filer; + data->path=(gchar *) dirs->data; /* Don't copy, use history list */ + + if(style!=MIS_NONE) { + ditem=diritem_new(data->path); + if(ditem) + diritem_restat(data->path, ditem); + } + if(style==MIS_NONE || !ditem || !ditem->image) { + item=gtk_menu_item_new_with_label(data->path); + } else { + GdkPixmap *icon; + GdkBitmap *mask; + GtkWidget *hbox; + GtkWidget *img; + GtkWidget *label; + + switch (style) { + case MIS_HUGE: + if (!ditem->image->huge_pixmap) + pixmap_make_huge(ditem->image); + icon = ditem->image->huge_pixmap; + mask = ditem->image->huge_mask; + break; + + case MIS_LARGE: + icon = ditem->image->pixmap; + mask = ditem->image->mask; + break; + + case MIS_SMALL: + default: + if (!ditem->image->sm_pixmap) + pixmap_make_small(ditem->image); + icon = ditem->image->sm_pixmap; + mask = ditem->image->sm_mask; + break; + } + item = gtk_menu_item_new(); + hbox = gtk_hbox_new(FALSE, 2); + gtk_container_add(GTK_CONTAINER(item), hbox); + + img = gtk_pixmap_new(icon, mask); + gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 2); + + label = gtk_label_new(data->path); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 2); + + diritem_free(ditem); + } + + gtk_widget_lock_accelerators(item); + gtk_signal_connect_object(GTK_OBJECT(item), "activate", + GTK_SIGNAL_FUNC(do_reopen), (GtkObject *) data); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item); + gtk_signal_connect_object(GTK_OBJECT(item), "destroy", + GTK_SIGNAL_FUNC(g_free), (GtkObject *) data); + + nitem++; + } + if(filer->history_menu) + gtk_widget_unref(filer->history_menu); + filer->history_menu=submenu; + gtk_widget_ref(filer->history_menu); + filer->history_menu_ok=TRUE; + + if(nitem==0) { + /*printf("no items\n");*/ + gtk_widget_set_sensitive(menu, FALSE); + return; + } + + gtk_widget_set_sensitive(menu, TRUE); + gtk_widget_show_all(submenu); + /* + * By setting a new submenu, the old one is removed and un-referenced, + * triggering a destroy. All its items are also destroyed, recursively + */ + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu), submenu); + } + /* Set n items from position 'from' in 'menu' to the 'shaded' state */ void menu_set_items_shaded(GtkWidget *menu, gboolean shaded, int from, int n) { Index:rox-1.2.0-history/ROX-Filer/src/toolbar.c *** rox-1.2.0/ROX-Filer/src/toolbar.c Wed Jan 2 15:36:04 2002 --- rox-1.2.0-history/ROX-Filer/src/toolbar.c Tue Feb 19 10:39:59 2002 *************** *** 299,312 **** static void toolbar_up_clicked(GtkWidget *widget, FilerWindow *filer_window) { GdkEvent *event; event = gtk_get_current_event(); if (event->type == GDK_BUTTON_RELEASE && NEW_WIN_BUTTON(event)) { ! filer_open_parent(filer_window); } - else - change_to_parent(filer_window); } static void toolbar_size_clicked(GtkWidget *widget, FilerWindow *filer_window) --- 299,323 ---- static void toolbar_up_clicked(GtkWidget *widget, FilerWindow *filer_window) { GdkEvent *event; + GdkEventButton *button=NULL; event = gtk_get_current_event(); + if(event->type == GDK_BUTTON_RELEASE || + event->type == GDK_BUTTON_PRESS) + button=(GdkEventButton *) event; + if (event->type == GDK_BUTTON_RELEASE && NEW_WIN_BUTTON(event)) { ! if(button->state & GDK_CONTROL_MASK) ! filer_open_back(filer_window); ! else ! filer_open_parent(filer_window); ! } else { ! if(button->state & GDK_CONTROL_MASK) ! filer_go_back(filer_window); ! else ! change_to_parent(filer_window); } } static void toolbar_size_clicked(GtkWidget *widget, FilerWindow *filer_window)