@@ -32,6 +32,16 @@ public class He.Bin : Gtk.Widget, Gtk.Buildable {
3232 private bool _content_color_override = false ;
3333 private RGBColor ? _content_source_color = null ;
3434
35+ // Cache for expensive color scheme generation
36+ private RGBColor ? _cached_source_color = null ;
37+ private bool _cached_is_dark = false ;
38+ private double _cached_contrast = - 1.0 ;
39+
40+ // Static cache shared across all Bin instances for identical color configurations
41+ private static Gee . HashMap<string, string> ? _css_cache = null ;
42+ private static ContentScheme ? _shared_content_scheme = null ;
43+ private static StyleManager ? _shared_style_manager = null ;
44+
3545 private Gtk . Widget ? _child;
3646 public Gtk . Widget child {
3747 get {
@@ -170,6 +180,7 @@ public class He.Bin : Gtk.Widget, Gtk.Buildable {
170180 if (! _content_color_override || _content_source_color == null ) {
171181 remove_color_provider ();
172182 cached_css = null ;
183+ _cached_source_color = null ;
173184 notify_children_color_changed ();
174185 return ;
175186 }
@@ -179,16 +190,30 @@ public class He.Bin : Gtk.Widget, Gtk.Buildable {
179190 bool is_dark = get_is_dark_theme ();
180191 double contrast = get_contrast_level ();
181192
193+ // Check if we can skip regeneration - color, theme, and contrast unchanged
194+ if (_cached_source_color != null &&
195+ colors_are_equal (_cached_source_color, source_argb) &&
196+ _cached_is_dark == is_dark &&
197+ Math . fabs (_cached_contrast - contrast) < 0.001 ) {
198+ // Nothing changed, skip expensive regeneration
199+ return ;
200+ }
201+
182202 string css = build_content_css (source_argb, is_dark, contrast);
183203
184204 if (css == " " ) {
185205 remove_color_provider ();
186206 cached_css = null ;
207+ _cached_source_color = null ;
187208 notify_children_color_changed ();
188209 return ;
189210 }
190211
191212 if (cached_css != null && cached_css == css) {
213+ // Update cache state even if CSS matches
214+ _cached_source_color = source_argb;
215+ _cached_is_dark = is_dark;
216+ _cached_contrast = contrast;
192217 return ;
193218 }
194219
@@ -198,10 +223,21 @@ public class He.Bin : Gtk.Widget, Gtk.Buildable {
198223 apply_color_provider_recursive (this , (! ) color_provider);
199224
200225 cached_css = css;
226+ _cached_source_color = source_argb;
227+ _cached_is_dark = is_dark;
228+ _cached_contrast = contrast;
201229 notify_children_color_changed ();
202230 queue_draw ();
203231 }
204232
233+ private bool colors_are_equal (RGBColor ? a , RGBColor b ) {
234+ if (a == null ) return false ;
235+ // Compare with small epsilon for floating point
236+ return Math . fabs (a. r - b. r) < 0.001 &&
237+ Math . fabs (a. g - b. g) < 0.001 &&
238+ Math . fabs (a. b - b. b) < 0.001 ;
239+ }
240+
205241 private void notify_children_color_changed () {
206242 notify_widget_tree_color_changed (this );
207243 }
@@ -288,15 +324,40 @@ public class He.Bin : Gtk.Widget, Gtk.Buildable {
288324 }
289325
290326 private string build_content_css (RGBColor source_color , bool is_dark , double contrast ) {
291- var source_hct = hct_from_int (rgb_to_argb_int (source_color));
327+ // Generate cache key from color + theme + contrast
328+ int argb = rgb_to_argb_int (source_color);
329+ string cache_key = " %d_%s_%.2f " . printf (argb, is_dark ? " dark" : " light" , contrast);
330+
331+ // Initialize static cache if needed
332+ if (_css_cache == null ) {
333+ _css_cache = new Gee .HashMap<string, string> ();
334+ }
292335
293- // Use ContentScheme to generate a full scheme from the source color
294- var content_scheme = new ContentScheme ();
295- var scheme = content_scheme. generate (source_hct, is_dark, contrast);
336+ // Check cache first
337+ if (_css_cache. has_key (cache_key)) {
338+ return _css_cache. get (cache_key);
339+ }
340+
341+ var source_hct = hct_from_int (argb);
342+
343+ // Reuse shared instances to avoid allocation overhead
344+ if (_shared_content_scheme == null ) {
345+ _shared_content_scheme = new ContentScheme ();
346+ }
347+ if (_shared_style_manager == null ) {
348+ _shared_style_manager = new StyleManager ();
349+ }
350+
351+ var scheme = _shared_content_scheme. generate (source_hct, is_dark, contrast);
352+ string css = _shared_style_manager. style_refresh (scheme);
353+ string result = extract_content_color_definitions (css);
354+
355+ // Cache the result (limit cache size to prevent memory bloat)
356+ if (_css_cache. size < 50 ) {
357+ _css_cache. set (cache_key, result);
358+ }
296359
297- var manager = new StyleManager ();
298- string css = manager. style_refresh (scheme);
299- return extract_content_color_definitions (css);
360+ return result;
300361 }
301362
302363 private string extract_content_color_definitions (string css ) {
@@ -412,4 +473,4 @@ public class He.Bin : Gtk.Widget, Gtk.Buildable {
412473
413474 this . unparent ();
414475 }
415- }
476+ }
0 commit comments