@@ -17,12 +17,15 @@ public class Gala.ShadowEffect : Clutter.Effect {
1717
1818 // the sizes of the textures often repeat, especially for the background actor
1919 // so we keep a cache to avoid creating the same texture all over again.
20- private static Gee . HashMap<string,Shadow > shadow_cache;
21- // Delay the style context creation at render stage as Gtk need to access
22- // the current display.
20+ private static Gee . HashMap<string, Shadow > shadow_cache;
21+
22+ // Sometimes we use a shadow in only one place and rapidly switch between two shadows
23+ // In order to not drop them and create them all over again we wait 5 seconds before finally dropping a shadow.
24+ private static Gee . HashMap<string, uint> shadows_marked_for_dropping;
2325
2426 static construct {
25- shadow_cache = new Gee .HashMap<string,Shadow > ();
27+ shadow_cache = new Gee .HashMap<string, Shadow > ();
28+ shadows_marked_for_dropping = new Gee .HashMap<string, uint> ();
2629 }
2730
2831 private string _css_class;
@@ -80,9 +83,9 @@ public class Gala.ShadowEffect : Clutter.Effect {
8083 decrement_shadow_users (old_key);
8184 }
8285
83- Shadow ? shadow = null ;
84- if (( shadow = shadow_cache . @ get (current_key)) != null ) {
85- shadow . users ++ ;
86+ var shadow = shadow_cache . @ get (current_key) ;
87+ if (shadow != null ) {
88+ increment_shadow_users (current_key) ;
8689 return shadow. texture;
8790 }
8891
@@ -126,18 +129,6 @@ public class Gala.ShadowEffect : Clutter.Effect {
126129 }
127130 }
128131
129- private void decrement_shadow_users (string key ) {
130- var shadow = shadow_cache. @get (key);
131-
132- if (shadow == null ) {
133- return ;
134- }
135-
136- if (-- shadow. users == 0 ) {
137- shadow_cache. unset (key);
138- }
139- }
140-
141132 public override void paint (Clutter .PaintNode node , Clutter .PaintContext context , Clutter .EffectPaintFlags flags ) {
142133 var bounding_box = get_bounding_box ();
143134 var width = (int ) (bounding_box. x2 - bounding_box. x1);
@@ -159,7 +150,7 @@ public class Gala.ShadowEffect : Clutter.Effect {
159150 actor. continue_paint (context);
160151 }
161152
162- public virtual Clutter .ActorBox get_bounding_box () {
153+ private Clutter .ActorBox get_bounding_box () {
163154 var size = shadow_size * scale_factor;
164155 var bounding_box = Clutter . ActorBox ();
165156
@@ -184,4 +175,39 @@ public class Gala.ShadowEffect : Clutter.Effect {
184175
185176 return true ;
186177 }
178+
179+ private static void increment_shadow_users (string key ) {
180+ var shadow = shadow_cache. @get (key);
181+
182+ if (shadow == null ) {
183+ return ;
184+ }
185+
186+ shadow. users++ ;
187+
188+ uint timeout_id;
189+ if (shadows_marked_for_dropping. unset (key, out timeout_id)) {
190+ Source . remove (timeout_id);
191+ }
192+ }
193+
194+ private static void decrement_shadow_users (string key ) {
195+ var shadow = shadow_cache. @get (key);
196+
197+ if (shadow == null ) {
198+ return ;
199+ }
200+
201+ if (-- shadow. users == 0 ) {
202+ queue_shadow_drop (key);
203+ }
204+ }
205+
206+ private static void queue_shadow_drop (string key ) {
207+ shadows_marked_for_dropping[key] = Timeout . add_seconds (5 , () = > {
208+ shadow_cache. unset (key);
209+ shadows_marked_for_dropping. unset (key);
210+ return Source . REMOVE ;
211+ });
212+ }
187213}
0 commit comments