Skip to content

Commit

Permalink
Added Desktop Switch Triggers for different animations
Browse files Browse the repository at this point in the history
This adds support for desktop switching animations by keeping track of _NET_CURRENT_DESKTOP atom on the root window. 

As far as I understand this atom is set by window managers and so if it changes we can know that it's a desktop switch happening. Unfortunately window manager may need to set this BEFORE hiding/showing windows so we can animate correctly, me personally using FluxBox and this quick change pijulius/fluxbox@83ee4db  makes it work just fine.

It adds the following animation triggers:
* workspace-out
* workspace-out-inverse
* workspace-in
* workspace-in-inverse

Unfortunately had to add inverse variables too as you may navigate to the next workspace from for e.g. 1st to 2nd but you may also go to 2nd from 1st and in that case the animations have to be totally different.

Here is a config example for switching workspace:

animations = ({
    triggers = ["workspace-out"];
    offset-y = {
        timing = "0.2s cubic-bezier(0.21, 0.02, 0.76, 0.36)";
        start = "0";
        end = "-window-height";
    };
    shadow-offset-y = "offset-y";
    opacity = {
        timing = "0.2s linear";
        start = "window-raw-opacity-before";
        end = "window-raw-opacity";
    };
    blur-opacity = "opacity";
    shadow-opacity = "opacity";
},
{
    triggers = ["workspace-out-inverse"];
    offset-y = {
        timing = "0.2s cubic-bezier(0.21, 0.02, 0.76, 0.36)";
        start = "0";
        end = "window-height + window-y";
    };
    shadow-offset-y = "offset-y";
    opacity = {
        timing = "0.2s linear";
        start = "window-raw-opacity-before";
        end = "window-raw-opacity";
    };
    blur-opacity = "opacity";
    shadow-opacity = "opacity";
},
{
    triggers = ["workspace-in"];
    offset-y = {
        timing = "0.2s cubic-bezier(0.24, 0.64, 0.79, 0.98)";
        start = "window-height + window-y";
        end = "0";
    };
    shadow-offset-y = "offset-y";
    opacity = {
        timing = "0.2s linear";
        start = "0";
        end = "window-raw-opacity";
    };
    blur-opacity = "opacity";
    shadow-opacity = "opacity";
},
{
    triggers = ["workspace-in-inverse"];
    offset-y = {
        timing = "0.2s cubic-bezier(0.24, 0.64, 0.79, 0.98)";
        start = "-window-height";
        end = "0";
    };
    shadow-offset-y = "offset-y";
    opacity = {
        timing = "0.2s linear";
        start = "0";
        end = "window-raw-opacity";
    };
    blur-opacity = "opacity";
    shadow-opacity = "opacity";
})
  • Loading branch information
pijulius authored May 18, 2024
1 parent 2899c78 commit df6ccb5
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/atom.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
_NET_WM_WINDOW_TYPE, \
_XROOTPMAP_ID, \
ESETROOT_PMAP_ID, \
_XSETROOT_ID
_XSETROOT_ID, \
_NET_CURRENT_DESKTOP

#define ATOM_LIST2 \
_NET_WM_WINDOW_TYPE_DESKTOP, \
Expand Down
4 changes: 4 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ typedef struct session {
int root_width;
/// Height of root window.
int root_height;
/// Current desktop number of root window
int root_desktop_num;
/// Desktop switch direction
int root_desktop_switch_direction;
/// X Composite overlay window.
xcb_window_t overlay;
/// The target window for debug mode
Expand Down
10 changes: 9 additions & 1 deletion src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,11 @@ enum animation_trigger {
ANIMATION_TRIGGER_OPEN,
/// When a window is closed
ANIMATION_TRIGGER_CLOSE,
ANIMATION_TRIGGER_LAST = ANIMATION_TRIGGER_CLOSE,
ANIMATION_TRIGGER_WORKSPACE_IN,
ANIMATION_TRIGGER_WORKSPACE_IN_INVERSE,
ANIMATION_TRIGGER_WORKSPACE_OUT,
ANIMATION_TRIGGER_WORKSPACE_OUT_INVERSE,
ANIMATION_TRIGGER_LAST = ANIMATION_TRIGGER_WORKSPACE_OUT_INVERSE,
};

static const char *animation_trigger_names[] attr_unused = {
Expand All @@ -105,6 +109,10 @@ static const char *animation_trigger_names[] attr_unused = {
[ANIMATION_TRIGGER_DECREASE_OPACITY] = "decrease-opacity",
[ANIMATION_TRIGGER_OPEN] = "open",
[ANIMATION_TRIGGER_CLOSE] = "close",
[ANIMATION_TRIGGER_WORKSPACE_IN] = "workspace-in",
[ANIMATION_TRIGGER_WORKSPACE_IN_INVERSE] = "workspace-in-inverse",
[ANIMATION_TRIGGER_WORKSPACE_OUT] = "workspace-out",
[ANIMATION_TRIGGER_WORKSPACE_OUT_INVERSE] = "workspace-out-inverse",
};

struct script;
Expand Down
11 changes: 11 additions & 0 deletions src/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,17 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
}

if (ps->c.screen_info->root == ev->window) {
// If desktop number property changes
if (ev->atom == ps->atoms->a_NET_CURRENT_DESKTOP) {
auto prop = x_get_prop(&ps->c, ps->c.screen_info->root, ps->atoms->a_NET_CURRENT_DESKTOP,
1L, XCB_ATOM_CARDINAL, 32);

if (prop.nitems) {
ps->root_desktop_switch_direction = ((int)*prop.c32) - ps->root_desktop_num;
ps->root_desktop_num = (int)*prop.c32;
}
}

if (ps->o.use_ewmh_active_win && ps->atoms->a_NET_ACTIVE_WINDOW == ev->atom) {
// to update focus
ps->pending_updates = true;
Expand Down
13 changes: 13 additions & 0 deletions src/picom.c
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,9 @@ static void draw_callback_impl(EV_P_ session_t *ps, int revents attr_unused) {
ps->next_render = 0;
ps->render_queued = false;

// Reset workspace switching so correct animations are used afterward
ps->root_desktop_switch_direction = 0;

// TODO(yshui) Investigate how big the X critical section needs to be. There are
// suggestions that rendering should be in the critical section as well.

Expand Down Expand Up @@ -2281,6 +2284,16 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
goto err;
}

// Initiate current workspace num so we correctly animate if picom
// started/restarted on different desktop number than 0
auto prop = x_get_prop(&ps->c, ps->c.screen_info->root, ps->atoms->a_NET_CURRENT_DESKTOP,
1L, XCB_ATOM_CARDINAL, 32);

ps->root_desktop_switch_direction = 0;
if (prop.nitems) {
ps->root_desktop_num = (int)*prop.c32;
}

rebuild_screen_reg(ps);

bool compositor_running = false;
Expand Down
18 changes: 18 additions & 0 deletions src/win.c
Original file line number Diff line number Diff line change
Expand Up @@ -2309,6 +2309,15 @@ void win_process_animation_and_state_change(struct session *ps, struct managed_w
case WSTATE_PAIR(WSTATE_UNMAPPED, WSTATE_MAPPED):
trigger = w->in_openclose ? ANIMATION_TRIGGER_OPEN
: ANIMATION_TRIGGER_SHOW;

if (ps->root_desktop_switch_direction != 0) {
trigger =
(ps->root_desktop_switch_direction < 0 &&
ps->root_desktop_switch_direction >= -1) ||
ps->root_desktop_switch_direction > 1 ?
ANIMATION_TRIGGER_WORKSPACE_IN_INVERSE :
ANIMATION_TRIGGER_WORKSPACE_IN;
}
break;
case WSTATE_PAIR(WSTATE_UNMAPPED, WSTATE_DESTROYED):
if ((!ps->o.no_fading_destroyed_argb || !win_has_alpha(w)) &&
Expand All @@ -2326,6 +2335,15 @@ void win_process_animation_and_state_change(struct session *ps, struct managed_w
break;
case WSTATE_PAIR(WSTATE_MAPPED, WSTATE_UNMAPPED):
trigger = ANIMATION_TRIGGER_HIDE;

if (ps->root_desktop_switch_direction != 0) {
trigger =
(ps->root_desktop_switch_direction < 0 &&
ps->root_desktop_switch_direction >= -1) ||
ps->root_desktop_switch_direction > 1 ?
ANIMATION_TRIGGER_WORKSPACE_OUT_INVERSE :
ANIMATION_TRIGGER_WORKSPACE_OUT;
}
break;
default:
log_error("Impossible state transition from %d to %d", old_state,
Expand Down

0 comments on commit df6ccb5

Please sign in to comment.