@@ -131,174 +131,181 @@ struct comp_workspace *comp_output_get_active_ws(struct comp_output *output,
131131 return active_ws ;
132132}
133133
134- static void output_configure_scene (struct comp_output * output ,
135- struct wlr_scene_node * node ,
136- bool is_in_saved_tree ,
137- struct comp_object * closest_object ) {
138- if (!node -> enabled ) {
134+ static void
135+ configure_apply_alpha_modifier (struct wlr_scene_surface * scene_surface ,
136+ float * opacity ) {
137+ if (!scene_surface ) {
139138 return ;
140139 }
141140
142- if (node -> data ) {
143- closest_object = node -> data ;
144- if (closest_object -> type == COMP_OBJECT_TYPE_SAVED_OBJECT ) {
145- is_in_saved_tree = true;
141+ const struct wlr_alpha_modifier_surface_v1_state * alpha_modifier_state =
142+ wlr_alpha_modifier_v1_get_surface_state (scene_surface -> surface );
143+ if (alpha_modifier_state ) {
144+ * opacity *= (float )alpha_modifier_state -> multiplier ;
145+ }
146+ }
147+
148+ static void configure_apply_toplevel (struct comp_toplevel * toplevel ,
149+ struct wlr_scene_buffer * buffer ,
150+ struct wlr_scene_surface * scene_surface ,
151+ bool is_in_saved_tree ) {
152+ bool has_effects = !toplevel -> fullscreen ;
153+
154+ // HACK: Force an node update after setting all other effects. This
155+ // avoids re-damaging the same region multiple times for each buffer,
156+ // each frame.
157+ bool options_changed = false;
158+
159+ // Stretch the saved toplevel buffer to fit the toplevel state
160+ if (!wl_list_empty (& toplevel -> saved_scene_tree -> children )) {
161+ int width = toplevel -> state .width ;
162+ int height = toplevel -> state .height ;
163+ if (buffer -> transform & WL_OUTPUT_TRANSFORM_90 ) {
164+ width = toplevel -> state .height ;
165+ height = toplevel -> state .width ;
146166 }
167+ buffer_change_option (options_changed , buffer -> dst_width , width );
168+ buffer_change_option (options_changed , buffer -> dst_height , height );
147169 }
148170
149- switch (node -> type ) {
150- default :
151- break ;
152- case WLR_SCENE_NODE_BUFFER : {
153- struct wlr_scene_buffer * buffer = wlr_scene_buffer_from_node (node );
154- if (!closest_object ) {
155- wlr_log (WLR_DEBUG ,
156- "Tried to apply effects to buffer with unknown data" );
157- break ;
171+ //
172+ // Opacity
173+ //
174+
175+ float opacity = has_effects ? toplevel -> opacity : 1 ;
176+ if (toplevel -> anim .resize .client -> state == ANIMATION_STATE_RUNNING ) {
177+ if (is_in_saved_tree ) {
178+ opacity *= toplevel -> anim .resize .crossfade_opacity ;
158179 }
159- comp_saved_object_try_extract (closest_object );
160- if (closest_object -> type != COMP_OBJECT_TYPE_TOPLEVEL ) {
180+ }
181+ if (toplevel -> anim .open_close .client -> state == ANIMATION_STATE_RUNNING ) {
182+ opacity *= toplevel -> anim .open_close .fade_opacity ;
183+ }
184+
185+ // Don't let alpha modifier adjust the blur alpha/strength
186+ float blur_alpha = ease_out_cubic (opacity );
187+ buffer_change_option (options_changed , buffer -> backdrop_blur_alpha ,
188+ blur_alpha );
189+ buffer_change_option (options_changed , buffer -> backdrop_blur_strength ,
190+ opacity );
191+
192+ // Alpha modifier support
193+ configure_apply_alpha_modifier (scene_surface , & opacity );
194+ buffer_change_option (options_changed , buffer -> opacity , opacity );
195+
196+ //
197+ // Toplevel only effects
198+ //
199+
200+ bool is_main_surface = false;
201+ if (scene_surface ) {
202+ switch (toplevel -> type ) {
203+ case COMP_TOPLEVEL_TYPE_XDG :;
204+ struct wlr_xdg_surface * xdg_surface =
205+ wlr_xdg_surface_try_from_wlr_surface (scene_surface -> surface );
206+ is_main_surface = xdg_surface && xdg_surface -> role ==
207+ WLR_XDG_SURFACE_ROLE_TOPLEVEL ;
208+ break ;
209+ case COMP_TOPLEVEL_TYPE_XWAYLAND :
210+ is_main_surface = wlr_xwayland_surface_try_from_wlr_surface (
211+ scene_surface -> surface );
161212 break ;
162213 }
214+ }
163215
164- struct comp_toplevel * toplevel = closest_object -> data ;
165- bool has_effects = !toplevel -> fullscreen ;
166-
167- // HACK: Force an node update after setting all other effects. This
168- // avoids re-damaging the same region multiple times for each buffer,
169- // each frame.
170- bool options_changed = false;
171-
172- // Stretch the saved toplevel buffer to fit the toplevel state
173- if (!wl_list_empty (& toplevel -> saved_scene_tree -> children )) {
174- int width = toplevel -> state .width ;
175- int height = toplevel -> state .height ;
176- if (buffer -> transform & WL_OUTPUT_TRANSFORM_90 ) {
177- width = toplevel -> state .height ;
178- height = toplevel -> state .width ;
179- }
180- buffer_change_option (options_changed , buffer -> dst_width , width );
181- buffer_change_option (options_changed , buffer -> dst_height , height );
182- }
183-
184- //
185- // Opacity
186- //
187-
188- float opacity = has_effects ? toplevel -> opacity : 1 ;
216+ // Ignore other unknown types
217+ if (is_in_saved_tree || is_main_surface ) {
218+ // Blur
219+ bool blur = has_effects ;
189220 if (toplevel -> anim .resize .client -> state == ANIMATION_STATE_RUNNING ) {
190221 if (is_in_saved_tree ) {
191- opacity *= toplevel -> anim . resize . crossfade_opacity ;
222+ blur = false ;
192223 }
193224 }
194- if (toplevel -> anim .open_close .client -> state ==
195- ANIMATION_STATE_RUNNING ) {
196- opacity *= toplevel -> anim .open_close .fade_opacity ;
225+ buffer_change_option (options_changed , buffer -> backdrop_blur , blur );
226+ switch (toplevel -> tiling_mode ) {
227+ case COMP_TILING_MODE_FLOATING :
228+ buffer_change_option (options_changed ,
229+ buffer -> backdrop_blur_optimized , false);
230+ break ;
231+ case COMP_TILING_MODE_TILED :
232+ buffer_change_option (options_changed ,
233+ buffer -> backdrop_blur_optimized , true);
234+ break ;
197235 }
236+ buffer_change_option (options_changed ,
237+ buffer -> backdrop_blur_ignore_transparent , true);
238+ }
198239
199- // Don't let alpha modifier adjust the blur alpha/strength
200- float blur_alpha = ease_out_cubic (opacity );
201- buffer_change_option (options_changed , buffer -> backdrop_blur_alpha ,
202- blur_alpha );
203- buffer_change_option (options_changed , buffer -> backdrop_blur_strength ,
204- opacity );
240+ // Set corners for subsurfaces as well. Fixes Firefox weirdness :/
241+ if (is_main_surface ||
242+ (scene_surface && scene_surface -> surface &&
243+ wlr_subsurface_try_from_wlr_surface (scene_surface -> surface ))) {
244+ // Corners
245+ float corner_radius = has_effects ? toplevel -> corner_radius : 0 ;
246+ buffer_change_option (options_changed , buffer -> corner_radius ,
247+ corner_radius );
248+ enum corner_location corners =
249+ toplevel -> using_csd ? CORNER_LOCATION_ALL : CORNER_LOCATION_BOTTOM ;
250+ corners = has_effects ? corners : CORNER_LOCATION_NONE ;
251+ buffer_change_option (options_changed , buffer -> corners , corners );
252+ }
205253
206- // Alpha modifier support
207- struct wlr_scene_surface * surface =
208- wlr_scene_surface_try_from_buffer (buffer );
209- if (surface ) {
210- const struct wlr_alpha_modifier_surface_v1_state
211- * alpha_modifier_state =
212- wlr_alpha_modifier_v1_get_surface_state (surface -> surface );
213- if (alpha_modifier_state ) {
214- opacity *= (float )alpha_modifier_state -> multiplier ;
215- }
216- }
217- buffer_change_option (options_changed , buffer -> opacity , opacity );
254+ // HACK: Lastly, force update the node if there were changes made
255+ if (options_changed ) {
256+ buffer -> opacity = -1 ;
257+ }
258+ wlr_scene_buffer_set_opacity (buffer , opacity );
259+ }
218260
219- //
220- // Toplevel only effects
221- //
261+ static void output_configure_scene (struct comp_output * output ,
262+ struct wlr_scene_node * node ,
263+ bool is_in_saved_tree ,
264+ struct comp_object * closest_object ) {
265+ if (!node -> enabled ) {
266+ return ;
267+ }
222268
223- bool is_main_surface = false;
269+ if (node -> data ) {
270+ closest_object = node -> data ;
271+ if (closest_object -> type == COMP_OBJECT_TYPE_SAVED_OBJECT ) {
272+ is_in_saved_tree = true;
273+ }
274+ }
224275
276+ if (node -> type == WLR_SCENE_NODE_BUFFER ) {
277+ struct wlr_scene_buffer * buffer = wlr_scene_buffer_from_node (node );
225278 struct wlr_scene_surface * scene_surface =
226279 wlr_scene_surface_try_from_buffer (buffer );
227- if (scene_surface ) {
228- switch (toplevel -> type ) {
229- case COMP_TOPLEVEL_TYPE_XDG :;
230- struct wlr_xdg_surface * xdg_surface =
231- wlr_xdg_surface_try_from_wlr_surface (
232- scene_surface -> surface );
233- is_main_surface =
234- xdg_surface &&
235- xdg_surface -> role == WLR_XDG_SURFACE_ROLE_TOPLEVEL ;
236- break ;
237- case COMP_TOPLEVEL_TYPE_XWAYLAND :
238- is_main_surface =
239- wlr_xwayland_surface_try_from_wlr_surface (surface -> surface );
280+ if (closest_object ) {
281+ comp_saved_object_try_extract (closest_object );
282+ switch (closest_object -> type ) {
283+ case COMP_OBJECT_TYPE_TOPLEVEL :
284+ configure_apply_toplevel (closest_object -> data , buffer ,
285+ scene_surface , is_in_saved_tree );
286+ return ;
287+ case COMP_OBJECT_TYPE_WIDGET :
288+ return ;
289+ case COMP_OBJECT_TYPE_LAYER_SURFACE : {
290+ // TODO: Layer effects
240291 break ;
241292 }
242- }
243-
244- // Ignore other unknown types
245- if (is_in_saved_tree || is_main_surface ) {
246- // Blur
247- bool blur = has_effects ;
248- if (toplevel -> anim .resize .client -> state ==
249- ANIMATION_STATE_RUNNING ) {
250- if (is_in_saved_tree ) {
251- blur = false;
252- }
253- }
254- buffer_change_option (options_changed , buffer -> backdrop_blur , blur );
255- switch (toplevel -> tiling_mode ) {
256- case COMP_TILING_MODE_FLOATING :
257- buffer_change_option (options_changed ,
258- buffer -> backdrop_blur_optimized , false);
259- break ;
260- case COMP_TILING_MODE_TILED :
261- buffer_change_option (options_changed ,
262- buffer -> backdrop_blur_optimized , true);
293+ default :
263294 break ;
264295 }
265- buffer_change_option (options_changed ,
266- buffer -> backdrop_blur_ignore_transparent ,
267- true);
268296 }
269297
270- // Set corners for subsurfaces as well. Fixes Firefox weirdness :/
271- if (is_main_surface ||
272- (surface && surface -> surface &&
273- wlr_subsurface_try_from_wlr_surface (surface -> surface ))) {
274- // Corners
275- float corner_radius = has_effects ? toplevel -> corner_radius : 0 ;
276- buffer_change_option (options_changed , buffer -> corner_radius ,
277- corner_radius );
278- enum corner_location corners = toplevel -> using_csd
279- ? CORNER_LOCATION_ALL
280- : CORNER_LOCATION_BOTTOM ;
281- corners = has_effects ? corners : CORNER_LOCATION_NONE ;
282- buffer_change_option (options_changed , buffer -> corners , corners );
283- }
284-
285- // HACK: Lastly, force update the node if there were changes made
286- if (options_changed ) {
287- buffer -> opacity = -1 ;
288- }
298+ // Alpha modifier support for other surfaces
299+ float opacity = 1.0 ;
300+ configure_apply_alpha_modifier (scene_surface , & opacity );
289301 wlr_scene_buffer_set_opacity (buffer , opacity );
290-
291- break ;
292- }
293- case WLR_SCENE_NODE_TREE : {
302+ } else if (node -> type == WLR_SCENE_NODE_TREE ) {
294303 struct wlr_scene_tree * tree = wlr_scene_tree_from_node (node );
295304 struct wlr_scene_node * node ;
296305 wl_list_for_each (node , & tree -> children , link ) {
297306 output_configure_scene (output , node , is_in_saved_tree ,
298307 closest_object );
299308 }
300- break ;
301- }
302309 }
303310}
304311
0 commit comments