diff --git a/config.def.h b/config.def.h index b7dd960a..8ff05094 100644 --- a/config.def.h +++ b/config.def.h @@ -8,6 +8,7 @@ /* animation */ static const bool animations = true; // Enable animations static const char *animation_type = "slide"; //slide or zoom +static const char animation_fade_in = 0; // Enable animation fade in static const float zoom_initial_ratio = 0.5; // Initial window ratio for animations static const uint32_t animation_duration = 300; // Animation speed // static const double animation_curve[4] = {0.05,0.9,0.1,1.05}; // Animation curve diff --git a/main.c b/main.c index 7eedc080..df427212 100644 --- a/main.c +++ b/main.c @@ -199,7 +199,7 @@ typedef struct { int iskilling; struct wlr_box bounds; bool resizing; - bool is_first_resize; + bool is_open_animation; bool is_restoring_from_ov; struct dwl_animation animation; @@ -509,6 +509,7 @@ static unsigned int get_tags_first_tag(unsigned int tags); void client_commit(Client *c); void apply_border(Client *c,struct wlr_box clip_box); +void client_set_opacity(Client *c, double opacity); /* variables */ static const char broken[] = "broken"; @@ -678,17 +679,25 @@ client_animation_next_tick(Client *c) (c->current.y - c->animation.initial.y) * factor; wlr_scene_node_set_position(&c->scene->node, x, y); - c->is_first_resize = false; c->animation.current = (struct wlr_box){ .x = x, .y = y, .width = width, .height = height, }; + + if(c->is_open_animation && animation_fade_in) + client_set_opacity(c,animation_passed); if (animation_passed == 1.0) - { + { + c->is_open_animation = false; c->animation.running = false; + if(c->iskilling) { + c->iskilling = false; + client_send_close(c); + return false; + } if(c->animation.tagouting) { c->animation.tagouting = false; wlr_scene_node_set_enabled(&c->scene->node, false); @@ -1086,6 +1095,8 @@ arrange(Monitor *m,bool want_animation) return; wl_list_for_each(c, &clients, link) { + if(c->iskilling) + continue; if(c->mon == m && c->isglobal) { c->tags = m->tagset[m->seltags]; focusclient(c,1); @@ -1647,7 +1658,7 @@ void client_set_pending_state(Client *c) c->animation.tagining = false; c->animation.should_animate = true; c->animation.initial = c->animainit_geom; - } else if (!animations || c == grabc || (!c->is_first_resize && wlr_box_equal(&c->current, &c->pending))) + } else if (!animations || c == grabc || (!c->is_open_animation && wlr_box_equal(&c->current, &c->pending))) { c->animation.should_animate = false; } else if (c->is_restoring_from_ov) { @@ -2605,6 +2616,8 @@ focustop(Monitor *m) { Client *c; wl_list_for_each(c, &fstack, flink) { + if(c->iskilling || c->animation.tagouting || c->animation.tagouted) + continue; if (VISIBLEON(c, m)) return c; } @@ -2872,6 +2885,40 @@ keypressmod(struct wl_listener *listener, void *data) &kb->wlr_keyboard->modifiers); } +void pending_kill_client(Client *c) { + c->iskilling = 1; + c->animainit_geom = c->geom; + c->pending = c->geom; + c->pending.y = c->geom.y + c->mon->m.height; + + if (c == selmon->sel) + selmon->sel = NULL; + + if (c == grabc) { + cursor_mode = CurNormal; + grabc = NULL; + } + + if(c->foreign_toplevel){ + wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); + c->foreign_toplevel = NULL; + } + + Client *nextfocus = focustop(selmon); + + if(nextfocus) { + focusclient(nextfocus,0); + } + + if(!nextfocus && selmon->isoverview){ + Arg arg = {0}; + toggleoverview(&arg); + } + resize(c,c->geom,0); + printstatus(); + motionnotify(0, NULL, 0, 0, 0, 0); + arrange(selmon,false); +} void killclient(const Arg *arg) @@ -2879,9 +2926,7 @@ killclient(const Arg *arg) Client *c; c = selmon->sel; if (c) { - c->iskilling = 1; - selmon->sel = NULL; - client_send_close(c); + pending_kill_client(c); } } @@ -2965,7 +3010,7 @@ mapnotify(struct wl_listener *listener, void *data) // c->animainit_geom.height = c->geom.height * zoom_initial_ratio; // c->animainit_geom.x = c->geom.x + (c->geom.width - c->animainit_geom.width)/2; // c->animainit_geom.y = c->geom.y + (c->geom.height - c->animainit_geom.height)/2; - c->is_first_resize = true; + c->is_open_animation = true; //nop if (new_is_master) // tile at the top @@ -3436,6 +3481,30 @@ quitsignal(int signo) quit(NULL); } +void +scene_buffer_apply_opacity(struct wlr_scene_buffer *buffer, + int sx, int sy, void *data) { + wlr_scene_buffer_set_opacity(buffer, *(double *)data); +} + +void client_set_opacity(Client *c, double opacity) { + wlr_scene_node_for_each_buffer(&c->scene_surface->node, scene_buffer_apply_opacity, &opacity); +} + +void +client_handle_opacity(Client *c) { + if (!c || !c->mon || !client_surface(c)->mapped) + return; + + double opacity = c->isfullscreen || c->isfakefullscreen + ? 1.0 + : c == selmon->sel + ? 0.8 + : 0.5; + + wlr_scene_node_for_each_buffer(&c->scene_surface->node, scene_buffer_apply_opacity, &opacity); +} + void // 0.5 rendermon(struct wl_listener *listener, void *data) { @@ -3459,12 +3528,16 @@ rendermon(struct wl_listener *listener, void *data) { // if (client_is_rendered_on_mon(c, m) && !client_is_stopped(c)) need_more_frames = client_draw_frame(c); + // the opacity is usabel, but don't enable temporarily + // client_handle_opacity(c); } if (need_more_frames) { wlr_output_schedule_frame(m->wlr_output); } + + /* * HACK: The "correct" way to set the gamma is to commit it together with * the rest of the state in one go, but to do that we would need to rewrite @@ -3720,7 +3793,7 @@ resize(Client *c, struct wlr_box geo, int interact) c->animainit_geom.height = oldgeom.height; c->animainit_geom.width = oldgeom.width; c->animainit_geom.y = oldgeom.y; - }else if(c->is_first_resize) { + }else if(c->is_open_animation) { set_open_animaiton(c,c->geom); } else { c->animainit_geom = oldgeom; @@ -3737,7 +3810,7 @@ resize(Client *c, struct wlr_box geo, int interact) // 如果不是工作区切换时划出去的窗口,就让动画的结束位置,就是上面的真实位置和大小 // c->pending 决定动画的终点,一般在其他调用resize的函数的附近设置了 - if(!c->animation.tagouting) { + if(!c->animation.tagouting && !c->iskilling) { c->pending = c->geom; } // 开始应用动画设置 @@ -4113,8 +4186,7 @@ void handle_foreign_close_request(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, foreign_close_request); if(c) { - c->iskilling = 1; - client_send_close(c); + pending_kill_client(c); } } @@ -4474,7 +4546,7 @@ void grid(Monitor *m, unsigned int gappo, unsigned int gappi) { Client *tempClients[100]; n = 0; wl_list_for_each(c, &clients, link) - if (VISIBLEON(c, c->mon) && !c->animation.tagouting && c->mon == selmon){ + if (VISIBLEON(c, c->mon) && !c->iskilling && !c->animation.tagouting && c->mon == selmon){ tempClients[n] = c; n++; } @@ -4644,7 +4716,7 @@ tile(Monitor *m,unsigned int gappo, unsigned int uappi) Client *c; wl_list_for_each(c, &clients, link) - if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen && !c->isfakefullscreen) + if (VISIBLEON(c, m) && !c->animation.tagouting && !c->iskilling && !c->isfloating && !c->isfullscreen && !c->isfakefullscreen) n++; if (n == 0) return; @@ -4660,7 +4732,7 @@ tile(Monitor *m,unsigned int gappo, unsigned int uappi) i = 0; my = ty = m->gappoh*oe; wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->animation.tagouting || c->isfloating || c->isfullscreen || c->isfakefullscreen ) + if (!VISIBLEON(c, m) || c->iskilling || c->animation.tagouting || c->isfloating || c->isfullscreen || c->isfakefullscreen ) continue; if (i < selmon->pertag->nmasters[selmon->pertag->curtag]) { r = MIN(n, selmon->pertag->nmasters[selmon->pertag->curtag]) - i; @@ -4801,14 +4873,6 @@ unmapnotify(struct wl_listener *listener, void *data) /* Called when the surface is unmapped, and should no longer be shown. */ Client *c = wl_container_of(listener, c, unmap); - if (c == selmon->sel) - selmon->sel = NULL; - - if (c == grabc) { - cursor_mode = CurNormal; - grabc = NULL; - } - if (client_is_unmanaged(c)) { if (c == exclusive_focus) exclusive_focus = NULL; @@ -4821,24 +4885,6 @@ unmapnotify(struct wl_listener *listener, void *data) } wlr_scene_node_destroy(&c->scene->node); - if(c->foreign_toplevel){ - wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); - c->foreign_toplevel = NULL; - } - - Client *nextfocus = focustop(selmon); - - if(nextfocus) { - focusclient(nextfocus,0); - } - - if(!nextfocus && selmon->isoverview){ - Arg arg = {0}; - toggleoverview(&arg); - } - - printstatus(); - motionnotify(0, NULL, 0, 0, 0, 0); } void //0.5