diff --git a/data/gala.metainfo.xml.in b/data/gala.metainfo.xml.in
index 522214f8..1927ab86 100644
--- a/data/gala.metainfo.xml.in
+++ b/data/gala.metainfo.xml.in
@@ -27,6 +27,18 @@
contact_at_elementary.io
+
+
+ Improvements:
+
+ - Updated translations
+ - Improved shadows performance
+
+
+
+
+
+
Improvements:
diff --git a/lib/ShadowEffect.vala b/lib/ShadowEffect.vala
index 909edb29..79fd89dd 100644
--- a/lib/ShadowEffect.vala
+++ b/lib/ShadowEffect.vala
@@ -17,12 +17,15 @@ public class Gala.ShadowEffect : Clutter.Effect {
// the sizes of the textures often repeat, especially for the background actor
// so we keep a cache to avoid creating the same texture all over again.
- private static Gee.HashMap shadow_cache;
- // Delay the style context creation at render stage as Gtk need to access
- // the current display.
+ private static Gee.HashMap shadow_cache;
+
+ // Sometimes we use a shadow in only one place and rapidly switch between two shadows
+ // In order to not drop them and create them all over again we wait 5 seconds before finally dropping a shadow.
+ private static Gee.HashMap shadows_marked_for_dropping;
static construct {
- shadow_cache = new Gee.HashMap ();
+ shadow_cache = new Gee.HashMap ();
+ shadows_marked_for_dropping = new Gee.HashMap ();
}
private string _css_class;
@@ -80,9 +83,9 @@ public class Gala.ShadowEffect : Clutter.Effect {
decrement_shadow_users (old_key);
}
- Shadow? shadow = null;
- if ((shadow = shadow_cache.@get (current_key)) != null) {
- shadow.users++;
+ var shadow = shadow_cache.@get (current_key);
+ if (shadow != null) {
+ increment_shadow_users (current_key);
return shadow.texture;
}
@@ -126,18 +129,6 @@ public class Gala.ShadowEffect : Clutter.Effect {
}
}
- private void decrement_shadow_users (string key) {
- var shadow = shadow_cache.@get (key);
-
- if (shadow == null) {
- return;
- }
-
- if (--shadow.users == 0) {
- shadow_cache.unset (key);
- }
- }
-
public override void paint (Clutter.PaintNode node, Clutter.PaintContext context, Clutter.EffectPaintFlags flags) {
var bounding_box = get_bounding_box ();
var width = (int) (bounding_box.x2 - bounding_box.x1);
@@ -159,7 +150,7 @@ public class Gala.ShadowEffect : Clutter.Effect {
actor.continue_paint (context);
}
- public virtual Clutter.ActorBox get_bounding_box () {
+ private Clutter.ActorBox get_bounding_box () {
var size = shadow_size * scale_factor;
var bounding_box = Clutter.ActorBox ();
@@ -184,4 +175,39 @@ public class Gala.ShadowEffect : Clutter.Effect {
return true;
}
+
+ private static void increment_shadow_users (string key) {
+ var shadow = shadow_cache.@get (key);
+
+ if (shadow == null) {
+ return;
+ }
+
+ shadow.users++;
+
+ uint timeout_id;
+ if (shadows_marked_for_dropping.unset (key, out timeout_id)) {
+ Source.remove (timeout_id);
+ }
+ }
+
+ private static void decrement_shadow_users (string key) {
+ var shadow = shadow_cache.@get (key);
+
+ if (shadow == null) {
+ return;
+ }
+
+ if (--shadow.users == 0) {
+ queue_shadow_drop (key);
+ }
+ }
+
+ private static void queue_shadow_drop (string key) {
+ shadows_marked_for_dropping[key] = Timeout.add_seconds (5, () => {
+ shadow_cache.unset (key);
+ shadows_marked_for_dropping.unset (key);
+ return Source.REMOVE;
+ });
+ }
}