aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sway/tree/container.h4
-rw-r--r--sway/desktop/transaction.c4
-rw-r--r--sway/tree/container.c47
3 files changed, 55 insertions, 0 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 37a6b2b3..93f6bfbb 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -91,6 +91,10 @@ struct sway_container {
} border;
struct wlr_scene_tree *content_tree;
+ struct wlr_scene_buffer *output_handler;
+
+ struct wl_listener output_enter;
+ struct wl_listener output_leave;
struct sway_container_state current;
struct sway_container_state pending;
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index 980e839e..acc3e3f9 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -385,6 +385,10 @@ static void arrange_container(struct sway_container *con,
// make sure it's enabled for viewing
wlr_scene_node_set_enabled(&con->scene_tree->node, true);
+ if (con->output_handler) {
+ wlr_scene_buffer_set_dest_size(con->output_handler, width, height);
+ }
+
if (con->view) {
int border_top = container_titlebar_height();
int border_width = con->current.border_thickness;
diff --git a/sway/tree/container.c b/sway/tree/container.c
index b19081fc..30cb97ba 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -25,6 +25,35 @@
#include "log.h"
#include "stringop.h"
+static void handle_output_enter(
+ struct wl_listener *listener, void *data) {
+ struct sway_container *con = wl_container_of(
+ listener, con, output_enter);
+ struct wlr_scene_output *output = data;
+
+ if (con->view->foreign_toplevel) {
+ wlr_foreign_toplevel_handle_v1_output_enter(
+ con->view->foreign_toplevel, output->output);
+ }
+}
+
+static void handle_output_leave(
+ struct wl_listener *listener, void *data) {
+ struct sway_container *con = wl_container_of(
+ listener, con, output_leave);
+ struct wlr_scene_output *output = data;
+
+ if (con->view->foreign_toplevel) {
+ wlr_foreign_toplevel_handle_v1_output_leave(
+ con->view->foreign_toplevel, output->output);
+ }
+}
+
+static bool handle_point_accepts_input(
+ struct wlr_scene_buffer *buffer, double *x, double *y) {
+ return false;
+}
+
static struct wlr_scene_rect *alloc_rect_node(struct wlr_scene_tree *parent,
bool *failed) {
if (*failed) {
@@ -63,6 +92,7 @@ struct sway_container *container_create(struct sway_view *view) {
// - content_tree (we put the content node here so when we disable the
// border everything gets disabled. We only render the content iff there
// is a border as well)
+ // - buffer used for output enter/leave events for foreign_toplevel
bool failed = false;
c->scene_tree = alloc_scene_tree(root->staging, &failed);
@@ -90,6 +120,22 @@ struct sway_container *container_create(struct sway_view *view) {
c->border.bottom = alloc_rect_node(c->border.tree, &failed);
c->border.left = alloc_rect_node(c->border.tree, &failed);
c->border.right = alloc_rect_node(c->border.tree, &failed);
+
+ c->output_handler = wlr_scene_buffer_create(c->border.tree, NULL);
+ if (!c->output_handler) {
+ sway_log(SWAY_ERROR, "Failed to allocate a scene node");
+ failed = true;
+ }
+
+ if (!failed) {
+ c->output_enter.notify = handle_output_enter;
+ wl_signal_add(&c->output_handler->events.output_enter,
+ &c->output_enter);
+ c->output_leave.notify = handle_output_leave;
+ wl_signal_add(&c->output_handler->events.output_leave,
+ &c->output_leave);
+ c->output_handler->point_accepts_input = handle_point_accepts_input;
+ }
}
if (!failed && !scene_descriptor_assign(&c->scene_tree->node,
@@ -456,6 +502,7 @@ void container_destroy(struct sway_container *con) {
if (con->view && con->view->container == con) {
con->view->container = NULL;
+ wlr_scene_node_destroy(&con->output_handler->node);
if (con->view->destroying) {
view_destroy(con->view);
}