11/*
22 * The MIT License (MIT)
33 *
4- * Copyright (c) 2023 Scott Moreau
4+ * Copyright (c) 2026 Scott Moreau
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a copy
77 * of this software and associated documentation files (the "Software"), to deal
@@ -132,13 +132,20 @@ class simple_node_t : public node_t
132132
133133 public:
134134 std::shared_ptr<workspace_name> workspace;
135- simple_node_t (wf::point_t offset) : node_t (false )
135+ wf::point_t ws;
136+ simple_node_t (wf::point_t offset, wf::point_t ws) : node_t (false )
136137 {
137- this ->offset = offset;
138+ this ->ws = ws;
139+ this ->offset = offset;
138140 this ->alpha_fade = 0.0 ;
139141 workspace = std::make_shared<workspace_name>();
140142 }
141143
144+ ~simple_node_t ()
145+ {
146+ workspace = nullptr ;
147+ }
148+
142149 void gen_render_instances (std::vector<render_instance_uptr>& instances,
143150 damage_callback push_damage, wf::output_t *shown_on) override
144151 {
@@ -164,10 +171,14 @@ class simple_node_t : public node_t
164171 workspace->rect .width , workspace->rect .height };
165172 }
166173
167- void set_offset (int x, int y)
174+ void set_offset (wf::point_t offset)
175+ {
176+ this ->offset = offset;
177+ }
178+
179+ wf::point_t get_ws ()
168180 {
169- this ->offset .x = x;
170- this ->offset .y = y;
181+ return this ->ws ;
171182 }
172183
173184 void set_alpha (double alpha)
@@ -177,18 +188,17 @@ class simple_node_t : public node_t
177188};
178189
179190std::shared_ptr<simple_node_t > add_simple_node (wf::output_t *output,
180- wf::point_t offset)
191+ wf::point_t offset, wf:: point_t ws )
181192{
182- auto subnode = std::make_shared<simple_node_t >(offset);
193+ auto subnode = std::make_shared<simple_node_t >(offset, ws );
183194 wf::scene::add_front (output->node_for_layer (wf::scene::layer::OVERLAY ), subnode);
184195 return subnode;
185196}
186197
187198class wayfire_workspace_names_output : public wf ::per_output_plugin_instance_t
188199{
189200 wf::wl_timer<false > timer;
190- bool hook_set = false ;
191- bool timed_out = false ;
201+ bool hook_set = false ;
192202 std::vector<std::vector<std::shared_ptr<simple_node_t >>> workspaces;
193203 wf::option_wrapper_t <std::string> font{" workspace-names/font" };
194204 wf::option_wrapper_t <std::string> position{" workspace-names/position" };
@@ -208,76 +218,90 @@ class wayfire_workspace_names_output : public wf::per_output_plugin_instance_t
208218 void init () override
209219 {
210220 alpha_fade.set (0 , 0 );
211- timed_out = false ;
212221
222+ output->wset ()->connect (&workspace_grid_changed);
223+ output->connect (&workarea_changed);
224+ output->connect (&viewport_changed);
225+ output->connect (&viewport_change_request);
226+ font.set_callback (option_changed);
227+ position.set_callback (option_changed);
228+ background_color.set_callback (option_changed);
229+ text_color.set_callback (option_changed);
230+ show_option_values.set_callback (option_changed);
231+ show_option_names.set_callback (show_options_changed);
232+
233+ if (show_option_names)
234+ {
235+ show_options_changed ();
236+ }
237+ }
238+
239+ void init_workspace_name_nodes ()
240+ {
213241 auto wsize = output->wset ()->get_workspace_grid_size ();
242+ auto og = output->get_relative_geometry ();
214243 workspaces.resize (wsize.width );
215244 for (int x = 0 ; x < wsize.width ; x++)
216245 {
217246 workspaces[x].resize (wsize.height );
218247 }
219248
220- auto og = output->get_relative_geometry ();
221249 for (int x = 0 ; x < wsize.width ; x++)
222250 {
223251 for (int y = 0 ; y < wsize.height ; y++)
224252 {
225253 workspaces[x][y] = add_simple_node (output, {x *og.width ,
226- y * og.height });
254+ y * og.height }, {x, y} );
227255 }
228256 }
257+ }
229258
230- output->connect (&workarea_changed);
231- output->connect (&viewport_changed);
232- font.set_callback (option_changed);
233- position.set_callback (option_changed);
234- background_color.set_callback (option_changed);
235- text_color.set_callback (option_changed);
236- show_option_names.set_callback (show_options_changed);
237-
238- if (show_option_names)
239- {
240- show_options_changed ();
241- } else
259+ void fini_workspace_name_nodes ()
260+ {
261+ for (auto & x : workspaces)
242262 {
243- update_names ();
263+ for (auto & workspace : x)
264+ {
265+ auto & wsn = workspace->workspace ;
266+ cairo_surface_destroy (wsn->cairo_surface );
267+ cairo_destroy (wsn->cr );
268+ wf::scene::remove_child (workspace);
269+ workspace.reset ();
270+ }
244271 }
245-
246- wf::get_core ().connect (&reload_config);
247272 }
248273
249- wf::signal::connection_t <wf::reload_config_signal> reload_config{[this ] (wf::reload_config_signal *ev)
274+ wf::signal::connection_t <wf::workspace_grid_changed_signal> workspace_grid_changed{[this ] (wf::
275+ workspace_grid_changed_signal
276+ *ev)
250277 {
251- update_names ();
278+ deactivate ();
279+ init_workspace_name_nodes ();
252280 }
253281 };
254282
255283 wf::config::option_base_t ::updated_callback_t show_options_changed = [=] ()
256284 {
257- update_names ();
258-
259- viewport_changed.emit (nullptr );
260-
261285 if (show_option_names)
262286 {
263- timer.disconnect ();
264- output->render ->rem_effect (&post_hook);
287+ activate ();
288+ update_names ();
289+ viewport_changed.emit (nullptr );
290+ alpha_fade.animate (alpha_fade, 1 );
265291 } else
266292 {
267- output->connect (&viewport_changed);
268- output->render ->add_effect (&post_hook, wf::OUTPUT_EFFECT_POST );
293+ alpha_fade.animate (alpha_fade, 0 );
269294 }
270295
271- alpha_fade.animate (alpha_fade, 1.0 );
272296 output->render ->damage_whole ();
273297 };
274298
275- void update_name (int x, int y )
299+ void update_name (std::shared_ptr< simple_node_t > workspace )
276300 {
277301 auto section = wf::get_core ().config ->get_section (" workspace-names" );
278302 auto wsize = output->wset ()->get_workspace_grid_size ();
279- auto wsn = workspaces[x][y] ->workspace ;
280- int ws_num = x + y * wsize.width + 1 ;
303+ auto wsn = workspace ->workspace ;
304+ int ws_num = workspace-> get_ws (). x + workspace-> get_ws (). y * wsize.width + 1 ;
281305
282306 // Get the option name (key) of the target workspace
283307 std::string key = output->to_string () + " _workspace_" + std::to_string (ws_num);
@@ -327,13 +351,12 @@ class wayfire_workspace_names_output : public wf::per_output_plugin_instance_t
327351
328352 void update_names ()
329353 {
330- auto wsize = output->wset ()->get_workspace_grid_size ();
331- for (int x = 0 ; x < wsize.width ; x++)
354+ for (auto & x : workspaces)
332355 {
333- for (int y = 0 ; y < wsize. height ; y++ )
356+ for (auto & workspace : x )
334357 {
335- update_name (x, y );
336- update_texture (workspaces[x][y] ->workspace );
358+ update_name (workspace );
359+ update_texture (workspace ->workspace );
337360 }
338361 }
339362 }
@@ -400,7 +423,11 @@ class wayfire_workspace_names_output : public wf::per_output_plugin_instance_t
400423
401424 wf::config::option_base_t ::updated_callback_t option_changed = [=] ()
402425 {
403- update_textures ();
426+ if (hook_set)
427+ {
428+ update_names ();
429+ update_textures ();
430+ }
404431 };
405432
406433 void update_texture_position (std::shared_ptr<workspace_name> wsn)
@@ -455,6 +482,7 @@ class wayfire_workspace_names_output : public wf::per_output_plugin_instance_t
455482 wf::signal::connection_t <wf::workarea_changed_signal> workarea_changed{[this ] (wf::workarea_changed_signal
456483 *ev)
457484 {
485+ update_workspace_names_timeout ();
458486 update_textures ();
459487 }
460488 };
@@ -528,73 +556,68 @@ class wayfire_workspace_names_output : public wf::per_output_plugin_instance_t
528556 if (alpha_fade.running ())
529557 {
530558 set_alpha ();
531- output->render ->damage_whole ();
532559 }
533560 };
534561
535- wf::signal::connection_t <wf::workspace_changed_signal> viewport_changed{[this ] (wf::
536- workspace_changed_signal*
537- ev)
538- {
539- auto wsize = output->wset ()->get_workspace_grid_size ();
540- auto nvp = output->wset ()->get_current_workspace ();
541- auto og = output->get_relative_geometry ();
562+ void update_workspace_names_timeout ()
563+ {
564+ auto wsize = output->wset ()->get_workspace_grid_size ();
565+ auto nvp = output->wset ()->get_current_workspace ();
566+ auto og = output->get_relative_geometry ();
567+
568+ activate ();
569+ update_textures ();
570+ update_names ();
542571
543- for (int x = 0 ; x < wsize.width ; x++)
572+ for (int x = 0 ; x < wsize.width ; x++)
573+ {
574+ for (int y = 0 ; y < wsize.height ; y++)
544575 {
545- for (int y = 0 ; y < wsize.height ; y++)
546- {
547- workspaces[x][y]->set_offset ((x - nvp.x ) * og.width ,
548- (y - nvp.y ) * og.height );
549- }
576+ workspaces[x][y]->set_offset ({(x - nvp.x ) * og.width , (y - nvp.y ) * og.height });
550577 }
578+ }
551579
552- output->render ->damage_whole ();
580+ output->render ->damage_whole ();
553581
554- activate ();
582+ if (show_option_names)
583+ {
584+ return ;
585+ }
555586
556- if (show_option_names)
557- {
558- return ;
559- }
587+ alpha_fade.animate (alpha_fade, 1 );
560588
561- if (!alpha_fade.running ())
562- {
563- if (!timer.is_connected ())
564- {
565- alpha_fade.animate (alpha_fade, 1.0 );
566- }
567- } else if (timed_out)
568- {
569- timed_out = false ;
570- alpha_fade.animate (alpha_fade, 1.0 );
571- }
589+ timer.disconnect ();
590+ timer.set_timeout ((int )display_duration, timeout);
591+ }
572592
573- timer.disconnect ();
574- timer.set_timeout ((int )display_duration, timeout);
593+ wf::signal::connection_t <wf::workspace_change_request_signal> viewport_change_request{[this ] (wf::
594+ workspace_change_request_signal
595+ *
596+ ev)
597+ {
598+ update_workspace_names_timeout ();
599+ }
600+ };
601+
602+ wf::signal::connection_t <wf::workspace_changed_signal> viewport_changed{[this ] (wf::
603+ workspace_changed_signal*
604+ ev)
605+ {
606+ update_workspace_names_timeout ();
575607 }
576608 };
577609
578610 wf::wl_timer<false >::callback_t timeout = [=] ()
579611 {
580612 output->render ->damage_whole ();
581- alpha_fade.animate (1.0 , 0.0 );
582- timed_out = true ;
613+ alpha_fade.animate (alpha_fade, 0 );
583614 };
584615
585616 wf::effect_hook_t post_hook = [=] ()
586617 {
587- if (!alpha_fade.running ())
618+ if (!alpha_fade.running () && !timer. is_connected () && !show_option_names )
588619 {
589- if (timed_out)
590- {
591- deactivate ();
592- timed_out = false ;
593- output->render ->damage_whole ();
594- } else if (!timer.is_connected ())
595- {
596- timer.set_timeout ((int )display_duration, timeout);
597- }
620+ deactivate ();
598621 } else
599622 {
600623 set_alpha ();
@@ -608,6 +631,7 @@ class wayfire_workspace_names_output : public wf::per_output_plugin_instance_t
608631 return ;
609632 }
610633
634+ init_workspace_name_nodes ();
611635 output->render ->add_effect (&post_hook, wf::OUTPUT_EFFECT_POST );
612636 output->render ->add_effect (&pre_hook, wf::OUTPUT_EFFECT_PRE );
613637 output->render ->damage_whole ();
@@ -621,6 +645,8 @@ class wayfire_workspace_names_output : public wf::per_output_plugin_instance_t
621645 return ;
622646 }
623647
648+ timer.disconnect ();
649+ fini_workspace_name_nodes ();
624650 output->render ->rem_effect (&post_hook);
625651 output->render ->rem_effect (&pre_hook);
626652 hook_set = false ;
@@ -629,18 +655,10 @@ class wayfire_workspace_names_output : public wf::per_output_plugin_instance_t
629655 void fini () override
630656 {
631657 deactivate ();
632- auto wsize = output->wset ()->get_workspace_grid_size ();
633- for (int x = 0 ; x < wsize.width ; x++)
634- {
635- for (int y = 0 ; y < wsize.height ; y++)
636- {
637- auto & wsn = workspaces[x][y]->workspace ;
638- cairo_surface_destroy (wsn->cairo_surface );
639- cairo_destroy (wsn->cr );
640- wf::scene::remove_child (workspaces[x][y]);
641- workspaces[x][y].reset ();
642- }
643- }
658+ workspace_grid_changed.disconnect ();
659+ viewport_change_request.disconnect ();
660+ viewport_changed.disconnect ();
661+ workarea_changed.disconnect ();
644662
645663 output->render ->damage_whole ();
646664 }
0 commit comments