Merge lp:~jeremywootten/pantheon-files/fix-refresh-after-paste into lp:~elementary-apps/pantheon-files/trunk

Proposed by Jeremy Wootten
Status: Merged
Approved by: Jeremy Wootten
Approved revision: 1740
Merge reported by: Jeremy Wootten
Merged at revision: not available
Proposed branch: lp:~jeremywootten/pantheon-files/fix-refresh-after-paste
Merge into: lp:~elementary-apps/pantheon-files/trunk
Diff against target: 303 lines (+64/-77)
7 files modified
libcore/gof-directory-async.vala (+4/-0)
src/View/AbstractDirectoryView.vala (+48/-68)
src/View/AbstractTreeView.vala (+4/-0)
src/View/IconView.vala (+4/-0)
src/View/PropertiesWindow.vala (+1/-1)
src/View/Slot.vala (+3/-2)
src/View/ViewContainer.vala (+0/-6)
To merge this branch: bzr merge lp:~jeremywootten/pantheon-files/fix-refresh-after-paste
Reviewer Review Type Date Requested Status
Fabio Zaramella (community) Approve
elementary Apps team Pending
Review via email: mp+249779@code.launchpad.net

Commit message

Fix refresh after pasting for local files and folders.

Description of the change

1) When refreshing a view, the directory cached information is cleared first to ensure the information is reloaded from source.

2) The code for selecting files after pasting is re-written avoiding fixed timeouts and reverting some changes that were blocking apparently duplicate signals (but which were sometimes needed)

NOTE. Copy/cut/paste and drag-drop of files between local folders should work as expected. There are still some problems with samba shared folders, where it is not 100% reliable. Networking issues will be dealt with in another branch.

To post a comment you must log in.
Revision history for this message
Fabio Zaramella (fabiozaramella) wrote :

I've tried copying some folders and files, whether hidden or not, and they were always immediately shown, so the branch seems to solve these bugs.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'libcore/gof-directory-async.vala'
--- libcore/gof-directory-async.vala 2015-02-07 13:09:34 +0000
+++ libcore/gof-directory-async.vala 2015-02-15 18:37:53 +0000
@@ -113,6 +113,10 @@
113 uri_contain_keypath_icons = "/icons" in file.uri || "/.icons" in file.uri;113 uri_contain_keypath_icons = "/icons" in file.uri || "/.icons" in file.uri;
114 }114 }
115115
116 ~Async () {
117 debug ("Async destruct");
118 }
119
116 /* This is also called when reloading the directory so that another attempt to connect to120 /* This is also called when reloading the directory so that another attempt to connect to
117 * the network is made */121 * the network is made */
118 private bool prepare_directory () {122 private bool prepare_directory () {
119123
=== modified file 'src/View/AbstractDirectoryView.vala'
--- src/View/AbstractDirectoryView.vala 2015-02-07 17:29:07 +0000
+++ src/View/AbstractDirectoryView.vala 2015-02-15 18:37:53 +0000
@@ -201,10 +201,10 @@
201 private bool can_trash_or_delete = true;201 private bool can_trash_or_delete = true;
202202
203 /* Rapid keyboard paste support */203 /* Rapid keyboard paste support */
204 protected bool pasting_files = false;204 protected bool pasting_files = false;
205 GLib.Timer? paste_timer = null;
206 protected uint paste_timeout_id = 0;
207 protected bool select_added_files = false;205 protected bool select_added_files = false;
206 private HashTable? pasted_files = null;
207
208208
209 public bool renaming {get; protected set; default = false;}209 public bool renaming {get; protected set; default = false;}
210210
@@ -214,7 +214,6 @@
214 private bool in_network_root = false;214 private bool in_network_root = false;
215 protected bool is_loading;215 protected bool is_loading;
216 protected bool helpers_shown;216 protected bool helpers_shown;
217 private uint select_timeout_id = 0;
218217
219 private Gtk.Widget view;218 private Gtk.Widget view;
220 private unowned Marlin.ClipboardManager clipboard;219 private unowned Marlin.ClipboardManager clipboard;
@@ -360,39 +359,35 @@
360 unselect_all ();359 unselect_all ();
361 GLib.List<GOF.File>? file_list = null;360 GLib.List<GOF.File>? file_list = null;
362361
363 if (focus_location == null)
364 focus_location = location_list.first ().data;
365
366 location_list.@foreach ((loc) => {362 location_list.@foreach ((loc) => {
367 file_list.prepend (GOF.File.@get (loc));363 file_list.prepend (GOF.File.@get (loc));
368 });364 });
369365
370 /* Because the Icon View disconnects the model while loading, we need to wait until366 /* Because the Icon View disconnects the model while loading, we need to wait until
371 * the tree is thawed and the model reconnected before selecting the files */367 * the tree is thawed and the model reconnected before selecting the files */
372 select_timeout_id = GLib.Timeout.add (100, () => {368 Idle.add (() => {
373 if (tree_frozen)369 bool try_again = true;
374 return true;370 if (!tree_frozen) {
375371 try_again = false;
376 file_list.@foreach ((file) => {372 file_list.@foreach ((file) => {
377 var iter = Gtk.TreeIter ();373 var iter = Gtk.TreeIter ();
378374 if (model.get_first_iter_for_file (file, out iter)) {
379 if (model.get_first_iter_for_file (file, out iter)) {375 Gtk.TreePath path = model.get_path (iter);
380 Gtk.TreePath path = model.get_path (iter);376 if (path != null) {
381 if (path != null) {377 if (focus_location != null && focus_location.equal (file.location))
382 if (focus_location.equal (file.location))378 set_cursor (path, false, true, false); /* set cursor and select */
383 set_cursor (path, false, true, false); /* set cursor and select */379 else
384 else380 select_path (path);
385 select_path (path);381 }
386 } 382 } else {
387 }383 /* model has not caught up yet - wait a bit */
388 });384 try_again = true;
389 select_timeout_id = 0;385 }
390 return false;386 });
387 }
388 return try_again;
391 });389 });
392
393 updates_frozen = false;390 updates_frozen = false;
394 update_selected_files ();
395 notify_selection_changed ();
396 }391 }
397392
398 public unowned GLib.List<GLib.AppInfo> get_open_with_apps () {393 public unowned GLib.List<GLib.AppInfo> get_open_with_apps () {
@@ -1070,29 +1065,23 @@
1070 assert (pointer != null);1065 assert (pointer != null);
10711066
1072 var view = pointer as FM.AbstractDirectoryView; 1067 var view = pointer as FM.AbstractDirectoryView;
1073 if (view.paste_timer == null)1068 view.pasted_files = uris;
1074 view.paste_timer = new GLib.Timer ();1069
10751070 Idle.add (() => {
1076 view.paste_timer.start (); /* restarts timer if already running */1071 /* Select the most recently pasted files */
10771072 GLib.List<GLib.File> pasted_files_list = null;
1078 /* Limit paste action rate to 10 per second, do not unblock the directory monitor1073 view.pasted_files.foreach ((k, v) => {
1079 * until at least one second after the last paste event in order to avoid duplicate1074 File f = k as File;
1080 * "add-file" events and messed up selection. */ 1075 pasted_files_list.prepend (f);
1081 if (view.paste_timeout_id == 0) {
1082 view.paste_timeout_id = Timeout.add (100, () => {
1083 view.pasting_files = false; /* allows another paste action to occur */
1084
1085 if (view.paste_timer.elapsed () < 1.0)
1086 return true;
1087
1088 view.slot.directory.unblock_monitor ();
1089 view.select_added_files = false;
1090 view.paste_timeout_id = 0;
1091 view.paste_timer.stop ();
1092 view.paste_timer = null;
1093 return false;
1094 });1076 });
1095 }1077
1078 if (!view.slot.directory.is_local)
1079 view.slot.directory.need_reload ();
1080
1081 view.select_glib_files (pasted_files_list, null);
1082 view.pasting_files = false;
1083 return false;
1084 });
1096 }1085 }
10971086
1098 private void on_common_action_paste_into (GLib.SimpleAction action, GLib.Variant? param) {1087 private void on_common_action_paste_into (GLib.SimpleAction action, GLib.Variant? param) {
@@ -1116,9 +1105,7 @@
1116 call_back = (GLib.Callback)after_trash_or_delete;1105 call_back = (GLib.Callback)after_trash_or_delete;
1117 } else {1106 } else {
1118 pasting_files = true;1107 pasting_files = true;
1119 prepare_to_select_added_files ();1108 /* callback takes care of selecting pasted files */
1120 /* Block the async directory file monitor to avoid generating unwanted "add-file" events */
1121 slot.directory.block_monitor ();
1122 call_back = (GLib.Callback)after_pasting_files;1109 call_back = (GLib.Callback)after_pasting_files;
1123 }1110 }
11241111
@@ -1465,8 +1452,10 @@
14651452
1466 case TargetType.TEXT_URI_LIST:1453 case TargetType.TEXT_URI_LIST:
1467 if ((current_actions & file_drag_actions) != 0) {1454 if ((current_actions & file_drag_actions) != 0) {
1468 prepare_to_select_added_files ();1455 if (selected_files != null)
14691456 unselect_all ();
1457
1458 select_added_files = true;
1470 success = dnd_handler.handle_file_drag_actions (get_real_view (),1459 success = dnd_handler.handle_file_drag_actions (get_real_view (),
1471 window,1460 window,
1472 context,1461 context,
@@ -2254,13 +2243,6 @@
2254 }2243 }
2255 }2244 }
22562245
2257 private void prepare_to_select_added_files () {
2258 if (selected_files != null)
2259 unselect_all ();
2260
2261 select_added_files = true;
2262 }
2263
2264 private void remove_marlin_icon_info_cache (GOF.File file) {2246 private void remove_marlin_icon_info_cache (GOF.File file) {
2265 string? path = file.get_thumbnail_path ();2247 string? path = file.get_thumbnail_path ();
22662248
@@ -2282,9 +2264,10 @@
2282 */ 2264 */
2283 private unowned GLib.List<unowned GOF.File> get_files_for_action () {2265 private unowned GLib.List<unowned GOF.File> get_files_for_action () {
2284 unowned GLib.List<unowned GOF.File> action_files = null;2266 unowned GLib.List<unowned GOF.File> action_files = null;
2285 if (selected_files == null) {2267
2268 if (selected_files == null)
2286 action_files.prepend (slot.directory.file);2269 action_files.prepend (slot.directory.file);
2287 } else2270 else
2288 action_files = selected_files;2271 action_files = selected_files;
22892272
2290 return action_files;2273 return action_files;
@@ -2296,12 +2279,10 @@
22962279
2297 protected virtual void on_view_selection_changed () {2280 protected virtual void on_view_selection_changed () {
2298 update_selected_files ();2281 update_selected_files ();
2299
2300 if (updates_frozen)2282 if (updates_frozen)
2301 return;2283 return;
23022284
2303 notify_selection_changed ();2285 notify_selection_changed ();
2304 update_menu_actions ();
2305 }2286 }
23062287
2307 protected virtual bool on_view_key_press_event (Gdk.EventKey event) {2288 protected virtual bool on_view_key_press_event (Gdk.EventKey event) {
@@ -2950,7 +2931,6 @@
2950 cancel_thumbnailing ();2931 cancel_thumbnailing ();
2951 slot.directory.cancel ();2932 slot.directory.cancel ();
2952 cancel_drag_timer ();2933 cancel_drag_timer ();
2953 cancel_timeout (ref select_timeout_id);
2954 cancel_timeout (ref drag_scroll_timer_id);2934 cancel_timeout (ref drag_scroll_timer_id);
2955 2935
2956 loaded_subdirectories.@foreach ((dir) => {2936 loaded_subdirectories.@foreach ((dir) => {
29572937
=== modified file 'src/View/AbstractTreeView.vala'
--- src/View/AbstractTreeView.vala 2015-01-24 12:31:20 +0000
+++ src/View/AbstractTreeView.vala 2015-02-15 18:37:53 +0000
@@ -28,6 +28,10 @@
28 base (_slot);28 base (_slot);
29 }29 }
3030
31 ~AbstractTreeView () {
32 debug ("ATV destruct");
33 }
34
31 protected virtual void create_and_set_up_name_column () {35 protected virtual void create_and_set_up_name_column () {
32 name_column = new Gtk.TreeViewColumn ();36 name_column = new Gtk.TreeViewColumn ();
33 name_column.set_sort_column_id (FM.ListModel.ColumnID.FILENAME);37 name_column.set_sort_column_id (FM.ListModel.ColumnID.FILENAME);
3438
=== modified file 'src/View/IconView.vala'
--- src/View/IconView.vala 2015-01-24 12:31:20 +0000
+++ src/View/IconView.vala 2015-02-15 18:37:53 +0000
@@ -31,6 +31,10 @@
31 zoom_level = minimum_zoom;31 zoom_level = minimum_zoom;
32 }32 }
3333
34 ~IconView () {
35 debug ("Icon View destruct");
36 }
37
34 private void set_up_view () {38 private void set_up_view () {
35 tree.set_model (model);39 tree.set_model (model);
36 tree.set_selection_mode (Gtk.SelectionMode.MULTIPLE);40 tree.set_selection_mode (Gtk.SelectionMode.MULTIPLE);
3741
=== modified file 'src/View/PropertiesWindow.vala'
--- src/View/PropertiesWindow.vala 2015-02-07 16:40:33 +0000
+++ src/View/PropertiesWindow.vala 2015-02-15 18:37:53 +0000
@@ -1375,7 +1375,7 @@
1375 if (allocated_size < file_size && !gof.is_directory)1375 if (allocated_size < file_size && !gof.is_directory)
1376 file_size = allocated_size;1376 file_size = allocated_size;
1377 } catch (Error err) {1377 } catch (Error err) {
1378 warning ("%s", err.message);1378 debug ("%s", err.message);
1379 gof.is_connected = false;1379 gof.is_connected = false;
1380 }1380 }
1381 }1381 }
13821382
=== modified file 'src/View/Slot.vala'
--- src/View/Slot.vala 2015-02-01 17:09:35 +0000
+++ src/View/Slot.vala 2015-02-15 18:37:53 +0000
@@ -37,9 +37,9 @@
37 public string denied_message = "<span size='x-large'>" + _("Access denied") + "</span>";37 public string denied_message = "<span size='x-large'>" + _("Access denied") + "</span>";
3838
39 public signal bool horizontal_scroll_event (double delta_x);39 public signal bool horizontal_scroll_event (double delta_x);
40 public signal void frozen_changed (bool freeze); 40 public signal void frozen_changed (bool freeze);
41 public signal void folder_deleted (GOF.File file, GOF.Directory.Async parent);41 public signal void folder_deleted (GOF.File file, GOF.Directory.Async parent);
42 public signal void active (bool scroll = true); 42 public signal void active (bool scroll = true);
43 public signal void inactive ();43 public signal void inactive ();
4444
45 /* Support for multi-slot view (Miller)*/45 /* Support for multi-slot view (Miller)*/
@@ -275,6 +275,7 @@
275 }275 }
276276
277 public override void reload () {277 public override void reload () {
278 directory.clear_directory_info ();
278 user_path_change_request (location, false);279 user_path_change_request (location, false);
279 }280 }
280281
281282
=== modified file 'src/View/ViewContainer.vala'
--- src/View/ViewContainer.vala 2015-02-06 22:57:55 +0000
+++ src/View/ViewContainer.vala 2015-02-15 18:37:53 +0000
@@ -155,12 +155,6 @@
155 view.cancel ();155 view.cancel ();
156 }156 }
157157
158 /* the following 2 lines delays destruction of the old view until this function returns
159 * and allows the processor to display or update the window more quickly
160 */
161 GOF.AbstractSlot temp;
162 temp = view;
163
164 if (mode == Marlin.ViewMode.MILLER_COLUMNS)158 if (mode == Marlin.ViewMode.MILLER_COLUMNS)
165 view = new Miller (loc, this, mode);159 view = new Miller (loc, this, mode);
166 else160 else

Subscribers

People subscribed via source and target branches

to all changes: