diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 041c1cc55..b750bb35c 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 79444cdc3..9b3057b99 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -393,6 +393,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 3a53854dd..f4bfd5085 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -32,6 +32,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, int x, int y) { + return false; +} + static struct wlr_scene_rect *alloc_rect_node(struct wlr_scene_tree *parent, bool *failed) { if (*failed) { @@ -69,6 +98,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 alloc_failure = false; c->scene_tree = alloc_scene_tree(root->staging, &alloc_failure); @@ -85,6 +115,21 @@ struct sway_container *container_create(struct sway_view *view) { c->border.bottom = alloc_rect_node(c->border.tree, &alloc_failure); c->border.left = alloc_rect_node(c->border.tree, &alloc_failure); c->border.right = alloc_rect_node(c->border.tree, &alloc_failure); + + c->output_handler = wlr_scene_buffer_create(c->border.tree, NULL); + if (!c->output_handler) { + alloc_failure = true; + } + + if (!alloc_failure) { + 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; + } } else { c->pending.children = create_list(); c->current.children = create_list(); @@ -375,6 +420,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); }