diff --git a/maomao.c b/maomao.c index 568433e..8a3b57a 100644 --- a/maomao.c +++ b/maomao.c @@ -3630,17 +3630,17 @@ void client_handle_opacity(Client *c) { scene_buffer_apply_opacity, &opacity); } -void // 0.5 -rendermon(struct wl_listener *listener, void *data) { - /* This function is called every time an output is ready to display a frame, - * generally at the output's refresh rate (e.g. 60Hz). */ +void rendermon(struct wl_listener *listener, void *data) { Monitor *m = wl_container_of(listener, m, frame); Client *c; struct wlr_output_state pending = {0}; - struct wlr_gamma_control_v1 *gamma_control; + struct wlr_gamma_control_v1 *gamma_control = NULL; struct timespec now; bool need_more_frames = false; + bool has_commit = false; + bool is_commit_pending = false; + // Draw frames for all clients wl_list_for_each(c, &clients, link) { need_more_frames = client_draw_frame(c); } @@ -3649,50 +3649,50 @@ rendermon(struct wl_listener *listener, void *data) { wlr_output_schedule_frame(m->wlr_output); } - /* Render if no XDG clients have an outstanding resize and are visible on - * this monitor. */ + // Check if we should skip rendering wl_list_for_each(c, &clients, link) { - if (c->configure_serial && !c->isfloating && client_is_rendered_on_mon(c, m) && - !client_is_stopped(c)) - goto skip; + if (c->configure_serial && !c->isfloating && client_is_rendered_on_mon(c, m) && + !client_is_stopped(c)) { + goto skip; + } } - - /* - * 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 - * wlr_scene_output_commit() in order to add the gamma to the pending - * state before committing, instead try to commit the gamma in one frame, - * and commit the rest of the state in the next one (or in the same frame if - * the gamma can not be committed). - */ + // Handle Gamma LUT changes if (m->gamma_lut_changed) { - gamma_control = wlr_gamma_control_manager_v1_get_control(gamma_control_mgr, - m->wlr_output); + gamma_control = wlr_gamma_control_manager_v1_get_control(gamma_control_mgr, m->wlr_output); m->gamma_lut_changed = 0; - if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) + if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) { goto commit; + } if (!wlr_output_test_state(m->wlr_output, &pending)) { wlr_gamma_control_v1_send_failed_and_destroy(gamma_control); goto commit; } + wlr_output_commit_state(m->wlr_output, &pending); wlr_output_schedule_frame(m->wlr_output); - } else { - commit: + is_commit_pending = true; + has_commit = true; // Gamma commit succeeded + } + +commit: + if (!has_commit) { wlr_scene_output_commit(m->scene_output, NULL); + has_commit = true; } skip: + if (!has_commit && !is_commit_pending) { + wlr_scene_output_commit(m->scene_output, NULL); + } - struct wlr_scene_output *scene_output = - wlr_scene_get_scene_output(scene, m->wlr_output); - wlr_scene_output_commit(scene_output, NULL); - + // Send frame done notification clock_gettime(CLOCK_MONOTONIC, &now); - wlr_scene_output_send_frame_done(scene_output, &now); + wlr_scene_output_send_frame_done(m->scene_output, &now); + + // Clean up pending state wlr_output_state_finish(&pending); }