Merge lp:~docky-core/plank/themes into lp:plank
- themes
- Merge into trunk
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Rico Tzschichholz | ||||||||
Approved revision: | 751 | ||||||||
Merged at revision: | 745 | ||||||||
Proposed branch: | lp:~docky-core/plank/themes | ||||||||
Merge into: | lp:plank | ||||||||
Diff against target: |
629 lines (+304/-10) 11 files modified
data/themes/Default/dock.theme (+54/-0) data/themes/Default/hover.theme (+17/-0) lib/DockPreferences.vala (+11/-0) lib/DockRenderer.vala (+22/-4) lib/Drawing/DockTheme.vala (+5/-0) lib/Drawing/HoverTheme.vala (+5/-0) lib/Drawing/Theme.vala (+113/-2) lib/Services/Paths.vala (+12/-0) lib/Services/Preferences.vala (+38/-1) lib/Widgets/HoverWindow.vala (+18/-3) lib/libplank.symbols (+9/-0) |
||||||||
To merge this branch: | bzr merge lp:~docky-core/plank/themes | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Dyer (community) | Needs Fixing | ||
Review via email:
|
Commit message
Make theme choosable through a settings-option
Theme would be the folder-name located in system's or user's themes-folder
(/usr/share/
This folder will contain the *.theme files as we know them.
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Robert Dyer (psybers) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Robert Dyer (psybers) wrote : | # |
Why do you have get_default_
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Robert Dyer (psybers) wrote : | # |
Also we should never give an error() when looking for themes. If we fail to find the them they want, or indeed any theme folder, just warn and return. The defaults are already in the properties so it is ok to not have an actual theme.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Rico Tzschichholz (ricotz) wrote : | # |
> What is the point of get_theme_list? It isn't used anywhere.
This is for future usage and I am already using it in another branch.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Rico Tzschichholz (ricotz) wrote : | # |
> Why do you have get_default_
> first is just a special case of the latter (for the default theme) and not
> needed. Also the default one is for some reason preferring global theme over
> user theme (which should NEVER be the case).
This behavior is intended. I want to preserve the ability of plank to generate the files of its internal default theme which is only possible in the user-folder. So if the choice/fallback is "Default" use the installed/packaged (distro-)theme, and if that isn't available use the writeable user-folder to generate it or use the existing one.
The error is there since it is an assert and should never happen.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Cody Garver (codygarver) wrote : | # |
This is a lot better than the old way. It doesn't require OS hacks and I it's far more modern to put things in /usr/share. Hope this gets merged soon, users desire theming in elementary OS. Great work on Plank guys, there's talk it could even be used in the panel after Luna for autohiding!
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Robert Dyer (psybers) wrote : | # |
[DEBUG 19:04:30.463962] [Preferences:286] Loading preferences from file '/usr/local/
[WARN 19:04:30.464671] [Preferences:301] Missing key 'TopRoundness' for group 'PlankDrawingTheme' in preferences file '/usr/local/
[WARN 19:04:30.464961] [Preferences:301] Missing key 'BottomRoundness' for group 'PlankDrawingTheme' in preferences file '/usr/local/
[WARN 19:04:30.465185] [Preferences:301] Missing key 'LineWidth' for group 'PlankDrawingTheme' in preferences file '/usr/local/
[WARN 19:04:30.465405] [Preferences:301] Missing key 'OuterStrokeColor' for group 'PlankDrawingTheme' in preferences file '/usr/local/
[WARN 19:04:30.465627] [Preferences:301] Missing key 'FillStartColor' for group 'PlankDrawingTheme' in preferences file '/usr/local/
[WARN 19:04:30.465845] [Preferences:301] Missing key 'FillEndColor' for group 'PlankDrawingTheme' in preferences file '/usr/local/
[WARN 19:04:30.466066] [Preferences:301] Missing key 'InnerStrokeColor' for group 'PlankDrawingTheme' in preferences file '/usr/local/
[WARN 19:04:30.466287] [Preferences:301] Missing key 'HorizPadding' for group 'PlankDrawingDo
[WARN 19:04:30.466503] [Preferences:301] Missing key 'TopPadding' for group 'PlankDrawingDo
[WARN 19:04:30.466713] [Preferences:301] Missing key 'BottomPadding' for group 'PlankDrawingDo
[WARN 19:04:30.466923] [Preferences:301] Missing key 'ItemPadding' for group 'PlankDrawingDo
[WARN 19:04:30.467144] [Preferences:301] Missing key 'IndicatorSize' for group 'PlankDrawingDo
[WARN 19:04:30.467366] [Preferences:301] Missing key 'UrgentBounceHe
[WARN 19:04:30.467589] [Preferences:301] Missing key 'LaunchBounceHe
[WARN 19:04:30.467810] [Preferences:301] Missing key 'FadeOpacity' for group 'PlankDrawingDo
[WARN 19:04:30.468033] [Preferences:301] Missing key 'ClickTime' for group 'PlankDrawingDo
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Robert Dyer (psybers) wrote : | # |
Basically, anyone upgrading would have a miserable time. Something needs to happen to make this fail more gracefully.
What is happening here is its using a theme out of /usr/local/share. But our Preferences wants to write values to that location, which clearly it has no write access to.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Rico Tzschichholz (ricotz) wrote : | # |
So the Preferences class should have field/property "read-only" which can be manually set to TRUE and is set automatically based on the write-permissions of the backing_file.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Robert Dyer (psybers) wrote : | # |
I don't know about that. If it is only a hack to make this upgrading possible then no.
It may be the case we simply break everyone's configs with this change and they have to fix it themselves.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Rico Tzschichholz (ricotz) wrote : | # |
This is not a hack but a reasonable change for trunk directly. It would solve this problem partly and makes it possible to have two Preferences instances pointing to the same backing_file which is currently the case for running plank with gala. Gala is using the Plank.Drawing.Theme classes to draw the fake-plank actor. So there are two processes watching the same file and this makes it possible they are fighting over this file if it changes.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Rico Tzschichholz (ricotz) wrote : | # |
- 735. By Rico Tzschichholz
-
items: No need for a SeparatorMenuItem if the associated folder is empty
- 736. By Rico Tzschichholz
-
main: Avoid calling Poxis.exit ()
Change the way we are passing the commandline-
arguments through the
initalization methods and return EXIT_SUCCESS or EXIT_FAILURE to the
actual main function - 737. By Rico Tzschichholz
-
items: Validate an item before adding it here too
- 738. By Rico Tzschichholz
-
items: Delay the start of watching our launchers directory
load_items can actually lead to updates of dockitem files if their
syntax was changed. So activing the monitor at the very last is more
appropriate. - 739. By Rico Tzschichholz
-
Use URIs instead of paths for saving the location of dockitem's Launcher
- 740. By Rico Tzschichholz
-
lib: Require valac >= 0.16.0 and fix deprecated syntax
- 741. By Rico Tzschichholz
-
Pass an URI to ApplicationDock
Item.parse_ launcher () Fixes fallout of r739
- 742. By Rico Tzschichholz
-
filedockitem: Make sure Hashmap keys are unique
Clashing keys will result in leftover menuitems leading to a crash
- 743. By Rico Tzschichholz
-
Make sure icon-regions and struts are updated on a dockwindow-resize
- 748. By Rico Tzschichholz
-
theme: Fallback to built-in defaults if needed
- 749. By Rico Tzschichholz
-
preferences: Handle file errors
- 750. By Rico Tzschichholz
-
data: add fully qualified Default theme
- 751. By Rico Tzschichholz
-
Don't allow slashes in "Theme" string
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sergey "Shnatsel" Davidoff (shnatsel) wrote : | # |
Works fine for me, including changing themes at runtime. Tested lookup from both $XDG_DATA_HOME and $XDG_DATA_DIRS.
Theme names with spaces and unicode characters in the name work as well. When given a nonexistent theme, falls back to theme "Default". Strips all "/" characters from malformed filenames.
Preview Diff
1 | === modified file 'data/themes/Default/dock.theme' |
2 | --- data/themes/Default/dock.theme 2012-11-16 16:05:23 +0000 |
3 | +++ data/themes/Default/dock.theme 2013-02-03 11:21:19 +0000 |
4 | @@ -1,4 +1,58 @@ |
5 | +#This file auto-generated by Plank. |
6 | +#2013-02-02T11:25:31+0000 |
7 | |
8 | [PlankDrawingTheme] |
9 | +#The roundness of the top corners. |
10 | +TopRoundness=4 |
11 | +#The roundness of the bottom corners. |
12 | +BottomRoundness=0 |
13 | +#The thickness (in pixels) of lines drawn. |
14 | +LineWidth=1 |
15 | +#The color (RGBA) of the outer stroke. |
16 | +OuterStrokeColor=41;;41;;41;;255 |
17 | +#The starting color (RGBA) of the fill gradient. |
18 | +FillStartColor=41;;41;;41;;255 |
19 | +#The ending color (RGBA) of the fill gradient. |
20 | +FillEndColor=80;;80;;80;;255 |
21 | +#The color (RGBA) of the inner stroke. |
22 | +InnerStrokeColor=255;;255;;255;;255 |
23 | |
24 | [PlankDrawingDockTheme] |
25 | +#The padding on the left/right dock edges, in tenths of a percent of IconSize. |
26 | +HorizPadding=0 |
27 | +#The padding on the top dock edge, in tenths of a percent of IconSize. |
28 | +TopPadding=-11 |
29 | +#The padding on the bottom dock edge, in tenths of a percent of IconSize. |
30 | +BottomPadding=2.5 |
31 | +#The padding between items on the dock, in tenths of a percent of IconSize. |
32 | +ItemPadding=2 |
33 | +#The size of item indicators, in tenths of a percent of IconSize. |
34 | +IndicatorSize=5 |
35 | +#The height (in percent of IconSize) to bounce an icon when the application sets urgent. |
36 | +UrgentBounceHeight=1.6666666666666667 |
37 | +#The height (in percent of IconSize) to bounce an icon when launching an application. |
38 | +LaunchBounceHeight=0.625 |
39 | +#The opacity value (0 to 1) to fade the dock to when hiding it. |
40 | +FadeOpacity=1 |
41 | +#The amount of time (in ms) for click animations. |
42 | +ClickTime=300 |
43 | +#The amount of time (in ms) to bounce an urgent icon. |
44 | +UrgentBounceTime=600 |
45 | +#The amount of time (in ms) to bounce an icon when launching an application. |
46 | +LaunchBounceTime=600 |
47 | +#The amount of time (in ms) for active window indicator animations. |
48 | +ActiveTime=300 |
49 | +#The amount of time (in ms) to slide icons into/out of the dock. |
50 | +SlideTime=300 |
51 | +#The time (in ms) to fade the dock in/out on a hide (if FadeOpacity is < 1). |
52 | +FadeTime=250 |
53 | +#The time (in ms) to slide the dock in/out on a hide (if FadeOpacity is 1). |
54 | +HideTime=150 |
55 | +#The size of the urgent glow (shown when dock is hidden), in tenths of a percent of IconSize. |
56 | +GlowSize=30 |
57 | +#The total time (in ms) to show the hidden-dock urgent glow. |
58 | +GlowTime=10000 |
59 | +#The time (in ms) of each pulse of the hidden-dock urgent glow. |
60 | +GlowPulseTime=2000 |
61 | +#The hue-shift (-180 to 180) of the urgent indicator color. |
62 | +UrgentHueShift=150 |
63 | |
64 | === modified file 'data/themes/Default/hover.theme' |
65 | --- data/themes/Default/hover.theme 2012-11-16 16:05:23 +0000 |
66 | +++ data/themes/Default/hover.theme 2013-02-03 11:21:19 +0000 |
67 | @@ -1,1 +1,18 @@ |
68 | +#This file auto-generated by Plank. |
69 | +#2013-02-02T11:25:30+0000 |
70 | + |
71 | [PlankDrawingTheme] |
72 | +#The roundness of the top corners. |
73 | +TopRoundness=3 |
74 | +#The roundness of the bottom corners. |
75 | +BottomRoundness=3 |
76 | +#The thickness (in pixels) of lines drawn. |
77 | +LineWidth=1 |
78 | +#The color (RGBA) of the outer stroke. |
79 | +OuterStrokeColor=41;;41;;41;;255 |
80 | +#The starting color (RGBA) of the fill gradient. |
81 | +FillStartColor=41;;41;;41;;255 |
82 | +#The ending color (RGBA) of the fill gradient. |
83 | +FillEndColor=80;;80;;80;;255 |
84 | +#The color (RGBA) of the inner stroke. |
85 | +InnerStrokeColor=255;;255;;255;;255 |
86 | |
87 | === modified file 'lib/DockPreferences.vala' |
88 | --- lib/DockPreferences.vala 2013-01-21 12:10:22 +0000 |
89 | +++ lib/DockPreferences.vala 2013-02-03 11:21:19 +0000 |
90 | @@ -55,6 +55,9 @@ |
91 | [Description(nick = "offset", blurb = "The dock's position offset from center (in percent).")] |
92 | public int Offset { get; set; } |
93 | |
94 | + [Description(nick = "theme", blurb = "The name of the dock's theme to use.")] |
95 | + public string Theme { get; set; } |
96 | + |
97 | [Description(nick = "alignment", blurb = "The alignment for the dock on the monitor's edge.")] |
98 | public Gtk.Align Alignment { get; set; } |
99 | |
100 | @@ -99,6 +102,7 @@ |
101 | DockItems = ""; |
102 | Position = PositionType.BOTTOM; |
103 | Offset = 0; |
104 | + Theme = Plank.Drawing.Theme.DEFAULT_NAME; |
105 | Alignment = Gtk.Align.CENTER; |
106 | ItemsAlignment = Gtk.Align.CENTER; |
107 | } |
108 | @@ -190,6 +194,13 @@ |
109 | Offset = 100; |
110 | break; |
111 | |
112 | + case "Theme": |
113 | + if (Theme == "") |
114 | + Theme = Plank.Drawing.Theme.DEFAULT_NAME; |
115 | + else if (Theme.contains ("/")) |
116 | + Theme = Theme.replace ("/", ""); |
117 | + break; |
118 | + |
119 | case "Alignment": |
120 | break; |
121 | |
122 | |
123 | === modified file 'lib/DockRenderer.vala' |
124 | --- lib/DockRenderer.vala 2013-01-21 12:10:22 +0000 |
125 | +++ lib/DockRenderer.vala 2013-02-03 11:21:19 +0000 |
126 | @@ -83,11 +83,7 @@ |
127 | { |
128 | this.controller = controller; |
129 | |
130 | - theme = new DockTheme (); |
131 | - theme.load ("dock"); |
132 | - |
133 | controller.prefs.notify.connect (prefs_changed); |
134 | - theme.changed.connect (theme_changed); |
135 | |
136 | controller.items.item_state_changed.connect (item_state_changed); |
137 | controller.items.item_position_changed.connect (item_position_changed); |
138 | @@ -106,9 +102,13 @@ |
139 | requires (controller.window != null) |
140 | { |
141 | set_widget (controller.window); |
142 | + |
143 | + load_theme (); |
144 | + |
145 | controller.position_manager.reset_caches (theme); |
146 | controller.position_manager.update_regions (); |
147 | controller.window.notify["HoveredItem"].connect (animated_draw); |
148 | + controller.prefs.notify["Theme"].connect (load_theme); |
149 | } |
150 | |
151 | ~DockRenderer () |
152 | @@ -124,6 +124,7 @@ |
153 | |
154 | notify["Hidden"].disconnect (hidden_changed); |
155 | |
156 | + controller.prefs.notify["Theme"].disconnect (load_theme); |
157 | controller.window.notify["HoveredItem"].disconnect (animated_draw); |
158 | } |
159 | |
160 | @@ -164,6 +165,23 @@ |
161 | controller.position_manager.update_regions (); |
162 | } |
163 | |
164 | + void load_theme () |
165 | + { |
166 | + var is_reload = (theme != null); |
167 | + |
168 | + if (is_reload) |
169 | + theme.changed.disconnect (theme_changed); |
170 | + |
171 | + theme = new DockTheme (controller.prefs.Theme); |
172 | + theme.load ("dock"); |
173 | + theme.changed.connect (theme_changed); |
174 | + |
175 | + controller.position_manager.reset_caches (theme); |
176 | + |
177 | + if (is_reload) |
178 | + controller.position_manager.update_regions (); |
179 | + } |
180 | + |
181 | /** |
182 | * The dock should be shown. |
183 | */ |
184 | |
185 | === modified file 'lib/Drawing/DockTheme.vala' |
186 | --- lib/Drawing/DockTheme.vala 2012-10-31 07:49:07 +0000 |
187 | +++ lib/Drawing/DockTheme.vala 2013-02-03 11:21:19 +0000 |
188 | @@ -87,6 +87,11 @@ |
189 | [Description(nick = "urgent-hue-shift", blurb = "The hue-shift (-180 to 180) of the urgent indicator color.")] |
190 | public int UrgentHueShift { get; set; } |
191 | |
192 | + public DockTheme (string name) |
193 | + { |
194 | + base.with_name (name); |
195 | + } |
196 | + |
197 | /** |
198 | * {@inheritDoc} |
199 | */ |
200 | |
201 | === modified file 'lib/Drawing/HoverTheme.vala' |
202 | --- lib/Drawing/HoverTheme.vala 2012-07-31 12:22:20 +0000 |
203 | +++ lib/Drawing/HoverTheme.vala 2013-02-03 11:21:19 +0000 |
204 | @@ -24,6 +24,11 @@ |
205 | */ |
206 | public class HoverTheme : Theme |
207 | { |
208 | + public HoverTheme (string name) |
209 | + { |
210 | + base.with_name (name); |
211 | + } |
212 | + |
213 | /** |
214 | * {@inheritDoc} |
215 | */ |
216 | |
217 | === modified file 'lib/Drawing/Theme.vala' |
218 | --- lib/Drawing/Theme.vala 2012-07-31 12:22:20 +0000 |
219 | +++ lib/Drawing/Theme.vala 2013-02-03 11:21:19 +0000 |
220 | @@ -17,6 +17,7 @@ |
221 | |
222 | using Cairo; |
223 | using Gdk; |
224 | +using Gee; |
225 | using Gtk; |
226 | |
227 | using Plank.Services; |
228 | @@ -28,6 +29,10 @@ |
229 | */ |
230 | public class Theme : Preferences |
231 | { |
232 | + public const string DEFAULT_NAME = "Default"; |
233 | + |
234 | + File? theme_folder; |
235 | + |
236 | [Description(nick = "top-roundness", blurb = "The roundness of the top corners.")] |
237 | public int TopRoundness { get; set; } |
238 | |
239 | @@ -52,6 +57,13 @@ |
240 | public Theme () |
241 | { |
242 | base (); |
243 | + theme_folder = get_theme_folder (DEFAULT_NAME); |
244 | + } |
245 | + |
246 | + public Theme.with_name (string name) |
247 | + { |
248 | + base (); |
249 | + theme_folder = get_theme_folder (name); |
250 | } |
251 | |
252 | /** |
253 | @@ -77,8 +89,13 @@ |
254 | */ |
255 | public void load (string type) |
256 | { |
257 | - Paths.ensure_directory_exists (Paths.AppConfigFolder.get_child ("theme")); |
258 | - init_from_filename ("theme/" + type + ".theme"); |
259 | + // if there is no folder available, fallback to the internal defaults |
260 | + if (theme_folder == null) { |
261 | + reset_properties (); |
262 | + return; |
263 | + } |
264 | + |
265 | + init_from_file (theme_folder.get_child (type + ".theme")); |
266 | } |
267 | |
268 | /** |
269 | @@ -288,5 +305,99 @@ |
270 | break; |
271 | } |
272 | } |
273 | + |
274 | + /** |
275 | + * Get a sorted list of all available theme-names |
276 | + * |
277 | + * @return {@link Gee.ArrayList} the list of theme-names |
278 | + */ |
279 | + public static ArrayList<string> get_theme_list () |
280 | + { |
281 | + var list = new HashSet<string> (str_hash, str_equal); |
282 | + |
283 | + list.add (DEFAULT_NAME); |
284 | + |
285 | + // Look in user's themes-folder |
286 | + try { |
287 | + var enumerator = Paths.AppThemeFolder.enumerate_children ("standard::name,standard::type", |
288 | + GLib.FileQueryInfoFlags.NONE); |
289 | + FileInfo info; |
290 | + while ((info = enumerator.next_file ()) != null) { |
291 | + if (info.get_is_hidden () |
292 | + || info.get_file_type () != GLib.FileType.DIRECTORY) |
293 | + continue; |
294 | + |
295 | + list.add (info.get_name ()); |
296 | + } |
297 | + } catch {} |
298 | + |
299 | + // Look in system's themes-folder |
300 | + try { |
301 | + var enumerator = Paths.ThemeFolder.enumerate_children ("standard::name,standard::type", |
302 | + GLib.FileQueryInfoFlags.NONE); |
303 | + FileInfo info; |
304 | + while ((info = enumerator.next_file ()) != null) { |
305 | + if (info.get_is_hidden () |
306 | + || info.get_file_type () != GLib.FileType.DIRECTORY) |
307 | + continue; |
308 | + |
309 | + list.add (info.get_name ()); |
310 | + } |
311 | + } catch {} |
312 | + |
313 | + var result = new ArrayList<string> (); |
314 | + result.add_all (list); |
315 | + result.sort ((CompareFunc) strcmp); |
316 | + |
317 | + return result; |
318 | + } |
319 | + |
320 | + /** |
321 | + * Try to get an already existing folder located in the |
322 | + * themes folder while prefering the user's themes folder. |
323 | + * If there is no folder found we fallback to the "Default" theme. |
324 | + * If even that folder doesn't exist return NULL (and use built-in defaults) |
325 | + * |
326 | + * @param basename the name of the folder |
327 | + * @return {@link GLib.File} the folder of the theme or NULL |
328 | + */ |
329 | + public static File? get_theme_folder (string name) |
330 | + { |
331 | + if (name == DEFAULT_NAME) |
332 | + return get_default_theme_folder (); |
333 | + |
334 | + File folder; |
335 | + |
336 | + // Look in user's themes-folder |
337 | + folder = Paths.AppThemeFolder.get_child (name); |
338 | + if (folder.query_exists () |
339 | + && folder.query_file_type (FileQueryInfoFlags.NONE, null) == FileType.DIRECTORY) |
340 | + return folder; |
341 | + |
342 | + // Look in system's themes-folder |
343 | + folder = Paths.ThemeFolder.get_child (name); |
344 | + if (folder.query_exists () |
345 | + && folder.query_file_type (FileQueryInfoFlags.NONE, null) == FileType.DIRECTORY) |
346 | + return folder; |
347 | + |
348 | + warning ("%s not found, falling back to %s.", name, DEFAULT_NAME); |
349 | + |
350 | + return get_default_theme_folder (); |
351 | + } |
352 | + |
353 | + static File? get_default_theme_folder () |
354 | + { |
355 | + File folder; |
356 | + |
357 | + // "Default" folder located in system's themes-folder |
358 | + folder = Paths.ThemeFolder.get_child (DEFAULT_NAME); |
359 | + if (folder.query_exists () |
360 | + && folder.query_file_type (FileQueryInfoFlags.NONE, null) == FileType.DIRECTORY) |
361 | + return folder; |
362 | + |
363 | + warning ("%s is not a folder fallback to the built-in defaults!", folder.get_path ()); |
364 | + |
365 | + return null; |
366 | + } |
367 | } |
368 | } |
369 | |
370 | === modified file 'lib/Services/Paths.vala' |
371 | --- lib/Services/Paths.vala 2013-01-22 18:35:52 +0000 |
372 | +++ lib/Services/Paths.vala 2013-02-03 11:21:19 +0000 |
373 | @@ -40,6 +40,10 @@ |
374 | */ |
375 | public static File DataFolder { get; protected set; } |
376 | |
377 | + /** |
378 | + * DataFolder/themes |
379 | + */ |
380 | + public static File ThemeFolder { get; protected set; } |
381 | |
382 | /** |
383 | * HomeFolder/.config |
384 | @@ -73,6 +77,11 @@ |
385 | public static File AppDataFolder { get; protected set; } |
386 | |
387 | /** |
388 | + * defaults to AppDataFolder/themes |
389 | + */ |
390 | + public static File AppThemeFolder { get; protected set; } |
391 | + |
392 | + /** |
393 | * defaults to CacheHomeFolder/app_name |
394 | */ |
395 | public static File AppCacheFolder { get; protected set; } |
396 | @@ -90,6 +99,7 @@ |
397 | // get environment-based settings |
398 | HomeFolder = File.new_for_path (Environment.get_home_dir ()); |
399 | DataFolder = File.new_for_path (data_folder); |
400 | + ThemeFolder = DataFolder.get_child ("themes"); |
401 | |
402 | |
403 | // get standard directories |
404 | @@ -106,12 +116,14 @@ |
405 | // set the program-specific directories to use |
406 | AppConfigFolder = ConfigHomeFolder.get_child (app_name); |
407 | AppDataFolder = DataHomeFolder.get_child (app_name); |
408 | + AppThemeFolder = AppDataFolder.get_child ("themes"); |
409 | AppCacheFolder = CacheHomeFolder.get_child (app_name); |
410 | |
411 | |
412 | // ensure all writable directories exist |
413 | ensure_directory_exists (AppConfigFolder); |
414 | ensure_directory_exists (AppDataFolder); |
415 | + ensure_directory_exists (AppThemeFolder); |
416 | ensure_directory_exists (AppCacheFolder); |
417 | } |
418 | |
419 | |
420 | === modified file 'lib/Services/Preferences.vala' |
421 | --- lib/Services/Preferences.vala 2012-05-08 11:19:34 +0000 |
422 | +++ lib/Services/Preferences.vala 2013-02-03 11:21:19 +0000 |
423 | @@ -84,6 +84,9 @@ |
424 | |
425 | void handle_notify (Object sender, ParamSpec property) |
426 | { |
427 | + if (read_only) |
428 | + return; |
429 | + |
430 | Logger.verbose ("property changed: %s", property.name); |
431 | |
432 | is_delayed_internal = true; |
433 | @@ -136,6 +139,7 @@ |
434 | |
435 | File? backing_file; |
436 | FileMonitor backing_monitor; |
437 | + bool read_only = false; |
438 | |
439 | /** |
440 | * Creates a preferences object with a backing file. |
441 | @@ -164,10 +168,31 @@ |
442 | */ |
443 | protected void init_from_file (GLib.File file) |
444 | { |
445 | + stop_monitor (); |
446 | + |
447 | backing_file = file; |
448 | + var file_exists = backing_file.query_exists (); |
449 | + |
450 | + if (!read_only) { |
451 | + try { |
452 | + FileInfo info; |
453 | + if (file_exists) |
454 | + info = file.query_info (FileAttribute.ACCESS_CAN_WRITE, FileQueryInfoFlags.NONE, null); |
455 | + else |
456 | + info = file.get_parent ().query_info (FileAttribute.ACCESS_CAN_WRITE, FileQueryInfoFlags.NONE, null); |
457 | + |
458 | + read_only = read_only || !info.get_attribute_boolean (FileAttribute.ACCESS_CAN_WRITE); |
459 | + |
460 | + if (read_only) |
461 | + warning ("'%s' is read-only!", file.get_path () ?? ""); |
462 | + } catch (Error e) { |
463 | + warning (e.message); |
464 | + read_only = true; |
465 | + } |
466 | + } |
467 | |
468 | // ensure the preferences file exists |
469 | - if (!backing_file.query_exists ()) { |
470 | + if (!file_exists) { |
471 | reset_properties (); |
472 | save_prefs (); |
473 | } else { |
474 | @@ -196,6 +221,9 @@ |
475 | */ |
476 | public void delay () |
477 | { |
478 | + if (read_only) |
479 | + return; |
480 | + |
481 | if (is_delayed) |
482 | return; |
483 | |
484 | @@ -212,6 +240,9 @@ |
485 | */ |
486 | public void apply () |
487 | { |
488 | + if (read_only) |
489 | + return; |
490 | + |
491 | if (!is_delayed) |
492 | return; |
493 | |
494 | @@ -242,6 +273,9 @@ |
495 | */ |
496 | public void delete () |
497 | { |
498 | + if (read_only) |
499 | + return; |
500 | + |
501 | is_delayed = false; |
502 | is_changed = false; |
503 | |
504 | @@ -365,6 +399,9 @@ |
505 | void save_prefs () |
506 | requires (backing_file != null) |
507 | { |
508 | + if (read_only) |
509 | + return; |
510 | + |
511 | if (is_delayed || is_delayed_internal) { |
512 | if (backing_file != null && backing_file.get_path () != null) |
513 | Logger.verbose ("Preferences.save_prefs('%s') - delaying save", backing_file.get_path ()); |
514 | |
515 | === modified file 'lib/Widgets/HoverWindow.vala' |
516 | --- lib/Widgets/HoverWindow.vala 2012-12-15 20:36:01 +0000 |
517 | +++ lib/Widgets/HoverWindow.vala 2013-02-03 11:21:19 +0000 |
518 | @@ -60,15 +60,15 @@ |
519 | |
520 | set_redraw_on_allocate (true); |
521 | |
522 | - theme = new HoverTheme (); |
523 | - theme.load ("hover"); |
524 | - theme.changed.connect (theme_changed); |
525 | + load_theme (); |
526 | |
527 | update_layout (); |
528 | style_set.connect (() => update_layout ()); |
529 | |
530 | notify["Text"].connect (invalidate); |
531 | |
532 | + controller.prefs.notify["Theme"].connect (load_theme); |
533 | + |
534 | stick (); |
535 | show_all (); |
536 | hide (); |
537 | @@ -80,6 +80,21 @@ |
538 | queue_draw (); |
539 | } |
540 | |
541 | + void load_theme () |
542 | + { |
543 | + var is_reload = (theme != null); |
544 | + |
545 | + if (is_reload) |
546 | + theme.changed.disconnect (theme_changed); |
547 | + |
548 | + theme = new HoverTheme (controller.prefs.Theme); |
549 | + theme.load ("hover"); |
550 | + theme.changed.connect (theme_changed); |
551 | + |
552 | + if (is_reload) |
553 | + theme_changed (); |
554 | + } |
555 | + |
556 | /** |
557 | * Centers the window at the x/y location specified. |
558 | * |
559 | |
560 | === modified file 'lib/libplank.symbols' |
561 | --- lib/libplank.symbols 2013-01-29 07:57:53 +0000 |
562 | +++ lib/libplank.symbols 2013-02-03 11:21:19 +0000 |
563 | @@ -26,6 +26,7 @@ |
564 | plank_dock_preferences_get_Monitor |
565 | plank_dock_preferences_get_Offset |
566 | plank_dock_preferences_get_Position |
567 | +plank_dock_preferences_get_Theme |
568 | plank_dock_preferences_get_type |
569 | plank_dock_preferences_get_UnhideDelay |
570 | plank_dock_preferences_increase_icon_size |
571 | @@ -41,6 +42,7 @@ |
572 | plank_dock_preferences_set_Monitor |
573 | plank_dock_preferences_set_Offset |
574 | plank_dock_preferences_set_Position |
575 | +plank_dock_preferences_set_Theme |
576 | plank_dock_preferences_set_UnhideDelay |
577 | plank_dock_renderer_construct |
578 | plank_dock_renderer_draw_dock |
579 | @@ -170,6 +172,7 @@ |
580 | plank_drawing_hover_theme_get_type |
581 | plank_drawing_hover_theme_new |
582 | plank_drawing_theme_construct |
583 | +plank_drawing_theme_construct_with_name |
584 | plank_drawing_theme_draw_background |
585 | plank_drawing_theme_draw_inner_rect |
586 | plank_drawing_theme_draw_rounded_line |
587 | @@ -181,11 +184,13 @@ |
588 | plank_drawing_theme_get_InnerStrokeColor |
589 | plank_drawing_theme_get_LineWidth |
590 | plank_drawing_theme_get_OuterStrokeColor |
591 | +plank_drawing_theme_get_theme_folder |
592 | plank_drawing_theme_get_top_offset |
593 | plank_drawing_theme_get_TopRoundness |
594 | plank_drawing_theme_get_type |
595 | plank_drawing_theme_load |
596 | plank_drawing_theme_new |
597 | +plank_drawing_theme_new_with_name |
598 | plank_drawing_theme_set_BottomRoundness |
599 | plank_drawing_theme_set_FillEndColor |
600 | plank_drawing_theme_set_FillStartColor |
601 | @@ -386,24 +391,28 @@ |
602 | plank_services_paths_get_AppCacheFolder |
603 | plank_services_paths_get_AppConfigFolder |
604 | plank_services_paths_get_AppDataFolder |
605 | +plank_services_paths_get_AppThemeFolder |
606 | plank_services_paths_get_CacheHomeFolder |
607 | plank_services_paths_get_ConfigHomeFolder |
608 | plank_services_paths_get_DataDirFolders |
609 | plank_services_paths_get_DataFolder |
610 | plank_services_paths_get_DataHomeFolder |
611 | plank_services_paths_get_HomeFolder |
612 | +plank_services_paths_get_ThemeFolder |
613 | plank_services_paths_get_type |
614 | plank_services_paths_initialize |
615 | plank_services_paths_new |
616 | plank_services_paths_set_AppCacheFolder |
617 | plank_services_paths_set_AppConfigFolder |
618 | plank_services_paths_set_AppDataFolder |
619 | +plank_services_paths_set_AppThemeFolder |
620 | plank_services_paths_set_CacheHomeFolder |
621 | plank_services_paths_set_ConfigHomeFolder |
622 | plank_services_paths_set_DataDirFolders |
623 | plank_services_paths_set_DataFolder |
624 | plank_services_paths_set_DataHomeFolder |
625 | plank_services_paths_set_HomeFolder |
626 | +plank_services_paths_set_ThemeFolder |
627 | plank_services_preferences_apply |
628 | plank_services_preferences_construct |
629 | plank_services_preferences_construct_with_file |
What is the point of get_theme_list? It isn't used anywhere.