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
1=== modified file 'libcore/gof-directory-async.vala'
2--- libcore/gof-directory-async.vala 2015-02-07 13:09:34 +0000
3+++ libcore/gof-directory-async.vala 2015-02-15 18:37:53 +0000
4@@ -113,6 +113,10 @@
5 uri_contain_keypath_icons = "/icons" in file.uri || "/.icons" in file.uri;
6 }
7
8+ ~Async () {
9+ debug ("Async destruct");
10+ }
11+
12 /* This is also called when reloading the directory so that another attempt to connect to
13 * the network is made */
14 private bool prepare_directory () {
15
16=== modified file 'src/View/AbstractDirectoryView.vala'
17--- src/View/AbstractDirectoryView.vala 2015-02-07 17:29:07 +0000
18+++ src/View/AbstractDirectoryView.vala 2015-02-15 18:37:53 +0000
19@@ -201,10 +201,10 @@
20 private bool can_trash_or_delete = true;
21
22 /* Rapid keyboard paste support */
23- protected bool pasting_files = false;
24- GLib.Timer? paste_timer = null;
25- protected uint paste_timeout_id = 0;
26+ protected bool pasting_files = false;
27 protected bool select_added_files = false;
28+ private HashTable? pasted_files = null;
29+
30
31 public bool renaming {get; protected set; default = false;}
32
33@@ -214,7 +214,6 @@
34 private bool in_network_root = false;
35 protected bool is_loading;
36 protected bool helpers_shown;
37- private uint select_timeout_id = 0;
38
39 private Gtk.Widget view;
40 private unowned Marlin.ClipboardManager clipboard;
41@@ -360,39 +359,35 @@
42 unselect_all ();
43 GLib.List<GOF.File>? file_list = null;
44
45- if (focus_location == null)
46- focus_location = location_list.first ().data;
47-
48 location_list.@foreach ((loc) => {
49 file_list.prepend (GOF.File.@get (loc));
50 });
51
52 /* Because the Icon View disconnects the model while loading, we need to wait until
53 * the tree is thawed and the model reconnected before selecting the files */
54- select_timeout_id = GLib.Timeout.add (100, () => {
55- if (tree_frozen)
56- return true;
57-
58- file_list.@foreach ((file) => {
59- var iter = Gtk.TreeIter ();
60-
61- if (model.get_first_iter_for_file (file, out iter)) {
62- Gtk.TreePath path = model.get_path (iter);
63- if (path != null) {
64- if (focus_location.equal (file.location))
65- set_cursor (path, false, true, false); /* set cursor and select */
66- else
67- select_path (path);
68- }
69- }
70- });
71- select_timeout_id = 0;
72- return false;
73+ Idle.add (() => {
74+ bool try_again = true;
75+ if (!tree_frozen) {
76+ try_again = false;
77+ file_list.@foreach ((file) => {
78+ var iter = Gtk.TreeIter ();
79+ if (model.get_first_iter_for_file (file, out iter)) {
80+ Gtk.TreePath path = model.get_path (iter);
81+ if (path != null) {
82+ if (focus_location != null && focus_location.equal (file.location))
83+ set_cursor (path, false, true, false); /* set cursor and select */
84+ else
85+ select_path (path);
86+ }
87+ } else {
88+ /* model has not caught up yet - wait a bit */
89+ try_again = true;
90+ }
91+ });
92+ }
93+ return try_again;
94 });
95-
96 updates_frozen = false;
97- update_selected_files ();
98- notify_selection_changed ();
99 }
100
101 public unowned GLib.List<GLib.AppInfo> get_open_with_apps () {
102@@ -1070,29 +1065,23 @@
103 assert (pointer != null);
104
105 var view = pointer as FM.AbstractDirectoryView;
106- if (view.paste_timer == null)
107- view.paste_timer = new GLib.Timer ();
108-
109- view.paste_timer.start (); /* restarts timer if already running */
110-
111- /* Limit paste action rate to 10 per second, do not unblock the directory monitor
112- * until at least one second after the last paste event in order to avoid duplicate
113- * "add-file" events and messed up selection. */
114- if (view.paste_timeout_id == 0) {
115- view.paste_timeout_id = Timeout.add (100, () => {
116- view.pasting_files = false; /* allows another paste action to occur */
117-
118- if (view.paste_timer.elapsed () < 1.0)
119- return true;
120-
121- view.slot.directory.unblock_monitor ();
122- view.select_added_files = false;
123- view.paste_timeout_id = 0;
124- view.paste_timer.stop ();
125- view.paste_timer = null;
126- return false;
127+ view.pasted_files = uris;
128+
129+ Idle.add (() => {
130+ /* Select the most recently pasted files */
131+ GLib.List<GLib.File> pasted_files_list = null;
132+ view.pasted_files.foreach ((k, v) => {
133+ File f = k as File;
134+ pasted_files_list.prepend (f);
135 });
136- }
137+
138+ if (!view.slot.directory.is_local)
139+ view.slot.directory.need_reload ();
140+
141+ view.select_glib_files (pasted_files_list, null);
142+ view.pasting_files = false;
143+ return false;
144+ });
145 }
146
147 private void on_common_action_paste_into (GLib.SimpleAction action, GLib.Variant? param) {
148@@ -1116,9 +1105,7 @@
149 call_back = (GLib.Callback)after_trash_or_delete;
150 } else {
151 pasting_files = true;
152- prepare_to_select_added_files ();
153- /* Block the async directory file monitor to avoid generating unwanted "add-file" events */
154- slot.directory.block_monitor ();
155+ /* callback takes care of selecting pasted files */
156 call_back = (GLib.Callback)after_pasting_files;
157 }
158
159@@ -1465,8 +1452,10 @@
160
161 case TargetType.TEXT_URI_LIST:
162 if ((current_actions & file_drag_actions) != 0) {
163- prepare_to_select_added_files ();
164-
165+ if (selected_files != null)
166+ unselect_all ();
167+
168+ select_added_files = true;
169 success = dnd_handler.handle_file_drag_actions (get_real_view (),
170 window,
171 context,
172@@ -2254,13 +2243,6 @@
173 }
174 }
175
176- private void prepare_to_select_added_files () {
177- if (selected_files != null)
178- unselect_all ();
179-
180- select_added_files = true;
181- }
182-
183 private void remove_marlin_icon_info_cache (GOF.File file) {
184 string? path = file.get_thumbnail_path ();
185
186@@ -2282,9 +2264,10 @@
187 */
188 private unowned GLib.List<unowned GOF.File> get_files_for_action () {
189 unowned GLib.List<unowned GOF.File> action_files = null;
190- if (selected_files == null) {
191+
192+ if (selected_files == null)
193 action_files.prepend (slot.directory.file);
194- } else
195+ else
196 action_files = selected_files;
197
198 return action_files;
199@@ -2296,12 +2279,10 @@
200
201 protected virtual void on_view_selection_changed () {
202 update_selected_files ();
203-
204 if (updates_frozen)
205 return;
206
207 notify_selection_changed ();
208- update_menu_actions ();
209 }
210
211 protected virtual bool on_view_key_press_event (Gdk.EventKey event) {
212@@ -2950,7 +2931,6 @@
213 cancel_thumbnailing ();
214 slot.directory.cancel ();
215 cancel_drag_timer ();
216- cancel_timeout (ref select_timeout_id);
217 cancel_timeout (ref drag_scroll_timer_id);
218
219 loaded_subdirectories.@foreach ((dir) => {
220
221=== modified file 'src/View/AbstractTreeView.vala'
222--- src/View/AbstractTreeView.vala 2015-01-24 12:31:20 +0000
223+++ src/View/AbstractTreeView.vala 2015-02-15 18:37:53 +0000
224@@ -28,6 +28,10 @@
225 base (_slot);
226 }
227
228+ ~AbstractTreeView () {
229+ debug ("ATV destruct");
230+ }
231+
232 protected virtual void create_and_set_up_name_column () {
233 name_column = new Gtk.TreeViewColumn ();
234 name_column.set_sort_column_id (FM.ListModel.ColumnID.FILENAME);
235
236=== modified file 'src/View/IconView.vala'
237--- src/View/IconView.vala 2015-01-24 12:31:20 +0000
238+++ src/View/IconView.vala 2015-02-15 18:37:53 +0000
239@@ -31,6 +31,10 @@
240 zoom_level = minimum_zoom;
241 }
242
243+ ~IconView () {
244+ debug ("Icon View destruct");
245+ }
246+
247 private void set_up_view () {
248 tree.set_model (model);
249 tree.set_selection_mode (Gtk.SelectionMode.MULTIPLE);
250
251=== modified file 'src/View/PropertiesWindow.vala'
252--- src/View/PropertiesWindow.vala 2015-02-07 16:40:33 +0000
253+++ src/View/PropertiesWindow.vala 2015-02-15 18:37:53 +0000
254@@ -1375,7 +1375,7 @@
255 if (allocated_size < file_size && !gof.is_directory)
256 file_size = allocated_size;
257 } catch (Error err) {
258- warning ("%s", err.message);
259+ debug ("%s", err.message);
260 gof.is_connected = false;
261 }
262 }
263
264=== modified file 'src/View/Slot.vala'
265--- src/View/Slot.vala 2015-02-01 17:09:35 +0000
266+++ src/View/Slot.vala 2015-02-15 18:37:53 +0000
267@@ -37,9 +37,9 @@
268 public string denied_message = "<span size='x-large'>" + _("Access denied") + "</span>";
269
270 public signal bool horizontal_scroll_event (double delta_x);
271- public signal void frozen_changed (bool freeze);
272+ public signal void frozen_changed (bool freeze);
273 public signal void folder_deleted (GOF.File file, GOF.Directory.Async parent);
274- public signal void active (bool scroll = true);
275+ public signal void active (bool scroll = true);
276 public signal void inactive ();
277
278 /* Support for multi-slot view (Miller)*/
279@@ -275,6 +275,7 @@
280 }
281
282 public override void reload () {
283+ directory.clear_directory_info ();
284 user_path_change_request (location, false);
285 }
286
287
288=== modified file 'src/View/ViewContainer.vala'
289--- src/View/ViewContainer.vala 2015-02-06 22:57:55 +0000
290+++ src/View/ViewContainer.vala 2015-02-15 18:37:53 +0000
291@@ -155,12 +155,6 @@
292 view.cancel ();
293 }
294
295- /* the following 2 lines delays destruction of the old view until this function returns
296- * and allows the processor to display or update the window more quickly
297- */
298- GOF.AbstractSlot temp;
299- temp = view;
300-
301 if (mode == Marlin.ViewMode.MILLER_COLUMNS)
302 view = new Miller (loc, this, mode);
303 else

Subscribers

People subscribed via source and target branches

to all changes: