Merge lp:~psybers/docky/xdg-basedir into lp:docky

Proposed by Robert Dyer
Status: Merged
Merged at revision: 1451
Proposed branch: lp:~psybers/docky/xdg-basedir
Merge into: lp:docky
Diff against target: 395 lines (+151/-110)
3 files modified
Docky.Services/Docky.Services/PathsService.cs (+123/-40)
Docky.Windowing/Windowing/WindowMatcher.cs (+21/-55)
Docky/Docky/PluginManager.cs (+7/-15)
To merge this branch: bzr merge lp:~psybers/docky/xdg-basedir
Reviewer Review Type Date Requested Status
Rico Tzschichholz Needs Fixing
Review via email: mp+26897@code.launchpad.net

Description of the change

Support the XDG Base Directory specification.

The paths service was reworked to support the spec and clean it up a bit. I attempted to make sure the rest of Docky uses that service now - specifically WindowManager.

To post a comment you must log in.
lp:~psybers/docky/xdg-basedir updated
1422. By Robert Dyer

fix bug spotted in the diff

1423. By Robert Dyer

fix CX_APPS path

Revision history for this message
Rico Tzschichholz (ricotz) wrote :

PluginManager.cs uses some Paths: UserAddinInstallationDirectory, UserPluginsDirectory which could be created in PathServices

review: Needs Fixing
lp:~psybers/docky/xdg-basedir updated
1424. By Robert Dyer

fix paths in PluginManager

1425. By Robert Dyer

clean code

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Docky.Services/Docky.Services/PathsService.cs'
2--- Docky.Services/Docky.Services/PathsService.cs 2010-05-31 19:30:58 +0000
3+++ Docky.Services/Docky.Services/PathsService.cs 2010-06-08 09:03:26 +0000
4@@ -1,5 +1,5 @@
5 //
6-// Copyright (C) 2010 Chris Szikszoy
7+// Copyright (C) 2010 Chris Szikszoy, Robert Dyer
8 //
9 // This program is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11@@ -15,52 +15,135 @@
12 // along with this program. If not, see <http://www.gnu.org/licenses/>.
13 //
14 using System;
15+using System.Collections.Generic;
16+using System.Linq;
17
18 using GLib;
19
20 namespace Docky.Services
21 {
22+ /// <summary>
23+ /// This class provides all paths used in Docky.
24+ ///
25+ /// It follows the XDG Base Directory specification. For more information see:
26+ /// http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
27+ /// </summary>
28 public class PathsService
29 {
30- static readonly File home_folder = FileFactory.NewForPath (Environment.GetEnvironmentVariable ("HOME"));
31-
32- public File SystemDataFolder {
33- get { return FileFactory.NewForPath (AssemblyInfo.DataDirectory).GetChild ("docky"); }
34- }
35-
36- public File DockManagerUserDataFolder {
37- get { return FileFactory.NewForPath (Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData)).GetChild ("dockmanager"); }
38- }
39-
40- public File UserDataFolder {
41- get { return FileFactory.NewForPath (Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData)).GetChild ("docky"); }
42- }
43-
44- File user_cache_folder;
45- public File UserCacheFolder {
46- get {
47- if (user_cache_folder != null)
48- return user_cache_folder;
49-
50- string xdg_cache_home = Environment.GetEnvironmentVariable ("XDG_CACHE_HOME");
51- if (!string.IsNullOrEmpty (xdg_cache_home))
52- user_cache_folder = FileFactory.NewForPath (xdg_cache_home).GetChild ("docky");
53- else
54- user_cache_folder = home_folder.GetChild (".cache").GetChild ("docky");
55-
56- if (!user_cache_folder.Exists)
57- try {
58- user_cache_folder.MakeDirectoryWithParents (null);
59- } catch {
60- Log<PathsService>.Fatal ("Could not access the cache directory '" + user_cache_folder.Path + "' or create it. Docky will not work properly unless this folder is writable.");
61- }
62-
63- return user_cache_folder;
64- }
65- }
66-
67- public File AutoStartFile {
68- get { return FileFactory.NewForPath (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData)).GetChild ("autostart").GetChild ("docky.desktop"); }
69+ #region XDG Base Directory independent paths
70+
71+ /// <summary>
72+ /// User's home folder - $HOME
73+ /// </summary>
74+ public File HomeFolder { get; protected set; }
75+
76+ /// <summary>
77+ /// Docky's installed data directory - defaults to /usr/share/docky for PPA
78+ /// </summary>
79+ public File SystemDataFolder { get; protected set; }
80+
81+ #endregion
82+
83+
84+ #region XDG Base Directory paths
85+
86+ /// <summary>
87+ /// $XDG_DATA_HOME - defaults to $HOME/.local/share
88+ /// </summary>
89+ public File XdgDataHomeFolder { get; protected set; }
90+
91+ /// <summary>
92+ /// $XDG_CACHE_HOME - defaults to $HOME/.cache
93+ /// </summary>
94+ public File XdgCacheHomeFolder { get; protected set; }
95+
96+ /// <summary>
97+ /// $XDG_DATA_DIRS - defaults to /usr/local/share/:/usr/share/
98+ /// </summary>
99+ public IEnumerable<File> XdgDataDirFolders { get; protected set; }
100+
101+
102+ /// <summary>
103+ /// defaults to XdgCacheHomeFolder/docky
104+ /// </summary>
105+ public File UserCacheFolder { get; protected set; }
106+
107+ /// <summary>
108+ /// defaults to XdgDataHomeFolder/docky
109+ /// </summary>
110+ public File UserDataFolder { get; protected set; }
111+
112+ /// <summary>
113+ /// defaults to XdgDataHomeFolder/dockmanager
114+ /// </summary>
115+ public File DockManagerUserDataFolder { get; protected set; }
116+
117+
118+ /// <summary>
119+ /// Path to the autostart file - defaults to
120+ /// </summary>
121+ public File AutoStartFile { get; protected set; }
122+
123+ #endregion
124+
125+
126+ public PathsService ()
127+ {
128+ // get environment-based settings
129+ File env_home = FileFactory.NewForPath (Environment.GetFolderPath (Environment.SpecialFolder.Personal));
130+ File env_data_install = FileFactory.NewForPath (AssemblyInfo.DataDirectory);
131+
132+
133+ // set the non-XDG Base Directory specified directories to use
134+ HomeFolder = env_home;
135+ SystemDataFolder = env_data_install.GetChild ("docky");
136+
137+
138+ // get XDG Base Directory settings
139+ string xdg_data_home = Environment.GetEnvironmentVariable ("XDG_DATA_HOME");
140+ string xdg_data_dirs = Environment.GetEnvironmentVariable ("XDG_DATA_DIRS");
141+ string xdg_cache_home = Environment.GetEnvironmentVariable ("XDG_CACHE_HOME");
142+
143+
144+ // determine directories based on XDG with fallbacks
145+ if (string.IsNullOrEmpty (xdg_cache_home))
146+ XdgCacheHomeFolder = HomeFolder.GetChild (".cache");
147+ else
148+ XdgCacheHomeFolder = FileFactory.NewForPath (xdg_cache_home);
149+
150+ if (string.IsNullOrEmpty (xdg_data_home))
151+ XdgDataHomeFolder = HomeFolder.GetChild (".local").GetChild ("share");
152+ else
153+ XdgDataHomeFolder = FileFactory.NewForPath (xdg_data_home);
154+
155+ if (string.IsNullOrEmpty (xdg_data_dirs))
156+ XdgDataDirFolders = new [] { GLib.FileFactory.NewForPath ("/usr/local/share"), GLib.FileFactory.NewForPath ("/usr/share") };
157+ else
158+ XdgDataDirFolders = xdg_data_dirs.Split (':').Select (d => GLib.FileFactory.NewForPath (d));
159+
160+
161+ // set the XDG Base Directory specified directories to use
162+ UserCacheFolder = XdgCacheHomeFolder.GetChild ("docky");
163+ UserDataFolder = XdgDataHomeFolder.GetChild ("docky");
164+ DockManagerUserDataFolder = XdgDataHomeFolder.GetChild ("dockmanager");
165+ AutoStartFile = XdgDataHomeFolder.GetChild ("autostart").GetChild ("docky.desktop");
166+
167+
168+ // ensure all writable directories exist
169+ EnsureDirectoryExists (UserCacheFolder);
170+ EnsureDirectoryExists (UserDataFolder);
171+ EnsureDirectoryExists (DockManagerUserDataFolder);
172+ EnsureDirectoryExists (XdgDataHomeFolder.GetChild ("autostart"));
173+ }
174+
175+ void EnsureDirectoryExists (File dir)
176+ {
177+ if (!dir.Exists)
178+ try {
179+ dir.MakeDirectoryWithParents (null);
180+ } catch {
181+ Log<PathsService>.Fatal ("Could not access the directory '" + dir.Path + "' or create it. Docky will not work properly unless this folder is writable.");
182+ }
183 }
184 }
185 }
186
187=== modified file 'Docky.Windowing/Windowing/WindowMatcher.cs'
188--- Docky.Windowing/Windowing/WindowMatcher.cs 2010-06-08 08:20:21 +0000
189+++ Docky.Windowing/Windowing/WindowMatcher.cs 2010-06-08 09:03:26 +0000
190@@ -140,7 +140,7 @@
191 SetupWindow (w);
192
193 // Set up monitors for cache files and desktop directories
194- foreach (GLib.File dir in DesktopFileDirectories.Select (d => GLib.FileFactory.NewForPath (d)))
195+ foreach (GLib.File dir in DesktopFileDirectories)
196 MonitorDesktopFileDirs (dir);
197 MonitorDesktopFileSystemCacheFiles ();
198
199@@ -149,12 +149,12 @@
200 }
201
202 #region Handle DesktopItems
203- static IEnumerable<string> DesktopFileSystemCacheFiles
204+ static IEnumerable<GLib.File> DesktopFileSystemCacheFiles
205 {
206 get {
207 return DesktopFileDirectories
208- .Select (d => Path.Combine (d, string.Format ("desktop.{0}.cache", Locale)))
209- .Where (f => File.Exists (f));
210+ .Select (d => d.GetChild (string.Format ("desktop.{0}.cache", Locale)))
211+ .Where (f => f.Exists);
212 }
213 }
214
215@@ -167,49 +167,18 @@
216 }
217 }
218
219- static IEnumerable<string> DesktopFileDirectories
220+ static IEnumerable<GLib.File> DesktopFileDirectories
221 {
222 get {
223- return new [] {
224- // These are XDG variables...
225- "XDG_DATA_HOME",
226- "XDG_DATA_DIRS",
227- // Crossover apps
228- "CX_APPS",
229- }.SelectMany (v => ExpandPathVar (v))
230- .Where (d => Directory.Exists (d));
231+ return DockServices.Paths.XdgDataDirFolders.Select (d => d.GetChild ("applications"))
232+ .Union(new [] {
233+ DockServices.Paths.XdgDataHomeFolder.GetChild ("applications"),
234+ DockServices.Paths.HomeFolder.GetChild (".cxoffice"),
235+ })
236+ .Where (d => d.Exists);
237 }
238 }
239
240- static IEnumerable<string> ExpandPathVar (string xdgVar)
241- {
242- string envPath = Environment.GetEnvironmentVariable (xdgVar);
243-
244- if (string.IsNullOrEmpty (envPath)) {
245- switch (xdgVar) {
246- case "XDG_DATA_HOME":
247- yield return Path.Combine (
248- Environment.GetFolderPath (Environment.SpecialFolder.Personal),
249- new [] {".local", "share", "applications"}.Aggregate ((w, s) => Path.Combine (w, s))
250- );
251- break;
252- case "XDG_DATA_DIRS":
253- yield return new [] {"/usr", "local", "share", "applications"}.Aggregate ((w, s) => Path.Combine (w,s));
254- yield return new [] {"/usr", "share", "applications"}.Aggregate ((w, s) => Path.Combine (w, s));
255- break;
256- case "CX_APPS":
257- yield return Path.Combine (
258- Environment.GetFolderPath (Environment.SpecialFolder.Personal),
259- ".cxoffice"
260- );
261- break;
262- }
263- } else {
264- foreach (string dir in envPath.Split (':'))
265- yield return Path.Combine (dir, "applications");
266- }
267- }
268-
269 void UpdateDesktopItemsList ()
270 {
271 if (desktop_items == null)
272@@ -220,8 +189,8 @@
273
274 // Get desktop items for new "valid" desktop files
275 new_items = DesktopFileDirectories
276- .SelectMany (dir => GLib.FileFactory.NewForPath (dir).SubDirs ())
277- .Union (DesktopFileDirectories.Select (f => GLib.FileFactory.NewForPath (f)))
278+ .SelectMany (dir => dir.SubDirs ())
279+ .Union (DesktopFileDirectories)
280 .SelectMany (file => file.GetFiles (".desktop"))
281 .Where (file => !known_desktop_files.Exists (known_file => (known_file.Path == file.Path)))
282 .Select (file => new DesktopItem (file))
283@@ -244,19 +213,19 @@
284
285 void ProcessAndMergeAllSystemCacheFiles (List<DesktopItem> items)
286 {
287- foreach (string cache_file in DesktopFileSystemCacheFiles)
288+ foreach (GLib.File cache_file in DesktopFileSystemCacheFiles)
289 ProcessAndMergeSystemCacheFile (cache_file, items);
290 }
291
292- void ProcessAndMergeSystemCacheFile (string cache_file, List<DesktopItem> items)
293+ void ProcessAndMergeSystemCacheFile (GLib.File cache_file, List<DesktopItem> items)
294 {
295- if (!GLib.FileFactory.NewForPath (cache_file).Exists)
296+ if (!cache_file.Exists)
297 return;
298
299- Log<WindowMatcher>.Debug ("Processing {0}", cache_file);
300+ Log<WindowMatcher>.Debug ("Processing {0}", cache_file.Path);
301
302 try {
303- using (StreamReader reader = new StreamReader (cache_file)) {
304+ using (StreamReader reader = new StreamReader (cache_file.Path)) {
305 DesktopItem desktop_item = null;
306 string line;
307
308@@ -269,9 +238,7 @@
309 if (match.Success) {
310 string section = match.Groups["Section"].Value;
311 if (section != null) {
312- GLib.File file = GLib.FileFactory
313- .NewForPath (Path.Combine (Path.GetDirectoryName (cache_file),
314- string.Format ("{0}.desktop", section)));
315+ GLib.File file = cache_file.Parent.GetChild (string.Format ("{0}.desktop", section));
316 desktop_item = items.First (item => item.File.Path == file.Path);
317 if (desktop_item == null && file.Exists) {
318 desktop_item = new DesktopItem (file);
319@@ -413,14 +380,13 @@
320
321 void MonitorDesktopFileSystemCacheFiles ()
322 {
323- foreach (string filename in DesktopFileSystemCacheFiles) {
324- GLib.File file = GLib.FileFactory.NewForPath (filename);
325+ foreach (GLib.File file in DesktopFileSystemCacheFiles) {
326 GLib.FileMonitor mon = file.Monitor (GLib.FileMonitorFlags.None, null);
327 mon.RateLimit = 2500;
328 mon.Changed += delegate {
329 DockServices.System.RunOnThread (() => {
330 lock (update_lock) {
331- ProcessAndMergeSystemCacheFile (file.Path, desktop_items);
332+ ProcessAndMergeSystemCacheFile (file, desktop_items);
333 DesktopItemsChanged ();
334 }
335 });
336
337=== modified file 'Docky/Docky/PluginManager.cs'
338--- Docky/Docky/PluginManager.cs 2010-04-11 00:41:58 +0000
339+++ Docky/Docky/PluginManager.cs 2010-06-08 09:03:26 +0000
340@@ -47,10 +47,6 @@
341 {
342 public static readonly string DefaultPluginIcon = "package";
343
344- const string PluginsDirectory = "plugins";
345- const string ApplicationDirectory = "docky";
346- const string DefaultAddinsDirectory = "addins";
347-
348 const string IPExtensionPath = "/Docky/ItemProvider";
349 const string ConfigExtensionPath = "/Docky/Configuration";
350
351@@ -59,15 +55,12 @@
352 //// <value>
353 /// Directory where Docky saves its Mono.Addins repository cache.
354 /// </value>
355- public static string UserPluginsDirectory {
356- get {
357- string userData = Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData);
358- return Path.Combine (Path.Combine (userData, ApplicationDirectory), PluginsDirectory);
359- }
360+ public static GLib.File UserPluginsDirectory {
361+ get { return DockServices.Paths.UserDataFolder.GetChild ("plugins"); }
362 }
363
364- public static string UserAddinInstallationDirectory {
365- get { return Path.Combine (UserPluginsDirectory, DefaultAddinsDirectory); }
366+ public static GLib.File UserAddinInstallationDirectory {
367+ get { return UserPluginsDirectory.GetChild ("addins"); }
368 }
369
370 /// <summary>
371@@ -78,13 +71,13 @@
372 {
373 // Initialize Mono.Addins.
374 try {
375- AddinManager.Initialize (UserPluginsDirectory);
376+ AddinManager.Initialize (UserPluginsDirectory.Path);
377 } catch (InvalidOperationException e) {
378 Log<PluginManager>.Error ("AddinManager.Initialize: {0}", e.Message);
379 Log<PluginManager>.Warn ("Rebuild Addin.Registry and reinitialize AddinManager");
380 AddinManager.Registry.Rebuild (null);
381 AddinManager.Shutdown ();
382- AddinManager.Initialize (UserPluginsDirectory);
383+ AddinManager.Initialize (UserPluginsDirectory.Path);
384 }
385
386 AddinManager.Registry.Update (null);
387@@ -160,8 +153,7 @@
388 {
389 IEnumerable<string> manual;
390
391- manual = Directory.GetFiles (UserAddinInstallationDirectory, "*.dll")
392- .Select (s => Path.GetFileName (s));
393+ manual = UserAddinInstallationDirectory.GetFiles ("*.dll").Select (f => f.Basename);
394
395 manual.ToList ().ForEach (dll => Log<PluginManager>.Info ("Installing {0}", dll));
396

Subscribers

People subscribed via source and target branches

to status/vote changes: