diff --git a/display/connection.c b/display/connection.c index d3c7d7b7..95cc1d18 100644 --- a/display/connection.c +++ b/display/connection.c @@ -196,6 +196,8 @@ CONNECTION_MESSAGE_HANDLER(render_window) msg->left, msg->top, msg->width, msg->height); framebuffer_copy_to_framebuffer(dst, src); + + window_schedule_redraw(window); } CONNECTION_MESSAGE_HANDLER(title_window) @@ -216,6 +218,8 @@ CONNECTION_MESSAGE_HANDLER_NO_AUX(show_window) struct window* window = connection_find_window(connection, msg->window_id); if ( !window ) return; + if ( !window->show ) + display_schedule_redraw(window->display); window->show = true; } @@ -224,6 +228,8 @@ CONNECTION_MESSAGE_HANDLER_NO_AUX(hide_window) struct window* window = connection_find_window(connection, msg->window_id); if ( !window ) return; + if ( window->show ) + display_schedule_redraw(window->display); window->show = false; } diff --git a/display/display-code.c b/display/display-code.c index 290d76f1..ddd149fc 100644 --- a/display/display-code.c +++ b/display/display-code.c @@ -46,6 +46,7 @@ extern struct framebuffer arrow_framebuffer; void display_initialize(struct display* display) { memset(display, 0, sizeof(*display)); + display->redraw = true; } void assert_is_well_formed_display_list(struct display* display) @@ -98,6 +99,8 @@ void display_link_window_at_top(struct display* display, struct window* window) display->bottom_window = window; assert_is_well_formed_display_list(display); + + display_schedule_redraw(display); } void display_unlink_window(struct display* display, struct window* window) @@ -123,6 +126,8 @@ void display_unlink_window(struct display* display, struct window* window) window->below_window = NULL; assert_is_well_formed_display_list(display); + + display_schedule_redraw(display); } void display_unlink_window_removal(struct display* display, @@ -139,6 +144,7 @@ void display_unlink_window_removal(struct display* display, display->active_window = NULL; window->focus = false; + display_schedule_redraw(display); assert_is_well_formed_display_list(display); @@ -392,8 +398,17 @@ void display_composit(struct display* display, struct framebuffer fb) memset(&damage_rect, 0, sizeof(damage_rect)); } +void display_schedule_redraw(struct display* display) +{ + display->redraw = true; +} + void display_render(struct display* display) { + if ( !display->redraw ) + return; + display->redraw = false; + struct dispmsg_get_crtc_mode get_mode_msg = {0}; get_mode_msg.msgid = DISPMSG_GET_CRTC_MODE; get_mode_msg.device = display->display.device; @@ -608,6 +623,8 @@ void display_mouse_event(struct display* display, uint8_t byte) } display->pointer_x += xm; display->pointer_y += ym; + if ( xm || ym ) + display_schedule_redraw(display); bool clipped_edge = false; if ( display->pointer_x < 0 ) @@ -788,6 +805,9 @@ void display_mouse_event(struct display* display, uint8_t byte) else if ( (ssize_t) window->width <= window_pointer_x && (ssize_t) window->height <= window_pointer_y ) display->mouse_state = MOUSE_STATE_RESIZE_BOTTOM_RIGHT; + if ( display->mouse_state != MOUSE_STATE_NONE && + display->mouse_state != MOUSE_STATE_IGNORE ) + display_schedule_redraw(display); } if ( xm || ym ) { @@ -805,15 +825,10 @@ void display_mouse_event(struct display* display, uint8_t byte) case MOUSE_STATE_TITLE_MOVE: if ( clipped_edge ) { - // TODO: Clean these up. - // I'd declare those in function scope but I'm afraid of - // messing with the code too much. ssize_t x = display->pointer_x; ssize_t y = display->pointer_y; - ssize_t sw = display->screen_width; ssize_t sh = display->screen_height; - ssize_t corner_size = (sw < sh ? sw : sh) / 4; if ( x < corner_size && y < corner_size ) window_tile_top_left(window); @@ -878,8 +893,11 @@ void display_mouse_event(struct display* display, uint8_t byte) // TODO: Leave mouse state if the top window closes. // TODO: Leave mouse state if the top window is switched. } - else + else if ( display->mouse_state != MOUSE_STATE_NONE ) + { display->mouse_state = MOUSE_STATE_NONE; + display_schedule_redraw(display); + } } void display_on_resolution_change(struct display* display, size_t width, diff --git a/display/display.h b/display/display.h index b591a6c7..bac429d6 100644 --- a/display/display.h +++ b/display/display.h @@ -66,6 +66,7 @@ struct display bool key_lalt; bool key_lsuper; bool key_rsuper; + bool redraw; int pointer_x; int pointer_y; enum mouse_state mouse_state; @@ -91,6 +92,7 @@ void display_set_active_window(struct display* display, struct window* window); void display_add_window(struct display* display, struct window* window); void display_remove_window(struct display* display, struct window* window); void display_composit(struct display* display, struct framebuffer fb); +void display_schedule_redraw(struct display* display); void display_render(struct display* display); void display_keyboard_event(struct display* display, uint32_t codepoint); void display_on_resolution_change(struct display* display, size_t width, diff --git a/display/server.c b/display/server.c index 964d9ebc..253ee595 100644 --- a/display/server.c +++ b/display/server.c @@ -275,7 +275,6 @@ void server_mainloop(struct server* server) { while ( true ) { - // TODO: Only do this if a redraw is actually needed. display_render(server->display); server_poll(server); } diff --git a/display/window.c b/display/window.c index 168ef613..7b70a51f 100644 --- a/display/window.c +++ b/display/window.c @@ -44,6 +44,12 @@ struct framebuffer window_client_buffer(struct window* window) window->height - TITLE_HEIGHT - BORDER_WIDTH); } +void window_schedule_redraw(struct window* window) +{ + if ( window->show ) + display_schedule_redraw(window->display); +} + void window_render_frame(struct window* window) { if ( !window->width || !window->height ) @@ -195,12 +201,14 @@ void window_render_frame(struct window* window) } render_text(framebuffer_crop(window->buffer, tt_pos_x, tt_pos_y, tt_width, tt_height), tt, tt_color); + window_schedule_redraw(window); } void window_move(struct window* window, size_t left, size_t top) { window->left = left; window->top = top; + window_schedule_redraw(window); } void window_client_resize(struct window* window, @@ -230,6 +238,7 @@ void window_client_resize(struct window* window, window_render_frame(window); window_notify_client_resize(window); + window_schedule_redraw(window); } void window_resize(struct window* window, size_t width, size_t height) diff --git a/display/window.h b/display/window.h index 2569b404..58f93e84 100644 --- a/display/window.h +++ b/display/window.h @@ -84,6 +84,7 @@ struct window }; struct framebuffer window_client_buffer(struct window* window); +void window_schedule_redraw(struct window* window); void window_render_frame(struct window* window); void window_move(struct window* window, size_t left, size_t top); void window_resize(struct window* window, size_t width, size_t height);