mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-11-10 13:29:55 -05:00
feat: scenefx blur shadow corner radius and opacity
This commit is contained in:
parent
d892b1048f
commit
55f82231a6
5 changed files with 588 additions and 230 deletions
662
src/maomao.c
662
src/maomao.c
|
|
@ -6,6 +6,11 @@
|
|||
#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>
|
||||
|
|
@ -54,7 +59,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>
|
||||
|
|
@ -121,6 +125,7 @@ enum { XDGShell, LayerShell, X11 }; /* client types */
|
|||
enum { AxisUp, AxisDown, AxisLeft, AxisRight }; // 滚轮滚动的方向
|
||||
enum {
|
||||
LyrBg,
|
||||
LyrBlur,
|
||||
LyrBottom,
|
||||
LyrTile,
|
||||
LyrFloat,
|
||||
|
|
@ -202,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;
|
||||
|
||||
|
|
@ -213,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;
|
||||
|
|
@ -286,6 +295,8 @@ struct Client {
|
|||
int nofadeout;
|
||||
int no_force_center;
|
||||
int isunglobal;
|
||||
float focused_opacity;
|
||||
float unfocused_opacity;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -384,6 +395,7 @@ struct Monitor {
|
|||
int gamma_lut_changed;
|
||||
int asleep;
|
||||
unsigned int visible_clients;
|
||||
struct wlr_scene_optimized_blur *blur;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -632,7 +644,8 @@ static unsigned int get_tags_first_tag(unsigned int tags);
|
|||
|
||||
static void client_commit(Client *c);
|
||||
static void apply_border(Client *c, struct wlr_box clip_box, int offsetx,
|
||||
int offsety);
|
||||
int offsety,
|
||||
enum corner_location current_corner_location);
|
||||
static void client_set_opacity(Client *c, double opacity);
|
||||
static void init_baked_points(void);
|
||||
static void scene_buffer_apply_opacity(struct wlr_scene_buffer *buffer, int sx,
|
||||
|
|
@ -1030,19 +1043,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
|
||||
|
|
@ -1105,222 +1108,298 @@ bool check_hit_no_border(Client *c) {
|
|||
return hit_no_border;
|
||||
}
|
||||
|
||||
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, struct wlr_box clip_box, int offsetx,
|
||||
int offsety) {
|
||||
bool hit_no_border = false;
|
||||
int offsety, enum corner_location border_radius_location) {
|
||||
bool hit_no_border = false;
|
||||
|
||||
if (c->iskilling || !client_surface(c)->mapped)
|
||||
return;
|
||||
if (c->iskilling || !client_surface(c)->mapped)
|
||||
return;
|
||||
|
||||
if (clip_box.width > c->animation.current.width) {
|
||||
clip_box.width = c->animation.current.width;
|
||||
if (clip_box.width > c->animation.current.width) {
|
||||
clip_box.width = c->animation.current.width;
|
||||
}
|
||||
|
||||
if (clip_box.height > c->animation.current.height) {
|
||||
clip_box.height = c->animation.current.height;
|
||||
}
|
||||
|
||||
hit_no_border = check_hit_no_border(c);
|
||||
|
||||
if (hit_no_border && smartgaps) {
|
||||
c->bw = 0;
|
||||
c->fake_no_border = true;
|
||||
} else if (hit_no_border && !smartgaps) {
|
||||
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;
|
||||
} else if (!c->isfullscreen && VISIBLEON(c, c->mon)) {
|
||||
c->bw = c->isnoborder ? 0 : borderpx;
|
||||
c->fake_no_border = false;
|
||||
}
|
||||
|
||||
int clip_box_width = clip_box.width - 2 * c->bw;
|
||||
int clip_box_height = clip_box.height - 2 * c->bw;
|
||||
|
||||
if(clip_box_width < 0) {
|
||||
clip_box_width = 0;
|
||||
}
|
||||
|
||||
if(clip_box_height < 0) {
|
||||
clip_box_height = 0;
|
||||
}
|
||||
|
||||
int clip_x = c->bw - offsetx;
|
||||
int clip_y = c->bw - offsety;
|
||||
|
||||
clip_x = clip_x < 0 ? 0 : clip_x;
|
||||
clip_y = clip_y < 0 ? 0 : clip_y;
|
||||
|
||||
struct clipped_region clipped_region = {
|
||||
.area = { clip_x, clip_y, clip_box_width, clip_box_height },
|
||||
.corner_radius = border_radius,
|
||||
.corners = border_radius_location,
|
||||
};
|
||||
|
||||
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.height - c->mon->m.y - c->mon->m.height);
|
||||
int rect_width = clip_box.width;
|
||||
int rect_height = clip_box.height;
|
||||
|
||||
|
||||
if(right_offset > 0) {
|
||||
clipped_region.area.width = MIN(clip_box.width,clipped_region.area.width + right_offset);
|
||||
}
|
||||
|
||||
if(bottom_offset > 0) {
|
||||
clipped_region.area.height = MIN(clip_box.height,clipped_region.area.height + bottom_offset);
|
||||
}
|
||||
|
||||
if(rect_width < 0) {
|
||||
rect_width = 0;
|
||||
}
|
||||
|
||||
if(rect_height < 0) {
|
||||
rect_height = 0;
|
||||
}
|
||||
|
||||
int node_x = offsetx;
|
||||
int node_y = offsety;
|
||||
|
||||
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, node_x, node_y);
|
||||
wlr_scene_rect_set_corner_radius(c->border, border_radius, border_radius_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 (clip_box.height > c->animation.current.height) {
|
||||
clip_box.height = c->animation.current.height;
|
||||
if (target_geom.x + target_geom.width - border_radius >=
|
||||
c->mon->m.x + c->mon->m.width) {
|
||||
current_corner_location &= ~CORNER_LOCATION_RIGHT; // 清除右标志位
|
||||
}
|
||||
|
||||
hit_no_border = check_hit_no_border(c);
|
||||
|
||||
if (hit_no_border && smartgaps) {
|
||||
c->bw = 0;
|
||||
c->fake_no_border = true;
|
||||
} else if (hit_no_border && !smartgaps) {
|
||||
set_rect_size(c->border[0], 0, 0);
|
||||
set_rect_size(c->border[1], 0, 0);
|
||||
set_rect_size(c->border[2], 0, 0);
|
||||
set_rect_size(c->border[3], 0, 0);
|
||||
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
||||
c->fake_no_border = true;
|
||||
return;
|
||||
} else if (!c->isfullscreen && VISIBLEON(c, c->mon)) {
|
||||
c->bw = c->isnoborder ? 0 : borderpx;
|
||||
c->fake_no_border = false;
|
||||
if (target_geom.y + border_radius <= c->mon->m.y) {
|
||||
current_corner_location &= ~CORNER_LOCATION_TOP; // 清除上标志位
|
||||
}
|
||||
|
||||
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
||||
set_rect_size(c->border[0], clip_box.width, c->bw);
|
||||
set_rect_size(c->border[1], clip_box.width, c->bw);
|
||||
set_rect_size(c->border[2], c->bw, clip_box.height - 2 * c->bw);
|
||||
set_rect_size(c->border[3], c->bw, clip_box.height - 2 * c->bw);
|
||||
wlr_scene_node_set_position(&c->border[0]->node, 0, 0);
|
||||
wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw);
|
||||
wlr_scene_node_set_position(&c->border[1]->node, 0,
|
||||
clip_box.height - c->bw);
|
||||
wlr_scene_node_set_position(&c->border[3]->node, clip_box.width - c->bw,
|
||||
c->bw);
|
||||
|
||||
if (ISTILED(c) || c->animation.tagining || c->animation.tagouted ||
|
||||
c->animation.tagouting) {
|
||||
if (c->animation.current.x < c->mon->m.x) {
|
||||
set_rect_size(c->border[2], GEZERO(c->bw - offsetx),
|
||||
clip_box.height - 2 * c->bw);
|
||||
} else if (c->animation.current.x + c->animation.current.width >
|
||||
c->mon->m.x + c->mon->m.width) {
|
||||
set_rect_size(c->border[3],
|
||||
GEZERO(c->bw - GEZERO(c->animation.current.x +
|
||||
c->animation.current.width -
|
||||
c->mon->m.x - c->mon->m.width)),
|
||||
clip_box.height - 2 * c->bw);
|
||||
set_rect_size(c->border[0], clip_box.width + c->bw,
|
||||
GEZERO(c->bw - offsety));
|
||||
set_rect_size(
|
||||
c->border[1], clip_box.width + c->bw,
|
||||
GEZERO(c->bw - GEZERO(c->animation.current.y +
|
||||
c->animation.current.height -
|
||||
c->mon->m.y - c->mon->m.height)));
|
||||
} else if (c->animation.current.y < c->mon->m.y) {
|
||||
set_rect_size(c->border[0], clip_box.width,
|
||||
GEZERO(c->bw - offsety));
|
||||
} else if (c->animation.current.y + c->animation.current.height >
|
||||
c->mon->m.y + c->mon->m.height) {
|
||||
set_rect_size(
|
||||
c->border[1], clip_box.width,
|
||||
GEZERO(c->bw - GEZERO(c->animation.current.y +
|
||||
c->animation.current.height -
|
||||
c->mon->m.y - c->mon->m.height)));
|
||||
set_rect_size(c->border[2], GEZERO(c->bw - offsetx),
|
||||
clip_box.height - c->bw);
|
||||
set_rect_size(c->border[3],
|
||||
GEZERO(c->bw - GEZERO(c->animation.current.x +
|
||||
c->animation.current.width -
|
||||
c->mon->m.x - c->mon->m.width)),
|
||||
clip_box.height - c->bw);
|
||||
}
|
||||
if (target_geom.y + target_geom.height - border_radius >=
|
||||
c->mon->m.y + c->mon->m.height) {
|
||||
current_corner_location &= ~CORNER_LOCATION_BOTTOM; // 清除下标志位
|
||||
}
|
||||
|
||||
wlr_scene_node_set_position(&c->border[0]->node, offsetx, offsety);
|
||||
wlr_scene_node_set_position(&c->border[2]->node, offsetx, c->bw + offsety);
|
||||
wlr_scene_node_set_position(&c->border[1]->node, offsetx,
|
||||
clip_box.height - c->bw + offsety);
|
||||
wlr_scene_node_set_position(
|
||||
&c->border[3]->node, clip_box.width - c->bw + offsetx, c->bw + offsety);
|
||||
return current_corner_location;
|
||||
}
|
||||
|
||||
struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) {
|
||||
int offsetx = 0;
|
||||
int offsety = 0;
|
||||
struct uvec2 offset;
|
||||
offset.x = 0;
|
||||
offset.y = 0;
|
||||
int offsetx = 0;
|
||||
int offsety = 0;
|
||||
struct uvec2 offset;
|
||||
offset.x = 0;
|
||||
offset.y = 0;
|
||||
|
||||
if (!ISTILED(c) && !c->animation.tagining && !c->animation.tagouted &&
|
||||
!c->animation.tagouting)
|
||||
return offset;
|
||||
if (!ISTILED(c) && !c->animation.tagining && !c->animation.tagouted &&
|
||||
!c->animation.tagouting)
|
||||
return offset;
|
||||
|
||||
// // make tagout tagin animations not visible in other monitors
|
||||
if (ISTILED(c) || c->animation.tagining || c->animation.tagouted ||
|
||||
c->animation.tagouting) {
|
||||
if (c->animation.current.x < c->mon->m.x) {
|
||||
offsetx = c->mon->m.x - c->bw - c->animation.current.x;
|
||||
offsetx = offsetx < 0 ? 0 : offsetx;
|
||||
clip_box->x = clip_box->x + offsetx;
|
||||
clip_box->width = clip_box->width - offsetx;
|
||||
} else if (c->animation.current.x + c->animation.current.width >
|
||||
c->mon->m.x + c->mon->m.width) {
|
||||
clip_box->width =
|
||||
clip_box->width -
|
||||
(c->animation.current.x + c->animation.current.width -
|
||||
c->mon->m.x - c->mon->m.width) +
|
||||
c->bw;
|
||||
}
|
||||
// // make tagout tagin animations not visible in other monitors
|
||||
if (ISTILED(c) || c->animation.tagining || c->animation.tagouted ||
|
||||
c->animation.tagouting) {
|
||||
if (c->animation.current.x < c->mon->m.x) {
|
||||
offsetx = c->mon->m.x - c->bw - c->animation.current.x;
|
||||
offsetx = offsetx < 0 ? 0 : offsetx;
|
||||
clip_box->x = clip_box->x + offsetx;
|
||||
clip_box->width = clip_box->width - offsetx;
|
||||
} else if (c->animation.current.x + c->animation.current.width >
|
||||
c->mon->m.x + c->mon->m.width) {
|
||||
clip_box->width = clip_box->width -
|
||||
(c->animation.current.x + c->animation.current.width -
|
||||
c->mon->m.x - c->mon->m.width) +
|
||||
c->bw;
|
||||
}
|
||||
|
||||
if (c->animation.current.y < c->mon->m.y) {
|
||||
offsety = c->mon->m.y - c->bw - c->animation.current.y;
|
||||
offsety = offsety < 0 ? 0 : offsety;
|
||||
clip_box->y = clip_box->y + offsety;
|
||||
clip_box->height = clip_box->height - offsety;
|
||||
} else if (c->animation.current.y + c->animation.current.height >
|
||||
c->mon->m.y + c->mon->m.height) {
|
||||
clip_box->height =
|
||||
clip_box->height -
|
||||
(c->animation.current.y + c->animation.current.height -
|
||||
c->mon->m.y - c->mon->m.height) +
|
||||
c->bw;
|
||||
}
|
||||
}
|
||||
if (c->animation.current.y < c->mon->m.y) {
|
||||
offsety = c->mon->m.y - c->bw - c->animation.current.y;
|
||||
offsety = offsety < 0 ? 0 : offsety;
|
||||
clip_box->y = clip_box->y + offsety;
|
||||
clip_box->height = clip_box->height - offsety;
|
||||
} else if (c->animation.current.y + c->animation.current.height >
|
||||
c->mon->m.y + c->mon->m.height) {
|
||||
clip_box->height = clip_box->height -
|
||||
(c->animation.current.y + c->animation.current.height -
|
||||
c->mon->m.y - c->mon->m.height) +
|
||||
c->bw;
|
||||
}
|
||||
}
|
||||
|
||||
offset.x = offsetx;
|
||||
offset.y = offsety;
|
||||
offset.x = offsetx;
|
||||
offset.y = offsety;
|
||||
|
||||
if ((clip_box->width < 0 || clip_box->height < 0) &&
|
||||
(ISTILED(c) || c->animation.tagouting || c->animation.tagining)) {
|
||||
c->is_clip_to_hide = true;
|
||||
wlr_scene_node_set_enabled(&c->scene->node, false);
|
||||
} else if (c->is_clip_to_hide && VISIBLEON(c, c->mon)) {
|
||||
c->is_clip_to_hide = false;
|
||||
wlr_scene_node_set_enabled(&c->scene->node, true);
|
||||
}
|
||||
if ((clip_box->width < 0 || clip_box->height < 0) &&
|
||||
(ISTILED(c) || c->animation.tagouting || c->animation.tagining)) {
|
||||
c->is_clip_to_hide = true;
|
||||
wlr_scene_node_set_enabled(&c->scene->node, false);
|
||||
} else if (c->is_clip_to_hide && VISIBLEON(c, c->mon)) {
|
||||
c->is_clip_to_hide = false;
|
||||
wlr_scene_node_set_enabled(&c->scene->node, true);
|
||||
}
|
||||
|
||||
if (clip_box->width > c->animation.current.width) {
|
||||
clip_box->width = c->animation.current.width;
|
||||
}
|
||||
if (clip_box->width > c->animation.current.width) {
|
||||
clip_box->width = c->animation.current.width;
|
||||
}
|
||||
|
||||
if (clip_box->height > c->animation.current.height) {
|
||||
clip_box->height = c->animation.current.height;
|
||||
}
|
||||
if (clip_box->height > c->animation.current.height) {
|
||||
clip_box->height = c->animation.current.height;
|
||||
}
|
||||
|
||||
return offset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
void client_apply_clip(Client *c) {
|
||||
|
||||
if (c->iskilling || !client_surface(c)->mapped)
|
||||
return;
|
||||
struct wlr_box clip_box;
|
||||
struct uvec2 offset;
|
||||
animationScale scale_data;
|
||||
if (c->iskilling || !client_surface(c)->mapped)
|
||||
return;
|
||||
struct wlr_box clip_box;
|
||||
struct uvec2 offset;
|
||||
animationScale scale_data;
|
||||
struct wlr_box surface_clip;
|
||||
enum corner_location current_corner_location = set_client_corner_location(c);
|
||||
|
||||
if (!animations) {
|
||||
c->animation.running = false;
|
||||
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, clip_box, offset.x, offset.y);
|
||||
if (!animations) {
|
||||
c->animation.running = false;
|
||||
c->need_output_flush = false;
|
||||
c->animainit_geom = c->current = c->pending = c->animation.current =
|
||||
c->geom;
|
||||
client_get_clip(c, &clip_box);
|
||||
|
||||
if (clip_box.width <= 0 || clip_box.height <= 0)
|
||||
return;
|
||||
offset = clip_to_hide(c, &clip_box);
|
||||
|
||||
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box);
|
||||
buffer_set_effect(c, (animationScale){0, 0, 0, 0, false});
|
||||
return;
|
||||
}
|
||||
apply_border(c, clip_box, offset.x, offset.y, current_corner_location);
|
||||
client_draw_shadow(c);
|
||||
|
||||
uint32_t width, height;
|
||||
client_actual_size(c, &width, &height);
|
||||
surface_clip = clip_box;
|
||||
surface_clip.width = surface_clip.width - 2 * c->bw;
|
||||
surface_clip.height = surface_clip.height - 2 * c->bw;
|
||||
|
||||
struct wlr_box geometry;
|
||||
client_get_geometry(c, &geometry);
|
||||
clip_box = (struct wlr_box){
|
||||
.x = geometry.x,
|
||||
.y = geometry.y,
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
if(surface_clip.width <= 0 || surface_clip.height <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (client_is_x11(c)) {
|
||||
clip_box.x = 0;
|
||||
clip_box.y = 0;
|
||||
}
|
||||
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &surface_clip);
|
||||
buffer_set_effect(c, (animationScale){0, 0, 0, 0, current_corner_location,false});
|
||||
return;
|
||||
}
|
||||
|
||||
offset = clip_to_hide(c, &clip_box);
|
||||
apply_border(c, clip_box, offset.x, offset.y);
|
||||
uint32_t width, height;
|
||||
client_actual_size(c, &width, &height);
|
||||
|
||||
if (clip_box.width <= 0 || clip_box.height <= 0)
|
||||
return;
|
||||
struct wlr_box geometry;
|
||||
client_get_geometry(c, &geometry);
|
||||
clip_box = (struct wlr_box){
|
||||
.x = geometry.x,
|
||||
.y = geometry.y,
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
|
||||
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box);
|
||||
if (client_is_x11(c)) {
|
||||
clip_box.x = 0;
|
||||
clip_box.y = 0;
|
||||
}
|
||||
|
||||
scale_data.should_scale = true;
|
||||
scale_data.width = clip_box.width - 2 * c->bw;
|
||||
scale_data.height = clip_box.height - 2 * c->bw;
|
||||
scale_data.width_scale =
|
||||
(float)scale_data.width / (geometry.width - offset.x);
|
||||
scale_data.height_scale =
|
||||
(float)scale_data.height / (geometry.height - offset.y);
|
||||
buffer_set_effect(c, scale_data);
|
||||
offset = clip_to_hide(c, &clip_box);
|
||||
apply_border(c, clip_box, offset.x, offset.y, current_corner_location);
|
||||
client_draw_shadow(c);
|
||||
|
||||
surface_clip = clip_box;
|
||||
surface_clip.width = surface_clip.width - 2 * c->bw;
|
||||
surface_clip.height = surface_clip.height - 2 * c->bw;
|
||||
|
||||
if(surface_clip.width <= 0 || surface_clip.height <= 0) {
|
||||
return;
|
||||
}
|
||||
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &surface_clip);
|
||||
|
||||
scale_data.should_scale = true;
|
||||
scale_data.width = clip_box.width - 2 * c->bw;
|
||||
scale_data.height = clip_box.height - 2 * c->bw;
|
||||
scale_data.width_scale = (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 = c->is_open_animation && animation_fade_in ? (double)c->animation.passed_frames / c->animation.total_frames : 1.0;
|
||||
scale_data.opacity = c->isfullscreen ? 1 : c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;
|
||||
buffer_set_effect(c, scale_data);
|
||||
}
|
||||
|
||||
bool client_draw_frame(Client *c) {
|
||||
|
|
@ -1328,6 +1407,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;
|
||||
|
||||
|
|
@ -1335,8 +1422,9 @@ bool client_draw_frame(Client *c) {
|
|||
client_animation_next_tick(c);
|
||||
client_apply_clip(c);
|
||||
} else {
|
||||
wlr_scene_node_set_position(&c->scene->node, c->pending.x,
|
||||
c->pending.y);
|
||||
if (!c->is_clip_to_hide)
|
||||
wlr_scene_node_set_position(&c->scene->node, c->pending.x,
|
||||
c->pending.y);
|
||||
c->animainit_geom = c->animation.initial = c->pending = c->current =
|
||||
c->geom;
|
||||
client_apply_clip(c);
|
||||
|
|
@ -1712,7 +1800,7 @@ void gpureset(struct wl_listener *listener, void *data) {
|
|||
|
||||
wlr_log(WLR_DEBUG, "gpu reset");
|
||||
|
||||
if (!(drw = wlr_renderer_autocreate(backend)))
|
||||
if (!(drw = fx_renderer_create(backend)))
|
||||
die("couldn't recreate renderer");
|
||||
|
||||
if (!(alloc = wlr_allocator_autocreate(backend, drw)))
|
||||
|
|
@ -1914,6 +2002,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 ? r->focused_opacity
|
||||
: c->focused_opacity;
|
||||
c->unfocused_opacity = r->unfocused_opacity > 0
|
||||
? r->unfocused_opacity
|
||||
: c->unfocused_opacity;
|
||||
|
||||
newtags = r->tags > 0 ? r->tags | newtags : newtags;
|
||||
i = 0;
|
||||
|
|
@ -2958,6 +3051,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);
|
||||
}
|
||||
|
|
@ -3043,6 +3140,19 @@ 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_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) {
|
||||
|
|
@ -3459,6 +3569,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
|
||||
|
|
@ -4170,7 +4288,12 @@ 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_optimized_blur_set_size(m->blur, m->m.width, m->m.height);
|
||||
}
|
||||
updatemons(NULL, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -4417,15 +4540,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 =
|
||||
|
|
@ -4435,10 +4559,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);
|
||||
|
||||
|
|
@ -4463,6 +4597,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;
|
||||
|
||||
|
|
@ -4476,6 +4619,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);
|
||||
|
|
@ -4541,12 +4709,33 @@ 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);
|
||||
|
|
@ -4583,11 +4772,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 |
|
||||
|
|
@ -4614,6 +4814,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;
|
||||
|
|
@ -5105,6 +5307,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,
|
||||
|
|
@ -5138,18 +5352,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;
|
||||
|
|
@ -5402,7 +5604,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 &&
|
||||
|
|
@ -5447,8 +5648,8 @@ void resize(Client *c, struct wlr_box geo, int interact) {
|
|||
c->need_output_flush = false;
|
||||
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);
|
||||
apply_border(c, c->geom, 0, 0);
|
||||
apply_border(c, c->geom, 0, 0, CORNER_LOCATION_ALL);
|
||||
client_draw_shadow(c);
|
||||
client_get_clip(c, &clip);
|
||||
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip);
|
||||
return;
|
||||
|
|
@ -6348,7 +6549,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_autocreate(backend)))
|
||||
if (!(drw = fx_renderer_create(backend)))
|
||||
die("couldn't create renderer");
|
||||
|
||||
wl_signal_add(&drw->events.lost, &gpu_reset);
|
||||
|
|
@ -6539,6 +6740,9 @@ 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);
|
||||
|
||||
/* 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);
|
||||
|
|
@ -7245,6 +7449,10 @@ 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_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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue