1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2025-03-24 17:26:22 -04:00

animation/presets: add geometry-change preset

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-08-12 06:21:13 +01:00
parent 719f2a2e6c
commit 34ecca52e3
No known key found for this signature in database
GPG key ID: D3A4405BE6CC17F4
4 changed files with 365 additions and 3 deletions

BIN
assets/geometry-change.mp4 Normal file

Binary file not shown.

View file

@ -162,4 +162,43 @@ fly-in = {
(2, "direction", [-1, 1, 0, 0]),
(3, "direction", [0, 0, 1, 1]),
);
}
};
geometry-change = {
scale-x = {
curve = "cubic-bezier(0.07, 0.65, 0, 1)";
duration = "placeholder0";
start = "window-width-before / window-width";
end = 1;
};
scale-y = {
curve = "cubic-bezier(0.07, 0.65, 0, 1)";
duration = "placeholder0";
start = "window-height-before / window-height";
end = 1;
};
shadow-scale-x = "scale-x";
shadow-scale-y = "scale-y";
offset-x = {
curve = "cubic-bezier(0.07, 0.65, 0, 1)";
duration = "placeholder0";
start = "window-x-before - window-x";
end = 0;
};
offset-y = {
curve = "cubic-bezier(0.07, 0.65, 0, 1)";
duration = "placeholder0";
start = "window-y-before - window-y";
end = 0;
};
saved-image-blend = {
duration = "placeholder0";
start = 1;
end = 0;
};
shadow-offset-x = "offset-x";
shadow-offset-y = "offset-y";
*knobs = {
duration = 0.4;
};
*placeholders = ((0, "duration"));
};

View file

@ -515,7 +515,7 @@ animations = ({
_decrease-opacity_:: When the opacity of a window is decreased.
_geometry_:: When the geometry of a window is changed. (EXPERIMENTAL)
[[trigger-geometry]]_geometry_:: When the geometry of a window is changed. (EXPERIMENTAL)
+
WARNING: The _geometry_ trigger is experimental. Using this means you accept the caveat that geometry animations will also trigger when you manually resize or move a window, like when you drag the window around with your mouse.
@ -598,6 +598,24 @@ endif::[]
_duration_:: Duration of the animation in seconds.
--
+
_geometry-change_:::
+
Animate the geometry (i.e. size and position) change of the window.
+
WARNING: This makes use of both the <<trigger-geometry>> trigger, and the <<saved-image-blend>> output variable. Both of these features are experimental and may not work as expected.
+
--
ifdef::env-web[]
video::assets/geometry-change.mp4[width=400]
endif::[]
--
+
--
*Options*:::
_duration_:: Duration of the animation in seconds.
--
=== Advanced
@ -697,7 +715,7 @@ Currently, these output variables are supported: :::
_crop-x_, _crop-y_, _crop-width_, _crop-height_:: These four values combined defines a rectangle on the screen. The window and its shadow will be cropped to this rectangle. If not defined, the window and shadow will not be cropped.
_saved-image-blend_:: When the window's geometry changes, its content will often change drastically, creating a jarring discontinuity. This output variable allows you to blend the window's content before and after the geometry change, the before and after images will be stretched appropriately to match the animation. This way you can smoothly animated geometry changes. This is a number between 0 and 1. 0 means the saved image is not used, whereas 1 means you will only see the saved image. (EXPERIMENTAL)
[[saved-image-blend]]_saved-image-blend_:: When the window's geometry changes, its content will often change drastically, creating a jarring discontinuity. This output variable allows you to blend the window's content before and after the geometry change, the before and after images will be stretched appropriately to match the animation. This way you can smoothly animated geometry changes. This is a number between 0 and 1. 0 means the saved image is not used, whereas 1 means you will only see the saved image. (EXPERIMENTAL)
+
WARNING: The _saved-image-blend_ variable is experimental. It might work incorrectly, cause visual artifacts, or slow down your system. You are welcome to open an issue on GitHub if you encounter any problems to help us improve it, though resolution is not guaranteed.

View file

@ -209,6 +209,7 @@ static struct script *script_template__disappear(int *output_slots) {
output_slots[12] = -1;
output_slots[13] = -1;
output_slots[14] = -1;
output_slots[15] = -1;
return ret;
}
@ -425,6 +426,7 @@ static struct script *script_template__appear(int *output_slots) {
output_slots[12] = -1;
output_slots[13] = -1;
output_slots[14] = -1;
output_slots[15] = -1;
return ret;
}
@ -619,6 +621,7 @@ static struct script *script_template__slide_out(int *output_slots) {
output_slots[12] = 6;
output_slots[13] = 7;
output_slots[14] = 8;
output_slots[15] = -1;
return ret;
}
@ -819,6 +822,7 @@ static struct script *script_template__slide_in(int *output_slots) {
output_slots[12] = 6;
output_slots[13] = 7;
output_slots[14] = 8;
output_slots[15] = -1;
return ret;
}
@ -1016,6 +1020,7 @@ static struct script *script_template__fly_out(int *output_slots) {
output_slots[12] = -1;
output_slots[13] = -1;
output_slots[14] = -1;
output_slots[15] = -1;
return ret;
}
@ -1204,6 +1209,7 @@ static struct script *script_template__fly_in(int *output_slots) {
output_slots[12] = -1;
output_slots[13] = -1;
output_slots[14] = -1;
output_slots[15] = -1;
return ret;
}
@ -1251,6 +1257,304 @@ static bool win_script_preset__fly_in(struct win_script *output, config_setting_
script_specialize(output->script, spec, ARR_SIZE(spec));
return true;
}
static struct script *script_template__geometry_change(int *output_slots) {
static const struct instruction instrs[] = {
{.type = INST_BRANCH_ONCE, .rel = 76},
{.type = INST_IMM, .imm = 0x1p+0},
{.type = INST_LOAD, .slot = 11},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_LOAD, .slot = 9},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_LOAD, .slot = 12},
{.type = INST_OP, .op = OP_DIV},
{
.type = INST_CURVE,
.curve = {.type = CURVE_CUBIC_BEZIER,
.bezier = {.ax = 0x1.35c28f5c28f5cp+0,
.bx = -0x1.ae147ae147ae2p-2,
.cx = 0x1.ae147ae147ae2p-3,
.ay = -0x1.999999999996p-5,
.by = -0x1.cccccccccccd4p-1,
.cy = 0x1.f333333333335p+0}},
},
{.type = INST_OP, .op = OP_MUL},
{.type = INST_LOAD, .slot = 11},
{.type = INST_OP, .op = OP_ADD},
{.type = INST_STORE, .slot = 0},
{.type = INST_IMM, .imm = 0x1p+0},
{.type = INST_LOAD, .slot = 13},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_LOAD, .slot = 9},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_LOAD, .slot = 14},
{.type = INST_OP, .op = OP_DIV},
{
.type = INST_CURVE,
.curve = {.type = CURVE_CUBIC_BEZIER,
.bezier = {.ax = 0x1.35c28f5c28f5cp+0,
.bx = -0x1.ae147ae147ae2p-2,
.cx = 0x1.ae147ae147ae2p-3,
.ay = -0x1.999999999996p-5,
.by = -0x1.cccccccccccd4p-1,
.cy = 0x1.f333333333335p+0}},
},
{.type = INST_OP, .op = OP_MUL},
{.type = INST_LOAD, .slot = 13},
{.type = INST_OP, .op = OP_ADD},
{.type = INST_STORE, .slot = 1},
{.type = INST_LOAD, .slot = 0},
{.type = INST_STORE, .slot = 2},
{.type = INST_LOAD, .slot = 1},
{.type = INST_STORE, .slot = 3},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_LOAD, .slot = 15},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_LOAD, .slot = 9},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_LOAD, .slot = 16},
{.type = INST_OP, .op = OP_DIV},
{
.type = INST_CURVE,
.curve = {.type = CURVE_CUBIC_BEZIER,
.bezier = {.ax = 0x1.35c28f5c28f5cp+0,
.bx = -0x1.ae147ae147ae2p-2,
.cx = 0x1.ae147ae147ae2p-3,
.ay = -0x1.999999999996p-5,
.by = -0x1.cccccccccccd4p-1,
.cy = 0x1.f333333333335p+0}},
},
{.type = INST_OP, .op = OP_MUL},
{.type = INST_LOAD, .slot = 15},
{.type = INST_OP, .op = OP_ADD},
{.type = INST_STORE, .slot = 4},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_LOAD, .slot = 17},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_LOAD, .slot = 9},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_LOAD, .slot = 18},
{.type = INST_OP, .op = OP_DIV},
{
.type = INST_CURVE,
.curve = {.type = CURVE_CUBIC_BEZIER,
.bezier = {.ax = 0x1.35c28f5c28f5cp+0,
.bx = -0x1.ae147ae147ae2p-2,
.cx = 0x1.ae147ae147ae2p-3,
.ay = -0x1.999999999996p-5,
.by = -0x1.cccccccccccd4p-1,
.cy = 0x1.f333333333335p+0}},
},
{.type = INST_OP, .op = OP_MUL},
{.type = INST_LOAD, .slot = 17},
{.type = INST_OP, .op = OP_ADD},
{.type = INST_STORE, .slot = 5},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_LOAD, .slot = 19},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_LOAD, .slot = 9},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_LOAD, .slot = 20},
{.type = INST_OP, .op = OP_DIV},
{
.type = INST_CURVE,
.curve = {.type = CURVE_LINEAR},
},
{.type = INST_OP, .op = OP_MUL},
{.type = INST_LOAD, .slot = 19},
{.type = INST_OP, .op = OP_ADD},
{.type = INST_STORE, .slot = 6},
{.type = INST_LOAD, .slot = 4},
{.type = INST_STORE, .slot = 7},
{.type = INST_LOAD, .slot = 5},
{.type = INST_STORE, .slot = 8},
{.type = INST_BRANCH_ONCE, .rel = 31},
{.type = INST_HALT},
{.type = INST_LOAD_CTX, .ctx = 48},
{.type = INST_LOAD_CTX, .ctx = 16},
{.type = INST_OP, .op = OP_DIV},
{.type = INST_STORE_OVER_NAN, .slot = 11},
{.type = INST_LOAD_CTX, .ctx = 1073741824},
{.type = INST_STORE, .slot = 12},
{.type = INST_LOAD_CTX, .ctx = 56},
{.type = INST_LOAD_CTX, .ctx = 24},
{.type = INST_OP, .op = OP_DIV},
{.type = INST_STORE_OVER_NAN, .slot = 13},
{.type = INST_LOAD_CTX, .ctx = 1073741824},
{.type = INST_STORE, .slot = 14},
{.type = INST_LOAD_CTX, .ctx = 32},
{.type = INST_LOAD_CTX, .ctx = 0},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_STORE_OVER_NAN, .slot = 15},
{.type = INST_LOAD_CTX, .ctx = 1073741824},
{.type = INST_STORE, .slot = 16},
{.type = INST_LOAD_CTX, .ctx = 40},
{.type = INST_LOAD_CTX, .ctx = 8},
{.type = INST_OP, .op = OP_SUB},
{.type = INST_STORE_OVER_NAN, .slot = 17},
{.type = INST_LOAD_CTX, .ctx = 1073741824},
{.type = INST_STORE, .slot = 18},
{.type = INST_IMM, .imm = 0x1p+0},
{.type = INST_STORE_OVER_NAN, .slot = 19},
{.type = INST_LOAD_CTX, .ctx = 1073741824},
{.type = INST_STORE, .slot = 20},
{.type = INST_BRANCH, .rel = -103},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_STORE, .slot = 10},
{.type = INST_LOAD, .slot = 12},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_OP, .op = OP_ADD},
{.type = INST_LOAD, .slot = 10},
{.type = INST_OP, .op = OP_MAX},
{.type = INST_STORE, .slot = 10},
{.type = INST_LOAD, .slot = 14},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_OP, .op = OP_ADD},
{.type = INST_LOAD, .slot = 10},
{.type = INST_OP, .op = OP_MAX},
{.type = INST_STORE, .slot = 10},
{.type = INST_LOAD, .slot = 16},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_OP, .op = OP_ADD},
{.type = INST_LOAD, .slot = 10},
{.type = INST_OP, .op = OP_MAX},
{.type = INST_STORE, .slot = 10},
{.type = INST_LOAD, .slot = 18},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_OP, .op = OP_ADD},
{.type = INST_LOAD, .slot = 10},
{.type = INST_OP, .op = OP_MAX},
{.type = INST_STORE, .slot = 10},
{.type = INST_LOAD, .slot = 20},
{.type = INST_IMM, .imm = 0x0p+0},
{.type = INST_OP, .op = OP_ADD},
{.type = INST_LOAD, .slot = 10},
{.type = INST_OP, .op = OP_MAX},
{.type = INST_STORE, .slot = 10},
{.type = INST_HALT},
};
struct script *ret = malloc(offsetof(struct script, instrs) + sizeof(instrs));
ret->len = ARR_SIZE(instrs);
ret->elapsed_slot = 9;
ret->n_slots = 21;
ret->stack_size = 3;
ret->vars = NULL;
ret->overrides = NULL;
memcpy(ret->instrs, instrs, sizeof(instrs));
{
struct variable_allocation *var = malloc(sizeof(*var));
*var = (struct variable_allocation){
.name = strdup("scale-x"), .slot = 0, .index = 0};
HASH_ADD_STR(ret->vars, name, var);
}
{
struct variable_allocation *var = malloc(sizeof(*var));
*var = (struct variable_allocation){
.name = strdup("scale-y"), .slot = 1, .index = 1};
HASH_ADD_STR(ret->vars, name, var);
}
{
struct variable_allocation *var = malloc(sizeof(*var));
*var = (struct variable_allocation){
.name = strdup("shadow-scale-x"), .slot = 2, .index = 2};
HASH_ADD_STR(ret->vars, name, var);
}
{
struct variable_allocation *var = malloc(sizeof(*var));
*var = (struct variable_allocation){
.name = strdup("shadow-scale-y"), .slot = 3, .index = 3};
HASH_ADD_STR(ret->vars, name, var);
}
{
struct variable_allocation *var = malloc(sizeof(*var));
*var = (struct variable_allocation){
.name = strdup("offset-x"), .slot = 4, .index = 4};
HASH_ADD_STR(ret->vars, name, var);
}
{
struct variable_allocation *var = malloc(sizeof(*var));
*var = (struct variable_allocation){
.name = strdup("offset-y"), .slot = 5, .index = 5};
HASH_ADD_STR(ret->vars, name, var);
}
{
struct variable_allocation *var = malloc(sizeof(*var));
*var = (struct variable_allocation){
.name = strdup("saved-image-blend"), .slot = 6, .index = 6};
HASH_ADD_STR(ret->vars, name, var);
}
{
struct variable_allocation *var = malloc(sizeof(*var));
*var = (struct variable_allocation){
.name = strdup("shadow-offset-x"), .slot = 7, .index = 7};
HASH_ADD_STR(ret->vars, name, var);
}
{
struct variable_allocation *var = malloc(sizeof(*var));
*var = (struct variable_allocation){
.name = strdup("shadow-offset-y"), .slot = 8, .index = 8};
HASH_ADD_STR(ret->vars, name, var);
}
{
struct overridable_slot *override = malloc(sizeof(*override));
*override = (struct overridable_slot){.name = strdup("scale-x"), .slot = 11};
HASH_ADD_STR(ret->overrides, name, override);
}
{
struct overridable_slot *override = malloc(sizeof(*override));
*override = (struct overridable_slot){.name = strdup("scale-y"), .slot = 13};
HASH_ADD_STR(ret->overrides, name, override);
}
{
struct overridable_slot *override = malloc(sizeof(*override));
*override = (struct overridable_slot){.name = strdup("offset-x"), .slot = 15};
HASH_ADD_STR(ret->overrides, name, override);
}
{
struct overridable_slot *override = malloc(sizeof(*override));
*override = (struct overridable_slot){.name = strdup("offset-y"), .slot = 17};
HASH_ADD_STR(ret->overrides, name, override);
}
{
struct overridable_slot *override = malloc(sizeof(*override));
*override = (struct overridable_slot){.name = strdup("saved-image-blend"),
.slot = 19};
HASH_ADD_STR(ret->overrides, name, override);
}
output_slots[0] = 4;
output_slots[1] = 5;
output_slots[2] = 7;
output_slots[3] = 8;
output_slots[4] = -1;
output_slots[5] = -1;
output_slots[6] = -1;
output_slots[7] = 0;
output_slots[8] = 1;
output_slots[9] = 2;
output_slots[10] = 3;
output_slots[11] = -1;
output_slots[12] = -1;
output_slots[13] = -1;
output_slots[14] = -1;
output_slots[15] = 6;
return ret;
}
static bool
win_script_preset__geometry_change(struct win_script *output, config_setting_t *setting) {
output->script = script_template__geometry_change(output->output_indices);
double knob_duration = 0x1.999999999999ap-2;
config_setting_lookup_float(setting, "duration", &knob_duration);
struct script_specialization_context spec[] = {
{.offset = SCRIPT_CTX_PLACEHOLDER_BASE + 0, .value = knob_duration},
};
script_specialize(output->script, spec, ARR_SIZE(spec));
return true;
}
struct {
const char *name;
bool (*func)(struct win_script *output, config_setting_t *setting);
@ -1261,5 +1565,6 @@ struct {
{"slide-in", win_script_preset__slide_in},
{"fly-out", win_script_preset__fly_out},
{"fly-in", win_script_preset__fly_in},
{"geometry-change", win_script_preset__geometry_change},
{NULL, NULL},
};