Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions libswc/compositor.c
Original file line number Diff line number Diff line change
Expand Up @@ -836,3 +836,28 @@ compositor_finalize(void)
pixman_region32_fini(&compositor.opaque);
wl_global_destroy(compositor.global);
}

void compositor_view_restack_above(struct compositor_view *view, struct wl_list *link)
{
wl_list_remove(&view->link);
wl_list_insert(link, &view->link);
damage_view(view);
update(&view->base);
}

void compositor_view_restack_below(struct compositor_view* view, struct wl_list *link)
{
compositor_view_restack_above(view, link->next);
}

void
compositor_view_restack_at_head(struct compositor_view* view)
{
compositor_view_restack_above(view, &compositor.views);
}

void
compositor_view_restack_at_tail(struct compositor_view* view)
{
compositor_view_restack_above(view, compositor.views.prev);
}
5 changes: 5 additions & 0 deletions libswc/compositor.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,9 @@ void compositor_view_hide(struct compositor_view *view);
void compositor_view_set_border_color(struct compositor_view *view, uint32_t color);
void compositor_view_set_border_width(struct compositor_view *view, uint32_t width);

void compositor_view_restack_above(struct compositor_view *view, struct wl_list *link);
void compositor_view_restack_below(struct compositor_view *view, struct wl_list *link);
void compositor_view_restack_at_head(struct compositor_view *view);
void compositor_view_restack_at_tail(struct compositor_view *view);

#endif
7 changes: 4 additions & 3 deletions libswc/subcompositor.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ static void
get_subsurface(struct wl_client *client, struct wl_resource *resource,
uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource)
{
struct subsurface *subsurface;

subsurface = subsurface_new(client, wl_resource_get_version(resource), id);
struct surface *surface = wl_resource_get_user_data(surface_resource);
struct surface *parent = wl_resource_get_user_data(parent_resource);
struct subsurface *subsurface;

subsurface = subsurface_new(client, wl_resource_get_version(resource), id, surface, parent);
if (!subsurface) {
wl_resource_post_no_memory(resource);
return;
Expand Down
108 changes: 97 additions & 11 deletions libswc/subsurface.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,40 +21,46 @@
* SOFTWARE.
*/

#include "compositor.h"
#include "subsurface.h"
#include "util.h"

#include <stdlib.h>
#include <stdbool.h>
#include <wayland-server.h>

static void
set_position(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y)
{
/* TODO: Implement. */
struct subsurface *subsurface = wl_resource_get_user_data(resource);

subsurface->position.x = x;
subsurface->position.y = y;
subsurface->position.set = true;
}

static void
place_above(struct wl_client *client, struct wl_resource *resource, struct wl_resource *sibling_resource)
{
/* TODO: Implement. */
DEBUG("subsurface::place_above\n");
}

static void
place_below(struct wl_client *client, struct wl_resource *resource, struct wl_resource *sibling_resource)
{
/* TODO: Implement. */
DEBUG("subsurface::place_below\n");
}

static void
set_sync(struct wl_client *client, struct wl_resource *resource)
{
/* TODO: Implement. */
DEBUG("subsurface::set_sync\n");
}

static void
set_desync(struct wl_client *client, struct wl_resource *resource)
{
/* TODO: Implement. */
DEBUG("subsurface::set_desync\n");
}

static const struct wl_subsurface_interface subsurface_impl = {
Expand All @@ -67,31 +73,111 @@ static const struct wl_subsurface_interface subsurface_impl = {
};

static void
subsurface_destroy(struct wl_resource *resource)
unlink_from_parent(struct subsurface* subsurface)
{
struct subsurface *subsurface = wl_resource_get_user_data(resource);
wl_list_remove(&subsurface->parent_link);
wl_list_remove(&subsurface->parent_destroy_listener.link);
subsurface->parent = NULL;
}

static void
subsurface_destroy(struct subsurface *subsurface)
{
if (subsurface->parent)
unlink_from_parent(subsurface);

struct compositor_view *comp_view = compositor_view(subsurface->surface->view);
if (comp_view)
compositor_view_destroy(comp_view);

wl_list_remove(&subsurface->surface_destroy_listener.link);

free(subsurface);
}

static void
subsurface_destroy_handler(struct wl_resource *resource)
{
struct subsurface *subsurface = wl_resource_get_user_data(resource);
if (subsurface)
subsurface_destroy(subsurface);
}

static void
subsurface_handle_surface_destroy(struct wl_listener *listener, void *data)
{
struct subsurface *subsurface;
subsurface = wl_container_of(listener, subsurface, surface_destroy_listener);

if (subsurface->resource)
wl_resource_set_user_data(subsurface->resource, NULL);

subsurface_destroy(subsurface);
}

static void
subsurface_handle_parent_destroy(struct wl_listener *listener, void *data)
{
struct subsurface *subsurface;
subsurface = wl_container_of(listener, subsurface, parent_destroy_listener);

struct compositor_view *comp_view = compositor_view(subsurface->surface->view);
if (comp_view)
compositor_view_hide(comp_view);

unlink_from_parent(subsurface);
}

struct subsurface *
subsurface_new(struct wl_client *client, uint32_t version, uint32_t id)
subsurface_new(struct wl_client *client, uint32_t version, uint32_t id, struct surface *surface, struct surface *parent)
{
struct subsurface *subsurface;

if (!(subsurface = malloc(sizeof(*subsurface))))
goto error0;

subsurface->resource = wl_resource_create(client, &wl_subsurface_interface, version, id);

if (!subsurface->resource)
goto error1;
wl_resource_set_implementation(subsurface->resource, &subsurface_impl, subsurface, &subsurface_destroy_handler);

subsurface->surface = surface;
subsurface->parent = parent;

subsurface->surface_destroy_listener.notify = subsurface_handle_surface_destroy;
subsurface->parent_destroy_listener.notify = subsurface_handle_parent_destroy;
wl_signal_add(&surface->destroy_signal, &subsurface->surface_destroy_listener);
wl_signal_add(&parent->destroy_signal, &subsurface->parent_destroy_listener);

wl_list_insert(&parent->subsurface_list, &subsurface->parent_link);

wl_resource_set_implementation(subsurface->resource, &subsurface_impl, subsurface, &subsurface_destroy);
subsurface->synchronized = true;

return subsurface;
struct compositor_view *comp_view = compositor_create_view(subsurface->surface);
compositor_view_show(comp_view);

return subsurface;

error1:
free(subsurface);
error0:
return NULL;
}

void
subsurface_parent_commit(struct subsurface *subsurface, bool is_parent_synchronized)
{
if (subsurface->position.set) {
int32_t oldx = subsurface->parent->view->geometry.x;
int32_t oldy = subsurface->parent->view->geometry.y;
int32_t newx = oldx + subsurface->position.x;
int32_t newy = oldy + subsurface->position.y;
view_move(subsurface->surface->view, newx, newy);

subsurface->position.set = false;
}

if (is_parent_synchronized || subsurface->synchronized) {
// TODO: handle this
}
}
21 changes: 20 additions & 1 deletion libswc/subsurface.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,33 @@
#ifndef SWC_SUBSURFACE_H
#define SWC_SUBSURFACE_H

#include "surface.h"

#include <stdbool.h>
#include <stdint.h>

struct wl_client;

struct subsurface {
struct wl_resource *resource;

struct surface *surface;
struct wl_listener surface_destroy_listener;

struct surface *parent;
struct wl_listener parent_destroy_listener;
struct wl_list parent_link;

struct {
int32_t x;
int32_t y;
bool set;
} position;

bool synchronized;
};

struct subsurface *subsurface_new(struct wl_client *client, uint32_t version, uint32_t id);
struct subsurface *subsurface_new(struct wl_client *client, uint32_t version, uint32_t id, struct surface *surface, struct surface *parent);
void subsurface_parent_commit(struct subsurface *subsurface, bool is_parent_synchronized);

#endif
12 changes: 11 additions & 1 deletion libswc/surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*/

#include "surface.h"
#include "subsurface.h"
#include "event.h"
#include "internal.h"
#include "output.h"
Expand Down Expand Up @@ -263,6 +264,11 @@ commit(struct wl_client *client, struct wl_resource *resource)
}

surface->pending.commit = 0;

struct subsurface *sub;
wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
subsurface_parent_commit(sub, false);
}
}

static void
Expand Down Expand Up @@ -305,6 +311,8 @@ surface_destroy(struct wl_resource *resource)
{
struct surface *surface = wl_resource_get_user_data(resource);

wl_signal_emit(&surface->destroy_signal, surface);

state_finalize(&surface->state);
state_finalize(&surface->pending.state);

Expand Down Expand Up @@ -339,10 +347,13 @@ surface_new(struct wl_client *client, uint32_t version, uint32_t id)
surface->pending.commit = 0;
surface->view = NULL;
surface->view_handler.impl = &view_handler_impl;
wl_list_init(&surface->subsurface_list);

state_initialize(&surface->state);
state_initialize(&surface->pending.state);

wl_signal_init(&surface->destroy_signal);

return surface;

error1:
Expand All @@ -361,7 +372,6 @@ surface_set_view(struct surface *surface, struct view *view)
wl_list_remove(&surface->view_handler.link);

surface->view = view;

if (view) {
wl_list_insert(&view->handlers, &surface->view_handler.link);
view_attach(view, surface->state.buffer);
Expand Down
3 changes: 3 additions & 0 deletions libswc/surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ struct surface {

struct view *view;
struct view_handler view_handler;

struct wl_signal destroy_signal;
struct wl_list subsurface_list;
};

struct surface *surface_new(struct wl_client *client, uint32_t version, uint32_t id);
Expand Down
21 changes: 21 additions & 0 deletions libswc/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ swc_window_set_stacked(struct swc_window *base)
if (window->impl->set_mode)
window->impl->set_mode(window, WINDOW_MODE_STACKED);
window->mode = WINDOW_MODE_STACKED;

window_raise(window);
}

EXPORT void
Expand All @@ -186,6 +188,8 @@ swc_window_set_tiled(struct swc_window *base)
if (window->impl->set_mode)
window->impl->set_mode(window, WINDOW_MODE_TILED);
window->mode = WINDOW_MODE_TILED;

window_drop(window);
}

EXPORT void
Expand Down Expand Up @@ -479,6 +483,8 @@ window_begin_move(struct window *window, struct button *button)
begin_interaction(&window->move.interaction, button);
window->move.offset.x = geometry->x - px;
window->move.offset.y = geometry->y - py;

window_raise(window);
}

void
Expand All @@ -505,3 +511,18 @@ window_begin_resize(struct window *window, uint32_t edges, struct button *button
window->resize.offset.y = geometry->y - py + ((edges & SWC_WINDOW_EDGE_BOTTOM) ? geometry->height : 0);
window->resize.edges = edges;
}

void
window_raise(struct window *window)
{
/* TODO: recursively raise other windows in the same tree */
compositor_view_restack_at_head(window->view);
}

void
window_drop(struct window *window)
{
/* TODO: recursively drop other windows in the same tree */
compositor_view_restack_at_tail(window->view);
}

2 changes: 2 additions & 0 deletions libswc/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,7 @@ void window_set_app_id(struct window *window, const char *app_id);
void window_set_parent(struct window *window, struct window *parent);
void window_begin_move(struct window *window, struct button *button);
void window_begin_resize(struct window *window, uint32_t edges, struct button *button);
void window_raise(struct window *window);
void window_drop(struct window *window);

#endif
Loading