diff --git a/src/main.c b/src/main.c index 6f15752..9a1c292 100644 --- a/src/main.c +++ b/src/main.c @@ -154,7 +154,7 @@ static gboolean send_apply(gpointer data) { GdkDisplay *display = gdk_window_get_display(window); struct wl_display *wl_display = gdk_wayland_display_get_wl_display(display); wd_apply_state(state, outputs, wl_display); - state->apply_pending = false; + state->apply_pending = FALSE; return FALSE; } @@ -175,7 +175,7 @@ static void apply_state(struct wd_state *state) { /* queue this once per iteration in order to prevent duplicate updates */ if (!state->apply_pending) { - state->apply_pending = true; + state->apply_pending = TRUE; g_idle_add(send_apply, state); } } @@ -257,11 +257,12 @@ static void cache_scroll(struct wd_state *state) { static gboolean redraw_canvas(GtkWidget *widget, GdkFrameClock *frame_clock, gpointer data); static void update_tick_callback(struct wd_state *state) { - bool any_animate = false; + bool any_animate = FALSE; struct wd_render_head_data *render; wl_list_for_each(render, &state->render.heads, link) { - if (state->render.updated_at < render->transition_begin + HOVER_USECS) { - any_animate = true; + if (state->render.updated_at < render->hover_begin + HOVER_USECS + || state->render.updated_at < render->click_begin + HOVER_USECS) { + any_animate = TRUE; break; } } @@ -279,12 +280,12 @@ static void update_tick_callback(struct wd_state *state) { } static void update_cursor(struct wd_state *state) { - bool any_hovered = false; + bool any_hovered = FALSE; struct wd_head *head; wl_list_for_each(head, &state->heads, link) { struct wd_render_head_data *render = head->render; if (render != NULL && render->hovered) { - any_hovered = true; + any_hovered = TRUE; break; } } @@ -300,6 +301,15 @@ static void update_cursor(struct wd_state *state) { } } +static inline void flip_anim(uint64_t *timer, uint64_t tick) { + uint64_t animate_end = *timer + HOVER_USECS; + if (tick < animate_end) { + *timer = tick - (animate_end - tick); + } else { + *timer = tick; + } +} + static void update_hovered(struct wd_state *state) { GdkDisplay *display = gdk_display_get_default(); GdkWindow *window = gtk_widget_get_window(state->canvas); @@ -309,17 +319,17 @@ static void update_hovered(struct wd_state *state) { GdkFrameClock *clock = gtk_widget_get_frame_clock(state->canvas); uint64_t tick = gdk_frame_clock_get_frame_time(clock); g_autoptr(GList) seats = gdk_display_list_seats(display); - bool any_hovered = false; + bool any_hovered = FALSE; struct wd_render_head_data *render; wl_list_for_each(render, &state->render.heads, link) { bool init_hovered = render->hovered; - render->hovered = false; + render->hovered = FALSE; if (any_hovered) { continue; } if (state->clicked == render) { - render->hovered = true; - any_hovered = true; + render->hovered = TRUE; + any_hovered = TRUE; } else if (state->clicked == NULL) { for (GList *iter = seats; iter != NULL; iter = iter->next) { double mouse_x; @@ -329,14 +339,14 @@ static void update_hovered(struct wd_state *state) { gdk_window_get_device_position_double(window, pointer, &mouse_x, &mouse_y, NULL); if (mouse_x >= render->x1 && mouse_x < render->x2 && mouse_y >= render->y1 && mouse_y < render->y2) { - render->hovered = true; - any_hovered = true; + render->hovered = TRUE; + any_hovered = TRUE; break; } } } if (init_hovered != render->hovered) { - render->transition_begin = tick; + flip_anim(&render->hover_begin, tick); } } update_cursor(state); @@ -812,11 +822,6 @@ static cairo_surface_t *draw_head(PangoContext *pango, cairo_set_source_color(cr, info->border_color); cairo_fill(cr); - cairo_set_line_width(cr, 1.); - cairo_rectangle(cr, 0, 0, width, height); - cairo_set_source_color(cr, info->fg_color); - cairo_stroke(cr); - PangoLayout *layout = pango_layout_new(pango); pango_layout_set_text(layout, name, -1); int text_width = pango_units_from_double(width - TEXT_MARGIN * 2); @@ -862,7 +867,7 @@ static void canvas_render(GtkGLArea *area, GdkGLContext *context, gpointer data) render->tex_width = frame->width; render->tex_height = frame->height; render->pixels = frame->pixels; - render->preview = true; + render->preview = TRUE; render->updated_at = tick; render->y_invert = frame->y_invert; render->swap_rgb = frame->swap_rgb; @@ -875,7 +880,7 @@ static void canvas_render(GtkGLArea *area, GdkGLContext *context, gpointer data) || render->pixels == NULL || size_changed(render)) { render->tex_width = render->x2 - render->x1; render->tex_height = render->y2 - render->y1; - render->preview = false; + render->preview = FALSE; if (head->surface != NULL) { cairo_surface_destroy(head->surface); } @@ -885,9 +890,9 @@ static void canvas_render(GtkGLArea *area, GdkGLContext *context, gpointer data) render->tex_stride = cairo_image_surface_get_stride(head->surface); render->updated_at = tick; render->active.rotation = 0; - render->active.x_invert = false; - render->y_invert = false; - render->swap_rgb = false; + render->active.x_invert = FALSE; + render->y_invert = FALSE; + render->swap_rgb = FALSE; } } } @@ -911,6 +916,23 @@ static void canvas_unrealize(GtkWidget *widget, gpointer data) { state->gl_data = NULL; } +static void set_clicked_head(struct wd_state *state, + struct wd_render_head_data *clicked) { + GdkFrameClock *clock = gtk_widget_get_frame_clock(state->canvas); + uint64_t tick = gdk_frame_clock_get_frame_time(clock); + if (clicked != state->clicked) { + if (state->clicked != NULL) { + state->clicked->clicked = FALSE; + flip_anim(&state->clicked->click_begin, tick); + } + if (clicked != NULL) { + clicked->clicked = TRUE; + flip_anim(&clicked->click_begin, tick); + } + } + state->clicked = clicked; +} + static gboolean canvas_click(GtkWidget *widget, GdkEvent *event, gpointer data) { struct wd_state *state = data; @@ -923,7 +945,7 @@ static gboolean canvas_click(GtkWidget *widget, GdkEvent *event, double mouse_y = event->button.y; if (mouse_x >= render->x1 && mouse_x < render->x2 && mouse_y >= render->y1 && mouse_y < render->y2) { - state->clicked = render; + set_clicked_head(state, render); state->click_offset.x = event->button.x - render->x1; state->click_offset.y = event->button.y - render->y1; break; @@ -936,7 +958,7 @@ static gboolean canvas_click(GtkWidget *widget, GdkEvent *event, struct wd_render_head_data *render; wl_list_for_each(render, &state->render.heads, link) { render->updated_at = 0; - render->preview = true; + render->preview = TRUE; } gtk_gl_area_queue_render(GTK_GL_AREA(state->canvas)); g_autoptr(GList) forms = gtk_container_get_children(GTK_CONTAINER(state->stack)); @@ -949,7 +971,7 @@ static gboolean canvas_click(GtkWidget *widget, GdkEvent *event, } } } else if (event->button.button == 2) { - state->panning = true; + state->panning = TRUE; state->pan_last.x = event->button.x; state->pan_last.y = event->button.y; } @@ -961,10 +983,10 @@ static gboolean canvas_release(GtkWidget *widget, GdkEvent *event, gpointer data) { struct wd_state *state = data; if (event->button.button == 1) { - state->clicked = NULL; + set_clicked_head(state, NULL); } if (event->button.button == 2) { - state->panning = false; + state->panning = FALSE; } update_cursor(state); return TRUE; @@ -1084,10 +1106,10 @@ static gboolean canvas_enter(GtkWidget *widget, GdkEvent *event, gpointer data) { struct wd_state *state = data; if (!(event->crossing.state & GDK_BUTTON1_MASK)) { - state->clicked = NULL; + set_clicked_head(state, NULL); } if (!(event->crossing.state & GDK_BUTTON2_MASK)) { - state->panning = false; + state->panning = FALSE; } update_cursor(state); return TRUE; @@ -1098,7 +1120,7 @@ static gboolean canvas_leave(GtkWidget *widget, GdkEvent *event, struct wd_state *state = data; struct wd_render_head_data *render; wl_list_for_each(render, &state->render.heads, link) { - render->hovered = false; + render->hovered = FALSE; } update_tick_callback(state); return TRUE; @@ -1321,12 +1343,12 @@ static void activate(GtkApplication* app, gpointer user_data) { wd_fatal_error(1, "Compositor doesn't support xdg-output-unstable-v1"); } if (state->copy_manager == NULL) { - state->capture = false; + state->capture = FALSE; g_simple_action_set_state(capture_action, g_variant_new_boolean(state->capture)); g_simple_action_set_enabled(capture_action, FALSE); } if (state->layer_shell == NULL) { - state->show_overlay = false; + state->show_overlay = FALSE; g_simple_action_set_state(overlay_action, g_variant_new_boolean(state->show_overlay)); g_simple_action_set_enabled(overlay_action, FALSE); } diff --git a/src/render.c b/src/render.c index 284770c..92e4f3c 100644 --- a/src/render.c +++ b/src/render.c @@ -37,6 +37,18 @@ #define BT_COLOR_QUAD_SIZE (6 * BT_COLOR_VERT_SIZE) #define BT_COLOR_MAX (BT_COLOR_QUAD_SIZE * HEADS_MAX) +#define BT_LINE_VERT_SIZE (2 + 4) +#define BT_LINE_QUAD_SIZE (8 * BT_LINE_VERT_SIZE) +#define BT_LINE_EXT_SIZE (24 * BT_LINE_VERT_SIZE) +#define BT_LINE_MAX (BT_LINE_EXT_SIZE * (HEADS_MAX + 1)) + +enum gl_buffers { + TEXTURE_BUFFER, + COLOR_BUFFER, + LINE_BUFFER, + NUM_BUFFERS +}; + struct wd_gl_data { GLuint color_program; GLuint color_vertex_shader; @@ -54,12 +66,12 @@ struct wd_gl_data { GLuint texture_texture_uniform; GLuint texture_color_transform_uniform; - GLuint buffers[2]; + GLuint buffers[NUM_BUFFERS]; unsigned texture_count; GLuint textures[HEADS_MAX]; - float tris[BT_COLOR_MAX]; + float verts[BT_LINE_MAX]; }; static const char *color_vertex_shader_src = "\ @@ -186,15 +198,19 @@ struct wd_gl_data *wd_gl_setup(void) { res->texture_color_transform_uniform = glGetUniformLocation( res->texture_program, "color_transform"); - glGenBuffers(2, res->buffers); - glBindBuffer(GL_ARRAY_BUFFER, res->buffers[0]); + glGenBuffers(NUM_BUFFERS, res->buffers); + glBindBuffer(GL_ARRAY_BUFFER, res->buffers[TEXTURE_BUFFER]); glBufferData(GL_ARRAY_BUFFER, BT_UV_MAX * sizeof(float), NULL, GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, res->buffers[1]); + glBindBuffer(GL_ARRAY_BUFFER, res->buffers[COLOR_BUFFER]); glBufferData(GL_ARRAY_BUFFER, BT_COLOR_MAX * sizeof(float), NULL, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, res->buffers[LINE_BUFFER]); + glBufferData(GL_ARRAY_BUFFER, BT_LINE_MAX * sizeof(float), + NULL, GL_DYNAMIC_DRAW); + return res; } @@ -210,27 +226,50 @@ static const GLfloat TRANSFORM_BGR[16] = { 1, 0, 0, 0, 0, 0, 0, 1}; -#define PUSH_POINT(_start, _a, _b) \ +#define PUSH_POINT_COLOR(_start, _a, _b, _color, _alpha) \ *((_start)++) = (_a);\ - *((_start)++) = (_b); + *((_start)++) = (_b);\ + *((_start)++) = ((_color)[0]);\ + *((_start)++) = ((_color)[1]);\ + *((_start)++) = ((_color)[2]);\ + *((_start)++) = (_alpha); -#define PUSH_COLOR(_start, _a, _b, _c, _d) \ +#define PUSH_POINT_UV(_start, _a, _b, _c, _d) \ *((_start)++) = (_a);\ *((_start)++) = (_b);\ *((_start)++) = (_c);\ *((_start)++) = (_d); -#define PUSH_POINT_UV(_start, _a, _b, _c, _d) \ - PUSH_COLOR(_start, _a, _b, _c, _d) +static inline float lerp(float x, float y, float a) { + return x * (1.f - a) + y * a; +} + +static inline void lerp_color(float out[3], float x[3], float y[3], float a) { + out[0] = lerp(x[0], y[0], a); + out[1] = lerp(x[1], y[1], a); + out[2] = lerp(x[2], y[2], a); + out[3] = lerp(x[3], y[3], a); +} + +static inline float ease(float d) { + d *= 2.f; + if (d <= 1.f) { + d = d * d; + } else { + d -= 1.f; + d = d * (2.f - d) + 1.f; + } + d /= 2.f; + return d; +} void wd_gl_render(struct wd_gl_data *res, struct wd_render_data *info, uint64_t tick) { - unsigned int tris = 0; + unsigned int tri_verts = 0; unsigned int head_count = wl_list_length(&info->heads); - if (head_count >= HEADS_MAX) { + if (head_count >= HEADS_MAX) head_count = HEADS_MAX; - } if (head_count > res->texture_count) { glGenTextures(head_count - res->texture_count, @@ -250,7 +289,7 @@ void wd_gl_render(struct wd_gl_data *res, struct wd_render_data *info, struct wd_render_head_data *head; int i = 0; wl_list_for_each_reverse(head, &info->heads, link) { - float *tri_ptr = res->tris + i * BT_UV_QUAD_SIZE; + float *tri_ptr = res->verts + i * BT_UV_QUAD_SIZE; float x1 = head->active.x_invert ? head->x2 : head->x1; float y1 = head->y_invert ? head->y2 : head->y1; float x2 = head->active.x_invert ? head->x1 : head->x2; @@ -285,11 +324,10 @@ void wd_gl_render(struct wd_gl_data *res, struct wd_render_data *info, PUSH_POINT_UV(tri_ptr, x2, y1, sb, tb) PUSH_POINT_UV(tri_ptr, x2, y2, sc, tc) - tris += 6; + tri_verts += 6; i++; - if (i >= HEADS_MAX) { + if (i >= HEADS_MAX) break; - } } glClearColor(info->bg_color[0], info->bg_color[1], info->bg_color[2], 1.f); @@ -297,11 +335,11 @@ void wd_gl_render(struct wd_gl_data *res, struct wd_render_data *info, float screen_size[2] = { info->viewport_width, info->viewport_height }; - if (tris > 0) { + if (tri_verts > 0) { glUseProgram(res->texture_program); - glBindBuffer(GL_ARRAY_BUFFER, res->buffers[0]); + glBindBuffer(GL_ARRAY_BUFFER, res->buffers[TEXTURE_BUFFER]); glBufferSubData(GL_ARRAY_BUFFER, 0, - tris * BT_UV_VERT_SIZE * sizeof(float), res->tris); + tri_verts * BT_UV_VERT_SIZE * sizeof(float), res->verts); glEnableVertexAttribArray(res->texture_position_attribute); glEnableVertexAttribArray(res->texture_uv_attribute); glVertexAttribPointer(res->texture_position_attribute, @@ -328,19 +366,23 @@ void wd_gl_render(struct wd_gl_data *res, struct wd_render_data *info, head->swap_rgb ? TRANSFORM_RGB : TRANSFORM_BGR); glDrawArrays(GL_TRIANGLES, i * 6, 6); i++; - if (i >= HEADS_MAX) { + if (i >= HEADS_MAX) break; - } } } - tris = 0; + tri_verts = 0; int j = 0; i = 0; + bool any_clicked = false; + uint64_t click_begin = 0; wl_list_for_each_reverse(head, &info->heads, link) { - if (head->hovered || tick < head->transition_begin + HOVER_USECS) { - float *tri_ptr = res->tris + j++ * BT_COLOR_QUAD_SIZE; + any_clicked = head->clicked || any_clicked; + if (head->click_begin > click_begin) + click_begin = head->click_begin; + if (head->hovered || tick < head->hover_begin + HOVER_USECS) { + float *tri_ptr = res->verts + j++ * BT_COLOR_QUAD_SIZE; float x1 = head->x1; float y1 = head->y1; float x2 = head->x2; @@ -348,48 +390,32 @@ void wd_gl_render(struct wd_gl_data *res, struct wd_render_data *info, float *color = info->selection_color; float d = fminf( - (tick - head->transition_begin) / (double) HOVER_USECS, 1.f); - if (!head->hovered) { + (tick - head->hover_begin) / (double) HOVER_USECS, 1.f); + if (!head->hovered) d = 1.f - d; - } - d *= 2.f; - if (d <= 1.f) { - d = d * d; - } else { - d -= 1.f; - d = d * (2.f - d) + 1.f; - } - d /= 2.f; - float alpha = color[3] * d * .5f; + float alpha = color[3] * ease(d) * .5f; - PUSH_POINT(tri_ptr, x1, y1) - PUSH_COLOR(tri_ptr, color[0], color[1], color[2], alpha) - PUSH_POINT(tri_ptr, x2, y1) - PUSH_COLOR(tri_ptr, color[0], color[1], color[2], alpha) - PUSH_POINT(tri_ptr, x1, y2) - PUSH_COLOR(tri_ptr, color[0], color[1], color[2], alpha) - PUSH_POINT(tri_ptr, x1, y2) - PUSH_COLOR(tri_ptr, color[0], color[1], color[2], alpha) - PUSH_POINT(tri_ptr, x2, y1) - PUSH_COLOR(tri_ptr, color[0], color[1], color[2], alpha) - PUSH_POINT(tri_ptr, x2, y2) - PUSH_COLOR(tri_ptr, color[0], color[1], color[2], alpha) + PUSH_POINT_COLOR(tri_ptr, x1, y1, color, alpha) + PUSH_POINT_COLOR(tri_ptr, x2, y1, color, alpha) + PUSH_POINT_COLOR(tri_ptr, x1, y2, color, alpha) + PUSH_POINT_COLOR(tri_ptr, x1, y2, color, alpha) + PUSH_POINT_COLOR(tri_ptr, x2, y1, color, alpha) + PUSH_POINT_COLOR(tri_ptr, x2, y2, color, alpha) - tris += 6; + tri_verts += 6; } i++; - if (i >= HEADS_MAX) { + if (i >= HEADS_MAX) break; - } } - if (tris > 0) { + if (tri_verts > 0) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glUseProgram(res->color_program); - glBindBuffer(GL_ARRAY_BUFFER, res->buffers[1]); + glBindBuffer(GL_ARRAY_BUFFER, res->buffers[COLOR_BUFFER]); glBufferSubData(GL_ARRAY_BUFFER, 0, - tris * BT_COLOR_VERT_SIZE * sizeof(float), res->tris); + tri_verts * BT_COLOR_VERT_SIZE * sizeof(float), res->verts); glEnableVertexAttribArray(res->color_position_attribute); glEnableVertexAttribArray(res->color_color_attribute); glVertexAttribPointer(res->color_position_attribute, 2, GL_FLOAT, GL_FALSE, @@ -397,13 +423,113 @@ void wd_gl_render(struct wd_gl_data *res, struct wd_render_data *info, glVertexAttribPointer(res->color_color_attribute, 4, GL_FLOAT, GL_FALSE, BT_COLOR_VERT_SIZE * sizeof(float), (void *) (2 * sizeof(float))); glUniform2fv(res->color_screen_size_uniform, 1, screen_size); - glDrawArrays(GL_TRIANGLES, 0, tris); + glDrawArrays(GL_TRIANGLES, 0, tri_verts); + glDisable(GL_BLEND); + } + + unsigned int line_verts = 0; + i = 0; + float *line_ptr = res->verts; + if (any_clicked || (click_begin && tick < click_begin + HOVER_USECS)) { + const float ox = -info->scroll_x - info->x_origin; + const float oy = -info->scroll_y - info->y_origin; + const float sx = screen_size[0]; + const float sy = screen_size[1]; + + float color[4]; + lerp_color(color, info->selection_color, info->fg_color, .5f); + float d = fminf( + (tick - click_begin) / (double) HOVER_USECS, 1.f); + if (!any_clicked) + d = 1.f - d; + float alpha = color[3] * ease(d) * .5f; + + PUSH_POINT_COLOR(line_ptr, ox, oy, color, alpha) + PUSH_POINT_COLOR(line_ptr, sx, oy, color, alpha) + PUSH_POINT_COLOR(line_ptr, ox, oy, color, alpha) + PUSH_POINT_COLOR(line_ptr, ox, sy, color, alpha) + + line_verts += 4; + } + wl_list_for_each(head, &info->heads, link) { + float x1 = head->x1; + float y1 = head->y1; + float x2 = head->x2; + float y2 = head->y2; + + float *color = info->fg_color; + float alpha = color[3] * (head->clicked ? .5f : .25f); + + PUSH_POINT_COLOR(line_ptr, x1, y1, color, alpha) + PUSH_POINT_COLOR(line_ptr, x2, y1, color, alpha) + PUSH_POINT_COLOR(line_ptr, x2, y1, color, alpha) + PUSH_POINT_COLOR(line_ptr, x2, y2, color, alpha) + PUSH_POINT_COLOR(line_ptr, x2, y2, color, alpha) + PUSH_POINT_COLOR(line_ptr, x1, y2, color, alpha) + PUSH_POINT_COLOR(line_ptr, x1, y2, color, alpha) + PUSH_POINT_COLOR(line_ptr, x1, y1, color, alpha) + + line_verts += 8; + + if (any_clicked || (click_begin && tick < click_begin + HOVER_USECS)) { + float d = fminf( + (tick - click_begin) / (double) HOVER_USECS, 1.f); + if (!any_clicked) + d = 1.f - d; + alpha = color[3] * ease(d) * (head->clicked ? .15f : .075f); + + const float sx = screen_size[0]; + const float sy = screen_size[1]; + + PUSH_POINT_COLOR(line_ptr, 0, y1, color, alpha) + PUSH_POINT_COLOR(line_ptr, x1, y1, color, alpha) + PUSH_POINT_COLOR(line_ptr, x1, 0, color, alpha) + PUSH_POINT_COLOR(line_ptr, x1, y1, color, alpha) + + PUSH_POINT_COLOR(line_ptr, sx, y1, color, alpha) + PUSH_POINT_COLOR(line_ptr, x2, y1, color, alpha) + PUSH_POINT_COLOR(line_ptr, x2, 0, color, alpha) + PUSH_POINT_COLOR(line_ptr, x2, y1, color, alpha) + + PUSH_POINT_COLOR(line_ptr, sx, y2, color, alpha) + PUSH_POINT_COLOR(line_ptr, x2, y2, color, alpha) + PUSH_POINT_COLOR(line_ptr, x2, sy, color, alpha) + PUSH_POINT_COLOR(line_ptr, x2, y2, color, alpha) + + PUSH_POINT_COLOR(line_ptr, 0, y2, color, alpha) + PUSH_POINT_COLOR(line_ptr, x1, y2, color, alpha) + PUSH_POINT_COLOR(line_ptr, x1, sy, color, alpha) + PUSH_POINT_COLOR(line_ptr, x1, y2, color, alpha) + + line_verts += 16; + } + + i++; + if (i >= HEADS_MAX) + break; + } + + if (line_verts > 0) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glUseProgram(res->color_program); + glBindBuffer(GL_ARRAY_BUFFER, res->buffers[LINE_BUFFER]); + glBufferSubData(GL_ARRAY_BUFFER, 0, + line_verts * BT_LINE_VERT_SIZE * sizeof(float), res->verts); + glEnableVertexAttribArray(res->color_position_attribute); + glEnableVertexAttribArray(res->color_color_attribute); + glVertexAttribPointer(res->color_position_attribute, 2, GL_FLOAT, GL_FALSE, + BT_LINE_VERT_SIZE * sizeof(float), (void *) (0 * sizeof(float))); + glVertexAttribPointer(res->color_color_attribute, 4, GL_FLOAT, GL_FALSE, + BT_LINE_VERT_SIZE * sizeof(float), (void *) (2 * sizeof(float))); + glUniform2fv(res->color_screen_size_uniform, 1, screen_size); + glDrawArrays(GL_LINES, 0, line_verts); glDisable(GL_BLEND); } } void wd_gl_cleanup(struct wd_gl_data *res) { - glDeleteBuffers(2, res->buffers); + glDeleteBuffers(NUM_BUFFERS, res->buffers); glDeleteShader(res->texture_fragment_shader); glDeleteShader(res->texture_vertex_shader); glDeleteProgram(res->texture_program); diff --git a/src/wdisplays.h b/src/wdisplays.h index cc6e58d..7f8c39e 100644 --- a/src/wdisplays.h +++ b/src/wdisplays.h @@ -156,7 +156,8 @@ struct wd_render_head_flags { struct wd_render_head_data { struct wl_list link; uint64_t updated_at; - uint64_t transition_begin; + uint64_t hover_begin; + uint64_t click_begin; float x1; float y1; @@ -175,6 +176,7 @@ struct wd_render_head_data { bool y_invert; bool swap_rgb; bool hovered; + bool clicked; }; struct wd_render_data {