mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-10-31 22:25:29 -04:00
Merge pull request #135 from DreamMaoMao/test_layer
feat: suuport layershell animaiton
This commit is contained in:
commit
19fbe41d54
3 changed files with 461 additions and 19 deletions
|
|
@ -126,10 +126,12 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *layer_name; // 布局名称
|
char *layer_name; // 布局名称
|
||||||
int noblur;
|
int noblur;
|
||||||
|
int noanim;
|
||||||
} ConfigLayerRule;
|
} ConfigLayerRule;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int animations;
|
int animations;
|
||||||
|
int layer_animations;
|
||||||
char animation_type_open[10];
|
char animation_type_open[10];
|
||||||
char animation_type_close[10];
|
char animation_type_close[10];
|
||||||
int animation_fade_in;
|
int animation_fade_in;
|
||||||
|
|
@ -832,6 +834,8 @@ void parse_config_line(Config *config, const char *line) {
|
||||||
|
|
||||||
if (strcmp(key, "animations") == 0) {
|
if (strcmp(key, "animations") == 0) {
|
||||||
config->animations = atoi(value);
|
config->animations = atoi(value);
|
||||||
|
} else if (strcmp(key, "layer_animations") == 0) {
|
||||||
|
config->layer_animations = atoi(value);
|
||||||
} else if (strcmp(key, "animation_type_open") == 0) {
|
} else if (strcmp(key, "animation_type_open") == 0) {
|
||||||
snprintf(config->animation_type_open,
|
snprintf(config->animation_type_open,
|
||||||
sizeof(config->animation_type_open), "%.9s",
|
sizeof(config->animation_type_open), "%.9s",
|
||||||
|
|
@ -1298,6 +1302,7 @@ void parse_config_line(Config *config, const char *line) {
|
||||||
// 设置默认值
|
// 设置默认值
|
||||||
rule->layer_name = NULL;
|
rule->layer_name = NULL;
|
||||||
rule->noblur = 0;
|
rule->noblur = 0;
|
||||||
|
rule->noanim = 0;
|
||||||
|
|
||||||
char *token = strtok(value, ",");
|
char *token = strtok(value, ",");
|
||||||
while (token != NULL) {
|
while (token != NULL) {
|
||||||
|
|
@ -1314,6 +1319,8 @@ void parse_config_line(Config *config, const char *line) {
|
||||||
rule->layer_name = strdup(val);
|
rule->layer_name = strdup(val);
|
||||||
} else if (strcmp(key, "noblur") == 0) {
|
} else if (strcmp(key, "noblur") == 0) {
|
||||||
rule->noblur = CLAMP_INT(atoi(val), 0, 1);
|
rule->noblur = CLAMP_INT(atoi(val), 0, 1);
|
||||||
|
} else if (strcmp(key, "noanim") == 0) {
|
||||||
|
rule->noanim = CLAMP_INT(atoi(val), 0, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
token = strtok(NULL, ",");
|
token = strtok(NULL, ",");
|
||||||
|
|
@ -2060,6 +2067,7 @@ void free_config(void) {
|
||||||
void override_config(void) {
|
void override_config(void) {
|
||||||
// 动画启用
|
// 动画启用
|
||||||
animations = CLAMP_INT(config.animations, 0, 1);
|
animations = CLAMP_INT(config.animations, 0, 1);
|
||||||
|
layer_animations = CLAMP_INT(config.layer_animations, 0, 1);
|
||||||
|
|
||||||
// 标签动画方向
|
// 标签动画方向
|
||||||
tag_animation_direction = CLAMP_INT(config.tag_animation_direction, 0, 1);
|
tag_animation_direction = CLAMP_INT(config.tag_animation_direction, 0, 1);
|
||||||
|
|
@ -2202,6 +2210,7 @@ void override_config(void) {
|
||||||
void set_value_default() {
|
void set_value_default() {
|
||||||
/* animaion */
|
/* animaion */
|
||||||
config.animations = animations; // 是否启用动画
|
config.animations = animations; // 是否启用动画
|
||||||
|
config.layer_animations = layer_animations; // 是否启用layer动画
|
||||||
config.animation_fade_in = animation_fade_in; // Enable animation fade in
|
config.animation_fade_in = animation_fade_in; // Enable animation fade in
|
||||||
config.animation_fade_out = animation_fade_out; // Enable animation fade out
|
config.animation_fade_out = animation_fade_out; // Enable animation fade out
|
||||||
config.tag_animation_direction = tag_animation_direction; // 标签动画方向
|
config.tag_animation_direction = tag_animation_direction; // 标签动画方向
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
char *animation_type_open = "slide"; // 是否启用动画 //slide,zoom
|
char *animation_type_open = "slide"; // 是否启用动画 //slide,zoom
|
||||||
char *animation_type_close = "slide"; // 是否启用动画 //slide,zoom
|
char *animation_type_close = "slide"; // 是否启用动画 //slide,zoom
|
||||||
int animations = 1; // 是否启用动画
|
int animations = 1; // 是否启用动画
|
||||||
|
int layer_animations = 1; // 是否启用layer动画
|
||||||
int tag_animation_direction = HORIZONTAL; // 标签动画方向
|
int tag_animation_direction = HORIZONTAL; // 标签动画方向
|
||||||
int animation_fade_in = 1; // Enable animation fade in
|
int animation_fade_in = 1; // Enable animation fade in
|
||||||
int animation_fade_out = 1; // Enable animation fade out
|
int animation_fade_out = 1; // Enable animation fade out
|
||||||
|
|
|
||||||
470
src/maomao.c
470
src/maomao.c
|
|
@ -344,12 +344,13 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Must keep these three elements in this order */
|
/* Must keep these three elements in this order */
|
||||||
unsigned int type; /* LayerShell */
|
unsigned int type; /* LayerShell */
|
||||||
struct wlr_box geom;
|
struct wlr_box geom, current, pending, animainit_geom;
|
||||||
Monitor *mon;
|
Monitor *mon;
|
||||||
struct wlr_scene_tree *scene;
|
struct wlr_scene_tree *scene;
|
||||||
struct wlr_scene_tree *popups;
|
struct wlr_scene_tree *popups;
|
||||||
struct wlr_scene_layer_surface_v1 *scene_layer;
|
struct wlr_scene_layer_surface_v1 *scene_layer;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
struct wl_list fadeout_link;
|
||||||
int mapped;
|
int mapped;
|
||||||
struct wlr_layer_surface_v1 *layer_surface;
|
struct wlr_layer_surface_v1 *layer_surface;
|
||||||
|
|
||||||
|
|
@ -357,6 +358,12 @@ typedef struct {
|
||||||
struct wl_listener map;
|
struct wl_listener map;
|
||||||
struct wl_listener unmap;
|
struct wl_listener unmap;
|
||||||
struct wl_listener surface_commit;
|
struct wl_listener surface_commit;
|
||||||
|
|
||||||
|
struct dwl_animation animation;
|
||||||
|
bool dirty;
|
||||||
|
int noblur;
|
||||||
|
int noanim;
|
||||||
|
bool need_output_flush;
|
||||||
} LayerSurface;
|
} LayerSurface;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -603,6 +610,7 @@ static struct wlr_box setclient_coordinate_center(Client *c,
|
||||||
static unsigned int get_tags_first_tag(unsigned int tags);
|
static unsigned int get_tags_first_tag(unsigned int tags);
|
||||||
|
|
||||||
static void client_commit(Client *c);
|
static void client_commit(Client *c);
|
||||||
|
static void layer_commit(LayerSurface *l);
|
||||||
static void apply_border(Client *c);
|
static void apply_border(Client *c);
|
||||||
static void client_set_opacity(Client *c, double opacity);
|
static void client_set_opacity(Client *c, double opacity);
|
||||||
static void init_baked_points(void);
|
static void init_baked_points(void);
|
||||||
|
|
@ -616,6 +624,7 @@ static void buffer_set_effect(Client *c, animationScale scale_data);
|
||||||
static void snap_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer,
|
static void snap_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer,
|
||||||
int sx, int sy, void *data);
|
int sx, int sy, void *data);
|
||||||
static void client_set_pending_state(Client *c);
|
static void client_set_pending_state(Client *c);
|
||||||
|
static void layer_set_pending_state(LayerSurface *l);
|
||||||
static void set_rect_size(struct wlr_scene_rect *rect, int width, int height);
|
static void set_rect_size(struct wlr_scene_rect *rect, int width, int height);
|
||||||
static Client *center_select(Monitor *m);
|
static Client *center_select(Monitor *m);
|
||||||
static void handlecursoractivity(void);
|
static void handlecursoractivity(void);
|
||||||
|
|
@ -624,6 +633,8 @@ static bool check_hit_no_border(Client *c);
|
||||||
static void reset_keyboard_layout(void);
|
static void reset_keyboard_layout(void);
|
||||||
static void client_update_oldmonname_record(Client *c, Monitor *m);
|
static void client_update_oldmonname_record(Client *c, Monitor *m);
|
||||||
static void pending_kill_client(Client *c);
|
static void pending_kill_client(Client *c);
|
||||||
|
static void set_layer_open_animaiton(LayerSurface *l, struct wlr_box geo);
|
||||||
|
static void init_fadeout_layers(LayerSurface *l);
|
||||||
|
|
||||||
#include "data/static_keymap.h"
|
#include "data/static_keymap.h"
|
||||||
#include "dispatch/dispatch.h"
|
#include "dispatch/dispatch.h"
|
||||||
|
|
@ -652,6 +663,7 @@ static struct wlr_xdg_decoration_manager_v1 *xdg_decoration_mgr;
|
||||||
static struct wl_list clients; /* tiling order */
|
static struct wl_list clients; /* tiling order */
|
||||||
static struct wl_list fstack; /* focus order */
|
static struct wl_list fstack; /* focus order */
|
||||||
static struct wl_list fadeout_clients;
|
static struct wl_list fadeout_clients;
|
||||||
|
static struct wl_list fadeout_layers;
|
||||||
static struct wlr_idle_notifier_v1 *idle_notifier;
|
static struct wlr_idle_notifier_v1 *idle_notifier;
|
||||||
static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr;
|
static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr;
|
||||||
static struct wlr_layer_shell_v1 *layer_shell;
|
static struct wlr_layer_shell_v1 *layer_shell;
|
||||||
|
|
@ -875,6 +887,51 @@ void apply_opacity_to_rect_nodes(Client *c, struct wlr_scene_node *node,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fadeout_layer_animation_next_tick(LayerSurface *l) {
|
||||||
|
if (!l)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double animation_passed =
|
||||||
|
(double)l->animation.passed_frames / l->animation.total_frames;
|
||||||
|
int type = l->animation.action = l->animation.action;
|
||||||
|
double factor = find_animation_curve_at(animation_passed, type);
|
||||||
|
unsigned int width =
|
||||||
|
l->animation.initial.width +
|
||||||
|
(l->current.width - l->animation.initial.width) * factor;
|
||||||
|
unsigned int height =
|
||||||
|
l->animation.initial.height +
|
||||||
|
(l->current.height - l->animation.initial.height) * factor;
|
||||||
|
|
||||||
|
unsigned int x = l->animation.initial.x +
|
||||||
|
(l->current.x - l->animation.initial.x) * factor;
|
||||||
|
unsigned int y = l->animation.initial.y +
|
||||||
|
(l->current.y - l->animation.initial.y) * factor;
|
||||||
|
|
||||||
|
wlr_scene_node_set_position(&l->scene->node, x, y);
|
||||||
|
|
||||||
|
l->animation.current = (struct wlr_box){
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
};
|
||||||
|
|
||||||
|
double opacity = MAX(fadeout_begin_opacity - animation_passed, 0);
|
||||||
|
|
||||||
|
if (animation_fade_out)
|
||||||
|
wlr_scene_node_for_each_buffer(&l->scene->node,
|
||||||
|
scene_buffer_apply_opacity, &opacity);
|
||||||
|
|
||||||
|
if (animation_passed == 1.0) {
|
||||||
|
wl_list_remove(&l->fadeout_link);
|
||||||
|
wlr_scene_node_destroy(&l->scene->node);
|
||||||
|
free(l);
|
||||||
|
l = NULL;
|
||||||
|
} else {
|
||||||
|
l->animation.passed_frames++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void fadeout_client_animation_next_tick(Client *c) {
|
void fadeout_client_animation_next_tick(Client *c) {
|
||||||
if (!c)
|
if (!c)
|
||||||
return;
|
return;
|
||||||
|
|
@ -938,6 +995,47 @@ void fadeout_client_animation_next_tick(Client *c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void layer_animation_next_tick(LayerSurface *l) {
|
||||||
|
|
||||||
|
if (!l || !l->mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double animation_passed =
|
||||||
|
(double)l->animation.passed_frames / l->animation.total_frames;
|
||||||
|
|
||||||
|
int type = l->animation.action == NONE ? MOVE : l->animation.action;
|
||||||
|
double factor = find_animation_curve_at(animation_passed, type);
|
||||||
|
|
||||||
|
unsigned int width =
|
||||||
|
l->animation.initial.width +
|
||||||
|
(l->current.width - l->animation.initial.width) * factor;
|
||||||
|
unsigned int height =
|
||||||
|
l->animation.initial.height +
|
||||||
|
(l->current.height - l->animation.initial.height) * factor;
|
||||||
|
|
||||||
|
unsigned int x = l->animation.initial.x +
|
||||||
|
(l->current.x - l->animation.initial.x) * factor;
|
||||||
|
unsigned int y = l->animation.initial.y +
|
||||||
|
(l->current.y - l->animation.initial.y) * factor;
|
||||||
|
|
||||||
|
wlr_scene_node_set_position(&l->scene->node, x, y);
|
||||||
|
|
||||||
|
l->animation.current = (struct wlr_box){
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (animation_passed == 1.0) {
|
||||||
|
l->animation.running = false;
|
||||||
|
l->need_output_flush = false;
|
||||||
|
l->animation.action = MOVE;
|
||||||
|
} else {
|
||||||
|
l->animation.passed_frames++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void client_animation_next_tick(Client *c) {
|
void client_animation_next_tick(Client *c) {
|
||||||
double animation_passed =
|
double animation_passed =
|
||||||
(double)c->animation.passed_frames / c->animation.total_frames;
|
(double)c->animation.passed_frames / c->animation.total_frames;
|
||||||
|
|
@ -1373,6 +1471,30 @@ void client_apply_clip(Client *c) {
|
||||||
buffer_set_effect(c, scale_data);
|
buffer_set_effect(c, scale_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool layer_draw_frame(LayerSurface *l) {
|
||||||
|
|
||||||
|
if (!l || !l->mapped)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!l->need_output_flush)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (l->layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_TOP &&
|
||||||
|
l->layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animations && layer_animations && l->animation.running && !l->noanim) {
|
||||||
|
layer_animation_next_tick(l);
|
||||||
|
} else {
|
||||||
|
wlr_scene_node_set_position(&l->scene->node, l->geom.x, l->geom.y);
|
||||||
|
l->animainit_geom = l->animation.initial = l->pending = l->current =
|
||||||
|
l->geom;
|
||||||
|
l->need_output_flush = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool client_draw_frame(Client *c) {
|
bool client_draw_frame(Client *c) {
|
||||||
|
|
||||||
if (!c || !client_surface(c)->mapped)
|
if (!c || !client_surface(c)->mapped)
|
||||||
|
|
@ -1411,6 +1533,14 @@ bool client_draw_fadeout_frame(Client *c) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool layer_draw_fadeout_frame(LayerSurface *l) {
|
||||||
|
if (!l)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
fadeout_layer_animation_next_tick(l);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void applybounds(Client *c, struct wlr_box *bbox) {
|
void applybounds(Client *c, struct wlr_box *bbox) {
|
||||||
/* set minimum possible */
|
/* set minimum possible */
|
||||||
c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width);
|
c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width);
|
||||||
|
|
@ -3049,8 +3179,91 @@ static void iter_layer_scene_buffers(struct wlr_scene_buffer *buffer, int sx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_layer_target_geometry(LayerSurface *l, struct wlr_box *target_box) {
|
||||||
|
|
||||||
|
if (!l || !l->mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const struct wlr_layer_surface_v1_state *state = &l->layer_surface->current;
|
||||||
|
|
||||||
|
// 限制区域
|
||||||
|
// waybar一般都是大于0,表示要占用多少区域,所以计算位置也要用全部区域作为基准
|
||||||
|
// 如果是-1可能表示独占所有可用空间
|
||||||
|
// 如果是0,应该是表示使用exclusive_zone外的可用区域
|
||||||
|
struct wlr_box bounds;
|
||||||
|
if (state->exclusive_zone > 0 || state->exclusive_zone == -1)
|
||||||
|
bounds = l->mon->m;
|
||||||
|
else
|
||||||
|
bounds = l->mon->w;
|
||||||
|
|
||||||
|
// 初始化几何位置
|
||||||
|
struct wlr_box box = {.width = state->desired_width,
|
||||||
|
.height = state->desired_height};
|
||||||
|
|
||||||
|
// 水平方向定位
|
||||||
|
const uint32_t both_horiz =
|
||||||
|
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||||
|
if (box.width == 0) {
|
||||||
|
box.x = bounds.x;
|
||||||
|
} else if ((state->anchor & both_horiz) == both_horiz) {
|
||||||
|
box.x = bounds.x + ((bounds.width - box.width) / 2);
|
||||||
|
} else if (state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) {
|
||||||
|
box.x = bounds.x;
|
||||||
|
} else if (state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) {
|
||||||
|
box.x = bounds.x + (bounds.width - box.width);
|
||||||
|
} else {
|
||||||
|
box.x = bounds.x + ((bounds.width - box.width) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 垂直方向定位
|
||||||
|
const uint32_t both_vert =
|
||||||
|
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||||
|
if (box.height == 0) {
|
||||||
|
box.y = bounds.y;
|
||||||
|
} else if ((state->anchor & both_vert) == both_vert) {
|
||||||
|
box.y = bounds.y + ((bounds.height - box.height) / 2);
|
||||||
|
} else if (state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) {
|
||||||
|
box.y = bounds.y;
|
||||||
|
} else if (state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM) {
|
||||||
|
box.y = bounds.y + (bounds.height - box.height);
|
||||||
|
} else {
|
||||||
|
box.y = bounds.y + ((bounds.height - box.height) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 应用边距
|
||||||
|
if (box.width == 0) {
|
||||||
|
box.x += state->margin.left;
|
||||||
|
box.width = bounds.width - (state->margin.left + state->margin.right);
|
||||||
|
} else if (!(state->anchor & both_horiz)) {
|
||||||
|
if (state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) {
|
||||||
|
box.x += state->margin.left;
|
||||||
|
} else if (state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) {
|
||||||
|
box.x -= state->margin.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (box.height == 0) {
|
||||||
|
box.y += state->margin.top;
|
||||||
|
box.height = bounds.height - (state->margin.top + state->margin.bottom);
|
||||||
|
} else if (!(state->anchor & both_vert)) {
|
||||||
|
if (state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) {
|
||||||
|
box.y += state->margin.top;
|
||||||
|
} else if (state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM) {
|
||||||
|
box.y -= state->margin.bottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target_box->x = box.x;
|
||||||
|
target_box->y = box.y;
|
||||||
|
target_box->width = box.width;
|
||||||
|
target_box->height = box.height;
|
||||||
|
}
|
||||||
|
|
||||||
void maplayersurfacenotify(struct wl_listener *listener, void *data) {
|
void maplayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
|
int ji;
|
||||||
LayerSurface *l = wl_container_of(listener, l, map);
|
LayerSurface *l = wl_container_of(listener, l, map);
|
||||||
|
l->mapped = 1;
|
||||||
|
|
||||||
if (!l->mon)
|
if (!l->mon)
|
||||||
return;
|
return;
|
||||||
struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
|
struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
|
||||||
|
|
@ -3058,7 +3271,38 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
sizeof(l->mon->last_surface_ws_name) - 1); // 最多拷贝255个字符
|
sizeof(l->mon->last_surface_ws_name) - 1); // 最多拷贝255个字符
|
||||||
l->mon->last_surface_ws_name[sizeof(l->mon->last_surface_ws_name) - 1] =
|
l->mon->last_surface_ws_name[sizeof(l->mon->last_surface_ws_name) - 1] =
|
||||||
'\0'; // 确保字符串以null结尾
|
'\0'; // 确保字符串以null结尾
|
||||||
|
|
||||||
|
struct wlr_box box;
|
||||||
|
get_layer_target_geometry(l, &box);
|
||||||
|
|
||||||
|
// 更新几何位置
|
||||||
|
l->geom = box;
|
||||||
|
l->noanim = 0;
|
||||||
|
l->dirty = false;
|
||||||
|
l->noblur = 0;
|
||||||
|
|
||||||
|
// 应用layer规则
|
||||||
|
for (ji = 0; ji < config.layer_rules_count; ji++) {
|
||||||
|
if (config.layer_rules_count < 1)
|
||||||
|
break;
|
||||||
|
if (strcmp(config.layer_rules[ji].layer_name,
|
||||||
|
l->layer_surface->namespace) == 0) {
|
||||||
|
if (config.layer_rules[ji].noblur > 0) {
|
||||||
|
l->noblur = 1;
|
||||||
|
}
|
||||||
|
if (config.layer_rules[ji].noanim > 0) {
|
||||||
|
l->noanim = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l->need_output_flush = true;
|
||||||
|
l->animation.action = OPEN;
|
||||||
|
layer_set_pending_state(l);
|
||||||
|
// 刷新布局,让窗口能感应到exclude_zone变化
|
||||||
|
arrangelayers(l->mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
LayerSurface *l = wl_container_of(listener, l, surface_commit);
|
LayerSurface *l = wl_container_of(listener, l, surface_commit);
|
||||||
struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
|
struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
|
||||||
|
|
@ -3066,8 +3310,7 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
layers[layermap[layer_surface->current.layer]];
|
layers[layermap[layer_surface->current.layer]];
|
||||||
struct wlr_layer_surface_v1_state old_state;
|
struct wlr_layer_surface_v1_state old_state;
|
||||||
struct wlr_layer_surface_v1 *wlr_layer_surface = l->layer_surface;
|
struct wlr_layer_surface_v1 *wlr_layer_surface = l->layer_surface;
|
||||||
int ji;
|
struct wlr_box box;
|
||||||
bool exclude_blur = false;
|
|
||||||
|
|
||||||
if (l->layer_surface->initial_commit) {
|
if (l->layer_surface->initial_commit) {
|
||||||
client_set_scale(layer_surface->surface, l->mon->wlr_output->scale);
|
client_set_scale(layer_surface->surface, l->mon->wlr_output->scale);
|
||||||
|
|
@ -3078,23 +3321,31 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
l->layer_surface->current = l->layer_surface->pending;
|
l->layer_surface->current = l->layer_surface->pending;
|
||||||
arrangelayers(l->mon);
|
arrangelayers(l->mon);
|
||||||
l->layer_surface->current = old_state;
|
l->layer_surface->current = old_state;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_layer_target_geometry(l, &box);
|
||||||
|
|
||||||
|
if (l->mapped &&
|
||||||
|
wlr_layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM &&
|
||||||
|
wlr_layer_surface->current.layer !=
|
||||||
|
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND &&
|
||||||
|
!wlr_box_equal(&box, &l->geom)) {
|
||||||
|
|
||||||
|
l->geom = box;
|
||||||
|
l->animation.action = MOVE;
|
||||||
|
l->need_output_flush = true;
|
||||||
|
layer_set_pending_state(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wlr_scene_node_set_position(&l->scene->node, 10, 10);
|
||||||
|
// wlr_output_schedule_frame(l->mon->wlr_output);
|
||||||
|
|
||||||
if (blur && blur_layer) {
|
if (blur && blur_layer) {
|
||||||
// 设置非背景layer模糊
|
// 设置非背景layer模糊
|
||||||
for (ji = 0; ji < config.layer_rules_count; ji++) {
|
|
||||||
if (config.layer_rules_count < 1)
|
|
||||||
break;
|
|
||||||
if (strcmp(config.layer_rules[ji].layer_name,
|
|
||||||
l->layer_surface->namespace) == 0 &&
|
|
||||||
config.layer_rules[ji].noblur) {
|
|
||||||
exclude_blur = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!exclude_blur &&
|
if (!l->noblur &&
|
||||||
wlr_layer_surface->current.layer !=
|
wlr_layer_surface->current.layer !=
|
||||||
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM &&
|
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM &&
|
||||||
wlr_layer_surface->current.layer !=
|
wlr_layer_surface->current.layer !=
|
||||||
|
|
@ -3139,6 +3390,33 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
arrangelayers(l->mon);
|
arrangelayers(l->mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void layer_set_pending_state(LayerSurface *l) {
|
||||||
|
|
||||||
|
if (!l || !l->mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
l->pending = l->geom;
|
||||||
|
if (l->animation.action == OPEN)
|
||||||
|
set_layer_open_animaiton(l, l->geom);
|
||||||
|
else
|
||||||
|
l->animainit_geom = l->animation.current;
|
||||||
|
// 判断是否需要动画
|
||||||
|
if (!animations || !layer_animations || l->noanim ||
|
||||||
|
l->layer_surface->current.layer ==
|
||||||
|
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND ||
|
||||||
|
l->layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) {
|
||||||
|
l->animation.should_animate = false;
|
||||||
|
} else {
|
||||||
|
l->animation.should_animate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
l->animation.duration = animation_duration_open;
|
||||||
|
l->animation.action = OPEN;
|
||||||
|
// 开始动画
|
||||||
|
layer_commit(l);
|
||||||
|
l->dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
void client_set_pending_state(Client *c) {
|
void client_set_pending_state(Client *c) {
|
||||||
|
|
||||||
// 判断是否需要动画
|
// 判断是否需要动画
|
||||||
|
|
@ -3159,7 +3437,7 @@ void client_set_pending_state(Client *c) {
|
||||||
c->dirty = true;
|
c->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double output_frame_duration_ms(Client *c) {
|
double output_frame_duration_ms() {
|
||||||
int32_t refresh_total = 0;
|
int32_t refresh_total = 0;
|
||||||
Monitor *m;
|
Monitor *m;
|
||||||
wl_list_for_each(m, &mons, link) {
|
wl_list_for_each(m, &mons, link) {
|
||||||
|
|
@ -3171,6 +3449,32 @@ double output_frame_duration_ms(Client *c) {
|
||||||
return 1000000.0 / refresh_total;
|
return 1000000.0 / refresh_total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void layer_commit(LayerSurface *l) {
|
||||||
|
|
||||||
|
if (!l || !l->mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
l->current = l->pending; // 设置动画的结束位置
|
||||||
|
|
||||||
|
if (l->animation.should_animate) {
|
||||||
|
if (!l->animation.running) {
|
||||||
|
l->animation.current = l->animainit_geom;
|
||||||
|
}
|
||||||
|
|
||||||
|
l->animation.initial = l->animainit_geom;
|
||||||
|
// 设置动画速度
|
||||||
|
l->animation.passed_frames = 0;
|
||||||
|
l->animation.total_frames =
|
||||||
|
l->animation.duration / output_frame_duration_ms();
|
||||||
|
|
||||||
|
// 标记动画开始
|
||||||
|
l->animation.running = true;
|
||||||
|
l->animation.should_animate = false;
|
||||||
|
}
|
||||||
|
// 请求刷新屏幕
|
||||||
|
wlr_output_schedule_frame(l->mon->wlr_output);
|
||||||
|
}
|
||||||
|
|
||||||
void client_commit(Client *c) {
|
void client_commit(Client *c) {
|
||||||
c->current = c->pending; // 设置动画的结束位置
|
c->current = c->pending; // 设置动画的结束位置
|
||||||
|
|
||||||
|
|
@ -3183,7 +3487,7 @@ void client_commit(Client *c) {
|
||||||
// 设置动画速度
|
// 设置动画速度
|
||||||
c->animation.passed_frames = 0;
|
c->animation.passed_frames = 0;
|
||||||
c->animation.total_frames =
|
c->animation.total_frames =
|
||||||
c->animation.duration / output_frame_duration_ms(c);
|
c->animation.duration / output_frame_duration_ms();
|
||||||
|
|
||||||
// 标记动画开始
|
// 标记动画开始
|
||||||
c->animation.running = true;
|
c->animation.running = true;
|
||||||
|
|
@ -5170,10 +5474,21 @@ void rendermon(struct wl_listener *listener, void *data) {
|
||||||
Monitor *m = wl_container_of(listener, m, frame);
|
Monitor *m = wl_container_of(listener, m, frame);
|
||||||
Client *c, *tmp;
|
Client *c, *tmp;
|
||||||
struct wlr_output_state pending = {0};
|
struct wlr_output_state pending = {0};
|
||||||
|
LayerSurface *l, *tmpl;
|
||||||
|
int i;
|
||||||
|
struct wl_list *layer_list;
|
||||||
|
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
bool need_more_frames = false;
|
bool need_more_frames = false;
|
||||||
|
|
||||||
|
for (i = 0; i < LENGTH(m->layers); i++) {
|
||||||
|
layer_list = &m->layers[i];
|
||||||
|
// Draw frames for all layer
|
||||||
|
wl_list_for_each_safe(l, tmpl, layer_list, link) {
|
||||||
|
need_more_frames = layer_draw_frame(l) || need_more_frames;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Draw frames for all clients
|
// Draw frames for all clients
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
need_more_frames = client_draw_frame(c) || need_more_frames;
|
need_more_frames = client_draw_frame(c) || need_more_frames;
|
||||||
|
|
@ -5183,6 +5498,10 @@ void rendermon(struct wl_listener *listener, void *data) {
|
||||||
need_more_frames = client_draw_fadeout_frame(c) || need_more_frames;
|
need_more_frames = client_draw_fadeout_frame(c) || need_more_frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_list_for_each_safe(l, tmpl, &fadeout_layers, fadeout_link) {
|
||||||
|
need_more_frames = layer_draw_fadeout_frame(l) || need_more_frames;
|
||||||
|
}
|
||||||
|
|
||||||
wlr_scene_output_commit(m->scene_output, NULL);
|
wlr_scene_output_commit(m->scene_output, NULL);
|
||||||
|
|
||||||
// Send frame done notification
|
// Send frame done notification
|
||||||
|
|
@ -5312,7 +5631,60 @@ int is_special_animaiton_rule(Client *c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_open_animaiton(Client *c, struct wlr_box geo) {
|
void set_layer_open_animaiton(LayerSurface *l, struct wlr_box geo) {
|
||||||
|
int slide_direction;
|
||||||
|
int horizontal, horizontal_value;
|
||||||
|
int vertical, vertical_value;
|
||||||
|
int center_x, center_y;
|
||||||
|
|
||||||
|
if (!l || !l->mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
center_x = l->geom.x + l->geom.width / 2;
|
||||||
|
center_y = l->geom.y + l->geom.height / 2;
|
||||||
|
horizontal =
|
||||||
|
l->mon->w.x + l->mon->w.width - center_x < center_x - l->mon->w.x
|
||||||
|
? RIGHT
|
||||||
|
: LEFT;
|
||||||
|
horizontal_value = horizontal == LEFT
|
||||||
|
? center_x - l->mon->w.x
|
||||||
|
: l->mon->w.x + l->mon->w.width - center_x;
|
||||||
|
vertical =
|
||||||
|
l->mon->w.y + l->mon->w.height - center_y < center_y - l->mon->w.y
|
||||||
|
? DOWN
|
||||||
|
: UP;
|
||||||
|
vertical_value = vertical == UP ? center_y - l->mon->w.y
|
||||||
|
: l->mon->w.y + l->mon->w.height - center_y;
|
||||||
|
slide_direction = horizontal_value < vertical_value ? horizontal : vertical;
|
||||||
|
|
||||||
|
l->animainit_geom.width = l->geom.width;
|
||||||
|
l->animainit_geom.height = l->geom.height;
|
||||||
|
switch (slide_direction) {
|
||||||
|
case UP:
|
||||||
|
l->animainit_geom.x = l->geom.x;
|
||||||
|
l->animainit_geom.y = l->mon->m.y - l->geom.height;
|
||||||
|
break;
|
||||||
|
case DOWN:
|
||||||
|
l->animainit_geom.x = l->geom.x;
|
||||||
|
l->animainit_geom.y =
|
||||||
|
l->geom.y + l->mon->m.height - (l->geom.y - l->mon->m.y);
|
||||||
|
break;
|
||||||
|
case LEFT:
|
||||||
|
l->animainit_geom.x = l->mon->m.x - l->geom.width;
|
||||||
|
l->animainit_geom.y = l->geom.y;
|
||||||
|
break;
|
||||||
|
case RIGHT:
|
||||||
|
l->animainit_geom.x =
|
||||||
|
l->geom.x + l->mon->m.width - (l->geom.x - l->mon->m.x);
|
||||||
|
l->animainit_geom.y = l->geom.y;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
l->animainit_geom.x = l->geom.x;
|
||||||
|
l->animainit_geom.y = 0 - l->geom.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_client_open_animaiton(Client *c, struct wlr_box geo) {
|
||||||
int slide_direction;
|
int slide_direction;
|
||||||
int horizontal, horizontal_value;
|
int horizontal, horizontal_value;
|
||||||
int vertical, vertical_value;
|
int vertical, vertical_value;
|
||||||
|
|
@ -5440,7 +5812,7 @@ void resize(Client *c, struct wlr_box geo, int interact) {
|
||||||
c->animainit_geom.height = c->animation.current.height;
|
c->animainit_geom.height = c->animation.current.height;
|
||||||
c->animainit_geom.width = c->animation.current.width;
|
c->animainit_geom.width = c->animation.current.width;
|
||||||
} else if (c->is_open_animation) {
|
} else if (c->is_open_animation) {
|
||||||
set_open_animaiton(c, c->geom);
|
set_client_open_animaiton(c, c->geom);
|
||||||
} else {
|
} else {
|
||||||
c->animainit_geom = c->animation.current;
|
c->animainit_geom = c->animation.current;
|
||||||
}
|
}
|
||||||
|
|
@ -6389,6 +6761,7 @@ void setup(void) {
|
||||||
wl_list_init(&clients);
|
wl_list_init(&clients);
|
||||||
wl_list_init(&fstack);
|
wl_list_init(&fstack);
|
||||||
wl_list_init(&fadeout_clients);
|
wl_list_init(&fadeout_clients);
|
||||||
|
wl_list_init(&fadeout_layers);
|
||||||
|
|
||||||
idle_notifier = wlr_idle_notifier_v1_create(dpy);
|
idle_notifier = wlr_idle_notifier_v1_create(dpy);
|
||||||
|
|
||||||
|
|
@ -7008,6 +7381,9 @@ void unmaplayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
LayerSurface *l = wl_container_of(listener, l, unmap);
|
LayerSurface *l = wl_container_of(listener, l, unmap);
|
||||||
|
|
||||||
l->mapped = 0;
|
l->mapped = 0;
|
||||||
|
|
||||||
|
init_fadeout_layers(l);
|
||||||
|
|
||||||
wlr_scene_node_set_enabled(&l->scene->node, false);
|
wlr_scene_node_set_enabled(&l->scene->node, false);
|
||||||
if (l == exclusive_focus)
|
if (l == exclusive_focus)
|
||||||
exclusive_focus = NULL;
|
exclusive_focus = NULL;
|
||||||
|
|
@ -7018,6 +7394,62 @@ void unmaplayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_fadeout_layers(LayerSurface *l) {
|
||||||
|
|
||||||
|
if (!layer_animations || l->noanim) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!l->mon)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!l->scene) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l->layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM ||
|
||||||
|
l->layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LayerSurface *fadeout_layer = ecalloc(1, sizeof(*fadeout_layer));
|
||||||
|
|
||||||
|
wlr_scene_node_set_enabled(&l->scene->node, true);
|
||||||
|
fadeout_layer->scene =
|
||||||
|
wlr_scene_tree_snapshot(&l->scene->node, layers[LyrFadeOut]);
|
||||||
|
wlr_scene_node_set_enabled(&l->scene->node, false);
|
||||||
|
|
||||||
|
if (!fadeout_layer->scene) {
|
||||||
|
free(fadeout_layer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fadeout_layer->animation.duration = animation_duration_close;
|
||||||
|
fadeout_layer->geom = fadeout_layer->current =
|
||||||
|
fadeout_layer->animainit_geom = fadeout_layer->animation.initial =
|
||||||
|
l->animation.current;
|
||||||
|
fadeout_layer->mon = l->mon;
|
||||||
|
fadeout_layer->animation.action = CLOSE;
|
||||||
|
|
||||||
|
// 这里snap节点的坐标设置是使用的相对坐标,所以不能加上原来坐标
|
||||||
|
// 这跟普通node有区别
|
||||||
|
|
||||||
|
fadeout_layer->animation.initial.x = 0;
|
||||||
|
fadeout_layer->animation.initial.y = 0;
|
||||||
|
|
||||||
|
fadeout_layer->current.y =
|
||||||
|
l->geom.y + l->geom.height / 2 > l->mon->m.y + l->mon->m.height / 2
|
||||||
|
? l->mon->m.height -
|
||||||
|
(l->animation.current.y - l->mon->m.y) // down out
|
||||||
|
: l->mon->m.y - l->geom.height; // up out
|
||||||
|
fadeout_layer->current.x = 0; // x无偏差,垂直划出
|
||||||
|
|
||||||
|
fadeout_layer->animation.passed_frames = 0;
|
||||||
|
fadeout_layer->animation.total_frames =
|
||||||
|
fadeout_layer->animation.duration / output_frame_duration_ms();
|
||||||
|
wlr_scene_node_set_enabled(&fadeout_layer->scene->node, true);
|
||||||
|
wl_list_insert(&fadeout_layers, &fadeout_layer->fadeout_link);
|
||||||
|
}
|
||||||
|
|
||||||
void init_fadeout_client(Client *c) {
|
void init_fadeout_client(Client *c) {
|
||||||
|
|
||||||
if (!c->mon || client_is_unmanaged(c))
|
if (!c->mon || client_is_unmanaged(c))
|
||||||
|
|
@ -7087,7 +7519,7 @@ void init_fadeout_client(Client *c) {
|
||||||
|
|
||||||
fadeout_cient->animation.passed_frames = 0;
|
fadeout_cient->animation.passed_frames = 0;
|
||||||
fadeout_cient->animation.total_frames =
|
fadeout_cient->animation.total_frames =
|
||||||
fadeout_cient->animation.duration / output_frame_duration_ms(c);
|
fadeout_cient->animation.duration / output_frame_duration_ms();
|
||||||
wlr_scene_node_set_enabled(&fadeout_cient->scene->node, true);
|
wlr_scene_node_set_enabled(&fadeout_cient->scene->node, true);
|
||||||
wl_list_insert(&fadeout_clients, &fadeout_cient->fadeout_link);
|
wl_list_insert(&fadeout_clients, &fadeout_cient->fadeout_link);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue