From cac578ad835e4aa08e8c238c99fa2918f95813b6 Mon Sep 17 00:00:00 2001 From: Carl Xiong Date: Tue, 17 Mar 2015 19:30:13 +0800 Subject: [PATCH] Reload specials when XDG user dirs changes --- extensions/places-menu/placeDisplay.js | 95 +++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 25 deletions(-) diff --git a/extensions/places-menu/placeDisplay.js b/extensions/places-menu/placeDisplay.js index f7a2567..ec321bc 100644 --- a/extensions/places-menu/placeDisplay.js +++ b/extensions/places-menu/placeDisplay.js @@ -193,32 +193,30 @@ const PlacesManager = new Lang.Class({ network: [], }; - let homePath = GLib.get_home_dir(); - - this._places.special.push(new PlaceInfo('special', - Gio.File.new_for_path(homePath), - _("Home"))); - - let specials = []; - for (let i = 0; i < DEFAULT_DIRECTORIES.length; i++) { - let specialPath = GLib.get_user_special_dir(DEFAULT_DIRECTORIES[i]); - if (specialPath == null || specialPath == homePath) - continue; - - let file = Gio.File.new_for_path(specialPath), info; - try { - info = new PlaceInfo('special', file); - } catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND)) { - continue; - } - - specials.push(info); + // unlike bookmark file, XDG's 'user-dirs.dirs' here only serves as a + // signal gnerator: when 'reload_user_special_dirs_cache' should be + // invoked, not a definitive source for user special dirs, which is + // handled by GLib as before. + this._userDirsFile = this._findUserDirsFile(); + this._userDirsTimeoutId = 0; + this._userDirsMonitor = null; + + if (this._userDirsFile) { + this._userDirsMonitor = this._userDirsFile.monitor_file(Gio.FileMonitorFlags.NONE, null); + this._userDirsMonitor.connect('changed', Lang.bind(this, function () { + if (this._userDirsTimeoutId > 0) + return; + /* Defensive event compression */ + this._userDirsTimeoutId = Mainloop.timeout_add(100, Lang.bind(this, function () { + this._userDirsTimeoutId = 0; + this._reloadSpecial(); + return false; + })); + })); } - - specials.sort(function(a, b) { - return GLib.utf8_collate(a.name, b.name); - }); - this._places.special = this._places.special.concat(specials); + // as stated above, special will always get loaded, even + // 'user-dirs.dirs' are not found. + this._reloadSpecial(); /* * Show devices, code more or less ported from nautilus-places-sidebar.c @@ -248,6 +246,40 @@ const PlacesManager = new Lang.Class({ } }, + _reloadSpecial: function() { + let homePath = GLib.get_home_dir(); + this._places.special = []; + + this._places.special.push(new PlaceInfo('special', + Gio.File.new_for_path(homePath), + _("Home"))); + + // Reload cache s.t. the changes on disk would appear here immediately + GLib.reload_user_special_dirs_cache(); + let specials = []; + for (let i = 0; i < DEFAULT_DIRECTORIES.length; i++) { + let specialPath = GLib.get_user_special_dir(DEFAULT_DIRECTORIES[i]); + if (specialPath == homePath) + continue; + + let file = Gio.File.new_for_path(specialPath), info; + try { + info = new PlaceInfo('special', file); + } catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND)) { + continue; + } + + specials.push(info); + } + + specials.sort(function(a, b) { + return GLib.utf8_collate(a.name, b.name); + }); + this._places.special = this._places.special.concat(specials); + + this.emit('special-updated'); + }, + _connectVolumeMonitorSignals: function() { const signals = ['volume-added', 'volume-removed', 'volume-changed', 'mount-added', 'mount-removed', 'mount-changed', @@ -354,6 +386,19 @@ const PlacesManager = new Lang.Class({ this.emit('network-updated'); }, + _findUserDirsFile: function() { + let paths = [ + GLib.build_filenamev([GLib.get_user_config_dir(), 'user-dirs.dirs']), + ]; + + for (let i = 0; i < paths.length; i++) { + if (GLib.file_test(paths[i], GLib.FileTest.EXISTS)) + return Gio.File.new_for_path(paths[i]); + } + + return null; + }, + _findBookmarksFile: function() { let paths = [ GLib.build_filenamev([GLib.get_user_config_dir(), 'gtk-3.0', 'bookmarks']), -- 1.8.1.4