Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Animation PR #1032

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/atom.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
_NET_WM_BYPASS_COMPOSITOR, \
UTF8_STRING, \
C_STRING

#define ATOM_LIST3 \
_NET_CURRENT_DESKTOP, \
_NET_WM_DESKTOP

// clang-format on

#define ATOM_DEF(x) xcb_atom_t a##x
Expand All @@ -53,6 +58,7 @@ struct atom {
struct cache *c;
LIST_APPLY(ATOM_DEF, SEP_COLON, ATOM_LIST1);
LIST_APPLY(ATOM_DEF, SEP_COLON, ATOM_LIST2);
LIST_APPLY(ATOM_DEF, SEP_COLON, ATOM_LIST3);
};

struct atom *init_atoms(xcb_connection_t *);
Expand Down
10 changes: 10 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ typedef struct session {
ev_timer unredir_timer;
/// Timer for fading
ev_timer fade_timer;
/// Timer for animations
ev_timer animation_timer;
/// Use an ev_idle callback for drawing
/// So we only start drawing when events are processed
ev_idle draw_idle;
Expand Down Expand Up @@ -205,6 +207,8 @@ typedef struct session {
int root_width;
// Damage of root window.
// Damage root_damage;
int selmon_center_x;
int selmon_center_y;
/// X Composite overlay window.
xcb_window_t overlay;
/// The target window for debug mode
Expand Down Expand Up @@ -266,6 +270,12 @@ typedef struct session {
xcb_render_picture_t *alpha_picts;
/// Time of last fading. In milliseconds.
long long fade_time;
/// Time of last window animation step. In milliseconds.
long animation_time; // TODO(dccsillag) turn into `long long`, like
// fade_time
int animation_mode; // special "full screen" animations modes
int previous_desk_nr; // allows tracking of desktop changes
// should probaby be an array for each screen
/// Head pointer of the error ignore linked list.
pending_reply_t *pending_reply_head;
/// Pointer to the <code>next</code> member of tail element of the error
Expand Down
53 changes: 52 additions & 1 deletion src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,13 +708,51 @@ void set_default_winopts(options_t *opt, win_option_mask_t *mask, bool shadow_en
// opacity logic is complicated, and needs an "unset" state
opt->wintype_option[i].opacity = NAN;
}
if (!mask[i].animation) {
mask[i].animation = OPEN_WINDOW_ANIMATION_INVALID;
opt->wintype_option[i].animation = OPEN_WINDOW_ANIMATION_INVALID;
}
if (!mask[i].clip_shadow_above) {
mask[i].clip_shadow_above = true;
opt->wintype_option[i].clip_shadow_above = false;
}
}
}

enum open_window_animation parse_open_window_animation(const char *src) {
if (strcmp(src, "none") == 0) {
return OPEN_WINDOW_ANIMATION_NONE;
} else if (strcmp(src, "fly-in") == 0) {
return OPEN_WINDOW_ANIMATION_FLYIN;
} else if (strcmp(src, "zoom") == 0) {
return OPEN_WINDOW_ANIMATION_ZOOM;
} else if (strcmp(src, "slide-up") == 0) {
return OPEN_WINDOW_ANIMATION_SLIDE_UP;
} else if (strcmp(src, "slide-down") == 0) {
return OPEN_WINDOW_ANIMATION_SLIDE_DOWN;
} else if (strcmp(src, "slide-left") == 0) {
return OPEN_WINDOW_ANIMATION_SLIDE_LEFT;
} else if (strcmp(src, "slide-right") == 0) {
return OPEN_WINDOW_ANIMATION_SLIDE_RIGHT;
} else if (strcmp(src, "slide-out") == 0) {
return OPEN_WINDOW_ANIMATION_SLIDE_OUT;
} else if (strcmp(src, "slide-in") == 0) {
return OPEN_WINDOW_ANIMATION_SLIDE_IN;
} else if (strcmp(src, "slide-out-center") == 0) {
return OPEN_WINDOW_ANIMATION_SLIDE_OUT_CENTER;
} else if (strcmp(src, "slide-in-center") == 0) {
return OPEN_WINDOW_ANIMATION_SLIDE_IN_CENTER;
} else if (strcmp(src, "minimize") == 0 || strcmp(src, "maximize") == 0) {
return OPEN_WINDOW_ANIMATION_MINIMIZE;
} else if (strcmp(src, "squeeze") == 0) {
return OPEN_WINDOW_ANIMATION_SQUEEZE;
} else if (strcmp(src, "squeeze-bottom") == 0) {
return OPEN_WINDOW_ANIMATION_SQUEEZE_BOTTOM;
}

return OPEN_WINDOW_ANIMATION_INVALID;
}

char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable,
bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask) {
// clang-format off
Expand Down Expand Up @@ -759,6 +797,18 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable,
.no_fading_destroyed_argb = false,
.fade_blacklist = NULL,

.animations = false,
.animation_for_open_window = OPEN_WINDOW_ANIMATION_SLIDE_IN,
.animation_for_transient_window = OPEN_WINDOW_ANIMATION_SLIDE_DOWN,
.animation_for_unmap_window = OPEN_WINDOW_ANIMATION_SLIDE_OUT,
.animation_for_tag_change = OPEN_WINDOW_ANIMATION_NONE,
.animation_extra_desktops = 0,
.animation_stiffness = 200.0,
.animation_stiffness_tag_change = 200.0,
.animation_window_mass = 1.0,
.animation_dampening = 25,
.animation_clamping = true,

.inactive_opacity = 1.0,
.inactive_opacity_override = false,
.active_opacity = 1.0,
Expand Down Expand Up @@ -790,7 +840,8 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable,

.track_leader = false,

.rounded_corners_blacklist = NULL
.rounded_corners_blacklist = NULL,
.animation_blacklist = NULL
};
// clang-format on

Expand Down
47 changes: 47 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@ enum backend {
NUM_BKEND,
};

enum open_window_animation {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo window_animation is more suited name

OPEN_WINDOW_ANIMATION_NONE = 0,
OPEN_WINDOW_ANIMATION_FLYIN,
OPEN_WINDOW_ANIMATION_SLIDE_UP,
OPEN_WINDOW_ANIMATION_SLIDE_DOWN,
OPEN_WINDOW_ANIMATION_SLIDE_LEFT,
OPEN_WINDOW_ANIMATION_SLIDE_RIGHT,
OPEN_WINDOW_ANIMATION_SLIDE_IN,
OPEN_WINDOW_ANIMATION_SLIDE_OUT,
OPEN_WINDOW_ANIMATION_SLIDE_IN_CENTER,
OPEN_WINDOW_ANIMATION_SLIDE_OUT_CENTER,
OPEN_WINDOW_ANIMATION_ZOOM,
OPEN_WINDOW_ANIMATION_MINIMIZE,
OPEN_WINDOW_ANIMATION_SQUEEZE,
OPEN_WINDOW_ANIMATION_SQUEEZE_BOTTOM,
OPEN_WINDOW_ANIMATION_INVALID,
};

typedef struct win_option_mask {
bool shadow : 1;
bool fade : 1;
Expand All @@ -49,6 +67,7 @@ typedef struct win_option_mask {
bool redir_ignore : 1;
bool opacity : 1;
bool clip_shadow_above : 1;
enum open_window_animation animation;
} win_option_mask_t;

typedef struct win_option {
Expand All @@ -60,6 +79,7 @@ typedef struct win_option {
bool redir_ignore;
double opacity;
bool clip_shadow_above;
enum open_window_animation animation;
} win_option_t;

enum blur_method {
Expand Down Expand Up @@ -172,6 +192,32 @@ typedef struct options {
/// Fading blacklist. A linked list of conditions.
c2_lptr_t *fade_blacklist;

// === Animations ===
/// Whether to do window animations
bool animations;
/// Which animation to run when opening a window
enum open_window_animation animation_for_open_window;
/// Which animation to run when opening a transient window
enum open_window_animation animation_for_transient_window;
/// Which animation to run when unmapping a window
enum open_window_animation animation_for_unmap_window;
/// Which animation to run when swapping to new tag
enum open_window_animation animation_for_tag_change;
/// number of desktops to strip at the end of the list
int animation_extra_desktops;
/// Spring stiffness for animation
double animation_stiffness;
/// Spring stiffness for current tag animation
double animation_stiffness_tag_change;
/// Window mass for animation
double animation_window_mass;
/// Animation dampening
double animation_dampening;
/// Whether to clamp animations
bool animation_clamping;
/// Animation blacklist. A linked list of conditions.
c2_lptr_t *animation_blacklist;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

animation_exclude is more suitable


// === Opacity ===
/// Default opacity for inactive windows.
/// 32-bit integer with the format of _NET_WM_WINDOW_OPACITY.
Expand Down Expand Up @@ -271,6 +317,7 @@ bool must_use parse_rule_window_shader(c2_lptr_t **, const char *, const char *)
char *must_use locate_auxiliary_file(const char *scope, const char *path,
const char *include_dir);
enum blur_method must_use parse_blur_method(const char *src);
enum open_window_animation must_use parse_open_window_animation(const char *src);

/**
* Add a pattern to a condition linked list.
Expand Down
73 changes: 73 additions & 0 deletions src/config_libconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,16 @@ static inline void parse_wintype_config(const config_t *cfg, const char *member_
o->clip_shadow_above = ival;
mask->clip_shadow_above = true;
}
const char *sval = NULL;
if (config_setting_lookup_string(setting, "animation", &sval)) {
enum open_window_animation animation =
parse_open_window_animation(sval);
if (animation >= OPEN_WINDOW_ANIMATION_INVALID)
animation = OPEN_WINDOW_ANIMATION_NONE;

o->animation = animation;
mask->animation = animation;
}

double fval;
if (config_setting_lookup_float(setting, "opacity", &fval)) {
Expand Down Expand Up @@ -438,6 +448,15 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
lcfg_lookup_bool(&cfg, "use-ewmh-active-win", &opt->use_ewmh_active_win);
// --unredir-if-possible
lcfg_lookup_bool(&cfg, "unredir-if-possible", &opt->unredir_if_possible);
// --animation-extra-desktops
if (config_lookup_int(&cfg, "animation-extra-desktops", &ival)) {
if (ival < 0) {
log_warn("Invalid animation-extra-desktops %d", ival);
} else {
opt->animation_extra_desktops = ival;
}
}

// --unredir-if-possible-delay
if (config_lookup_int(&cfg, "unredir-if-possible-delay", &ival)) {
if (ival < 0) {
Expand Down Expand Up @@ -467,6 +486,60 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
parse_cfg_condlst(&cfg, &opt->shadow_clip_list, "clip-shadow-above");
// --fade-exclude
parse_cfg_condlst(&cfg, &opt->fade_blacklist, "fade-exclude");
// --animations
lcfg_lookup_bool(&cfg, "animations", &opt->animations);
// --animation-for-open-window
if (config_lookup_string(&cfg, "animation-for-open-window", &sval)) {
enum open_window_animation animation = parse_open_window_animation(sval);
if (animation >= OPEN_WINDOW_ANIMATION_INVALID) {
log_fatal("Invalid open-window animation %s", sval);
goto err;
}
opt->animation_for_open_window = animation;
}
// --animation-for-transient-window
if (config_lookup_string(&cfg, "animation-for-transient-window", &sval)) {
enum open_window_animation animation = parse_open_window_animation(sval);
if (animation >= OPEN_WINDOW_ANIMATION_INVALID) {
log_fatal("Invalid open-window animation %s", sval);
goto err;
}
opt->animation_for_transient_window = animation;
}
// --animation-for-unmap-window
if (config_lookup_string(&cfg, "animation-for-unmap-window", &sval)) {
enum open_window_animation animation = parse_open_window_animation(sval);
if (animation >= OPEN_WINDOW_ANIMATION_INVALID) {
log_fatal("Invalid unmap-window animation %s", sval);
goto err;
}
opt->animation_for_unmap_window = animation;
}
// --animation-for-next-tag
if (config_lookup_string(&cfg, "animation-for-tag-change", &sval)) {
enum open_window_animation animation = parse_open_window_animation(sval);
if (animation >= OPEN_WINDOW_ANIMATION_INVALID) {
log_fatal("Invalid tag-change animation %s", sval);
goto err;
}
opt->animation_for_tag_change = animation;
}
// --animations-exclude
parse_cfg_condlst(&cfg, &opt->animation_blacklist, "animation-exclude");

// --animation-stiffness
config_lookup_float(&cfg, "animation-stiffness-in-tag", &opt->animation_stiffness);
// --animation-stiffness-tag-change
config_lookup_float(&cfg, "animation-stiffness-tag-change",
&opt->animation_stiffness_tag_change);
// --animation-window-mass
config_lookup_float(&cfg, "animation-window-mass", &opt->animation_window_mass);
// --animation-dampening
config_lookup_float(&cfg, "animation-dampening", &opt->animation_dampening);
// --animation-extra-desktops
config_lookup_int(&cfg, "animation-extra-desktops", &opt->animation_extra_desktops);
// --animation-clamping
lcfg_lookup_bool(&cfg, "animation-clamping", &opt->animation_clamping);
// --focus-exclude
parse_cfg_condlst(&cfg, &opt->focus_blacklist, "focus-exclude");
// --invert-color-include
Expand Down
77 changes: 77 additions & 0 deletions src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,17 @@ static const struct picom_option picom_options[] = {
"you want to attach a debugger to picom"},
{"no-ewmh-fullscreen" , no_argument , 803, NULL , "Do not use EWMH to detect fullscreen windows. Reverts to checking if a "
"window is fullscreen based only on its size and coordinates."},
{"animations" ,no_argument , 804, NULL , "Enable/disable animations."},
{"animation-stiffness-in-tag" , required_argument, 805, NULL , "Animation speed in current tag (float)."},
{"animation-stiffness-tag-change", required_argument, 806, NULL , "Animation speed when tag changes (change to a new desktop)."},
{"animation-dampening" , required_argument, 807, NULL , "Animation dampening ratio (spring dampening as an example)."},
{"animation-window-mass" , required_argument, 808, NULL , "Animation window mass (lower mass makes animations bumpy)."},
{"animation-clamping" , no_argument , 809, NULL , "Enable/disable animation clamping. Disabling increases performance"},
{"animation-for-open-window" , required_argument, 810, NULL , "Set animation for opening window (Check sample.conf for options)."},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is sample.conf 😄

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I switched to hyprland in the meantime and quite happy with it so I'm not sure I'll spend a lot of time on this PR, I can do some tiny things but maybe not more... note that most of the code isn't from me, I just simplified some of the code and added a couple of things after fixing it for my own use case.

Looks like FTLabs made another branch which could be worth checking: https://github.com/FT-Labs/picom/tree/generalanimation

{"animation-for-transient-window", required_argument, 811, NULL , "Set animation for transient (child) windows."},
// blacklist ??
{"animation-for-tag-change", required_argument , 813, NULL , "Set animation for switching desktops."},
{"animation-extra-desktops", required_argument , 814, NULL , "N desktops will not be considered as standard desktops (useful for some window managers)."},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no command for --animation-for-unmap-window?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it's always the "mirror" animation of the "open".

};
// clang-format on

Expand Down Expand Up @@ -738,6 +749,72 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
break;
P_CASEBOOL(802, debug_mode);
P_CASEBOOL(803, no_ewmh_fullscreen);
P_CASEBOOL(804, animations);
case 805:
// --animation-stiffness
opt->animation_stiffness = atof(optarg);
break;
case 806:
// --animation-stiffness-for-tags
opt->animation_stiffness_tag_change = atof(optarg);
break;
case 807:
// --animation-dampening
opt->animation_dampening = atof(optarg);
break;
case 808:
// --animation-window-masss
opt->animation_window_mass = atof(optarg);
break;
case 809:
// --animation-clamping
opt->animation_clamping = true;
break;
case 810: {
// --animation-for-open-window
enum open_window_animation animation = parse_open_window_animation(optarg);
if (animation >= OPEN_WINDOW_ANIMATION_INVALID) {
log_warn("Invalid open-window animation %s, ignoring.", optarg);
} else {
opt->animation_for_open_window = animation;
}
break;
}
case 811: {
// --animation-for-transient-window
enum open_window_animation animation = parse_open_window_animation(optarg);
if (animation >= OPEN_WINDOW_ANIMATION_INVALID) {
log_warn("Invalid transient-window animation %s, ignoring.", optarg);
} else {
opt->animation_for_transient_window = animation;
}
break;
}
case 812: {
// --animation-exclude
condlst_add(&opt->animation_blacklist, optarg);
break;
}
case 813: {
// --animation-for-tag-change
enum open_window_animation animation = parse_open_window_animation(optarg);
if (animation >= OPEN_WINDOW_ANIMATION_INVALID) {
log_warn("Invalid tag-change animation %s, ignoring.", optarg);
} else {
if (animation == OPEN_WINDOW_ANIMATION_SLIDE_RIGHT) {
animation = OPEN_WINDOW_ANIMATION_SLIDE_LEFT;
}
if (animation == OPEN_WINDOW_ANIMATION_SLIDE_DOWN) {
animation = OPEN_WINDOW_ANIMATION_SLIDE_UP;
}
opt->animation_for_tag_change = animation;
}
break;
}
case 814: {
opt->animation_extra_desktops = atoi(optarg);
break;
}
default: usage(argv[0], 1); break;
#undef P_CASEBOOL
}
Expand Down
Loading