1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2025-04-28 18:07:55 -04:00

win: support animatable cropping

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-05-16 20:08:05 +01:00
parent a320091753
commit 55d556fc49
No known key found for this signature in database
GPG key ID: D3A4405BE6CC17F4
7 changed files with 47 additions and 7 deletions

View file

@ -200,3 +200,11 @@ region_symmetric_difference_local(region_t *result, region_t *scratch,
pixman_region32_subtract(scratch, scratch, region1);
pixman_region32_union(result, result, scratch);
}
static inline region_t region_from_box(struct ibox a) {
region_t ret;
unsigned width = (unsigned)(min2(INT_MAX - a.origin.x, a.size.width)),
height = (unsigned)(min2(INT_MAX - a.origin.y, a.size.height));
pixman_region32_init_rect(&ret, a.origin.x, a.origin.y, width, height);
return ret;
}

View file

@ -18,6 +18,7 @@ commands_for_window_body(struct layer *layer, struct backend_command *cmd,
const region_t *frame_region, bool inactive_dim_fixed,
double inactive_dim, double max_brightness) {
auto w = layer->win;
scoped_region_t crop = region_from_box(layer->crop);
auto mode = win_calc_mode_raw(layer->win);
int border_width = w->g.border_width;
double dim = 0;
@ -51,6 +52,8 @@ commands_for_window_body(struct layer *layer, struct backend_command *cmd,
}
region_scale(&cmd->target_mask, layer->window.origin, layer->scale);
region_scale(&cmd->opaque_region, layer->window.origin, layer->scale);
pixman_region32_intersect(&cmd->target_mask, &cmd->target_mask, &crop);
pixman_region32_intersect(&cmd->opaque_region, &cmd->opaque_region, &crop);
cmd->op = BACKEND_COMMAND_BLIT;
cmd->source = BACKEND_COMMAND_SOURCE_WINDOW;
cmd->origin = layer->window.origin;
@ -74,6 +77,7 @@ commands_for_window_body(struct layer *layer, struct backend_command *cmd,
pixman_region32_copy(&cmd->target_mask, frame_region);
region_scale(&cmd->target_mask, cmd->origin, layer->scale);
pixman_region32_intersect(&cmd->target_mask, &cmd->target_mask, &crop);
pixman_region32_init(&cmd->opaque_region);
cmd->op = BACKEND_COMMAND_BLIT;
cmd->origin = layer->window.origin;
@ -140,6 +144,9 @@ command_for_shadow(struct layer *layer, struct backend_command *cmd,
ivec2_sub(layer->window.origin, layer->shadow.origin);
}
scoped_region_t crop = region_from_box(layer->crop);
pixman_region32_intersect(&cmd->target_mask, &cmd->target_mask, &crop);
cmd->blit = (struct backend_blit_args){
.opacity = layer->shadow_opacity,
.max_brightness = 1,
@ -170,6 +177,10 @@ command_for_blur(struct layer *layer, struct backend_command *cmd,
return 0;
}
region_scale(&cmd->target_mask, layer->window.origin, layer->scale);
scoped_region_t crop = region_from_box(layer->crop);
pixman_region32_intersect(&cmd->target_mask, &cmd->target_mask, &crop);
cmd->op = BACKEND_COMMAND_BLUR;
cmd->origin = (ivec2){};
if (w->corner_radius > 0) {

View file

@ -51,6 +51,14 @@ static bool layer_from_window(struct layer *out_layer, struct managed_win *w, iv
.y = w->g.y + win_animatable_get(w, WIN_SCRIPT_OFFSET_Y)});
out_layer->window.size = vec2_as((vec2){.width = w->widthb * out_layer->scale.x,
.height = w->heightb * out_layer->scale.y});
out_layer->crop.origin = vec2_as((vec2){
.x = win_animatable_get(w, WIN_SCRIPT_CROP_X),
.y = win_animatable_get(w, WIN_SCRIPT_CROP_Y),
});
out_layer->crop.size = vec2_as((vec2){
.x = win_animatable_get(w, WIN_SCRIPT_CROP_WIDTH),
.y = win_animatable_get(w, WIN_SCRIPT_CROP_HEIGHT),
});
if (w->shadow) {
out_layer->shadow_scale = (vec2){
.x = win_animatable_get(w, WIN_SCRIPT_SHADOW_SCALE_X),
@ -71,7 +79,7 @@ static bool layer_from_window(struct layer *out_layer, struct managed_win *w, iv
}
struct ibox screen = {.origin = {0, 0}, .size = size};
if (!ibox_overlap(out_layer->window, screen)) {
if (!ibox_overlap(out_layer->window, screen) || !ibox_overlap(out_layer->crop, screen)) {
goto out;
}

View file

@ -45,6 +45,8 @@ struct layer {
float blur_opacity;
/// Opacity of this window's shadow
float shadow_opacity;
/// Crop the content of this layer to this box, in screen coordinates.
struct ibox crop;
/// How many commands are needed to render this layer
unsigned number_of_commands;
@ -65,11 +67,6 @@ struct layer {
// things like blur-background-frame
// region_t opaque_region;
// region_t blur_region;
// TODO(yshui) support cropping
/// x and y offset for cropping. Anything to the top or
/// left of the crop point will be cropped out.
// uint32_t crop_x, crop_y;
};
/// Layout of windows at a specific frame

View file

@ -2209,6 +2209,8 @@ double win_animatable_get(const struct managed_win *w, enum win_script_output ou
case WIN_SCRIPT_BLUR_OPACITY: return w->state == WSTATE_MAPPED ? 1.0 : 0.0;
case WIN_SCRIPT_OPACITY:
case WIN_SCRIPT_SHADOW_OPACITY: return w->opacity;
case WIN_SCRIPT_CROP_X:
case WIN_SCRIPT_CROP_Y:
case WIN_SCRIPT_OFFSET_X:
case WIN_SCRIPT_OFFSET_Y:
case WIN_SCRIPT_SHADOW_OFFSET_X:
@ -2217,6 +2219,8 @@ double win_animatable_get(const struct managed_win *w, enum win_script_output ou
case WIN_SCRIPT_SCALE_Y:
case WIN_SCRIPT_SHADOW_SCALE_X:
case WIN_SCRIPT_SHADOW_SCALE_Y: return 1;
case WIN_SCRIPT_CROP_WIDTH:
case WIN_SCRIPT_CROP_HEIGHT: return INFINITY;
}
unreachable();
}

View file

@ -340,6 +340,10 @@ static const struct script_output_info win_script_outputs[] = {
[WIN_SCRIPT_SCALE_Y] = {"scale-y"},
[WIN_SCRIPT_SHADOW_SCALE_X] = {"shadow-scale-x"},
[WIN_SCRIPT_SHADOW_SCALE_Y] = {"shadow-scale-y"},
[WIN_SCRIPT_CROP_X] = {"crop-x"},
[WIN_SCRIPT_CROP_Y] = {"crop-y"},
[WIN_SCRIPT_CROP_WIDTH] = {"crop-width"},
[WIN_SCRIPT_CROP_HEIGHT] = {"crop-height"},
[NUM_OF_WIN_SCRIPT_OUTPUTS] = {NULL},
};

View file

@ -90,5 +90,13 @@ enum win_script_output {
WIN_SCRIPT_SHADOW_SCALE_X,
/// Vertical scale of the shadow
WIN_SCRIPT_SHADOW_SCALE_Y,
/// X coordinate of the origin of the crop box
WIN_SCRIPT_CROP_X,
/// Y coordinate of the origin of the crop box
WIN_SCRIPT_CROP_Y,
/// Width of the crop box
WIN_SCRIPT_CROP_WIDTH,
/// Height of the crop box
WIN_SCRIPT_CROP_HEIGHT,
};
#define NUM_OF_WIN_SCRIPT_OUTPUTS (WIN_SCRIPT_SHADOW_SCALE_Y + 1)
#define NUM_OF_WIN_SCRIPT_OUTPUTS (WIN_SCRIPT_CROP_HEIGHT + 1)