515 lines
14 KiB
C
515 lines
14 KiB
C
|
#include "e.h"
|
||
|
#include "e_mod_main.h"
|
||
|
#ifdef HAVE_WAYLAND
|
||
|
# include "e_mod_comp_wl.h"
|
||
|
# include "e_mod_comp_wl_comp.h"
|
||
|
# include "e_mod_comp_wl_output.h"
|
||
|
# include "e_mod_comp_wl_surface.h"
|
||
|
# include "e_mod_comp_wl_shell.h"
|
||
|
#endif
|
||
|
|
||
|
/* local function prototypes */
|
||
|
static void _e_mod_comp_wl_surface_buffer_destroy_handle(struct wl_listener *listener, struct wl_resource *resource __UNUSED__, uint32_t timestamp __UNUSED__);
|
||
|
static int _e_mod_comp_wl_surface_texture_region(Wayland_Surface *ws, pixman_region32_t *region);
|
||
|
static int _e_mod_comp_wl_surface_texture_transformed_surface(Wayland_Surface *ws);
|
||
|
static void _e_mod_comp_wl_surface_transform_vertex(Wayland_Surface *ws, GLfloat x, GLfloat y, GLfloat u, GLfloat v, GLfloat *r);
|
||
|
static void _e_mod_comp_wl_surface_frame_destroy_callback(struct wl_resource *resource);
|
||
|
static void _e_mod_comp_wl_surface_damage_rectangle(Wayland_Surface *ws, int32_t x, int32_t y, int32_t width, int32_t height);
|
||
|
static void _e_mod_comp_wl_surface_flush_damage(Wayland_Surface *ws);
|
||
|
static void _e_mod_comp_wl_surface_raise(Wayland_Surface *ws);
|
||
|
|
||
|
Wayland_Surface *
|
||
|
e_mod_comp_wl_surface_create(int32_t x, int32_t y, int32_t width, int32_t height)
|
||
|
{
|
||
|
Wayland_Surface *surface;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
if (!(surface = calloc(1, sizeof(Wayland_Surface)))) return NULL;
|
||
|
|
||
|
wl_list_init(&surface->link);
|
||
|
wl_list_init(&surface->buffer_link);
|
||
|
|
||
|
glGenTextures(1, &surface->texture);
|
||
|
glBindTexture(GL_TEXTURE_2D, surface->texture);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||
|
|
||
|
surface->surface.resource.client = NULL;
|
||
|
|
||
|
surface->visual = WAYLAND_NONE_VISUAL;
|
||
|
surface->saved_texture = 0;
|
||
|
surface->x = x;
|
||
|
surface->y = y;
|
||
|
surface->width = width;
|
||
|
surface->height = height;
|
||
|
surface->buffer = NULL;
|
||
|
|
||
|
pixman_region32_init(&surface->damage);
|
||
|
pixman_region32_init(&surface->opaque);
|
||
|
|
||
|
wl_list_init(&surface->frame_callbacks);
|
||
|
|
||
|
surface->buffer_destroy_listener.func =
|
||
|
_e_mod_comp_wl_surface_buffer_destroy_handle;
|
||
|
|
||
|
return surface;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_destroy(struct wl_client *client __UNUSED__, struct wl_resource *resource)
|
||
|
{
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
wl_resource_destroy(resource, e_mod_comp_wl_time_get());
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_attach(struct wl_client *client __UNUSED__, struct wl_resource *resource, struct wl_resource *buffer_resource, int32_t x, int32_t y)
|
||
|
{
|
||
|
Wayland_Surface *ws;
|
||
|
Wayland_Shell *shell;
|
||
|
struct wl_buffer *buffer;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
ws = resource->data;
|
||
|
buffer = buffer_resource->data;
|
||
|
shell = e_mod_comp_wl_shell_get();
|
||
|
|
||
|
e_mod_comp_wl_surface_damage_below(ws);
|
||
|
|
||
|
if (ws->buffer)
|
||
|
{
|
||
|
e_mod_comp_wl_buffer_post_release(ws->buffer);
|
||
|
wl_list_remove(&ws->buffer_destroy_listener.link);
|
||
|
}
|
||
|
|
||
|
buffer->busy_count++;
|
||
|
ws->buffer = buffer;
|
||
|
wl_list_insert(ws->buffer->resource.destroy_listener_list.prev,
|
||
|
&ws->buffer_destroy_listener.link);
|
||
|
|
||
|
if (!ws->visual)
|
||
|
shell->map(shell, ws, buffer->width, buffer->height);
|
||
|
else if ((x != 0) || (y != 0) || (ws->width != buffer->width) ||
|
||
|
(ws->height != buffer->height))
|
||
|
shell->configure(shell, ws, ws->x + x, ws->y + y,
|
||
|
buffer->width, buffer->height);
|
||
|
|
||
|
e_mod_comp_wl_buffer_attach(buffer, &ws->surface);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_damage(struct wl_client *client __UNUSED__, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height)
|
||
|
{
|
||
|
Wayland_Surface *ws;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
ws = resource->data;
|
||
|
_e_mod_comp_wl_surface_damage_rectangle(ws, x, y, width, height);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback)
|
||
|
{
|
||
|
Wayland_Surface *ws;
|
||
|
Wayland_Frame_Callback *cb;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
ws = resource->data;
|
||
|
|
||
|
if (!(cb = malloc(sizeof(*cb))))
|
||
|
{
|
||
|
wl_resource_post_no_memory(resource);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
cb->resource.object.interface = &wl_callback_interface;
|
||
|
cb->resource.object.id = callback;
|
||
|
cb->resource.destroy = _e_mod_comp_wl_surface_frame_destroy_callback;
|
||
|
cb->resource.client = client;
|
||
|
cb->resource.data = cb;
|
||
|
|
||
|
wl_client_add_resource(client, &cb->resource);
|
||
|
|
||
|
wl_list_insert(ws->frame_callbacks.prev, &cb->link);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_destroy_surface(struct wl_resource *resource)
|
||
|
{
|
||
|
Wayland_Surface *ws;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
ws = container_of(resource, Wayland_Surface, surface.resource);
|
||
|
|
||
|
e_mod_comp_wl_surface_damage_below(ws);
|
||
|
|
||
|
_e_mod_comp_wl_surface_flush_damage(ws);
|
||
|
|
||
|
wl_list_remove(&ws->link);
|
||
|
|
||
|
e_mod_comp_wl_comp_repick();
|
||
|
|
||
|
if (!ws->saved_texture)
|
||
|
glDeleteTextures(1, &ws->texture);
|
||
|
else
|
||
|
glDeleteTextures(1, &ws->saved_texture);
|
||
|
|
||
|
if (ws->buffer)
|
||
|
wl_list_remove(&ws->buffer_destroy_listener.link);
|
||
|
|
||
|
wl_list_remove(&ws->buffer_link);
|
||
|
|
||
|
pixman_region32_fini(&ws->damage);
|
||
|
pixman_region32_fini(&ws->opaque);
|
||
|
|
||
|
free(ws);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_draw(Wayland_Surface *ws, Wayland_Output *output __UNUSED__, pixman_region32_t *clip)
|
||
|
{
|
||
|
Wayland_Compositor *comp;
|
||
|
GLfloat *v;
|
||
|
pixman_region32_t repaint;
|
||
|
GLint filter;
|
||
|
int n = 0;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
comp = e_mod_comp_wl_comp_get();
|
||
|
pixman_region32_init_rect(&repaint, ws->x, ws->y, ws->width, ws->height);
|
||
|
pixman_region32_intersect(&repaint, &repaint, clip);
|
||
|
if (!pixman_region32_not_empty(&repaint)) return;
|
||
|
switch (ws->visual)
|
||
|
{
|
||
|
case WAYLAND_ARGB_VISUAL:
|
||
|
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||
|
glEnable(GL_BLEND);
|
||
|
break;
|
||
|
case WAYLAND_RGB_VISUAL:
|
||
|
glDisable(GL_BLEND);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (ws->alpha != comp->current_alpha)
|
||
|
{
|
||
|
glUniform1f(comp->texture_shader.alpha_uniform, ws->alpha / 255.0);
|
||
|
comp->current_alpha = ws->alpha;
|
||
|
}
|
||
|
|
||
|
if (ws->transform == NULL)
|
||
|
{
|
||
|
filter = GL_NEAREST;
|
||
|
n = _e_mod_comp_wl_surface_texture_region(ws, &repaint);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
filter = GL_LINEAR;
|
||
|
n = _e_mod_comp_wl_surface_texture_transformed_surface(ws);
|
||
|
}
|
||
|
|
||
|
glBindTexture(GL_TEXTURE_2D, ws->texture);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||
|
|
||
|
v = comp->vertices.data;
|
||
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(*v), &v[0]);
|
||
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(*v), &v[2]);
|
||
|
glEnableVertexAttribArray(0);
|
||
|
glEnableVertexAttribArray(1);
|
||
|
glDrawElements(GL_TRIANGLES, n * 6, GL_UNSIGNED_INT, comp->indices.data);
|
||
|
|
||
|
comp->vertices.size = 0;
|
||
|
comp->indices.size = 0;
|
||
|
pixman_region32_fini(&repaint);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_damage_surface(Wayland_Surface *ws)
|
||
|
{
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
_e_mod_comp_wl_surface_damage_rectangle(ws, 0, 0, ws->width, ws->height);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_transform(Wayland_Surface *ws, int32_t x, int32_t y, int32_t *sx, int32_t *sy)
|
||
|
{
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
*sx = x - ws->x;
|
||
|
*sy = y - ws->y;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_configure(Wayland_Surface *ws, int32_t x, int32_t y, int32_t width, int32_t height)
|
||
|
{
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
e_mod_comp_wl_surface_damage_below(ws);
|
||
|
|
||
|
ws->x = x;
|
||
|
ws->y = y;
|
||
|
ws->width = width;
|
||
|
ws->height = height;
|
||
|
|
||
|
e_mod_comp_wl_surface_assign_output(ws);
|
||
|
e_mod_comp_wl_surface_damage_surface(ws);
|
||
|
|
||
|
pixman_region32_fini(&ws->opaque);
|
||
|
if (ws->visual == WAYLAND_RGB_VISUAL)
|
||
|
pixman_region32_init_rect(&ws->opaque, ws->x, ws->y, ws->width, ws->height);
|
||
|
else
|
||
|
pixman_region32_init(&ws->opaque);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_assign_output(Wayland_Surface *ws)
|
||
|
{
|
||
|
Wayland_Output *output;
|
||
|
pixman_region32_t region;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
output = e_mod_comp_wl_output_get();
|
||
|
pixman_region32_init_rect(®ion, ws->x, ws->y, ws->width, ws->height);
|
||
|
pixman_region32_intersect(®ion, ®ion, &output->region);
|
||
|
|
||
|
/* NB: maybe region32_extents if we handle more than one output */
|
||
|
|
||
|
if (!wl_list_empty(&ws->frame_callbacks))
|
||
|
{
|
||
|
wl_list_insert_list(output->frame_callbacks.prev,
|
||
|
&ws->frame_callbacks);
|
||
|
wl_list_init(&ws->frame_callbacks);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_damage_below(Wayland_Surface *ws)
|
||
|
{
|
||
|
Wayland_Compositor *comp;
|
||
|
Wayland_Surface *below;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
comp = e_mod_comp_wl_comp_get();
|
||
|
if (ws->link.next == &comp->surfaces) return;
|
||
|
below = container_of(ws->link.next, Wayland_Surface, link);
|
||
|
pixman_region32_union_rect(&below->damage, &below->damage,
|
||
|
ws->x, ws->y, ws->width, ws->height);
|
||
|
e_mod_comp_wl_comp_schedule_repaint();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e_mod_comp_wl_surface_activate(Wayland_Surface *ws, Wayland_Input *device, uint32_t timestamp)
|
||
|
{
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
_e_mod_comp_wl_surface_raise(ws);
|
||
|
wl_input_device_set_keyboard_focus(&device->input_device, &ws->surface, timestamp);
|
||
|
wl_data_device_set_keyboard_focus(&device->input_device);
|
||
|
}
|
||
|
|
||
|
Eina_Bool
|
||
|
e_mod_comp_wl_surface_move(Wayland_Surface *ws, Wayland_Input *wi, uint32_t timestamp)
|
||
|
{
|
||
|
/* TODO: Code me */
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
wl_input_device_set_pointer_focus(&wi->input_device, NULL, timestamp,
|
||
|
0, 0, 0, 0);
|
||
|
return EINA_TRUE;
|
||
|
}
|
||
|
|
||
|
Eina_Bool
|
||
|
e_mod_comp_wl_surface_resize(Wayland_Shell_Surface *wss, Wayland_Input *wi, uint32_t timestamp, uint32_t edges)
|
||
|
{
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
/* TODO: Code me */
|
||
|
|
||
|
wl_input_device_set_pointer_focus(&wi->input_device, NULL, timestamp,
|
||
|
0, 0, 0, 0);
|
||
|
return EINA_TRUE;
|
||
|
}
|
||
|
|
||
|
/* local functions */
|
||
|
static void
|
||
|
_e_mod_comp_wl_surface_buffer_destroy_handle(struct wl_listener *listener, struct wl_resource *resource __UNUSED__, uint32_t timestamp __UNUSED__)
|
||
|
{
|
||
|
Wayland_Surface *ws;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
ws = container_of(listener, Wayland_Surface, buffer_destroy_listener);
|
||
|
ws->buffer = NULL;
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
_e_mod_comp_wl_surface_texture_region(Wayland_Surface *ws, pixman_region32_t *region)
|
||
|
{
|
||
|
Wayland_Compositor *comp;
|
||
|
GLfloat *v, inv_width, inv_height;
|
||
|
pixman_box32_t *rects;
|
||
|
unsigned int *p;
|
||
|
int i, n;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
comp = e_mod_comp_wl_comp_get();
|
||
|
rects = pixman_region32_rectangles(region, &n);
|
||
|
v = wl_array_add(&comp->vertices, n * 16 * sizeof *v);
|
||
|
p = wl_array_add(&comp->indices, n * 6 * sizeof *p);
|
||
|
inv_width = 1.0 / ws->pitch;
|
||
|
inv_height = 1.0 / ws->height;
|
||
|
|
||
|
for (i = 0; i < n; i++, v += 16, p += 6) {
|
||
|
v[ 0] = rects[i].x1;
|
||
|
v[ 1] = rects[i].y1;
|
||
|
v[ 2] = (GLfloat) (rects[i].x1 - ws->x) * inv_width;
|
||
|
v[ 3] = (GLfloat) (rects[i].y1 - ws->y) * inv_height;
|
||
|
|
||
|
v[ 4] = rects[i].x1;
|
||
|
v[ 5] = rects[i].y2;
|
||
|
v[ 6] = v[ 2];
|
||
|
v[ 7] = (GLfloat) (rects[i].y2 - ws->y) * inv_height;
|
||
|
|
||
|
v[ 8] = rects[i].x2;
|
||
|
v[ 9] = rects[i].y1;
|
||
|
v[10] = (GLfloat) (rects[i].x2 - ws->x) * inv_width;
|
||
|
v[11] = v[ 3];
|
||
|
|
||
|
v[12] = rects[i].x2;
|
||
|
v[13] = rects[i].y2;
|
||
|
v[14] = v[10];
|
||
|
v[15] = v[ 7];
|
||
|
|
||
|
p[0] = i * 4 + 0;
|
||
|
p[1] = i * 4 + 1;
|
||
|
p[2] = i * 4 + 2;
|
||
|
p[3] = i * 4 + 2;
|
||
|
p[4] = i * 4 + 1;
|
||
|
p[5] = i * 4 + 3;
|
||
|
}
|
||
|
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
_e_mod_comp_wl_surface_texture_transformed_surface(Wayland_Surface *ws)
|
||
|
{
|
||
|
Wayland_Compositor *comp;
|
||
|
GLfloat *v;
|
||
|
unsigned int *p;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
comp = e_mod_comp_wl_comp_get();
|
||
|
v = wl_array_add(&comp->vertices, 16 * sizeof *v);
|
||
|
p = wl_array_add(&comp->indices, 6 * sizeof *p);
|
||
|
|
||
|
_e_mod_comp_wl_surface_transform_vertex(ws, ws->x, ws->y, 0.0, 0.0, &v[0]);
|
||
|
_e_mod_comp_wl_surface_transform_vertex(ws, ws->x, ws->y + ws->height,
|
||
|
0.0, 1.0, &v[4]);
|
||
|
_e_mod_comp_wl_surface_transform_vertex(ws, ws->x + ws->width, ws->y,
|
||
|
1.0, 0.0, &v[8]);
|
||
|
_e_mod_comp_wl_surface_transform_vertex(ws, ws->x + ws->width,
|
||
|
ws->y + ws->height, 1.0, 1.0,
|
||
|
&v[12]);
|
||
|
|
||
|
p[0] = 0;
|
||
|
p[1] = 1;
|
||
|
p[2] = 2;
|
||
|
p[3] = 2;
|
||
|
p[4] = 1;
|
||
|
p[5] = 3;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_e_mod_comp_wl_surface_transform_vertex(Wayland_Surface *ws, GLfloat x, GLfloat y, GLfloat u, GLfloat v, GLfloat *r)
|
||
|
{
|
||
|
Wayland_Vector t;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
t.f[0] = x;
|
||
|
t.f[1] = y;
|
||
|
t.f[2] = 0.0;
|
||
|
t.f[3] = 1.0;
|
||
|
|
||
|
e_mod_comp_wl_matrix_transform(&ws->transform->matrix, &t);
|
||
|
|
||
|
r[ 0] = t.f[0];
|
||
|
r[ 1] = t.f[1];
|
||
|
r[ 2] = u;
|
||
|
r[ 3] = v;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_e_mod_comp_wl_surface_frame_destroy_callback(struct wl_resource *resource)
|
||
|
{
|
||
|
Wayland_Frame_Callback *cb;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
cb = resource->data;
|
||
|
wl_list_remove(&cb->link);
|
||
|
free(cb);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_e_mod_comp_wl_surface_damage_rectangle(Wayland_Surface *ws, int32_t x, int32_t y, int32_t width, int32_t height)
|
||
|
{
|
||
|
Wayland_Compositor *comp;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
comp = e_mod_comp_wl_comp_get();
|
||
|
pixman_region32_union_rect(&ws->damage, &ws->damage,
|
||
|
ws->x + x, ws->y + y, width, height);
|
||
|
e_mod_comp_wl_comp_schedule_repaint();
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_e_mod_comp_wl_surface_flush_damage(Wayland_Surface *ws)
|
||
|
{
|
||
|
Wayland_Compositor *comp;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
comp = e_mod_comp_wl_comp_get();
|
||
|
if (ws->link.next != &comp->surfaces)
|
||
|
{
|
||
|
Wayland_Surface *below;
|
||
|
|
||
|
below = container_of(ws->link.next, Wayland_Surface, link);
|
||
|
pixman_region32_union(&below->damage, &below->damage, &ws->damage);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_e_mod_comp_wl_surface_raise(Wayland_Surface *ws)
|
||
|
{
|
||
|
Wayland_Compositor *comp;
|
||
|
|
||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||
|
|
||
|
comp = e_mod_comp_wl_comp_get();
|
||
|
wl_list_remove(&ws->link);
|
||
|
wl_list_insert(&comp->surfaces, &ws->link);
|
||
|
e_mod_comp_wl_comp_repick();
|
||
|
e_mod_comp_wl_surface_damage_surface(ws);
|
||
|
}
|