diff --git a/src/mango.c b/src/mango.c index fcb38c5..839f372 100644 --- a/src/mango.c +++ b/src/mango.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -229,6 +230,11 @@ struct Client { struct wlr_scene_tree *scene; struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ struct wlr_scene_tree *scene_surface; + + struct wlr_scene_tree *image_capture_tree; + struct wlr_scene *image_capture_scene; + struct wlr_ext_image_capture_source_v1 *image_capture_source; + struct wl_list link; struct wl_list flink; struct wl_list fadeout_link; @@ -245,6 +251,8 @@ struct Client { struct wl_listener set_title; struct wl_listener fullscreen; #ifdef XWAYLAND + struct wlr_scene_surface *image_capture_scene_surface; + struct wl_listener activate; struct wl_listener associate; struct wl_listener dissociate; @@ -303,6 +311,7 @@ struct Client { float unfocused_opacity; char oldmonname[128]; int scratchpad_width, scratchpad_height; + struct wlr_ext_foreign_toplevel_handle_v1 *ext_foreign_toplevel; }; typedef struct { @@ -720,6 +729,11 @@ static unsigned int cursor_mode; static Client *grabc; static int grabcx, grabcy; /* client-relative */ +static struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1 + *ext_foreign_toplevel_image_capture_source_manager_v1; +static struct wl_listener new_foreign_toplevel_capture_request; +static struct wlr_ext_foreign_toplevel_list_v1 *foreign_toplevel_list; + static struct wlr_output_layout *output_layout; static struct wlr_box sgeom; static struct wl_list mons; @@ -1882,6 +1896,7 @@ void cleanuplisteners(void) { wl_list_remove(&request_start_drag.link); wl_list_remove(&start_drag.link); wl_list_remove(&new_session_lock.link); + wl_list_remove(&new_foreign_toplevel_capture_request.link); #ifdef XWAYLAND wl_list_remove(&new_xwayland_surface.link); wl_list_remove(&xwayland_ready.link); @@ -3184,6 +3199,22 @@ mapnotify(struct wl_listener *listener, void *data) { c->geom.width += 2 * c->bw; c->geom.height += 2 * c->bw; + c->image_capture_scene = wlr_scene_create(); + + struct wlr_ext_foreign_toplevel_handle_v1_state foreign_toplevel_state = { + .app_id = client_get_appid(c), + .title = client_get_title(c), + }; + c->image_capture_scene = wlr_scene_create(); + c->ext_foreign_toplevel = wlr_ext_foreign_toplevel_handle_v1_create( + foreign_toplevel_list, &foreign_toplevel_state); + c->ext_foreign_toplevel->data = c; + +#ifdef XWAYLAND + c->image_capture_scene_surface = wlr_scene_surface_create( + &c->image_capture_scene->tree, client_surface(c)); +#endif + /* Handle unmanaged clients first so we can return prior create borders */ if (client_is_unmanaged(c)) { /* Unmanaged clients always are floating */ @@ -3473,6 +3504,26 @@ void outputmgrapply(struct wl_listener *listener, void *data) { outputmgrapplyortest(config, 0); } +static void +handle_new_foreign_toplevel_capture_request(struct wl_listener *listener, + void *data) { + struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request + *request = data; + Client *c = request->toplevel_handle->data; + + if (c->image_capture_source == NULL) { + c->image_capture_source = + wlr_ext_image_capture_source_v1_create_with_scene_node( + &c->image_capture_scene->tree.node, event_loop, alloc, drw); + if (c->image_capture_source == NULL) { + return; + } + } + + wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request_accept( + request, c->image_capture_source); +} + void // 0.7 custom outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) { /* @@ -4297,6 +4348,15 @@ void setup(void) { power_mgr = wlr_output_power_manager_v1_create(dpy); wl_signal_add(&power_mgr->events.set_mode, &output_power_mgr_set_mode); + foreign_toplevel_list = wlr_ext_foreign_toplevel_list_v1_create(dpy, 1); + ext_foreign_toplevel_image_capture_source_manager_v1 = + wlr_ext_foreign_toplevel_image_capture_source_manager_v1_create(dpy, 1); + new_foreign_toplevel_capture_request.notify = + handle_new_foreign_toplevel_capture_request; + wl_signal_add(&ext_foreign_toplevel_image_capture_source_manager_v1->events + .new_request, + &new_foreign_toplevel_capture_request); + /* Creates an output layout, which a wlroots utility for working with an * arrangement of screens in a physical layout. */ output_layout = wlr_output_layout_create(dpy); @@ -4742,6 +4802,11 @@ void unmapnotify(struct wl_listener *listener, void *data) { c->foreign_toplevel = NULL; } + if (c->ext_foreign_toplevel) { + wlr_ext_foreign_toplevel_handle_v1_destroy(c->ext_foreign_toplevel); + c->ext_foreign_toplevel = NULL; + } + if (c->swallowedby) { setfullscreen(c->swallowedby, c->isfullscreen); setmaxmizescreen(c->swallowedby, c->ismaxmizescreen); @@ -4754,6 +4819,13 @@ void unmapnotify(struct wl_listener *listener, void *data) { c->swallowing = NULL; } +#ifdef XWAYLAND + if (client_is_x11(c)) { + wlr_scene_node_destroy(&c->image_capture_scene_surface->buffer->node); + c->image_capture_scene_surface = NULL; + } +#endif + wlr_scene_node_destroy(&c->image_capture_scene->tree.node); wlr_scene_node_destroy(&c->scene->node); printstatus(); motionnotify(0, NULL, 0, 0, 0, 0);