Merge lp:~niclasl/pantheon-files/fix-1198334 into lp:~elementary-apps/pantheon-files/trunk

Proposed by Niclas Lockner
Status: Merged
Approved by: Niclas Lockner
Approved revision: 1474
Merged at revision: 1549
Proposed branch: lp:~niclasl/pantheon-files/fix-1198334
Merge into: lp:~elementary-apps/pantheon-files/trunk
Diff against target: 244 lines (+67/-45)
3 files modified
libcore/gof-directory-async.vala (+9/-24)
src/View/ViewContainer.vala (+54/-21)
src/View/Window.vala (+4/-0)
To merge this branch: bzr merge lp:~niclasl/pantheon-files/fix-1198334
Reviewer Review Type Date Requested Status
Cody Garver (community) Approve
Robert Roth (community) Needs Fixing
Review via email: mp+215001@code.launchpad.net

Commit message

Mount a remote share before entering it so that the display name can be properly read when refreshing the tab (lp:1198334)

Description of the change

Mount a remote share before entering it so that the display name can be properly read when refreshing the tab.

To post a comment you must log in.
Revision history for this message
David Gomes (davidgomes) wrote :

Cannot replicate bug ergo cannot review this.

Revision history for this message
Niclas Lockner (niclasl) wrote :

To reproduce it, I added a bookmark to a smb share which I then opened in Files. Without this fix, you should see "folder does not exist" as the tab title after the share has been mounted and the directory has been loaded.

Revision history for this message
David Gomes (davidgomes) wrote :

Yeah, but I have a couple of SSH entries on my Files sidebar and when I open them the tab title is the name of the folder it opens.

Revision history for this message
Cody Garver (codygarver) wrote :

I still get it for some places where I need credentials or where it turns out a share apparently does not exist as advertised: http://i.imgur.com/ycCZ48I.png[

Revision history for this message
Jeremy Wootten (jeremywootten) wrote :

It appears that this is a timing issue. I only get the problem when navigating to an unmounted share - this is because it takes longer to mount the share and establish the folder exists than it does to create and activate the slot (at which point the tab name is written). However, once the share is mounted, the information is available before the slot becomes active, even if you close and reopen the program. If you log out and back in the problem recurs (once).

The branch cures the problem to the extent that once the share has been mounted and loaded, the tab name is corrected, although it still shows "Folder does not exist" until then.

A possibly better solution would be to name the tab on the assumption that the folder exists and only change it to "Folder does not exist" once it has been established that the folder really does not exist. It could be argued that it is not necessary to rename the tab even then because the content gives the "Folder does not exist" information.

Revision history for this message
Robert Roth (evfool) wrote :

@Niclas Lockner: Could you implement Jeremy's suggestion from his last comment: name the tab with the folder name and change it to "Folder does not exist" if the connection is established and the folder is really missing?

@Jeremy Wooten: I think there's no point in arguing about not renaming the tab even when the folder does not exist, as the user somehow has to be informed that the folder does not exist, and forced to select another folder from the share/ssh. This could be an infobar, showing an edit button to edit the location the bookmark is pointing to, but that should be treated as a separate enhancement.

review: Needs Fixing
Revision history for this message
Niclas Lockner (niclasl) wrote :

I've started looking into this again and it seems to be hard to fix this in a clean way.

The problem is that a directory's display name, which is used as the tab name right now, is only accessible through a FileInfo object, but the GOF.File's FileInfo property isn't accessible as long as the share isn't mounted (GLib.File.query_info returns null for unmounted shares).
So what should be shown as the tab label until the share has been properly mounted?

One possibility is to manually extract the basename from the uri and add it as a tab label, e.g.
sftp://foo/bar would get "bar" as the tab label, but that approach doesn't work well on smb shares, since the display name of "smb://foo/bar" is "bar on foo" and not "foo". I.e. if a user moves away from a smb share and then go back to it, the user will see two different labels for the same directory.

Another approach is to let the tab label be empty until it can be properly named by the directory_done_loading method.

Revision history for this message
Cody Garver (codygarver) wrote :

Talked to Dan about it, he said "Connecting…" with a gtk.spinner tab icon if possible.

Revision history for this message
Niclas Lockner (niclasl) wrote :

I've committed a working version now, but it has an issue with the tab icons which is fixed by lp:~niclasl/granite/tab-icon-visibility

Once that branch has been merged, I'll propose this for merging.

Revision history for this message
Cody Garver (codygarver) wrote :

Use a real elipsis …

Revision history for this message
Niclas Lockner (niclasl) wrote :

As in I should bring back the Gtk.Label I removed?

Revision history for this message
Cody Garver (codygarver) wrote :

Copy and paste the elipsis character in this comment over the three periods on diff line 30 …

Revision history for this message
Cody Garver (codygarver) wrote :

Also I notice that if you cancel the authentication dialog it continues to say it's loading

Revision history for this message
Niclas Lockner (niclasl) wrote :

I noticed that too. Would it be an acceptable behavior to change directory to the user's home directory when cancel is clicked? If not, what should happen?

Revision history for this message
Cody Garver (codygarver) wrote :

What about kicking them up a "level"? e.g.

Entire Network > click Some Host > click Some Share that asks for password > Cancel > Get returned to Some Host

And would that work for everything? I've only been testing this with samba shares

Revision history for this message
Cody Garver (codygarver) wrote :

I just tested nautilus 3.10 and it doesn't even enter the share until you successfully authenticate.

Let's see what Dan says.

Revision history for this message
Niclas Lockner (niclasl) wrote :

I use bookmarks to smb and ssh shares and there's no "up" if I click on them. Another solution would be to just go back to the previous location (and maybe to home if there's no previous location). You would sort of get the behavior you described, but only if you actually clicked Entire Network > Some host > Some share.

Revision history for this message
Danielle Foré (danrabbit) wrote :

It might be better to, like Cody suggested, wait to enter the directory until after we've authenticated.

Revision history for this message
Niclas Lockner (niclasl) wrote :

Now it mounts the share before entering it, and if the mount operation fails it stays in the current directory.

Revision history for this message
Cody Garver (codygarver) wrote :

Everything with this branch is great, we just need to verify the required dynamicnotebook changes here and in granite are good

review: Approve
Revision history for this message
RabbitBot (rabbitbot-a) wrote :

Attempt to merge into lp:pantheon-files failed due to conflicts:

text conflict in src/View/ViewContainer.vala

1474. By Niclas Lockner

Merge with trunk

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 2014-06-05 06:52:48 +0000
3+++ libcore/gof-directory-async.vala 2014-07-31 20:18:53 +0000
4@@ -139,11 +139,6 @@
5 if (state == State.LOADING)
6 clear_directory_info ();
7
8- if (!file.is_mounted) {
9- mount_mountable.begin ();
10- return;
11- }
12-
13 list_directory.begin ();
14
15 try {
16@@ -204,25 +199,19 @@
17 }
18 }
19
20- private async void mount_mountable () {
21+ public async void mount_mountable () throws Error {
22 debug ("mount_mountable %s", file.uri);
23
24 /* TODO pass GtkWindow *parent to Gtk.MountOperation */
25 var mount_op = new Gtk.MountOperation (null);
26
27- try {
28- if (file.file_type != FileType.MOUNTABLE) {
29- yield location.mount_enclosing_volume (0, mount_op, cancellable);
30- } else {
31- yield location.mount_mountable (0, mount_op, cancellable);
32- }
33+ if (file.file_type != FileType.MOUNTABLE)
34+ yield location.mount_enclosing_volume (0, mount_op, cancellable);
35+ else
36+ yield location.mount_mountable (0, mount_op, cancellable);
37
38- file.is_mounted = true;
39- yield query_info_async (file, file_info_available);
40- load ();
41- } catch (Error e) {
42- warning ("mount_mountable failed: %s %s", e.message, file.uri);
43- }
44+ file.is_mounted = true;
45+ yield query_info_async (file, file_info_available);
46 }
47
48 private async void list_directory () {
49@@ -278,15 +267,11 @@
50 if (err is IOError.NOT_FOUND || err is IOError.NOT_DIRECTORY)
51 file.exists = false;
52
53- if (err is IOError.PERMISSION_DENIED)
54+ else if (err is IOError.PERMISSION_DENIED)
55 permission_denied = true;
56
57- if (err is IOError.NOT_MOUNTED) {
58+ else if (err is IOError.NOT_MOUNTED)
59 file.is_mounted = false;
60- /* try again this time it shoould be mounted */
61- load ();
62- return;
63- }
64 }
65
66 //TODO send err code
67
68=== modified file 'src/View/ViewContainer.vala'
69--- src/View/ViewContainer.vala 2014-07-16 19:21:40 +0000
70+++ src/View/ViewContainer.vala 2014-07-31 20:18:53 +0000
71@@ -27,7 +27,7 @@
72 public Gtk.Widget? content_item;
73 public bool content_shown = false;
74 public bool can_show_folder = true;
75- public Gtk.Label label;
76+ private string label;
77 private Marlin.View.Window window;
78 public GOF.Window.Slot? slot = null;
79 public Marlin.Window.Columns? mwcol = null;
80@@ -43,6 +43,7 @@
81 public signal void back (int n=1);
82 public signal void forward (int n=1);
83 public signal void tab_name_changed (string tab_name);
84+ public signal void loading (bool is_loading);
85
86 public ViewContainer (Marlin.View.Window win, GLib.File location, int _view_mode = 0) {
87 window = win;
88@@ -51,11 +52,7 @@
89
90 /* set active tab */
91 browser = new Browser ();
92- label = new Gtk.Label ("Loading...");
93- label.set_ellipsize (Pango.EllipsizeMode.END);
94- label.set_single_line_mode (true);
95- label.set_alignment (0.0f, 0.5f);
96- label.set_padding (0, 0);
97+ label = _("Loading…");
98 window.button_back.fetcher = get_back_menu;
99 window.button_forward.fetcher = get_forward_menu;
100
101@@ -116,11 +113,11 @@
102
103 public string tab_name {
104 set {
105- label.label = value;
106+ label = value;
107 tab_name_changed (value);
108 }
109 get {
110- return label.label;
111+ return label;
112 }
113 }
114
115@@ -139,13 +136,14 @@
116 }
117
118 public void refresh_slot_info () {
119+ loading (false);
120 var aslot = get_active_slot ();
121 var slot_path = aslot.directory.file.location.get_path ();
122 if (slot_path == Environment.get_home_dir ())
123 tab_name = _("Home");
124 else if (slot_path == "/")
125 tab_name = _("File System");
126- else if (slot.directory.file.exists && (aslot.directory.file.info is FileInfo))
127+ else if (aslot.directory.file.exists && (aslot.directory.file.info is FileInfo))
128 tab_name = aslot.directory.file.info.get_attribute_string (FileAttribute.STANDARD_DISPLAY_NAME);
129 else {
130 tab_name = _("This folder does not exist");
131@@ -188,7 +186,12 @@
132 }
133 } catch (Error err) {
134 /* query_info will throw an expception if it cannot find the file */
135- content = new DirectoryNotFound (slot.directory, this);
136+
137+ if (err is IOError.NOT_MOUNTED) {
138+ reload ();
139+ } else {
140+ content = new DirectoryNotFound (slot.directory, this);
141+ }
142 }
143
144 warning ("directory done loading");
145@@ -223,26 +226,54 @@
146 select_childs.prepend (slot.directory.file.location);
147 }
148 }
149- if (slot != null && slot.directory != null && slot.directory.file.exists) {
150- slot.directory.cancel ();
151- slot.directory.track_longest_name = false;
152- }
153
154 if (focus_file != null)
155 select_childs.prepend (focus_file);
156
157+ Marlin.Window.Columns new_mwcol;
158+ GOF.Window.Slot new_slot;
159+
160 if (nview == ViewMode.MILLER) {
161- mwcol = new Marlin.Window.Columns (location, this);
162- slot = mwcol.active_slot;
163+ new_mwcol = new Marlin.Window.Columns (location, this);
164+ new_slot = mwcol.active_slot;
165 } else {
166- mwcol = null;
167- slot = new GOF.Window.Slot (location, this);
168+ new_mwcol = null;
169+ new_slot = new GOF.Window.Slot (location, this);
170 }
171
172 /* automagicly enable icon view for icons keypath */
173- if (!user_change_rq && slot.directory.uri_contain_keypath_icons)
174+ if (!user_change_rq && new_slot.directory.uri_contain_keypath_icons)
175 nview = 0; /* icon view */
176
177+ /* Mount the directory if it's not mounted */
178+ if (!new_slot.directory.file.is_mounted) {
179+ tab_name = _("Connecting…");
180+ loading (true);
181+
182+ new_slot.directory.mount_mountable.begin ((obj,res) => {
183+ try {
184+ new_slot.directory.mount_mountable.end (res);
185+ make_view (nview, new_mwcol, new_slot);
186+ } catch (Error e) {
187+ warning ("mount_mountable failed: %s", e.message);
188+ // Reset the tab label
189+ refresh_slot_info ();
190+ }
191+ });
192+ } else {
193+ make_view (nview, new_mwcol, new_slot);
194+ }
195+ }
196+
197+ private void make_view (int nview, Marlin.Window.Columns? new_mwcol, GOF.Window.Slot new_slot) {
198+ if (slot != null && slot.directory != null && slot.directory.file.exists) {
199+ slot.directory.cancel ();
200+ slot.directory.track_longest_name = false;
201+ }
202+
203+ slot = new_slot;
204+ mwcol = new_mwcol;
205+
206 /* Setting up view_mode and its button */
207 view_mode = nview;
208 if (window.top_menu.view_switcher != null)
209@@ -299,8 +330,10 @@
210 public string? get_root_uri () {
211 if (mwcol != null)
212 return mwcol.get_root_uri ();
213- else
214+ else if (slot != null)
215 return slot.location.get_uri ();
216+
217+ return null;
218 }
219
220 public string? get_tip_uri () {
221@@ -319,7 +352,7 @@
222 }
223
224 public void update_location_state (bool save_history) {
225- if (!slot.directory.file.exists)
226+ if (slot == null || !slot.directory.file.exists)
227 return;
228
229 if (save_history)
230
231=== modified file 'src/View/Window.vala'
232--- src/View/Window.vala 2014-07-30 02:20:58 +0000
233+++ src/View/Window.vala 2014-07-31 20:18:53 +0000
234@@ -382,6 +382,10 @@
235 tab.label = tab_name;
236 });
237
238+ content.loading.connect ((is_loading) => {
239+ tab.working = is_loading;
240+ });
241+
242 change_tab ((int)tabs.insert_tab (tab, -1));
243 tabs.current = tab;
244 }

Subscribers

People subscribed via source and target branches

to all changes: