Merge lp:~docky-core/plank/indicator-style into lp:plank
- indicator-style
- Merge into trunk
Status: | Work in progress |
---|---|
Proposed branch: | lp:~docky-core/plank/indicator-style |
Merge into: | lp:plank |
Diff against target: |
649 lines (+378/-47) 8 files modified
data/themes/Glowless/dock.theme (+70/-0) data/themes/Makefile.am (+5/-0) docs/Makefile.am (+1/-0) lib/DockRenderer.vala (+35/-42) lib/Drawing/DockTheme.vala (+193/-5) lib/Drawing/Enums.vala (+63/-0) lib/Makefile.am (+1/-0) lib/libplank.symbols (+10/-0) |
To merge this branch: | bzr merge lp:~docky-core/plank/indicator-style |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
truu (community) | testing | Needs Information | |
Docky Core | Pending | ||
Review via email: mp+290904@code.launchpad.net |
Commit message
Description of the change
* Reworked indicator-drawing while adding some styles
(Branch will get rebased and squashed in self-contained/
TODO:
* Naming of new theme-settings needs some more thinking
* Add new theme "Modern" / "Flat" (?) which makes use of the new features
THOUGHTS:
* Moving caching in the theme rather than handle it in the renderer?
- 1550. By Rico Tzschichholz
-
surface: Some minor cleaning
Rico Tzschichholz (ricotz) wrote : | # |
> Theme naming:
> I'd vote for "flat" in case of a theme with the line type indicator and
> "modern" in case of the circle.
Let's see how this turns out when the styles are finished ;-)
> Looks:
> The circular ones look better if their center is in the middle of bottom
> padding: http://
> An extra slight bump off the ground instead might look better too.
I am not really convinced here.
> The circles also end up a bit too close together at times, depending on the
> size set (indicatorsize 1 looked to be too close, while 1.2 looked fine at
> icon size 48)
> http://
Should be better now
> In my opinion lines should not indicate several instances being open, as it
> appears strange :D
> Neither chrome os nor windows seem to provide such information while having
> that kind of indicators. It feels as if the application were somehow divided
> into smaller fragments.
I agree here.
truu (marten-truu) wrote : | # |
stroke_preserve seems to make the indicators strangely fuzzy :D
Can't really tell with circles but it's very noticeable with lines.
The lines are also now lifted slightly off the ground by about the amount that I like the indicators to be. But I suppose that's a up to personal preference.
I'll also add a side-by-side of the lifted and not circles with values I'd actually use:
http://
Perhaps of some use as reference when deciding which way to go.
tldr: imo the lines should be grounded and not fuzzy.
- 1551. By Rico Tzschichholz
-
drawing/color: Add support for HSL and some convenience functions
- 1555. By Rico Tzschichholz
-
WIP
- 1556. By Rico Tzschichholz
-
WIP
- 1557. By Rico Tzschichholz
-
WIP
- 1558. By Rico Tzschichholz
-
WIP
- 1559. By Rico Tzschichholz
-
WIP
Rico Tzschichholz (ricotz) wrote : | # |
Unmerged revisions
- 1559. By Rico Tzschichholz
-
WIP
- 1558. By Rico Tzschichholz
-
WIP
- 1557. By Rico Tzschichholz
-
WIP
- 1556. By Rico Tzschichholz
-
WIP
- 1555. By Rico Tzschichholz
-
WIP
- 1554. By truu
-
Removed Spacing and Height options, probably created a weird style enum in a weird place and put some things where they should've been put all along.
- 1553. By truu
-
Add missing newline.
- 1552. By truu
-
Makes gradients optional by adding a few theming options.
Preview Diff
1 | === added directory 'data/themes/Glowless' | |||
2 | === added file 'data/themes/Glowless/dock.theme' | |||
3 | --- data/themes/Glowless/dock.theme 1970-01-01 00:00:00 +0000 | |||
4 | +++ data/themes/Glowless/dock.theme 2016-04-10 16:22:24 +0000 | |||
5 | @@ -0,0 +1,70 @@ | |||
6 | 1 | |||
7 | 2 | [PlankTheme] | ||
8 | 3 | #The roundness of the top corners. | ||
9 | 4 | TopRoundness=4 | ||
10 | 5 | #The roundness of the bottom corners. | ||
11 | 6 | BottomRoundness=0 | ||
12 | 7 | #The thickness (in pixels) of lines drawn. | ||
13 | 8 | LineWidth=0 | ||
14 | 9 | #The color (RGBA) of the outer stroke. | ||
15 | 10 | OuterStrokeColor=255;;255;;255;;200 | ||
16 | 11 | #The starting color (RGBA) of the fill gradient. | ||
17 | 12 | FillStartColor=38;;50;;56;;200 | ||
18 | 13 | #The ending color (RGBA) of the fill gradient. | ||
19 | 14 | FillEndColor=38;;50;;56;;200 | ||
20 | 15 | #The color (RGBA) of the inner stroke. | ||
21 | 16 | InnerStrokeColor=2;;2;;2;;0 | ||
22 | 17 | |||
23 | 18 | [PlankDockTheme] | ||
24 | 19 | #The padding on the left/right dock edges, in tenths of a percent of IconSize. | ||
25 | 20 | HorizPadding=1 | ||
26 | 21 | #The padding on the top dock edge, in tenths of a percent of IconSize. | ||
27 | 22 | TopPadding=1 | ||
28 | 23 | #The padding on the bottom dock edge, in tenths of a percent of IconSize. | ||
29 | 24 | BottomPadding=1.5 | ||
30 | 25 | #The padding between items on the dock, in tenths of a percent of IconSize. | ||
31 | 26 | ItemPadding=2 | ||
32 | 27 | #The size of item indicators, in tenths of a percent of IconSize. | ||
33 | 28 | IndicatorSize=5 | ||
34 | 29 | #The size of the icon-shadow behind every item, in tenths of a percent of IconSize. | ||
35 | 30 | IconShadowSize=1 | ||
36 | 31 | #The style of item indicators (values 0 - 3), styles: 0 - circle-glow, 1 - circle-color-glow, 2 - circle, 3 - underline. | ||
37 | 32 | IndicatorStyle=2 | ||
38 | 33 | #The color (RGBA) of the indicator. | ||
39 | 34 | IndicatorColor=225;;225;;225;;255 | ||
40 | 35 | #The height (in percent of IconSize) to bounce an icon when the application sets urgent. | ||
41 | 36 | UrgentBounceHeight=1.6666666666666667 | ||
42 | 37 | #The height (in percent of IconSize) to bounce an icon when launching an application. | ||
43 | 38 | LaunchBounceHeight=0.625 | ||
44 | 39 | #The opacity value (0 to 1) to fade the dock to when hiding it. | ||
45 | 40 | FadeOpacity=1 | ||
46 | 41 | #The amount of time (in ms) for click animations. | ||
47 | 42 | ClickTime=300 | ||
48 | 43 | #The amount of time (in ms) to bounce an urgent icon. | ||
49 | 44 | UrgentBounceTime=600 | ||
50 | 45 | #The amount of time (in ms) to bounce an icon when launching an application. | ||
51 | 46 | LaunchBounceTime=600 | ||
52 | 47 | #The amount of time (in ms) for active window indicator animations. | ||
53 | 48 | ActiveTime=300 | ||
54 | 49 | #The amount of time (in ms) to slide icons into/out of the dock. | ||
55 | 50 | SlideTime=300 | ||
56 | 51 | #The time (in ms) to fade the dock in/out on a hide (if FadeOpacity is < 1). | ||
57 | 52 | FadeTime=250 | ||
58 | 53 | #The time (in ms) to slide the dock in/out on a hide (if FadeOpacity is 1). | ||
59 | 54 | HideTime=250 | ||
60 | 55 | #The size of the urgent glow (shown when dock is hidden), in tenths of a percent of IconSize. | ||
61 | 56 | GlowSize=30 | ||
62 | 57 | #The total time (in ms) to show the hidden-dock urgent glow. | ||
63 | 58 | GlowTime=10000 | ||
64 | 59 | #The time (in ms) of each pulse of the hidden-dock urgent glow. | ||
65 | 60 | GlowPulseTime=2000 | ||
66 | 61 | #The hue-shift (-180 to 180) of the urgent indicator color. | ||
67 | 62 | UrgentHueShift=150 | ||
68 | 63 | #The time (in ms) to move an item to its new position or its addition/removal to/from the dock. | ||
69 | 64 | ItemMoveTime=450 | ||
70 | 65 | #Whether background and icons will unhide/hide with different speeds. The top-border of both will leave/hit the screen-edge at the same time. | ||
71 | 66 | CascadeHide=true | ||
72 | 67 | #Whether an item has an active background glow. If not, active-item-color (RGBA) will be used instead. | ||
73 | 68 | SelectionStyle=1 | ||
74 | 69 | #The color (RGBA) of the active item background. | ||
75 | 70 | SelectionColor=0;;0;;0;;0 | ||
76 | 0 | 71 | ||
77 | === modified file 'data/themes/Makefile.am' | |||
78 | --- data/themes/Makefile.am 2013-11-10 12:52:40 +0000 | |||
79 | +++ data/themes/Makefile.am 2016-04-10 16:22:24 +0000 | |||
80 | @@ -14,3 +14,8 @@ | |||
81 | 14 | dist_transparenttheme_DATA = \ | 14 | dist_transparenttheme_DATA = \ |
82 | 15 | Transparent/dock.theme \ | 15 | Transparent/dock.theme \ |
83 | 16 | $(NULL) | 16 | $(NULL) |
84 | 17 | |||
85 | 18 | glowlessthemedir = $(pkgdatadir)/themes/Glowless | ||
86 | 19 | dist_glowlesstheme_DATA = \ | ||
87 | 20 | Glowless/dock.theme \ | ||
88 | 21 | $(NULL) | ||
89 | 17 | 22 | ||
90 | === modified file 'docs/Makefile.am' | |||
91 | --- docs/Makefile.am 2016-02-28 12:06:16 +0000 | |||
92 | +++ docs/Makefile.am 2016-04-10 16:22:24 +0000 | |||
93 | @@ -34,6 +34,7 @@ | |||
94 | 34 | $(top_srcdir)/lib/Drawing/DrawingService.vala \ | 34 | $(top_srcdir)/lib/Drawing/DrawingService.vala \ |
95 | 35 | $(top_srcdir)/lib/Drawing/DockTheme.vala \ | 35 | $(top_srcdir)/lib/Drawing/DockTheme.vala \ |
96 | 36 | $(top_srcdir)/lib/Drawing/Easing.vala \ | 36 | $(top_srcdir)/lib/Drawing/Easing.vala \ |
97 | 37 | $(top_srcdir)/lib/Drawing/Enums.vala \ | ||
98 | 37 | $(top_srcdir)/lib/Drawing/Renderer.vala \ | 38 | $(top_srcdir)/lib/Drawing/Renderer.vala \ |
99 | 38 | $(top_srcdir)/lib/Drawing/Surface.vala \ | 39 | $(top_srcdir)/lib/Drawing/Surface.vala \ |
100 | 39 | $(top_srcdir)/lib/Drawing/SurfaceCache.vala \ | 40 | $(top_srcdir)/lib/Drawing/SurfaceCache.vala \ |
101 | 40 | 41 | ||
102 | === modified file 'lib/DockRenderer.vala' | |||
103 | --- lib/DockRenderer.vala 2016-02-28 12:06:16 +0000 | |||
104 | +++ lib/DockRenderer.vala 2016-04-10 16:22:24 +0000 | |||
105 | @@ -59,8 +59,8 @@ | |||
106 | 59 | 59 | ||
107 | 60 | Surface? background_buffer = null; | 60 | Surface? background_buffer = null; |
108 | 61 | Gdk.Rectangle background_rect; | 61 | Gdk.Rectangle background_rect; |
111 | 62 | Surface? indicator_buffer = null; | 62 | Surface[] indicator_buffer = new Surface[2]; |
112 | 63 | Surface? urgent_indicator_buffer = null; | 63 | Surface[] urgent_indicator_buffer = new Surface[2]; |
113 | 64 | Surface? urgent_glow_buffer = null; | 64 | Surface? urgent_glow_buffer = null; |
114 | 65 | 65 | ||
115 | 66 | int64 last_hide = 0LL; | 66 | int64 last_hide = 0LL; |
116 | @@ -209,8 +209,10 @@ | |||
117 | 209 | shadow_buffer = null; | 209 | shadow_buffer = null; |
118 | 210 | 210 | ||
119 | 211 | background_buffer = null; | 211 | background_buffer = null; |
122 | 212 | indicator_buffer = null; | 212 | indicator_buffer[0] = null; |
123 | 213 | urgent_indicator_buffer = null; | 213 | indicator_buffer[1] = null; |
124 | 214 | urgent_indicator_buffer[0] = null; | ||
125 | 215 | urgent_indicator_buffer[1] = null; | ||
126 | 214 | urgent_glow_buffer = null; | 216 | urgent_glow_buffer = null; |
127 | 215 | 217 | ||
128 | 216 | animated_draw (); | 218 | animated_draw (); |
129 | @@ -819,7 +821,8 @@ | |||
130 | 819 | if ((item.State & ItemState.ACTIVE) == 0) | 821 | if ((item.State & ItemState.ACTIVE) == 0) |
131 | 820 | opacity = 1 - opacity; | 822 | opacity = 1 - opacity; |
132 | 821 | if (opacity > 0) { | 823 | if (opacity > 0) { |
134 | 822 | theme.draw_active_glow (item_buffer, background_rect, draw_value.background_region, item.AverageIconColor, opacity, position); | 824 | var color = (theme.SelectionStyle == SelectionStyleType.LEGACY ? item.AverageIconColor : theme.SelectionColor); |
135 | 825 | theme.draw_active_glow (item_buffer, background_rect, draw_value.background_region, color, opacity, position); | ||
136 | 823 | } | 826 | } |
137 | 824 | 827 | ||
138 | 825 | // draw the icon | 828 | // draw the icon |
139 | @@ -837,7 +840,7 @@ | |||
140 | 837 | cr.restore (); | 840 | cr.restore (); |
141 | 838 | 841 | ||
142 | 839 | // draw indicators | 842 | // draw indicators |
144 | 840 | if (draw_value.show_indicator && item.Indicator != IndicatorState.NONE) | 843 | if (draw_value.show_indicator) |
145 | 841 | draw_indicator_state (cr, draw_value.hover_region, item.Indicator, item.State); | 844 | draw_indicator_state (cr, draw_value.hover_region, item.Indicator, item.State); |
146 | 842 | } | 845 | } |
147 | 843 | 846 | ||
148 | @@ -877,7 +880,7 @@ | |||
149 | 877 | var surface = new Surface.with_surface (width, height, model); | 880 | var surface = new Surface.with_surface (width, height, model); |
150 | 878 | 881 | ||
151 | 879 | var icon_size = int.min (width, height); | 882 | var icon_size = int.min (width, height); |
153 | 880 | var urgent_color = get_styled_color (); | 883 | var urgent_color = (theme.IndicatorStyle == IndicatorStyleType.LEGACY ? get_styled_color () : theme.IndicatorColor); |
154 | 881 | urgent_color.add_hue (theme.UrgentHueShift); | 884 | urgent_color.add_hue (theme.UrgentHueShift); |
155 | 882 | 885 | ||
156 | 883 | // draw item's count | 886 | // draw item's count |
157 | @@ -930,60 +933,50 @@ | |||
158 | 930 | return surface; | 933 | return surface; |
159 | 931 | } | 934 | } |
160 | 932 | 935 | ||
162 | 933 | void draw_indicator_state (Cairo.Context cr, Gdk.Rectangle item_rect, IndicatorState indicator, ItemState item_state) | 936 | void draw_indicator_state (Cairo.Context cr, Gdk.Rectangle item_rect, IndicatorState indicator_state, ItemState item_state) |
163 | 934 | { | 937 | { |
164 | 938 | if (indicator_state == IndicatorState.NONE || theme.IndicatorSize <= 0) | ||
165 | 939 | return; | ||
166 | 940 | |||
167 | 935 | unowned PositionManager position_manager = controller.position_manager; | 941 | unowned PositionManager position_manager = controller.position_manager; |
182 | 936 | 942 | unowned Surface indicator_surface; | |
183 | 937 | if (indicator_buffer == null) { | 943 | var index = indicator_state - 1; |
184 | 938 | var indicator_color = get_styled_color (); | 944 | |
185 | 939 | indicator_color.set_min_sat (0.4); | 945 | if ((item_state & ItemState.URGENT) == 0) { |
186 | 940 | indicator_buffer = theme.create_indicator (position_manager.IndicatorSize, indicator_color, item_buffer); | 946 | if (indicator_buffer[index] == null) |
187 | 941 | } | 947 | indicator_buffer[index] = theme.create_indicator_for_state (indicator_state, ItemState.NORMAL, |
188 | 942 | if (urgent_indicator_buffer == null) { | 948 | position_manager.IconSize, position_manager.Position, item_buffer); |
189 | 943 | var urgent_indicator_color = get_styled_color (); | 949 | indicator_surface = indicator_buffer[index]; |
190 | 944 | urgent_indicator_color.add_hue (theme.UrgentHueShift); | 950 | } else { |
191 | 945 | urgent_indicator_color.set_sat (1.0); | 951 | if (urgent_indicator_buffer[index] == null) |
192 | 946 | urgent_indicator_buffer = theme.create_indicator (position_manager.IndicatorSize, urgent_indicator_color, item_buffer); | 952 | urgent_indicator_buffer[index] = theme.create_indicator_for_state (indicator_state, ItemState.URGENT, |
193 | 947 | } | 953 | position_manager.IconSize, position_manager.Position, item_buffer); |
194 | 948 | 954 | indicator_surface = urgent_indicator_buffer[index]; | |
195 | 949 | unowned Surface indicator_surface = (item_state & ItemState.URGENT) != 0 ? urgent_indicator_buffer : indicator_buffer; | 955 | } |
196 | 950 | 956 | ||
197 | 951 | var x = 0.0, y = 0.0; | 957 | var x = 0.0, y = 0.0; |
198 | 952 | switch (position_manager.Position) { | 958 | switch (position_manager.Position) { |
199 | 953 | default: | 959 | default: |
200 | 954 | case Gtk.PositionType.BOTTOM: | 960 | case Gtk.PositionType.BOTTOM: |
201 | 955 | x = item_rect.x + item_rect.width / 2.0 - indicator_surface.Width / 2.0; | 961 | x = item_rect.x + item_rect.width / 2.0 - indicator_surface.Width / 2.0; |
203 | 956 | y = item_buffer.Height - indicator_surface.Height / 2.0 - 2.0 * theme.get_bottom_offset () - indicator_surface.Height / 24.0; | 962 | y = item_buffer.Height - theme.get_bottom_offset () - indicator_surface.Height; |
204 | 957 | break; | 963 | break; |
205 | 958 | case Gtk.PositionType.TOP: | 964 | case Gtk.PositionType.TOP: |
206 | 959 | x = item_rect.x + item_rect.width / 2.0 - indicator_surface.Width / 2.0; | 965 | x = item_rect.x + item_rect.width / 2.0 - indicator_surface.Width / 2.0; |
208 | 960 | y = - indicator_surface.Height / 2.0 + 2.0 * theme.get_bottom_offset () + indicator_surface.Height / 24.0; | 966 | y = theme.get_bottom_offset (); |
209 | 961 | break; | 967 | break; |
210 | 962 | case Gtk.PositionType.LEFT: | 968 | case Gtk.PositionType.LEFT: |
212 | 963 | x = - indicator_surface.Width / 2.0 + 2.0 * theme.get_bottom_offset () + indicator_surface.Width / 24.0; | 969 | x = theme.get_bottom_offset (); |
213 | 964 | y = item_rect.y + item_rect.height / 2.0 - indicator_surface.Height / 2.0; | 970 | y = item_rect.y + item_rect.height / 2.0 - indicator_surface.Height / 2.0; |
214 | 965 | break; | 971 | break; |
215 | 966 | case Gtk.PositionType.RIGHT: | 972 | case Gtk.PositionType.RIGHT: |
217 | 967 | x = item_buffer.Width - indicator_surface.Width / 2.0 - 2.0 * theme.get_bottom_offset () - indicator_surface.Width / 24.0; | 973 | x = item_buffer.Width - theme.get_bottom_offset () - indicator_surface.Width; |
218 | 968 | y = item_rect.y + item_rect.height / 2.0 - indicator_surface.Height / 2.0; | 974 | y = item_rect.y + item_rect.height / 2.0 - indicator_surface.Height / 2.0; |
219 | 969 | break; | 975 | break; |
220 | 970 | } | 976 | } |
221 | 971 | 977 | ||
237 | 972 | if (indicator == IndicatorState.SINGLE) { | 978 | cr.set_source_surface (indicator_surface.Internal, x, y); |
238 | 973 | cr.set_source_surface (indicator_surface.Internal, x, y); | 979 | cr.paint (); |
224 | 974 | cr.paint (); | ||
225 | 975 | } else { | ||
226 | 976 | var x_offset = 0.0, y_offset = 0.0; | ||
227 | 977 | if (position_manager.is_horizontal_dock ()) | ||
228 | 978 | x_offset = position_manager.IconSize / 16.0; | ||
229 | 979 | else | ||
230 | 980 | y_offset = position_manager.IconSize / 16.0; | ||
231 | 981 | |||
232 | 982 | cr.set_source_surface (indicator_surface.Internal, x - x_offset, y - y_offset); | ||
233 | 983 | cr.paint (); | ||
234 | 984 | cr.set_source_surface (indicator_surface.Internal, x + x_offset, y + y_offset); | ||
235 | 985 | cr.paint (); | ||
236 | 986 | } | ||
239 | 987 | } | 980 | } |
240 | 988 | 981 | ||
241 | 989 | void draw_urgent_glow (DockItem item, Cairo.Context cr, int64 frame_time) | 982 | void draw_urgent_glow (DockItem item, Cairo.Context cr, int64 frame_time) |
242 | @@ -999,7 +992,7 @@ | |||
243 | 999 | var x_offset = 0, y_offset = 0; | 992 | var x_offset = 0, y_offset = 0; |
244 | 1000 | 993 | ||
245 | 1001 | if (urgent_glow_buffer == null) { | 994 | if (urgent_glow_buffer == null) { |
247 | 1002 | var urgent_color = get_styled_color (); | 995 | var urgent_color = (theme.IndicatorStyle == IndicatorStyleType.LEGACY ? get_styled_color () : theme.IndicatorColor); |
248 | 1003 | urgent_color.add_hue (theme.UrgentHueShift); | 996 | urgent_color.add_hue (theme.UrgentHueShift); |
249 | 1004 | urgent_color.set_sat (1.0); | 997 | urgent_color.set_sat (1.0); |
250 | 1005 | urgent_glow_buffer = theme.create_urgent_glow (position_manager.GlowSize, urgent_color, main_buffer); | 998 | urgent_glow_buffer = theme.create_urgent_glow (position_manager.GlowSize, urgent_color, main_buffer); |
251 | 1006 | 999 | ||
252 | === modified file 'lib/Drawing/DockTheme.vala' | |||
253 | --- lib/Drawing/DockTheme.vala 2016-03-12 15:14:09 +0000 | |||
254 | +++ lib/Drawing/DockTheme.vala 2016-04-10 16:22:24 +0000 | |||
255 | @@ -40,9 +40,15 @@ | |||
256 | 40 | [Description(nick = "item-padding", blurb = "The padding between items on the dock, in tenths of a percent of IconSize.")] | 40 | [Description(nick = "item-padding", blurb = "The padding between items on the dock, in tenths of a percent of IconSize.")] |
257 | 41 | public double ItemPadding { get; set; } | 41 | public double ItemPadding { get; set; } |
258 | 42 | 42 | ||
259 | 43 | [Description(nick = "indicator-color", blurb = "The color (RGBA) of the indicator.")] | ||
260 | 44 | public Color IndicatorColor { get; set; } | ||
261 | 45 | |||
262 | 43 | [Description(nick = "indicator-size", blurb = "The size of item indicators, in tenths of a percent of IconSize.")] | 46 | [Description(nick = "indicator-size", blurb = "The size of item indicators, in tenths of a percent of IconSize.")] |
263 | 44 | public double IndicatorSize { get; set; } | 47 | public double IndicatorSize { get; set; } |
264 | 45 | 48 | ||
265 | 49 | [Description(nick = "indicator-style", blurb = "The style of item indicators, styles: circle-glow, circle-color-glow, circle, underline.")] | ||
266 | 50 | public IndicatorStyleType IndicatorStyle { get; set; } | ||
267 | 51 | |||
268 | 46 | [Description(nick = "icon-shadow-size", blurb = "The size of the icon-shadow behind every item, in tenths of a percent of IconSize.")] | 52 | [Description(nick = "icon-shadow-size", blurb = "The size of the icon-shadow behind every item, in tenths of a percent of IconSize.")] |
269 | 47 | public double IconShadowSize { get; set; } | 53 | public double IconShadowSize { get; set; } |
270 | 48 | 54 | ||
271 | @@ -94,6 +100,12 @@ | |||
272 | 94 | [Description(nick = "cascade-hide", blurb = "Whether background and icons will unhide/hide with different speeds. The top-border of both will leave/hit the screen-edge at the same time.")] | 100 | [Description(nick = "cascade-hide", blurb = "Whether background and icons will unhide/hide with different speeds. The top-border of both will leave/hit the screen-edge at the same time.")] |
273 | 95 | public bool CascadeHide { get; set; } | 101 | public bool CascadeHide { get; set; } |
274 | 96 | 102 | ||
275 | 103 | [Description(nick = "selection-style", blurb = "Whether an item has an active background glow. If not, active-item-color (RGBA) will be used instead.")] | ||
276 | 104 | public SelectionStyleType SelectionStyle { get; set; } | ||
277 | 105 | |||
278 | 106 | [Description(nick = "selection-color", blurb = "The color (RGBA) of the active item background.")] | ||
279 | 107 | public Color SelectionColor { get; set; } | ||
280 | 108 | |||
281 | 97 | public DockTheme (string name) | 109 | public DockTheme (string name) |
282 | 98 | { | 110 | { |
283 | 99 | base.with_name (name); | 111 | base.with_name (name); |
284 | @@ -111,7 +123,9 @@ | |||
285 | 111 | TopPadding = -11.0; | 123 | TopPadding = -11.0; |
286 | 112 | BottomPadding = 2.5; | 124 | BottomPadding = 2.5; |
287 | 113 | ItemPadding = 2.5; | 125 | ItemPadding = 2.5; |
288 | 126 | IndicatorColor = { 1.0, 1.0, 1.0, 1.0 }; | ||
289 | 114 | IndicatorSize = 5.0; | 127 | IndicatorSize = 5.0; |
290 | 128 | IndicatorStyle = IndicatorStyleType.LEGACY; | ||
291 | 115 | IconShadowSize = 1.0; | 129 | IconShadowSize = 1.0; |
292 | 116 | UrgentBounceHeight = 5.0 / 3.0; | 130 | UrgentBounceHeight = 5.0 / 3.0; |
293 | 117 | LaunchBounceHeight = 0.625; | 131 | LaunchBounceHeight = 0.625; |
294 | @@ -129,6 +143,8 @@ | |||
295 | 129 | UrgentHueShift = 150; | 143 | UrgentHueShift = 150; |
296 | 130 | ItemMoveTime = 450; | 144 | ItemMoveTime = 450; |
297 | 131 | CascadeHide = true; | 145 | CascadeHide = true; |
298 | 146 | SelectionColor = { 0.0, 0.0, 0.0, 1.0 }; | ||
299 | 147 | SelectionStyle = SelectionStyleType.LEGACY; | ||
300 | 132 | } | 148 | } |
301 | 133 | 149 | ||
302 | 134 | /** | 150 | /** |
303 | @@ -238,6 +254,112 @@ | |||
304 | 238 | } | 254 | } |
305 | 239 | 255 | ||
306 | 240 | /** | 256 | /** |
307 | 257 | * Creates a surface of an indicator for the given states. | ||
308 | 258 | * | ||
309 | 259 | * @param indicator_state the state of indicator | ||
310 | 260 | * @param item_state the state of item | ||
311 | 261 | * @param icon_size the size of icons | ||
312 | 262 | * @param color the color of the indicator | ||
313 | 263 | * @param position the position of the dock | ||
314 | 264 | * @param model existing surface to use as basis of new surface | ||
315 | 265 | * @return a new surface with the indicator drawn on it | ||
316 | 266 | */ | ||
317 | 267 | public Surface create_indicator_for_state (IndicatorState indicator_state, ItemState item_state, int icon_size, | ||
318 | 268 | Gtk.PositionType position, Surface model) | ||
319 | 269 | { | ||
320 | 270 | double width = icon_size; | ||
321 | 271 | double height = icon_size / 3.0 + get_bottom_offset (); | ||
322 | 272 | var size = (int) (IndicatorSize * icon_size / 10.0); | ||
323 | 273 | |||
324 | 274 | Logger.verbose ("DockTheme.create_indicator (width = %i, height = %i, state = [%i,%i])", (int) width, (int) height, indicator_state, item_state); | ||
325 | 275 | |||
326 | 276 | var surface = new Surface.with_surface ((int) width, (int) height, model); | ||
327 | 277 | surface.clear (); | ||
328 | 278 | |||
329 | 279 | if (width <= 0 || height <= 0 || size <= 0 || indicator_state == IndicatorState.NONE) | ||
330 | 280 | return surface; | ||
331 | 281 | |||
332 | 282 | Color color; | ||
333 | 283 | if ((item_state & ItemState.URGENT) != 0) { | ||
334 | 284 | color = (IndicatorStyle == IndicatorStyleType.LEGACY ? get_styled_color () : IndicatorColor); | ||
335 | 285 | color.add_hue (UrgentHueShift); | ||
336 | 286 | color.set_sat (1.0); | ||
337 | 287 | } else { | ||
338 | 288 | if (IndicatorStyle == IndicatorStyleType.LEGACY) { | ||
339 | 289 | color = get_styled_color (); | ||
340 | 290 | color.set_min_sat (0.4); | ||
341 | 291 | } else { | ||
342 | 292 | color = IndicatorColor; | ||
343 | 293 | } | ||
344 | 294 | } | ||
345 | 295 | |||
346 | 296 | unowned Cairo.Context cr = surface.Context; | ||
347 | 297 | cr.save (); | ||
348 | 298 | cr.set_line_width (1.0); | ||
349 | 299 | |||
350 | 300 | switch (IndicatorStyle) { | ||
351 | 301 | default: | ||
352 | 302 | case IndicatorStyleType.LEGACY: | ||
353 | 303 | case IndicatorStyleType.GLOW: | ||
354 | 304 | var x = 0.0; | ||
355 | 305 | var y = Math.round (height - size / 12.0 - get_bottom_offset ()); | ||
356 | 306 | |||
357 | 307 | for (var i = 0; i < indicator_state; i++) { | ||
358 | 308 | x = Math.round (width / 2.0 + (2.0 * i - (indicator_state - 1)) * size / 8.0); | ||
359 | 309 | |||
360 | 310 | cr.move_to (x, y); | ||
361 | 311 | cr.arc (x, y, height / 2, 0, Math.PI * 2); | ||
362 | 312 | cr.close_path (); | ||
363 | 313 | |||
364 | 314 | var rg = new Cairo.Pattern.radial (x, y, 0, x, y, size / 2); | ||
365 | 315 | rg.add_color_stop_rgba (0, 1, 1, 1, 1); | ||
366 | 316 | rg.add_color_stop_rgba (0.1, color.red, color.green, color.blue, 1); | ||
367 | 317 | rg.add_color_stop_rgba (0.2, color.red, color.green, color.blue, 0.6); | ||
368 | 318 | rg.add_color_stop_rgba (0.25, color.red, color.green, color.blue, 0.25); | ||
369 | 319 | rg.add_color_stop_rgba (0.5, color.red, color.green, color.blue, 0.15); | ||
370 | 320 | rg.add_color_stop_rgba (1.0, color.red, color.green, color.blue, 0.0); | ||
371 | 321 | |||
372 | 322 | cr.set_source (rg); | ||
373 | 323 | cr.fill (); | ||
374 | 324 | } | ||
375 | 325 | break; | ||
376 | 326 | case IndicatorStyleType.CIRCLE: | ||
377 | 327 | var x = 0.0; | ||
378 | 328 | var y = Math.round (height - size / 1.666 - get_bottom_offset ()); | ||
379 | 329 | |||
380 | 330 | for (var i = 0; i < indicator_state; i++) { | ||
381 | 331 | x = Math.round (width / 2.0 + (2.0 * i - (indicator_state - 1)) * size / 1.2); | ||
382 | 332 | |||
383 | 333 | cr.move_to (x, y); | ||
384 | 334 | cr.arc (x, y, size / 2, 0, Math.PI * 2); | ||
385 | 335 | cr.close_path (); | ||
386 | 336 | |||
387 | 337 | cr.set_source_rgba (color.red, color.green, color.blue, color.alpha); | ||
388 | 338 | cr.stroke_preserve (); | ||
389 | 339 | cr.fill (); | ||
390 | 340 | } | ||
391 | 341 | break; | ||
392 | 342 | case IndicatorStyleType.LINE: | ||
393 | 343 | var x = Math.round (icon_size / 10.0); | ||
394 | 344 | var y = Math.round (height - size - get_bottom_offset () - icon_size / 30.0); | ||
395 | 345 | width = Math.round (width - icon_size / 5.0); | ||
396 | 346 | |||
397 | 347 | cr.rectangle (x, y, width, size); | ||
398 | 348 | cr.set_source_rgba (color.red, color.green, color.blue, color.alpha); | ||
399 | 349 | cr.stroke_preserve (); | ||
400 | 350 | cr.fill (); | ||
401 | 351 | break; | ||
402 | 352 | } | ||
403 | 353 | |||
404 | 354 | cr.restore (); | ||
405 | 355 | |||
406 | 356 | if (position != Gtk.PositionType.BOTTOM) | ||
407 | 357 | surface = rotate_for_position ((owned) surface, position); | ||
408 | 358 | |||
409 | 359 | return surface; | ||
410 | 360 | } | ||
411 | 361 | |||
412 | 362 | /** | ||
413 | 241 | * Creates a surface for an urgent glow. | 363 | * Creates a surface for an urgent glow. |
414 | 242 | * | 364 | * |
415 | 243 | * @param size the size of the urgent glow | 365 | * @param size the size of the urgent glow |
416 | @@ -339,12 +461,17 @@ | |||
417 | 339 | 461 | ||
418 | 340 | cr.set_line_width (LineWidth); | 462 | cr.set_line_width (LineWidth); |
419 | 341 | cr.clip (); | 463 | cr.clip (); |
420 | 342 | |||
421 | 343 | gradient.add_color_stop_rgba (0, color.red, color.green, color.blue, 0); | ||
422 | 344 | gradient.add_color_stop_rgba (1, color.red, color.green, color.blue, 0.6 * opacity); | ||
423 | 345 | 464 | ||
424 | 346 | cr.rectangle (rect.x, rect.y, rect.width, rect.height); | 465 | cr.rectangle (rect.x, rect.y, rect.width, rect.height); |
426 | 347 | cr.set_source (gradient); | 466 | |
427 | 467 | if (SelectionStyle == SelectionStyleType.LEGACY) { | ||
428 | 468 | gradient.add_color_stop_rgba (0, color.red, color.green, color.blue, 0); | ||
429 | 469 | gradient.add_color_stop_rgba (1, color.red, color.green, color.blue, 0.6 * opacity); | ||
430 | 470 | cr.set_source (gradient); | ||
431 | 471 | } else { | ||
432 | 472 | cr.set_source_rgba (color.red, color.green, color.blue, color.alpha * opacity); | ||
433 | 473 | } | ||
434 | 474 | |||
435 | 348 | cr.fill (); | 475 | cr.fill (); |
436 | 349 | 476 | ||
437 | 350 | cr.reset_clip (); | 477 | cr.reset_clip (); |
438 | @@ -568,6 +695,11 @@ | |||
439 | 568 | IconShadowSize = MAX_ICON_SHADOW_SIZE; | 695 | IconShadowSize = MAX_ICON_SHADOW_SIZE; |
440 | 569 | break; | 696 | break; |
441 | 570 | 697 | ||
442 | 698 | case "IndicatorStyle": | ||
443 | 699 | if (IndicatorStyle < 0 || IndicatorStyle > 3) | ||
444 | 700 | IndicatorStyle = IndicatorStyleType.LEGACY; | ||
445 | 701 | break; | ||
446 | 702 | |||
447 | 571 | case "UrgentBounceHeight": | 703 | case "UrgentBounceHeight": |
448 | 572 | if (UrgentBounceHeight < 0) | 704 | if (UrgentBounceHeight < 0) |
449 | 573 | UrgentBounceHeight = 0; | 705 | UrgentBounceHeight = 0; |
450 | @@ -641,7 +773,63 @@ | |||
451 | 641 | else if (UrgentHueShift > 180) | 773 | else if (UrgentHueShift > 180) |
452 | 642 | UrgentHueShift = 180; | 774 | UrgentHueShift = 180; |
453 | 643 | break; | 775 | break; |
455 | 644 | } | 776 | |
456 | 777 | case "IndicatorColor": | ||
457 | 778 | break; | ||
458 | 779 | |||
459 | 780 | case "ActiveItemColor": | ||
460 | 781 | break; | ||
461 | 782 | } | ||
462 | 783 | } | ||
463 | 784 | |||
464 | 785 | static Surface rotate_for_position (owned Surface surface, Gtk.PositionType position) | ||
465 | 786 | { | ||
466 | 787 | if (position == Gtk.PositionType.BOTTOM) | ||
467 | 788 | return surface; | ||
468 | 789 | |||
469 | 790 | Surface result; | ||
470 | 791 | var width = surface.Width; | ||
471 | 792 | var height = surface.Height; | ||
472 | 793 | var rotate = 0.0; | ||
473 | 794 | |||
474 | 795 | if (position == Gtk.PositionType.TOP) | ||
475 | 796 | result = new Surface.with_surface (width, height, surface); | ||
476 | 797 | else | ||
477 | 798 | result = new Surface.with_surface (height, width, surface); | ||
478 | 799 | |||
479 | 800 | unowned Cairo.Context cr = result.Context; | ||
480 | 801 | |||
481 | 802 | switch (position) { | ||
482 | 803 | case Gtk.PositionType.TOP: | ||
483 | 804 | rotate = Math.PI; | ||
484 | 805 | break; | ||
485 | 806 | case Gtk.PositionType.LEFT: | ||
486 | 807 | rotate = Math.PI_2; | ||
487 | 808 | break; | ||
488 | 809 | case Gtk.PositionType.RIGHT: | ||
489 | 810 | rotate = -Math.PI_2; | ||
490 | 811 | break; | ||
491 | 812 | default: | ||
492 | 813 | assert_not_reached (); | ||
493 | 814 | } | ||
494 | 815 | |||
495 | 816 | cr.save (); | ||
496 | 817 | cr.translate (result.Width / 2.0, result.Height / 2.0); | ||
497 | 818 | cr.rotate (rotate); | ||
498 | 819 | cr.translate (- width / 2.0, - height / 2.0); | ||
499 | 820 | cr.set_source_surface (surface.Internal, 0.0, 0.0); | ||
500 | 821 | cr.paint (); | ||
501 | 822 | cr.restore (); | ||
502 | 823 | |||
503 | 824 | return result; | ||
504 | 825 | } | ||
505 | 826 | |||
506 | 827 | Color get_styled_color () | ||
507 | 828 | { | ||
508 | 829 | unowned Gtk.StyleContext context = get_style_context (); | ||
509 | 830 | var color = (Color) context.get_background_color (context.get_state ()); | ||
510 | 831 | color.set_min_val (90 / (double) uint16.MAX); | ||
511 | 832 | return color; | ||
512 | 645 | } | 833 | } |
513 | 646 | } | 834 | } |
514 | 647 | } | 835 | } |
515 | 648 | 836 | ||
516 | === added file 'lib/Drawing/Enums.vala' | |||
517 | --- lib/Drawing/Enums.vala 1970-01-01 00:00:00 +0000 | |||
518 | +++ lib/Drawing/Enums.vala 2016-04-10 16:22:24 +0000 | |||
519 | @@ -0,0 +1,63 @@ | |||
520 | 1 | // | ||
521 | 2 | // Copyright (C) 2016 Rico Tzschichholz | ||
522 | 3 | // | ||
523 | 4 | // This file is part of Plank. | ||
524 | 5 | // | ||
525 | 6 | // Plank is free software: you can redistribute it and/or modify | ||
526 | 7 | // it under the terms of the GNU General Public License as published by | ||
527 | 8 | // the Free Software Foundation, either version 3 of the License, or | ||
528 | 9 | // (at your option) any later version. | ||
529 | 10 | // | ||
530 | 11 | // Plank is distributed in the hope that it will be useful, | ||
531 | 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
532 | 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
533 | 14 | // GNU General Public License for more details. | ||
534 | 15 | // | ||
535 | 16 | // You should have received a copy of the GNU General Public License | ||
536 | 17 | // along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
537 | 18 | // | ||
538 | 19 | |||
539 | 20 | namespace Plank | ||
540 | 21 | { | ||
541 | 22 | /** | ||
542 | 23 | * The style of the item indicator. | ||
543 | 24 | */ | ||
544 | 25 | public enum IndicatorStyleType | ||
545 | 26 | { | ||
546 | 27 | /** | ||
547 | 28 | * A glowing dot which is gtk-theme-colored. | ||
548 | 29 | */ | ||
549 | 30 | LEGACY, | ||
550 | 31 | /** | ||
551 | 32 | * A glowing dot. | ||
552 | 33 | */ | ||
553 | 34 | GLOW, | ||
554 | 35 | /** | ||
555 | 36 | * A solid circle. | ||
556 | 37 | */ | ||
557 | 38 | CIRCLE, | ||
558 | 39 | /** | ||
559 | 40 | * A solid line. | ||
560 | 41 | */ | ||
561 | 42 | LINE | ||
562 | 43 | } | ||
563 | 44 | |||
564 | 45 | /** | ||
565 | 46 | * The style of the item indicator. | ||
566 | 47 | */ | ||
567 | 48 | public enum SelectionStyleType | ||
568 | 49 | { | ||
569 | 50 | /** | ||
570 | 51 | * A vertical gradient which is colored based of the item's icon'. | ||
571 | 52 | */ | ||
572 | 53 | LEGACY, | ||
573 | 54 | /** | ||
574 | 55 | * A vertical gradient. | ||
575 | 56 | */ | ||
576 | 57 | GRADIENT, | ||
577 | 58 | /** | ||
578 | 59 | * A solid color. | ||
579 | 60 | */ | ||
580 | 61 | SOLID | ||
581 | 62 | } | ||
582 | 63 | } | ||
583 | 0 | 64 | ||
584 | === modified file 'lib/Makefile.am' | |||
585 | --- lib/Makefile.am 2016-02-28 12:06:16 +0000 | |||
586 | +++ lib/Makefile.am 2016-04-10 16:22:24 +0000 | |||
587 | @@ -75,6 +75,7 @@ | |||
588 | 75 | Drawing/DrawingService.vala \ | 75 | Drawing/DrawingService.vala \ |
589 | 76 | Drawing/DockTheme.vala \ | 76 | Drawing/DockTheme.vala \ |
590 | 77 | Drawing/Easing.vala \ | 77 | Drawing/Easing.vala \ |
591 | 78 | Drawing/Enums.vala \ | ||
592 | 78 | Drawing/Renderer.vala \ | 79 | Drawing/Renderer.vala \ |
593 | 79 | Drawing/Surface.vala \ | 80 | Drawing/Surface.vala \ |
594 | 80 | Drawing/SurfaceCache.vala \ | 81 | Drawing/SurfaceCache.vala \ |
595 | 81 | 82 | ||
596 | === modified file 'lib/libplank.symbols' | |||
597 | --- lib/libplank.symbols 2016-04-10 09:00:49 +0000 | |||
598 | +++ lib/libplank.symbols 2016-04-10 16:22:24 +0000 | |||
599 | @@ -340,10 +340,13 @@ | |||
600 | 340 | plank_dock_theme_construct | 340 | plank_dock_theme_construct |
601 | 341 | plank_dock_theme_create_background | 341 | plank_dock_theme_create_background |
602 | 342 | plank_dock_theme_create_indicator | 342 | plank_dock_theme_create_indicator |
603 | 343 | plank_dock_theme_create_indicator_for_state | ||
604 | 343 | plank_dock_theme_create_urgent_glow | 344 | plank_dock_theme_create_urgent_glow |
605 | 344 | plank_dock_theme_draw_active_glow | 345 | plank_dock_theme_draw_active_glow |
606 | 345 | plank_dock_theme_draw_item_count | 346 | plank_dock_theme_draw_item_count |
607 | 346 | plank_dock_theme_draw_item_progress | 347 | plank_dock_theme_draw_item_progress |
608 | 348 | plank_dock_theme_get_ActiveGlow | ||
609 | 349 | plank_dock_theme_get_ActiveItemColor | ||
610 | 347 | plank_dock_theme_get_ActiveTime | 350 | plank_dock_theme_get_ActiveTime |
611 | 348 | plank_dock_theme_get_BottomPadding | 351 | plank_dock_theme_get_BottomPadding |
612 | 349 | plank_dock_theme_get_CascadeHide | 352 | plank_dock_theme_get_CascadeHide |
613 | @@ -356,7 +359,9 @@ | |||
614 | 356 | plank_dock_theme_get_HideTime | 359 | plank_dock_theme_get_HideTime |
615 | 357 | plank_dock_theme_get_HorizPadding | 360 | plank_dock_theme_get_HorizPadding |
616 | 358 | plank_dock_theme_get_IconShadowSize | 361 | plank_dock_theme_get_IconShadowSize |
617 | 362 | plank_dock_theme_get_IndicatorColor | ||
618 | 359 | plank_dock_theme_get_IndicatorSize | 363 | plank_dock_theme_get_IndicatorSize |
619 | 364 | plank_dock_theme_get_IndicatorStyle | ||
620 | 360 | plank_dock_theme_get_ItemMoveTime | 365 | plank_dock_theme_get_ItemMoveTime |
621 | 361 | plank_dock_theme_get_ItemPadding | 366 | plank_dock_theme_get_ItemPadding |
622 | 362 | plank_dock_theme_get_LaunchBounceHeight | 367 | plank_dock_theme_get_LaunchBounceHeight |
623 | @@ -368,6 +373,8 @@ | |||
624 | 368 | plank_dock_theme_get_UrgentBounceTime | 373 | plank_dock_theme_get_UrgentBounceTime |
625 | 369 | plank_dock_theme_get_UrgentHueShift | 374 | plank_dock_theme_get_UrgentHueShift |
626 | 370 | plank_dock_theme_new | 375 | plank_dock_theme_new |
627 | 376 | plank_dock_theme_set_ActiveGlow | ||
628 | 377 | plank_dock_theme_set_ActiveItemColor | ||
629 | 371 | plank_dock_theme_set_ActiveTime | 378 | plank_dock_theme_set_ActiveTime |
630 | 372 | plank_dock_theme_set_BottomPadding | 379 | plank_dock_theme_set_BottomPadding |
631 | 373 | plank_dock_theme_set_CascadeHide | 380 | plank_dock_theme_set_CascadeHide |
632 | @@ -380,7 +387,9 @@ | |||
633 | 380 | plank_dock_theme_set_HideTime | 387 | plank_dock_theme_set_HideTime |
634 | 381 | plank_dock_theme_set_HorizPadding | 388 | plank_dock_theme_set_HorizPadding |
635 | 382 | plank_dock_theme_set_IconShadowSize | 389 | plank_dock_theme_set_IconShadowSize |
636 | 390 | plank_dock_theme_set_IndicatorColor | ||
637 | 383 | plank_dock_theme_set_IndicatorSize | 391 | plank_dock_theme_set_IndicatorSize |
638 | 392 | plank_dock_theme_set_IndicatorStyle | ||
639 | 384 | plank_dock_theme_set_ItemMoveTime | 393 | plank_dock_theme_set_ItemMoveTime |
640 | 385 | plank_dock_theme_set_ItemPadding | 394 | plank_dock_theme_set_ItemPadding |
641 | 386 | plank_dock_theme_set_LaunchBounceHeight | 395 | plank_dock_theme_set_LaunchBounceHeight |
642 | @@ -462,6 +471,7 @@ | |||
643 | 462 | plank_hover_window_set_text | 471 | plank_hover_window_set_text |
644 | 463 | plank_hover_window_show_at | 472 | plank_hover_window_show_at |
645 | 464 | plank_indicator_state_get_type | 473 | plank_indicator_state_get_type |
646 | 474 | plank_indicator_style_type_get_type | ||
647 | 465 | plank_item_factory_construct | 475 | plank_item_factory_construct |
648 | 466 | plank_item_factory_default_make_element | 476 | plank_item_factory_default_make_element |
649 | 467 | plank_item_factory_get_item_for_dock | 477 | plank_item_factory_get_item_for_dock |
Theme naming:
I'd vote for "flat" in case of a theme with the line type indicator and "modern" in case of the circle.
Looks: imgur.com/ co1S0t7
The circular ones look better if their center is in the middle of bottom padding: http://
An extra slight bump off the ground instead might look better too.
The circles also end up a bit too close together at times, depending on the size set (indicatorsize 1 looked to be too close, while 1.2 looked fine at icon size 48) imgur.com/ sUCYEoN
http://
In my opinion lines should not indicate several instances being open, as it appears strange :D
Neither chrome os nor windows seem to provide such information while having that kind of indicators. It feels as if the application were somehow divided into smaller fragments.