summaryrefslogtreecommitdiff
path: root/tinywl
diff options
context:
space:
mode:
Diffstat (limited to 'tinywl')
-rw-r--r--tinywl/tinywl.c56
1 files changed, 45 insertions, 11 deletions
diff --git a/tinywl/tinywl.c b/tinywl/tinywl.c
index c7dfa3a..973780a 100644
--- a/tinywl/tinywl.c
+++ b/tinywl/tinywl.c
@@ -6,7 +6,6 @@
#include <stdio.h>
#include <time.h>
#include <scenefx/render/fx_renderer/fx_renderer.h>
-#include <scenefx/types/fx/shadow_data.h>
#include <scenefx/types/wlr_scene.h>
#include <unistd.h>
#include <wayland-server-core.h>
@@ -85,9 +84,11 @@ struct tinywl_toplevel {
struct wl_list link;
struct tinywl_server *server;
struct wlr_xdg_toplevel *xdg_toplevel;
+ struct wlr_scene_tree *xdg_scene_tree;
struct wlr_scene_tree *scene_tree;
struct wl_listener map;
struct wl_listener unmap;
+ struct wl_listener commit;
struct wl_listener destroy;
struct wl_listener request_move;
struct wl_listener request_resize;
@@ -96,7 +97,7 @@ struct tinywl_toplevel {
float opacity;
int corner_radius;
- struct shadow_data shadow_data;
+ struct wlr_scene_shadow *shadow;
};
struct tinywl_keyboard {
@@ -583,13 +584,10 @@ static void output_configure_scene(struct wlr_scene_node *node,
if (toplevel &&
xdg_surface &&
xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
- // TODO: Be able to set whole decoration_data instead of calling
- // each individually?
wlr_scene_buffer_set_opacity(buffer, toplevel->opacity);
if (!wlr_subsurface_try_from_wlr_surface(xdg_surface->surface)) {
wlr_scene_buffer_set_corner_radius(buffer, toplevel->corner_radius);
- wlr_scene_buffer_set_shadow_data(buffer, toplevel->shadow_data);
}
}
} else if (node->type == WLR_SCENE_NODE_TREE) {
@@ -707,15 +705,30 @@ static void xdg_toplevel_map(struct wl_listener *listener, void *data) {
/* Called when the surface is mapped, or ready to display on-screen. */
struct tinywl_toplevel *toplevel = wl_container_of(listener, toplevel, map);
+ wlr_scene_node_set_enabled(&toplevel->scene_tree->node, true);
+
wl_list_insert(&toplevel->server->toplevels, &toplevel->link);
- focus_toplevel(toplevel, toplevel->xdg_toplevel->base->surface);
+ struct wlr_surface *surface = toplevel->xdg_toplevel->base->surface;
+
+ int blur_sigma = toplevel->shadow->blur_sigma;
+ struct wlr_box geometry;
+ wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &geometry);
+ wlr_scene_shadow_set_size(toplevel->shadow,
+ geometry.width + blur_sigma * 2,
+ geometry.height + blur_sigma * 2);
+
+ wlr_scene_node_set_position(&toplevel->shadow->node, -blur_sigma, -blur_sigma);
+
+ focus_toplevel(toplevel, surface);
}
static void xdg_toplevel_unmap(struct wl_listener *listener, void *data) {
/* Called when the surface is unmapped, and should no longer be shown. */
struct tinywl_toplevel *toplevel = wl_container_of(listener, toplevel, unmap);
+ wlr_scene_node_set_enabled(&toplevel->scene_tree->node, false);
+
/* Reset the cursor mode if the grabbed toplevel was unmapped. */
if (toplevel == toplevel->server->grabbed_toplevel) {
reset_cursor_mode(toplevel->server);
@@ -724,18 +737,33 @@ static void xdg_toplevel_unmap(struct wl_listener *listener, void *data) {
wl_list_remove(&toplevel->link);
}
+static void xdg_toplevel_commit(struct wl_listener *listener, void *data) {
+ struct tinywl_toplevel *toplevel = wl_container_of(listener, toplevel, commit);
+
+ struct wlr_box geometry;
+ wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &geometry);
+ wlr_scene_subsurface_tree_set_clip(&toplevel->xdg_scene_tree->node, &geometry);
+
+ int blur_sigma = toplevel->shadow->blur_sigma;
+ wlr_scene_shadow_set_size(toplevel->shadow,
+ geometry.width + blur_sigma * 2, geometry.height + blur_sigma * 2);
+}
+
static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) {
/* Called when the xdg_toplevel is destroyed. */
struct tinywl_toplevel *toplevel = wl_container_of(listener, toplevel, destroy);
wl_list_remove(&toplevel->map.link);
wl_list_remove(&toplevel->unmap.link);
+ wl_list_remove(&toplevel->commit.link);
wl_list_remove(&toplevel->destroy.link);
wl_list_remove(&toplevel->request_move.link);
wl_list_remove(&toplevel->request_resize.link);
wl_list_remove(&toplevel->request_maximize.link);
wl_list_remove(&toplevel->request_fullscreen.link);
+ wlr_scene_node_destroy(&toplevel->scene_tree->node);
+
free(toplevel);
}
@@ -847,23 +875,29 @@ static void server_new_xdg_surface(struct wl_listener *listener, void *data) {
struct tinywl_toplevel *toplevel = calloc(1, sizeof(*toplevel));
toplevel->server = server;
toplevel->xdg_toplevel = xdg_surface->toplevel;
- toplevel->scene_tree = wlr_scene_xdg_surface_create(
- &toplevel->server->scene->tree, toplevel->xdg_toplevel->base);
+ toplevel->scene_tree = wlr_scene_tree_create(&toplevel->server->scene->tree);
+ toplevel->xdg_scene_tree = wlr_scene_xdg_surface_create(
+ toplevel->scene_tree, toplevel->xdg_toplevel->base);
toplevel->scene_tree->node.data = toplevel;
xdg_surface->data = toplevel->scene_tree;
/* Set the scene_nodes decoration data */
toplevel->opacity = 1;
toplevel->corner_radius = 20;
- toplevel->shadow_data = shadow_data_get_default();
- toplevel->shadow_data.enabled = true;
- toplevel->shadow_data.color = (struct wlr_render_color) {1.0f, 0.0f, 0.0f, 1.0f};
+
+ float blur_sigma = 20.0f;
+ toplevel->shadow = wlr_scene_shadow_create(toplevel->scene_tree,
+ 0, 0, toplevel->corner_radius, blur_sigma, (float[4]){ 1.0f, 0.f, 0.f, 1.0f });
+ // Lower the shadow below the XDG scene tree
+ wlr_scene_node_lower_to_bottom(&toplevel->shadow->node);
/* Listen to the various events it can emit */
toplevel->map.notify = xdg_toplevel_map;
wl_signal_add(&xdg_surface->surface->events.map, &toplevel->map);
toplevel->unmap.notify = xdg_toplevel_unmap;
wl_signal_add(&xdg_surface->surface->events.unmap, &toplevel->unmap);
+ toplevel->commit.notify = xdg_toplevel_commit;
+ wl_signal_add(&xdg_surface->surface->events.commit, &toplevel->commit);
toplevel->destroy.notify = xdg_toplevel_destroy;
wl_signal_add(&xdg_surface->events.destroy, &toplevel->destroy);