diff --git a/src/animation/client.h b/src/animation/client.h index 51ad35e..849bc10 100644 --- a/src/animation/client.h +++ b/src/animation/client.h @@ -840,8 +840,7 @@ void init_fadeout_client(Client *c) { wl_list_insert(&fadeout_clients, &fadeout_cient->fadeout_link); // 请求刷新屏幕 - if (c->mon) - wlr_output_schedule_frame(c->mon->wlr_output); + request_fresh_all_monitors(); } void client_commit(Client *c) { @@ -860,8 +859,7 @@ void client_commit(Client *c) { c->animation.should_animate = false; } // 请求刷新屏幕 - if (c->mon) - wlr_output_schedule_frame(c->mon->wlr_output); + request_fresh_all_monitors(); } void client_set_pending_state(Client *c) { diff --git a/src/animation/common.h b/src/animation/common.h index 5e4ded9..9f022db 100644 --- a/src/animation/common.h +++ b/src/animation/common.h @@ -250,3 +250,13 @@ struct wlr_scene_tree *wlr_scene_tree_snapshot(struct wlr_scene_node *node, return snapshot; } + +void request_fresh_all_monitors(void) { + Monitor *m = NULL; + wl_list_for_each(m, &mons, link) { + if (!m->wlr_output->enabled) { + continue; + } + wlr_output_schedule_frame(m->wlr_output); + } +} \ No newline at end of file diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 2ade07e..28879df 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -31,13 +31,28 @@ int32_t bind_to_view(const Arg *arg) { } int32_t chvt(const Arg *arg) { + struct timespec ts; + // prevent the animation to rquest the new frame + allow_frame_scheduling = false; + + // backup current tag and monitor name if (selmon) { chvt_backup_tag = selmon->pertag->curtag; strncpy(chvt_backup_selmon, selmon->wlr_output->name, sizeof(chvt_backup_selmon) - 1); } + wlr_session_change_vt(session, arg->ui); + + // wait for DRM device to stabilize and ensure the session state is inactive + ts.tv_sec = 0; + ts.tv_nsec = 100000000; // 200ms + nanosleep(&ts, NULL); + + // allow frame scheduling, + // because session state is now inactive, rendermon will not enter + allow_frame_scheduling = true; return 1; } diff --git a/src/mango.c b/src/mango.c index b19cfbf..e3e658a 100644 --- a/src/mango.c +++ b/src/mango.c @@ -761,6 +761,7 @@ static void refresh_monitors_workspaces_status(Monitor *m); static void init_client_properties(Client *c); static float *get_border_color(Client *c); static void clear_fullscreen_and_maximized_state(Monitor *m); +static void request_fresh_all_monitors(void); #include "data/static_keymap.h" #include "dispatch/bind_declare.h" @@ -845,6 +846,7 @@ static double swipe_dy = 0; bool render_border = true; uint32_t chvt_backup_tag = 0; +bool allow_frame_scheduling = true; char chvt_backup_selmon[32] = {0}; struct dvec2 *baked_points_move; @@ -4237,7 +4239,7 @@ void rendermon(struct wl_listener *listener, void *data) { return; } - if (!m->wlr_output->enabled) + if (!m->wlr_output->enabled || !allow_frame_scheduling) return; frame_allow_tearing = check_tearing_frame_allow(m); @@ -4258,11 +4260,6 @@ void rendermon(struct wl_listener *listener, void *data) { need_more_frames = layer_draw_fadeout_frame(l) || need_more_frames; } - // 如果需要更多帧,确保安排下一帧 - if (need_more_frames) { - wlr_output_schedule_frame(m->wlr_output); - } - // 绘制客户端 wl_list_for_each(c, &clients, link) { need_more_frames = client_draw_frame(c) || need_more_frames; @@ -4289,6 +4286,11 @@ skip: wlr_scene_output_send_frame_done(m->scene_output, &now); wlr_output_state_finish(&pending); } + + // 如果需要更多帧,确保安排下一帧 + if (need_more_frames && allow_frame_scheduling) { + request_fresh_all_monitors(); + } } void requestdecorationmode(struct wl_listener *listener, void *data) {