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:
parent
a320091753
commit
55d556fc49
7 changed files with 47 additions and 7 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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},
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue