Merge lp:~docky-core/plank/item-foreground-buffer into lp:plank

Proposed by Rico Tzschichholz
Status: Merged
Approved by: Robert Dyer
Approved revision: 812
Merged at revision: 816
Proposed branch: lp:~docky-core/plank/item-foreground-buffer
Merge into: lp:plank
Prerequisite: lp:~docky-core/plank/item-shadows
Diff against target: 363 lines (+151/-57)
3 files modified
lib/DockRenderer.vala (+62/-27)
lib/Drawing/DockSurface.vala (+16/-0)
lib/Items/DockItem.vala (+73/-30)
To merge this branch: bzr merge lp:~docky-core/plank/item-foreground-buffer
Reviewer Review Type Date Requested Status
Robert Dyer (community) Approve
Review via email: mp+160124@code.launchpad.net

Description of the change

* Refactor the way item-layers are drawn.

* Draw item-shadows behind the dock-background. (The theme should disable the shadows if TopPadding isn't < 0)

* Puts the badge/progress-bar onto a foreground_surface owned by the dock-item. This avoids the redraw from scratch of the badge/progress-bar on every dock-redraw.

To post a comment you must log in.
805. By Rico Tzschichholz

build: Use LT_LIB_M instead of hardcoding -lm

806. By Rico Tzschichholz

Add theme-configurable icon-shaped shadows

This adds new DockTheme preference "IconShadowSize" to adjust the shadow
with a default of 1.0

Revision history for this message
Robert Dyer (psybers) wrote :

Lines 9-13 - this check shouldnt be here. Always pass in the func and instead do this check inside the item itself (let the item decide if it needs to draw overlay, based on its own count/progress)

review: Needs Fixing
Revision history for this message
Robert Dyer (psybers) wrote :

the blocks 194-200 and 210-217 are the same, arent they? you can refactor this code to eliminate this duplication

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

> Lines 9-13 - this check shouldnt be here. Always pass in the func and instead
> do this check inside the item itself (let the item decide if it needs to draw
> overlay, based on its own count/progress)

Checking it that early and passing null as func saves a cr.set_source_surface () call, same for checking the shadow-size above that.

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

> the blocks 194-200 and 210-217 are the same, arent they? you can refactor this
> code to eliminate this duplication

It is nearly identical except for their sizes which depend on the func==null condition, an alternative might be to put it in an extra inline function.

Suggest a diff then.

807. By Rico Tzschichholz

positionmanager: Refactor get_background_position to get_background_region

This makes its usage in DockRenderer easier.

808. By Rico Tzschichholz

Use compact way to initialize structs

Note that all fields need be qualified in their defined order.

809. By Rico Tzschichholz

titledseparatormenuitem: Don't use deprecated gtk+ api

It didn't work before and doesnt completely now either.

811. By Rico Tzschichholz

Draw item-shadows separately behind the dock background

812. By Rico Tzschichholz

Refactor the item drawing

Revision history for this message
Robert Dyer (psybers) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/DockRenderer.vala'
2--- lib/DockRenderer.vala 2013-04-24 07:55:37 +0000
3+++ lib/DockRenderer.vala 2013-04-25 12:50:31 +0000
4@@ -40,6 +40,7 @@
5 Gdk.Rectangle background_rect;
6 DockSurface? main_buffer;
7 DockSurface? indicator_buffer;
8+ DockSurface? shadow_buffer;
9 DockSurface? urgent_indicator_buffer;
10 DockSurface? urgent_glow_buffer;
11
12@@ -236,6 +237,7 @@
13 main_buffer = null;
14 background_buffer = null;
15 indicator_buffer = null;
16+ shadow_buffer = null;
17 urgent_indicator_buffer = null;
18 urgent_glow_buffer = null;
19
20@@ -276,13 +278,19 @@
21 var start = new DateTime.now_local ();
22 #endif
23
24+ var width = position_manager.DockWidth;
25+ var height = position_manager.DockHeight;
26+
27 if (main_buffer == null) {
28- var width = position_manager.DockWidth;
29- var height = position_manager.DockHeight;
30 main_buffer = new DockSurface.with_surface (width, height, cr.get_target ());
31 }
32
33+ if (shadow_buffer == null) {
34+ shadow_buffer = new DockSurface.with_surface (width, height, cr.get_target ());
35+ }
36+
37 main_buffer.clear ();
38+ shadow_buffer.clear ();
39
40 #if BENCHMARK
41 var start2 = new DateTime.now_local ();
42@@ -316,6 +324,9 @@
43
44 // draw the dock on the window
45 cr.set_operator (Operator.SOURCE);
46+ cr.set_source_surface (shadow_buffer.Internal, x_offset, y_offset);
47+ cr.paint ();
48+ cr.set_operator (Operator.OVER);
49 cr.set_source_surface (main_buffer.Internal, x_offset, y_offset);
50 cr.paint ();
51
52@@ -363,6 +374,7 @@
53 unowned DragManager drag_manager = controller.drag_manager;
54
55 unowned Context main_cr = main_buffer.Context;
56+ unowned Context shadow_cr = shadow_buffer.Context;
57 var icon_size = position_manager.IconSize;
58 var shadow_size = controller.position_manager.IconShadowSize;
59
60@@ -370,12 +382,20 @@
61 #if BENCHMARK
62 var start = new DateTime.now_local ();
63 #endif
64- unowned DrawItemFunc? shadow_func = null;
65+ var icon_surface = item.get_surface_copy (icon_size, icon_size, main_buffer);
66+ unowned Context icon_cr = icon_surface.Context;
67+
68+ DockSurface? icon_shadow_surface = null;
69 if (shadow_size > 0)
70- shadow_func = draw_item_shadow;
71-
72- var icon_surface = item.get_surface_copy (icon_size, icon_size, main_buffer, shadow_func);
73- unowned Context icon_cr = icon_surface.Context;
74+ icon_shadow_surface = item.get_background_surface (draw_item_shadow);
75+
76+ DockSurface? icon_overlay_surface = null;
77+ if (item.CountVisible || item.ProgressVisible)
78+ icon_overlay_surface = item.get_foreground_surface (draw_item_overlay);
79+
80+ if (icon_overlay_surface != null)
81+ icon_cr.set_source_surface (icon_overlay_surface.Internal, 0, 0);
82+
83 #if BENCHMARK
84 var end = new DateTime.now_local ();
85 benchmark.add (" item.get_surface time - %f ms".printf (end.difference (start) / 1000.0));
86@@ -444,22 +464,6 @@
87 icon_cr.set_operator (Cairo.Operator.OVER);
88 }
89
90-
91- // TODO put them onto a cached icon_overlay_surface for performance reasons?
92- // maybe even draw outside of the item-draw-area (considering the hover-area)
93-
94- var urgent_color = get_styled_color ();
95- urgent_color.add_hue (theme.UrgentHueShift);
96-
97- // draw item's count
98- if (item.CountVisible)
99- theme.draw_item_count (icon_surface, icon_size, urgent_color, item.Count);
100-
101- // draw item's progress
102- if (item.ProgressVisible)
103- theme.draw_item_progress (icon_surface, icon_size, urgent_color, item.Progress);
104-
105-
106 // darken the icon
107 if (darken > 0) {
108 icon_cr.rectangle (0, 0, icon_surface.Width, icon_surface.Height);
109@@ -501,8 +505,14 @@
110 theme.draw_active_glow (main_buffer, background_rect, glow_rect, item.AverageIconColor, opacity, controller.prefs.Position);
111 }
112
113+ // draw the icon shadow
114+ if (icon_shadow_surface != null) {
115+ shadow_cr.set_source_surface (icon_shadow_surface.Internal, draw_rect.x - shadow_size, draw_rect.y - shadow_size);
116+ shadow_cr.paint ();
117+ }
118+
119 // draw the icon
120- main_cr.set_source_surface (icon_surface.Internal, draw_rect.x - shadow_size, draw_rect.y - shadow_size);
121+ main_cr.set_source_surface (icon_surface.Internal, draw_rect.x, draw_rect.y);
122 main_cr.paint ();
123
124 // draw indicators
125@@ -510,6 +520,34 @@
126 draw_indicator_state (hover_rect, item.Indicator, item.State);
127 }
128
129+ DockSurface draw_item_overlay (DockItem item, DockSurface icon_surface, DockSurface? current_surface)
130+ {
131+ unowned PositionManager position_manager = controller.position_manager;
132+ var width = icon_surface.Width;
133+ var height = icon_surface.Height;
134+
135+ if (current_surface != null
136+ && width == current_surface.Width && height == current_surface.Height)
137+ return current_surface;
138+
139+ Logger.verbose ("DockItem.draw_item_overlay (width = %i, height = %i)", width, height);
140+ var surface = new DockSurface.with_dock_surface (width, height, icon_surface);
141+
142+ var icon_size = position_manager.IconSize;
143+ var urgent_color = get_styled_color ();
144+ urgent_color.add_hue (theme.UrgentHueShift);
145+
146+ // draw item's count
147+ if (item.CountVisible)
148+ theme.draw_item_count (surface, icon_size, urgent_color, item.Count);
149+
150+ // draw item's progress
151+ if (item.ProgressVisible)
152+ theme.draw_item_progress (surface, icon_size, urgent_color, item.Progress);
153+
154+ return surface;
155+ }
156+
157 DockSurface draw_item_shadow (DockItem item, DockSurface icon_surface, DockSurface? current_surface)
158 {
159 var shadow_size = controller.position_manager.IconShadowSize;
160@@ -548,9 +586,6 @@
161 cr.paint_with_alpha (0.44);
162 surface.gaussian_blur (shadow_size);
163
164- cr.set_source_surface (icon_surface.Internal, shadow_size, shadow_size);
165- cr.paint ();
166-
167 return surface;
168 }
169
170
171=== modified file 'lib/Drawing/DockSurface.vala'
172--- lib/Drawing/DockSurface.vala 2013-04-19 12:37:27 +0000
173+++ lib/Drawing/DockSurface.vala 2013-04-25 12:50:31 +0000
174@@ -111,6 +111,22 @@
175 }
176
177 /**
178+ * Create a copy of the surface
179+ *
180+ * @return copy of this surface
181+ */
182+ public DockSurface copy ()
183+ {
184+ var copy = new DockSurface.with_dock_surface (Width, Height, this);
185+ unowned Cairo.Context cr = copy.Context;
186+
187+ cr.set_source_surface (Internal, 0, 0);
188+ cr.paint ();
189+
190+ return copy;
191+ }
192+
193+ /**
194 * Saves the current dock surface to a {@link Gdk.Pixbuf}.
195 *
196 * @return the {@link Gdk.Pixbuf}
197
198=== modified file 'lib/Items/DockItem.vala'
199--- lib/Items/DockItem.vala 2013-04-22 13:19:32 +0000
200+++ lib/Items/DockItem.vala 2013-04-25 12:50:31 +0000
201@@ -29,7 +29,7 @@
202 * Draws a modified surface onto another newly created or given surface
203 *
204 * @param item the dock-item
205- * @param source original surface
206+ * @param source original surface which may not be changed
207 * @param target the previously modified surface
208 * @return the modified surface or passed through target
209 */
210@@ -289,6 +289,7 @@
211
212 DockSurface? surface = null;
213 DockSurface? background_surface = null;
214+ DockSurface? foreground_surface = null;
215
216 /**
217 * Creates a new dock item.
218@@ -304,6 +305,11 @@
219 Gtk.IconTheme.get_default ().changed.connect (icon_theme_changed);
220 notify["Icon"].connect (reset_icon_buffer);
221 notify["ForcePixbuf"].connect (reset_icon_buffer);
222+
223+ notify["Count"].connect (reset_foreground_buffer);
224+ notify["CountVisible"].connect (reset_foreground_buffer);
225+ notify["Progress"].connect (reset_foreground_buffer);
226+ notify["ProgressVisible"].connect (reset_foreground_buffer);
227 }
228
229 ~DockItem ()
230@@ -312,6 +318,11 @@
231 Gtk.IconTheme.get_default ().changed.disconnect (icon_theme_changed);
232 notify["Icon"].disconnect (reset_icon_buffer);
233 notify["ForcePixbuf"].disconnect (reset_icon_buffer);
234+
235+ notify["Count"].disconnect (reset_foreground_buffer);
236+ notify["CountVisible"].disconnect (reset_foreground_buffer);
237+ notify["Progress"].disconnect (reset_foreground_buffer);
238+ notify["ProgressVisible"].disconnect (reset_foreground_buffer);
239 }
240
241 /**
242@@ -337,6 +348,7 @@
243 {
244 surface = null;
245 background_surface = null;
246+ foreground_surface = null;
247
248 needs_redraw ();
249 }
250@@ -347,6 +359,12 @@
251 public void reset_buffers ()
252 {
253 background_surface = null;
254+ foreground_surface = null;
255+ }
256+
257+ void reset_foreground_buffer ()
258+ {
259+ foreground_surface = null;
260 }
261
262 void icon_theme_changed ()
263@@ -359,7 +377,7 @@
264 });
265 }
266
267- DockSurface get_surface (int width, int height, DockSurface model)
268+ unowned DockSurface get_surface (int width, int height, DockSurface model)
269 {
270 if (surface == null || width != surface.Width || height != surface.Height) {
271 surface = new DockSurface.with_dock_surface (width, height, model);
272@@ -374,38 +392,63 @@
273 }
274
275 /**
276- * Returns a copy of the dock surface for this item and triggers an
277- * internal redraw if the requested size isn't matching the cache.
278- *
279- * @param width width of the requested surface
280- * @param height height of the requested surface
281+ * Returns the background surface for this item.
282+ *
283+ * The draw_func may pass through the given previously computed surface
284+ * or change it as needed. This surface will be buffered internally.
285+ *
286+ * Passing null as draw_func will destroy the internal background buffer.
287+ *
288+ * @param draw_func function which creates/changes the background surface
289+ * @return the background surface of this item which may not be changed
290+ */
291+ public unowned DockSurface? get_background_surface (DrawItemFunc? draw_func = null)
292+ requires (surface != null)
293+ {
294+ if (draw_func != null)
295+ background_surface = draw_func (this, surface, background_surface);
296+ else
297+ background_surface = null;
298+
299+ return background_surface;
300+ }
301+
302+ /**
303+ * Returns the foreground surface for this item.
304+ *
305+ * The draw_func may pass through the given previously computed surface
306+ * or change it as needed. This surface will be buffered internally.
307+ *
308+ * Passing null as draw_func will destroy the internal foreground buffer.
309+ *
310+ * @param draw_func function which creates/changes the foreground surface
311+ * @return the background surface of this item which may not be changed
312+ */
313+ public unowned DockSurface? get_foreground_surface (DrawItemFunc? draw_func = null)
314+ requires (surface != null)
315+ {
316+ if (draw_func != null)
317+ foreground_surface = draw_func (this, surface, foreground_surface);
318+ else
319+ foreground_surface = null;
320+
321+ return foreground_surface;
322+ }
323+
324+ /**
325+ * Returns a copy of the dock surface for this item.
326+ *
327+ * It will trigger an internal redraw if the requested size
328+ * isn't matching the cache.
329+ *
330+ * @param width width of the icon surface
331+ * @param height height of the icon surface
332 * @param model existing surface to use as basis of new surface
333- * @param draw_func function which manipulates the resulting surface
334 * @return the copied dock surface for this item
335 */
336- public DockSurface get_surface_copy (int width, int height, DockSurface model, DrawItemFunc? draw_func = null)
337+ public DockSurface get_surface_copy (int width, int height, DockSurface model)
338 {
339- var icon_surface = get_surface (width, height, model);
340-
341- if (draw_func == null) {
342- var surface_copy = new DockSurface.with_dock_surface (width, height, model);
343- unowned Cairo.Context cr = surface_copy.Context;
344-
345- cr.set_source_surface (icon_surface.Internal, 0, 0);
346- cr.paint ();
347-
348- return surface_copy;
349- }
350-
351- background_surface = draw_func (this, icon_surface, background_surface);
352-
353- var surface_copy = new DockSurface.with_dock_surface (background_surface.Width, background_surface.Height, model);
354- unowned Cairo.Context cr = surface_copy.Context;
355-
356- cr.set_source_surface (background_surface.Internal, 0, 0);
357- cr.paint ();
358-
359- return surface_copy;
360+ return get_surface (width, height, model).copy ();
361 }
362
363 /**

Subscribers

People subscribed via source and target branches

to status/vote changes: