@@ -1,11 +1,17 @@
/*
* See LICENSE file for copyright and license details.
*/
# include "wlr-layer-shell-unstable-v1-protocol.h"
# include "wlr/util/box.h"
# include <getopt.h>
# include <libinput.h>
# include <limits.h>
# include <linux/input-event-codes.h>
# include <scenefx/render/fx_renderer/fx_renderer.h>
# include <scenefx/types/fx/blur_data.h>
# include <scenefx/types/fx/clipped_region.h>
# include <scenefx/types/fx/corner_location.h>
# include <scenefx/types/wlr_scene.h>
# include <signal.h>
# include <stdbool.h>
# include <stdint.h>
@@ -55,7 +61,6 @@
# include <wlr/types/wlr_primary_selection.h>
# include <wlr/types/wlr_primary_selection_v1.h>
# include <wlr/types/wlr_relative_pointer_v1.h>
# include <wlr/types/wlr_scene.h>
# include <wlr/types/wlr_screencopy_v1.h>
# include <wlr/types/wlr_seat.h>
# include <wlr/types/wlr_server_decoration.h>
@@ -119,6 +124,7 @@ enum { XDGShell, LayerShell, X11 }; /* client types */
enum { AxisUp , AxisDown , AxisLeft , AxisRight } ; // 滚轮滚动的方向
enum {
LyrBg ,
LyrBlur ,
LyrBottom ,
LyrTile ,
LyrFloat ,
@@ -201,6 +207,9 @@ typedef struct {
float height_scale ;
int width ;
int height ;
double percent ;
float opacity ;
enum corner_location corner_location ;
bool should_scale ;
} animationScale ;
@@ -212,7 +221,8 @@ struct Client {
overview_backup_geom , current ; /* layout-relative, includes border */
Monitor * mon ;
struct wlr_scene_tree * scene ;
struct wlr_scene_rect * border [ 4 ] ; /* top, bottom, left, right */
struct wlr_scene_rect * border ; /* top, bottom, left, right */
struct wlr_scene_shadow * shadow ;
struct wlr_scene_tree * scene_surface ;
struct wl_list link ;
struct wl_list flink ;
@@ -285,6 +295,8 @@ struct Client {
int nofadeout ;
int no_force_center ;
int isunglobal ;
float focused_opacity ;
float unfocused_opacity ;
char oldmonname [ 128 ] ;
} ;
@@ -384,6 +396,7 @@ struct Monitor {
int gamma_lut_changed ;
int asleep ;
unsigned int visible_clients ;
struct wlr_scene_optimized_blur * blur ;
} ;
typedef struct {
@@ -846,39 +859,14 @@ double find_animation_curve_at(double t, int type) {
void apply_opacity_to_rect_nodes ( Client * c , struct wlr_scene_node * node ,
double animation_passed ) {
int offsetx = 0 ;
int offsety = 0 ;
if ( node - > type = = WLR_SCENE_NODE_RECT ) {
struct wlr_scene_rect * rect = wlr_scene_rect_from_node ( node ) ;
// Assuming the rect has a color field and we can modify it
rect - > color [ 0 ] = ( 1 - animation_passed ) * rect - > color [ 0 ] ;
rect - > color [ 1 ] = ( 1 - animation_passed ) * rect - > color [ 1 ] ;
rect - > color [ 2 ] = ( 1 - animation_passed ) * rect - > color [ 2 ] ;
rect - > color [ 3 ] = ( 1 - animation_passed ) * rect - > color [ 3 ] ;
rect - > color [ 0 ] = 0 ;
rect - > color [ 1 ] = 0 ;
rect - > color [ 2 ] = 0 ;
rect - > color [ 3 ] = 0 ;
wlr_scene_rect_set_color ( rect , rect - > color ) ;
offsetx = c - > geom . width - c - > animation . current . width ;
offsety = c - > geom . height - c - > animation . current . height ;
if ( node - > y > c - > geom . y + c - > geom . height / 2 ) {
wlr_scene_node_set_position ( node , c - > geom . x ,
c - > geom . y + c - > geom . height - offsety ) ;
wlr_scene_rect_set_size ( rect , c - > animation . current . width ,
c - > bw ) ; // down
} else if ( node - > y < c - > geom . y + c - > geom . height / 2 & &
rect - > width > rect - > height ) {
wlr_scene_node_set_position ( node , c - > geom . x , c - > geom . y ) ;
wlr_scene_rect_set_size ( rect , c - > animation . current . width ,
c - > bw ) ; // up
} else if ( node - > x < c - > geom . x + c - > geom . width / 2 & &
rect - > width < rect - > height ) {
wlr_scene_rect_set_size ( rect , c - > bw ,
c - > animation . current . height ) ; // left
} else {
wlr_scene_node_set_position (
node , c - > geom . x + c - > geom . width - offsetx , c - > geom . y ) ;
wlr_scene_rect_set_size ( rect , c - > bw ,
c - > animation . current . height ) ; // right
}
}
// If the node is a tree, recursively traverse its children
@@ -985,19 +973,9 @@ void client_animation_next_tick(Client *c) {
. height = height ,
} ;
if ( ! c - > iskilling & & ( c - > is_open_animation | | c - > animation . begin_fade_in ) & &
animation_fade_in & & ! c - > nofadein ) {
c - > animation . begin_fade_in = true ;
client_set_opacity ( c ,
MIN ( animation_passed + fadein_begin_opacity , 1.0 ) ) ;
}
c - > is_open_animation = false ;
if ( animation_passed = = 1.0 ) {
if ( c - > animation . begin_fade_in ) {
c - > animation . begin_fade_in = false ;
}
// clear the open action state
// To prevent him from being mistaken that
@@ -1068,19 +1046,72 @@ bool check_hit_no_border(Client *c) {
return hit_no_border ;
}
void apply_border ( Client * c ) {
void client_draw_shadow ( Client * c ) {
if ( c - > iskilling | | ! client_surface ( c ) - > mapped )
return ;
if ( ! shadows | | ! c - > isfloating ) {
wlr_scene_shadow_set_size ( c - > shadow , 0 , 0 ) ;
return ;
}
uint32_t width , height ;
client_actual_size ( c , & width , & height ) ;
uint32_t delta = shadows_size + c - > bw ;
/* we calculate where to clip the shadow */
struct wlr_box client_box = {
. x = 0 ,
. y = 0 ,
. width = width ,
. height = height ,
} ;
struct wlr_box shadow_box = {
. x = shadows_position_x ,
. y = shadows_position_y ,
. width = width + 2 * delta ,
. height = height + 2 * delta ,
} ;
struct wlr_box intersection_box ;
wlr_box_intersection ( & intersection_box , & client_box , & shadow_box ) ;
/* clipped region takes shadow relative coords, so we translate everything
* by its position */
intersection_box . x - = shadows_position_x ;
intersection_box . y - = shadows_position_y ;
struct clipped_region clipped_region = {
. area = intersection_box ,
. corner_radius = border_radius ,
. corners = border_radius_location_default ,
} ;
wlr_scene_node_set_position ( & c - > shadow - > node , shadow_box . x , shadow_box . y ) ;
wlr_scene_shadow_set_size ( c - > shadow , shadow_box . width , shadow_box . height ) ;
wlr_scene_shadow_set_clipped_region ( c - > shadow , clipped_region ) ;
}
void apply_border ( Client * c ) {
if ( ! c | | c - > iskilling | | ! client_surface ( c ) - > mapped )
return ;
bool hit_no_border = check_hit_no_border ( c ) ;
enum corner_location current_corner_location =
c - > isfullscreen | | ( no_radius_when_single & & c - > mon & &
c - > mon - > visible_clients = = 1 )
? CORNER_LOCATION_NONE
: CORNER_LOCATION_ALL ;
// Handle no-border cases
if ( hit_no_border & & smartgaps ) {
c - > bw = 0 ;
c - > fake_no_border = true ;
} else if ( hit_no_border & & ! smartgaps ) {
for ( int i = 0 ; i < 4 ; i + + )
set_rect_size ( c - > border [ i ] , 0 , 0 ) ;
wlr_scene_rect_set_size ( c - > border , 0 , 0 ) ;
wlr_scene_node_set_position ( & c - > scene_surface - > node , c - > bw , c - > bw ) ;
c - > fake_no_border = true ;
return ;
@@ -1089,92 +1120,83 @@ void apply_border(Client *c) {
c - > fake_no_border = false ;
}
struct wlr_box geom = c - > animation . current ;
int bw = c - > bw ;
struct wlr_box clip_box = c - > animation . current ;
// 一但在GEZERO如果使用无符号, 那么其他数据也会转换为无符号导致没有负数出错
int bw = ( int ) c - > bw ;
// Calculate how much the window is outside the monitor
// These values will be positive when window is outside the monitor
int outside_left = GEZERO ( c - > mon - > m . x - c - > animation . current . x ) ;
int outside_top = GEZERO ( c - > mon - > m . y - c - > animation . current . y ) ;
int outside_r ight =
GEZERO ( ( c - > animation . current . x + c - > animation . current . width ) -
( c - > mon - > m . x + c - > mon - > m . width ) ) ;
int outside_bottom =
GEZERO ( ( c - > animation . current . y + c - > animation . current . height ) -
( c - > mon - > m . y + c - > mon - > m . height ) ) ;
int right_offset =
GEZERO ( c - > animation . current . x + c - > animation . current . width -
c - > mon - > m . x - c - > mon - > m . width ) ;
int bottom_offset =
GEZERO ( c - > animation . current . y + c - > animation . current . he ight -
c - > mon - > m . y - c - > mon - > m . height ) ;
// Initialize border dimensions
int top_width = geom . width ;
int top_height = bw ;
int bottom_width = geom . width ;
int bottom_height = bw ;
int left_width = bw ;
int left_height = geom . height - 2 * bw ;
int right_width = bw ;
int right_height = geom . height - 2 * bw ;
int left_offset = GEZERO ( c - > mon - > m . x - c - > animation . current . x ) ;
int top_offset = GEZERO ( c - > mon - > m . y - c - > animation . current . y ) ;
// Initialize border positions
int top_x = 0 ;
int top_y = 0 ;
int bottom_x = 0 ;
int bottom_y = geom . height - bottom_height ;
int left_x = 0 ;
int left_y = bw ;
int right_x = geom . width - right_width ;
int right_y = bw ;
int inner_surface_width = GEZERO ( clip_box . width - 2 * bw ) ;
int inner_surface_height = GEZERO ( clip_box . height - 2 * bw ) ;
// Adjust borders when window is outside monitor
if ( ISTILED ( c ) | | c - > animation . tagining | | c - > animation . tagouted | |
c - > animation . tagouting ) {
// Top border - reduce height when window goes above monitor
if ( outside_top > 0 ) {
top_height = GEZERO ( bw - outside_top ) ;
top_y = top_y + outside_top ;
left_height = left_height - outside_top ;
right_height = right_height - outside_top ;
left_y = left_y + outside_top ;
right_y = right_y + outside_top ;
}
int inner_surface_x = GEZERO ( bw - left_offset ) ;
int inner_surface_y = GEZERO ( bw - top_offset ) ;
// Bottom border - reduce height when window goes below monitor
if ( outside_bottom > 0 ) {
bottom_height = GEZERO ( bw - outside_bottom ) ;
left_height = left_height - outside_bottom ;
right_height = right_height - outside_bottom ;
}
int rect_x = left_offset ;
int rect_y = top_offset ;
// Left border - reduce width when window goes left of monitor
if ( outside_lef t > 0 ) {
left_width = GEZERO ( bw - outside_left ) ;
left_x = left_x + outside_left ;
top_width = top_width - outside_left ;
bottom_width = bottom_width - outside_left ;
top_x = top_x + outside_left ;
bottom_x = bottom_x + outside_left ;
}
int rect_width =
GEZERO ( c - > animation . current . width - left_offse t - right_offset ) ;
int rect_height =
GEZERO ( c - > animation . current . height - top_offset - bottom_offset ) ;
// Right border - reduce width when window goes right of monitor
if ( outside_righ t > 0 ) {
right_width = GEZERO ( bw - outside_right ) ;
top_width = top_width - outside_right ;
bottom_width = bottom_width - outside_right ;
}
if ( left_offset > c - > bw )
inner_surface_width = inner_surface_width - left_offse t + c - > bw ;
if ( top_offset > c - > bw )
inner_surface_height = inner_surface_height - top_offset + c - > bw ;
if ( right_offset > 0 ) {
inner_surface_width =
MIN ( clip_box . width , inner_surface_width + right_offset ) ;
}
// Position the surface within the borders
wlr_scene_node_set_position ( & c - > sce ne_surface- > node , bw , bw ) ;
if ( bottom_offset > 0 ) {
in ner _surface_height =
MIN ( clip_box . height , inner_surface_height + bottom_offset ) ;
}
// Set border sizes
set_rect_size ( c - > border [ 0 ] , top_width , top_height ) ; // Top
set_rect_size ( c - > border [ 1 ] , bottom_width , bottom _height) ; // Bottom
set_rect_size ( c - > border [ 2 ] , left_width , left_height ) ; // Left
set_rect_size ( c - > b ord er[ 3 ] , right_width , right_height ) ; // Right
struct clipped_region clipped_region = {
. area = { inner_surface_x , inner_surface_y , inner_surface_width ,
inner_surface _height } ,
. corner_radius = border_radius ,
. c orn ers = current_corner_location ,
} ;
// Position borders with offsets
wlr_scene_node _set_position ( & c - > border [ 0 ] - > node , top_x , top_y ) ;
wlr_scene_node_set_position ( & c - > border [ 1 ] - > node , bottom _x, bottom _y) ;
wlr_scene_node _set_position ( & c - > border [ 2 ] - > node , left_x , left_y ) ;
wlr_scene_node_set_position ( & c - > border [ 3 ] - > node , right_x , right_y ) ;
wlr_scene_node_set_position ( & c - > scene_surface - > node , c - > bw , c - > bw ) ;
wlr_scene_rect _set_size ( c - > border , rect_width , rect_height ) ;
wlr_scene_node_set_position ( & c - > border - > node , rect _x, rect _y) ;
wlr_scene_rect _set_corner_radius ( c - > border , border_radius ,
current_corner_location ) ;
wlr_scene_rect_set_clipped_region ( c - > border , clipped_region ) ;
}
enum corner_location set_client_corner_location ( Client * c ) {
enum corner_location current_corner_location = CORNER_LOCATION_ALL ;
struct wlr_box target_geom = animations ? c - > animation . current : c - > geom ;
if ( target_geom . x + border_radius < = c - > mon - > m . x ) {
current_corner_location & = ~ CORNER_LOCATION_LEFT ; // 清除左标志位
}
if ( target_geom . x + target_geom . width - border_radius > =
c - > mon - > m . x + c - > mon - > m . width ) {
current_corner_location & = ~ CORNER_LOCATION_RIGHT ; // 清除右标志位
}
if ( target_geom . y + border_radius < = c - > mon - > m . y ) {
current_corner_location & = ~ CORNER_LOCATION_TOP ; // 清除上标志位
}
if ( target_geom . y + target_geom . height - border_radius > =
c - > mon - > m . y + c - > mon - > m . height ) {
current_corner_location & = ~ CORNER_LOCATION_BOTTOM ; // 清除下标志位
}
return current_corner_location ;
}
struct ivec2 clip_to_hide ( Client * c , struct wlr_box * clip_box ) {
@@ -1250,8 +1272,21 @@ void client_apply_clip(Client *c) {
if ( c - > iskilling | | ! client_surface ( c ) - > mapped )
return ;
struct wlr_box clip_box ;
bool should_render_client_surface = false ;
struct ivec2 offset ;
animationScale scale_data ;
struct wlr_box surface_clip ;
enum corner_location current_corner_location =
set_client_corner_location ( c ) ;
float percent =
c - > animation . action = = OPEN & & animation_fade_in & & ! c - > nofadein
? ( double ) c - > animation . passed_frames / c - > animation . total_frames
: 1.0 ;
float opacity = c - > isfullscreen ? 1
: c = = selmon - > sel ? c - > focused_opacity
: c - > unfocused_opacity ;
int bw = ( int ) c - > bw ;
if ( ! animations ) {
@@ -1259,15 +1294,31 @@ void client_apply_clip(Client *c) {
c - > need_output_flush = false ;
c - > animainit_geom = c - > current = c - > pending = c - > animation . current =
c - > geom ;
client_get_clip ( c , & clip_box ) ;
offset = clip_to_hide ( c , & clip_box ) ;
apply_border ( c ) ;
if ( clip_box . width < = 0 | | clip_box . height < = 0 )
return ;
client_draw_shadow ( c ) ;
wlr_scene_subsurface_tree_set_clip ( & c - > scene_surface - > node , & clip_box ) ;
buffer_set_effect ( c , ( animationScale ) { 0 , 0 , 0 , 0 , fal se} ) ;
surface_clip = clip_box ;
surface_clip . width = surface_clip . width - GEZERO ( bw - off set . width ) ;
surface_clip . height = surface_clip . height - GEZERO ( bw - offset . height ) ;
scale_data . opacity = c - > isfullscreen ? 1
: c = = selmon - > sel ? c - > focused_opacity
: c - > unfocused_opacity ;
if ( surface_clip . width < = 0 | | surface_clip . height < = 0 ) {
return ;
}
wlr_scene_subsurface_tree_set_clip ( & c - > scene_surface - > node ,
& surface_clip ) ;
buffer_set_effect ( c , ( animationScale ) { 0 , 0 , 0 , 0 , opacity , opacity ,
current_corner_location , false } ) ;
return ;
}
@@ -1289,12 +1340,29 @@ void client_apply_clip(Client *c) {
}
offset = clip_to_hide ( c , & clip_box ) ;
apply_border ( c ) ;
if ( clip_box . width < = 0 | | clip_box . height < = 0 )
return ;
surface_clip = clip_box ;
surface_clip . width = surface_clip . width - GEZERO ( bw - offset . width ) ;
surface_clip . height = surface_clip . height - GEZERO ( bw - offset . height ) ;
wlr_scene_subsurface_tree_set_clip ( & c - > scene_surface - > node , & clip_box ) ;
if ( surface_clip . width < = 0 | | surface_clip . height < = 0 ) {
should_render_client_surface = false ;
wlr_scene_node_set_enabled ( & c - > scene_surface - > node , false ) ;
} else {
should_render_client_surface = true ;
wlr_scene_node_set_enabled ( & c - > scene_surface - > node , true ) ;
}
apply_border ( c ) ;
client_draw_shadow ( c ) ;
if ( ! should_render_client_surface ) {
return ;
}
wlr_scene_subsurface_tree_set_clip ( & c - > scene_surface - > node , & surface_clip ) ;
scale_data . should_scale = true ;
scale_data . width = clip_box . width - GEZERO ( bw - offset . width ) ;
@@ -1303,6 +1371,9 @@ void client_apply_clip(Client *c) {
( float ) scale_data . width / ( geometry . width - offset . x ) ;
scale_data . height_scale =
( float ) scale_data . height / ( geometry . height - offset . y ) ;
scale_data . corner_location = current_corner_location ;
scale_data . percent = percent ;
scale_data . opacity = opacity ;
buffer_set_effect ( c , scale_data ) ;
}
@@ -1311,6 +1382,14 @@ bool client_draw_frame(Client *c) {
if ( ! c | | ! client_surface ( c ) - > mapped )
return false ;
if ( c - > isfullscreen ) {
client_set_opacity ( c , 1 ) ;
} else if ( c = = selmon - > sel & & ! c - > animation . running ) {
client_set_opacity ( c , c - > focused_opacity ) ;
} else if ( ! c - > animation . running ) {
client_set_opacity ( c , c - > unfocused_opacity ) ;
}
if ( ! c - > need_output_flush )
return false ;
@@ -1652,7 +1731,7 @@ void gpureset(struct wl_listener *listener, void *data) {
wlr_log ( WLR_DEBUG , " gpu reset " ) ;
if ( ! ( drw = wlr _renderer_auto create( backend ) ) )
if ( ! ( drw = fx _renderer_create( backend ) ) )
die ( " couldn't recreate renderer " ) ;
if ( ! ( alloc = wlr_allocator_autocreate ( backend , drw ) ) )
@@ -1855,6 +1934,11 @@ applyrules(Client *c) {
c - > isglobal = r - > isglobal > = 0 ? r - > isglobal : c - > isglobal ;
c - > isoverlay = r - > isoverlay > = 0 ? r - > isoverlay : c - > isoverlay ;
c - > isunglobal = r - > isunglobal > = 0 ? r - > isunglobal : c - > isunglobal ;
c - > focused_opacity = r - > focused_opacity > 0.0f ? r - > focused_opacity
: c - > focused_opacity ;
c - > unfocused_opacity = r - > unfocused_opacity > 0.0f
? r - > unfocused_opacity
: c - > unfocused_opacity ;
newtags = r - > tags > 0 ? r - > tags | newtags : newtags ;
i = 0 ;
@@ -2901,6 +2985,10 @@ void cleanupmon(struct wl_listener *listener, void *data) {
wlr_scene_output_destroy ( m - > scene_output ) ;
closemon ( m ) ;
if ( m - > blur ) {
wlr_scene_node_destroy ( & m - > blur - > node ) ;
m - > blur = NULL ;
}
// wlr_scene_node_destroy(&m->fullscreen_bg->node);
free ( m ) ;
}
@@ -2940,6 +3028,25 @@ void closemon(Monitor *m) {
}
}
static void iter_layer_scene_buffers ( struct wlr_scene_buffer * buffer , int sx ,
int sy , void * user_data ) {
LayerSurface * l = user_data ;
struct wlr_scene_surface * scene_surface =
wlr_scene_surface_try_from_buffer ( buffer ) ;
if ( ! scene_surface ) {
return ;
}
if ( blur & & blur_layer & & l ) {
wlr_scene_buffer_set_backdrop_blur ( buffer , true ) ;
wlr_scene_buffer_set_backdrop_blur_optimized ( buffer , true ) ;
wlr_scene_buffer_set_backdrop_blur_ignore_transparent ( buffer , true ) ;
} else {
wlr_scene_buffer_set_backdrop_blur ( buffer , false ) ;
}
}
void commitlayersurfacenotify ( struct wl_listener * listener , void * data ) {
LayerSurface * l = wl_container_of ( listener , l , surface_commit ) ;
struct wlr_layer_surface_v1 * layer_surface = l - > layer_surface ;
@@ -2981,6 +3088,28 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
}
arrangelayers ( l - > mon ) ;
if ( blur ) {
// Rerender the optimized blur on change
struct wlr_layer_surface_v1 * wlr_layer_surface = l - > layer_surface ;
if ( wlr_layer_surface - > current . layer ! =
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM & &
wlr_layer_surface - > current . layer ! =
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND ) {
wlr_scene_node_for_each_buffer ( & l - > scene - > node ,
iter_layer_scene_buffers , l ) ;
}
if ( wlr_layer_surface - > current . layer = =
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND | |
wlr_layer_surface - > current . layer = =
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM ) {
if ( l - > mon ) {
wlr_scene_optimized_blur_mark_dirty ( l - > mon - > blur ) ;
}
}
}
}
void client_set_pending_state ( Client * c ) {
@@ -3397,6 +3526,14 @@ void createmon(struct wl_listener *listener, void *data) {
wlr_output_layout_add_auto ( output_layout , wlr_output ) ;
else
wlr_output_layout_add ( output_layout , wlr_output , m - > m . x , m - > m . y ) ;
if ( blur ) {
m - > blur = wlr_scene_optimized_blur_create ( & scene - > tree , 0 , 0 ) ;
wlr_scene_node_set_position ( & m - > blur - > node , m - > m . x , m - > m . y ) ;
wlr_scene_node_reparent ( & m - > blur - > node , layers [ LyrBlur ] ) ;
wlr_scene_optimized_blur_set_size ( m - > blur , m - > m . width , m - > m . height ) ;
// wlr_scene_node_set_enabled(&m->blur->node, 1);
}
}
void // fix for 0.5
@@ -3904,7 +4041,13 @@ void incovgaps(const Arg *arg) {
void requestmonstate ( struct wl_listener * listener , void * data ) {
struct wlr_output_event_request_state * event = data ;
Monitor * m = wl_container_of ( listener , m , frame ) ;
wlr_output_commit_state ( event - > output , event - > state ) ;
if ( blur ) {
wlr_scene_node_set_position ( & m - > blur - > node , m - > m . x , m - > m . y ) ;
wlr_scene_optimized_blur_set_size ( m - > blur , m - > m . width , m - > m . height ) ;
}
updatemons ( NULL , NULL ) ;
}
@@ -4151,15 +4294,16 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly,
struct wlr_scene_node * snapshot_node = NULL ;
switch ( node - > type ) {
case WLR_SCENE_NODE_TREE : ;
case WLR_SCENE_NODE_TREE : {
struct wlr_scene_tree * scene_tree = wlr_scene_tree_from_node ( node ) ;
struct wlr_scene_node * child ;
wl_list_for_each ( child , & scene_tree - > children , link ) {
scene_node_snapshot ( child , lx , ly , snapshot_tree ) ;
}
break ;
case WLR_SCENE_NODE_RECT : ;
}
case WLR_SCENE_NODE_RECT : {
struct wlr_scene_rect * scene_rect = wlr_scene_rect_from_node ( node ) ;
struct wlr_scene_rect * snapshot_rect =
@@ -4169,10 +4313,20 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly,
if ( snapshot_rect = = NULL ) {
return false ;
}
wlr_scene_rect_set_clipped_region ( scene_rect ,
snapshot_rect - > clipped_region ) ;
wlr_scene_rect_set_backdrop_blur ( scene_rect , false ) ;
// wlr_scene_rect_set_backdrop_blur_optimized(
// scene_rect, snapshot_rect->backdrop_blur_optimized);
wlr_scene_rect_set_corner_radius (
scene_rect , snapshot_rect - > corner_radius , snapshot_rect - > corners ) ;
wlr_scene_rect_set_color ( scene_rect , snapshot_rect - > color ) ;
snapshot_node = & snapshot_rect - > node ;
break ;
case WLR_SCENE_NODE_BUFFER : ;
}
case WLR_SCENE_NODE_BUFFER : {
struct wlr_scene_buffer * scene_buffer =
wlr_scene_buffer_from_node ( node ) ;
@@ -4197,6 +4351,15 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly,
// Effects
wlr_scene_buffer_set_opacity ( snapshot_buffer , scene_buffer - > opacity ) ;
wlr_scene_buffer_set_corner_radius ( snapshot_buffer ,
scene_buffer - > corner_radius ,
scene_buffer - > corners ) ;
// wlr_scene_buffer_set_backdrop_blur_optimized(
// snapshot_buffer, scene_buffer->backdrop_blur_optimized);
// wlr_scene_buffer_set_backdrop_blur_ignore_transparent(
// snapshot_buffer, scene_buffer->backdrop_blur_ignore_transparent);
wlr_scene_buffer_set_backdrop_blur ( snapshot_buffer , false ) ;
snapshot_buffer - > node . data = scene_buffer - > node . data ;
@@ -4210,6 +4373,31 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly,
}
break ;
}
case WLR_SCENE_NODE_SHADOW : {
struct wlr_scene_shadow * scene_shadow =
wlr_scene_shadow_from_node ( node ) ;
struct wlr_scene_shadow * snapshot_shadow = wlr_scene_shadow_create (
snapshot_tree , scene_shadow - > width , scene_shadow - > height ,
scene_shadow - > corner_radius , scene_shadow - > blur_sigma ,
scene_shadow - > color ) ;
if ( snapshot_shadow = = NULL ) {
return false ;
}
snapshot_node = & snapshot_shadow - > node ;
wlr_scene_shadow_set_clipped_region ( snapshot_shadow ,
scene_shadow - > clipped_region ) ;
snapshot_shadow - > node . data = scene_shadow - > node . data ;
wlr_scene_node_set_enabled ( & snapshot_shadow - > node , false ) ;
break ;
}
case WLR_SCENE_NODE_OPTIMIZED_BLUR :
return true ;
}
if ( snapshot_node ! = NULL ) {
wlr_scene_node_set_position ( snapshot_node , lx , ly ) ;
@@ -4300,12 +4488,35 @@ void locksession(struct wl_listener *listener, void *data) {
wlr_session_lock_v1_send_locked ( session_lock ) ;
}
static void iter_xdg_scene_buffers ( struct wlr_scene_buffer * buffer , int sx ,
int sy , void * user_data ) {
Client * c = user_data ;
struct wlr_scene_surface * scene_surface =
wlr_scene_surface_try_from_buffer ( buffer ) ;
if ( ! scene_surface ) {
return ;
}
struct wlr_surface * surface = scene_surface - > surface ;
/* we dont blur subsurfaces */
if ( wlr_subsurface_try_from_wlr_surface ( surface ) ! = NULL )
return ;
if ( blur & & c ) {
wlr_scene_buffer_set_backdrop_blur ( buffer , true ) ;
wlr_scene_buffer_set_backdrop_blur_optimized ( buffer , true ) ;
wlr_scene_buffer_set_backdrop_blur_ignore_transparent ( buffer , true ) ;
} else {
wlr_scene_buffer_set_backdrop_blur ( buffer , false ) ;
}
}
void // old fix to 0.5
mapnotify ( struct wl_listener * listener , void * data ) {
/* Called when the surface is mapped, or ready to display on-screen. */
Client * p = NULL ;
Client * c = wl_container_of ( listener , c , map ) ;
int i ;
/* Create scene tree for this client and its border */
c - > scene = client_surface ( c ) - > data = wlr_scene_tree_create ( layers [ LyrTile ] ) ;
wlr_scene_node_set_enabled ( & c - > scene - > node , c - > type ! = XDGShell ) ;
@@ -4342,11 +4553,22 @@ mapnotify(struct wl_listener *listener, void *data) {
return ;
}
for ( i = 0 ; i < 4 ; i + + ) {
c - > border [ i ] = wlr_scene_rect_create (
c - > scene , 0 , 0 , c - > isurgent ? urgentcolor : bordercolor ) ;
c - > border [ i ] - > node . data = c ;
}
c - > border = wlr_scene_rect_create ( c - > scene , 0 , 0 ,
c - > isurgent ? urgentcolor : bordercolor ) ;
wlr_scene_node_lower_to_bottom ( & c - > border - > node ) ;
wlr_scene_node_set_position ( & c - > border - > node , 0 , 0 ) ;
wlr_scene_rect_set_corner_radius ( c - > border , border_radius ,
border_radius_location_default ) ;
wlr_scene_node_set_enabled ( & c - > border - > node , true ) ;
c - > shadow = wlr_scene_shadow_create ( c - > scene , 0 , 0 , border_radius ,
shadows_blur , shadowscolor ) ;
wlr_scene_node_lower_to_bottom ( & c - > shadow - > node ) ;
wlr_scene_node_set_enabled ( & c - > shadow - > node , true ) ;
wlr_scene_node_for_each_buffer ( & c - > scene_surface - > node ,
iter_xdg_scene_buffers , c ) ;
/* Initialize client geometry with room for border */
client_set_tiled ( c , WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT |
@@ -4373,6 +4595,8 @@ mapnotify(struct wl_listener *listener, void *data) {
c - > is_open_animation = true ;
c - > drag_to_tile = false ;
c - > fake_no_border = false ;
c - > focused_opacity = focused_opacity ;
c - > unfocused_opacity = unfocused_opacity ;
c - > nofadein = 0 ;
c - > nofadeout = 0 ;
c - > no_force_center = 0 ;
@@ -4864,6 +5088,18 @@ void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx, int sy,
}
}
// TODO: blur set, opacity set
if ( wlr_xdg_popup_try_from_wlr_surface ( surface ) ! = NULL )
return ;
wlr_scene_buffer_set_corner_radius ( buffer , border_radius ,
scale_data - > corner_location ) ;
float target_opacity = scale_data - > percent + fadein_begin_opacity ;
if ( target_opacity > scale_data - > opacity ) {
target_opacity = scale_data - > opacity ;
}
wlr_scene_buffer_set_opacity ( buffer , target_opacity ) ;
}
void snap_scene_buffer_apply_effect ( struct wlr_scene_buffer * buffer , int sx ,
@@ -4875,7 +5111,10 @@ void snap_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx,
void buffer_set_effect ( Client * c , animationScale data ) {
if ( c - > iskilling | | c - > animation . tagouting | | c - > animation . tagouted | |
if ( ! c | | c - > iskilling )
return ;
if ( c - > animation . tagouting | | c - > animation . tagouted | |
c - > animation . tagining ) {
data . should_scale = false ;
}
@@ -4883,6 +5122,11 @@ void buffer_set_effect(Client *c, animationScale data) {
if ( c = = grabc )
data . should_scale = false ;
if ( c - > isfullscreen | |
( no_radius_when_single & & c - > mon & & c - > mon - > visible_clients = = 1 ) ) {
data . corner_location = CORNER_LOCATION_NONE ;
}
wlr_scene_node_for_each_buffer ( & c - > scene_surface - > node ,
scene_buffer_apply_effect , & data ) ;
}
@@ -4892,18 +5136,6 @@ void client_set_opacity(Client *c, double opacity) {
scene_buffer_apply_opacity , & opacity ) ;
}
void client_handle_opacity ( Client * c ) {
if ( ! c | | ! c - > mon | | ! client_surface ( c ) - > mapped )
return ;
double opacity = c - > isfullscreen | | c - > ismaxmizescreen ? 1.0
: c = = selmon - > sel ? 0.8
: 0.5 ;
wlr_scene_node_for_each_buffer ( & c - > scene_surface - > node ,
scene_buffer_apply_opacity , & opacity ) ;
}
void rendermon ( struct wl_listener * listener , void * data ) {
Monitor * m = wl_container_of ( listener , m , frame ) ;
Client * c , * tmp ;
@@ -5156,7 +5388,6 @@ void resize(Client *c, struct wlr_box geo, int interact) {
if ( ! c - > is_open_animation ) {
c - > animation . begin_fade_in = false ;
client_set_opacity ( c , 1 ) ;
}
if ( c - > animation . action = = OPEN & & ! c - > animation . tagining & &
@@ -5202,12 +5433,13 @@ void resize(Client *c, struct wlr_box geo, int interact) {
c - > animainit_geom = c - > current = c - > pending = c - > animation . current =
c - > geom ;
wlr_scene_node_set_position ( & c - > scene - > node , c - > geom . x , c - > geom . y ) ;
client_draw_shadow ( c ) ;
apply_border ( c ) ;
client_get_clip ( c , & clip ) ;
wlr_scene_subsurface_tree_set_clip ( & c - > scene_surface - > node , & clip ) ;
return ;
}
// 如果不是工作区切换时划出去的窗口,就让动画的结束位置,就是上面的真实位置和大小
// c->pending 决定动画的终点, 一般在其他调用resize的函数的附近设置了
if ( ! c - > animation . tagouting & & ! c - > iskilling ) {
@@ -6053,7 +6285,7 @@ void setup(void) {
wlr_scene_node_place_below ( & drag_icon - > node , & layers [ LyrBlock ] - > node ) ;
/* Create a renderer with the default implementation */
if ( ! ( drw = wlr _renderer_auto create( backend ) ) )
if ( ! ( drw = fx _renderer_create( backend ) ) )
die ( " couldn't create renderer " ) ;
wl_signal_add ( & drw - > events . lost , & gpu_reset ) ;
@@ -6245,6 +6477,11 @@ void setup(void) {
wl_signal_add ( & output_mgr - > events . apply , & output_mgr_apply ) ;
wl_signal_add ( & output_mgr - > events . test , & output_mgr_test ) ;
// blur
wlr_scene_set_blur_data ( scene , blur_params . num_passes , blur_params . radius ,
blur_params . noise , blur_params . brightness ,
blur_params . contrast , blur_params . saturation ) ;
/* create text_input-, and input_method-protocol relevant globals */
input_method_manager = wlr_input_method_manager_v2_create ( dpy ) ;
text_input_manager = wlr_text_input_manager_v3_create ( dpy ) ;
@@ -6998,6 +7235,11 @@ void updatemons(struct wl_listener *listener, void *data) {
// wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y);
// wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height);
if ( blur & & m - > blur ) {
wlr_scene_node_set_position ( & m - > blur - > node , m - > m . x , m - > m . y ) ;
wlr_scene_optimized_blur_set_size ( m - > blur , m - > m . width , m - > m . height ) ;
}
if ( m - > lock_surface ) {
struct wlr_scene_tree * scene_tree = m - > lock_surface - > surface - > data ;
wlr_scene_node_set_position ( & scene_tree - > node , m - > m . x , m - > m . y ) ;