Skip to content

Commit af0a3cf

Browse files
ftyghomeemersion
authored andcommitted
Add support for wlr-foreign-toplevel-management
1 parent f9626f7 commit af0a3cf

File tree

6 files changed

+85
-7
lines changed

6 files changed

+85
-7
lines changed

cage.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <wlr/types/wlr_compositor.h>
2525
#include <wlr/types/wlr_data_device.h>
2626
#include <wlr/types/wlr_export_dmabuf_v1.h>
27+
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
2728
#include <wlr/types/wlr_gamma_control_v1.h>
2829
#include <wlr/types/wlr_idle_inhibit_v1.h>
2930
#include <wlr/types/wlr_idle_notify_v1.h>
@@ -527,6 +528,13 @@ main(int argc, char *argv[])
527528
goto end;
528529
}
529530

531+
server.foreign_toplevel_manager = wlr_foreign_toplevel_manager_v1_create(server.wl_display);
532+
if (!server.foreign_toplevel_manager) {
533+
wlr_log(WLR_ERROR, "Unable to create the foreign toplevel manager");
534+
ret = 1;
535+
goto end;
536+
}
537+
530538
#if CAGE_HAS_XWAYLAND
531539
struct wlr_xcursor_manager *xcursor_manager = NULL;
532540
struct wlr_xwayland *xwayland = wlr_xwayland_create(server.wl_display, compositor, true);

server.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ struct cg_server {
6161

6262
struct wlr_relative_pointer_manager_v1 *relative_pointer_manager;
6363

64+
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
65+
6466
bool xdg_decoration;
6567
bool allow_vt_switch;
6668
bool return_app_code;

view.c

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <stdlib.h>
1414
#include <string.h>
1515
#include <wayland-server-core.h>
16+
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
1617
#include <wlr/types/wlr_output.h>
1718
#include <wlr/types/wlr_scene.h>
1819

@@ -50,6 +51,7 @@ void
5051
view_activate(struct cg_view *view, bool activate)
5152
{
5253
view->impl->activate(view, activate);
54+
wlr_foreign_toplevel_handle_v1_set_activated(view->foreign_toplevel_handle, activate);
5355
}
5456

5557
static bool
@@ -115,20 +117,39 @@ view_unmap(struct cg_view *view)
115117
{
116118
wl_list_remove(&view->link);
117119

120+
wl_list_remove(&view->request_activate.link);
121+
wl_list_remove(&view->request_close.link);
122+
wlr_foreign_toplevel_handle_v1_destroy(view->foreign_toplevel_handle);
123+
view->foreign_toplevel_handle = NULL;
124+
118125
wlr_scene_node_destroy(&view->scene_tree->node);
119126

120127
view->wlr_surface->data = NULL;
121128
view->wlr_surface = NULL;
122129
}
123130

131+
void
132+
handle_surface_request_activate(struct wl_listener *listener, void *data)
133+
{
134+
struct cg_view *view = wl_container_of(listener, view, request_activate);
135+
136+
wlr_scene_node_raise_to_top(&view->scene_tree->node);
137+
seat_set_focus(view->server->seat, view);
138+
}
139+
140+
void
141+
handle_surface_request_close(struct wl_listener *listener, void *data)
142+
{
143+
struct cg_view *view = wl_container_of(listener, view, request_close);
144+
view->impl->close(view);
145+
}
146+
124147
void
125148
view_map(struct cg_view *view, struct wlr_surface *surface)
126149
{
127150
view->scene_tree = wlr_scene_subsurface_tree_create(&view->server->scene->tree, surface);
128-
if (!view->scene_tree) {
129-
wl_resource_post_no_memory(surface->resource);
130-
return;
131-
}
151+
if (!view->scene_tree)
152+
goto fail;
132153
view->scene_tree->node.data = view;
133154

134155
view->wlr_surface = surface;
@@ -144,7 +165,21 @@ view_map(struct cg_view *view, struct wlr_surface *surface)
144165
}
145166

146167
wl_list_insert(&view->server->views, &view->link);
168+
169+
view->foreign_toplevel_handle = wlr_foreign_toplevel_handle_v1_create(view->server->foreign_toplevel_manager);
170+
if (!view->foreign_toplevel_handle)
171+
goto fail;
172+
173+
view->request_activate.notify = handle_surface_request_activate;
174+
wl_signal_add(&view->foreign_toplevel_handle->events.request_activate, &view->request_activate);
175+
view->request_close.notify = handle_surface_request_close;
176+
wl_signal_add(&view->foreign_toplevel_handle->events.request_close, &view->request_close);
177+
147178
seat_set_focus(view->server->seat, view);
179+
return;
180+
181+
fail:
182+
wl_resource_post_no_memory(surface->resource);
148183
}
149184

150185
void

view.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ struct cg_view {
3232

3333
enum cg_view_type type;
3434
const struct cg_view_impl *impl;
35+
36+
struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel_handle;
37+
struct wl_listener request_activate;
38+
struct wl_listener request_close;
3539
};
3640

3741
struct cg_view_impl {
@@ -41,6 +45,7 @@ struct cg_view_impl {
4145
bool (*is_transient_for)(struct cg_view *child, struct cg_view *parent);
4246
void (*activate)(struct cg_view *view, bool activate);
4347
void (*maximize)(struct cg_view *view, int output_width, int output_height);
48+
void (*close)(struct cg_view *view);
4449
void (*destroy)(struct cg_view *view);
4550
};
4651

xdg_shell.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <stdbool.h>
1111
#include <stdlib.h>
1212
#include <wayland-server-core.h>
13+
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
1314
#include <wlr/types/wlr_scene.h>
1415
#include <wlr/types/wlr_xdg_shell.h>
1516
#include <wlr/util/log.h>
@@ -183,10 +184,18 @@ destroy(struct cg_view *view)
183184
free(xdg_shell_view);
184185
}
185186

187+
static void
188+
close(struct cg_view *view)
189+
{
190+
struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view);
191+
wlr_xdg_toplevel_send_close(xdg_shell_view->xdg_toplevel);
192+
}
193+
186194
static void
187195
handle_xdg_toplevel_request_fullscreen(struct wl_listener *listener, void *data)
188196
{
189197
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, request_fullscreen);
198+
bool fullscreen = xdg_shell_view->xdg_toplevel->requested.fullscreen;
190199

191200
/**
192201
* Certain clients do not like figuring out their own window geometry if they
@@ -195,9 +204,8 @@ handle_xdg_toplevel_request_fullscreen(struct wl_listener *listener, void *data)
195204
struct wlr_box layout_box;
196205
wlr_output_layout_get_box(xdg_shell_view->view.server->output_layout, NULL, &layout_box);
197206
wlr_xdg_toplevel_set_size(xdg_shell_view->xdg_toplevel, layout_box.width, layout_box.height);
198-
199-
wlr_xdg_toplevel_set_fullscreen(xdg_shell_view->xdg_toplevel,
200-
xdg_shell_view->xdg_toplevel->requested.fullscreen);
207+
wlr_xdg_toplevel_set_fullscreen(xdg_shell_view->xdg_toplevel, fullscreen);
208+
wlr_foreign_toplevel_handle_v1_set_fullscreen(xdg_shell_view->view.foreign_toplevel_handle, fullscreen);
201209
}
202210

203211
static void
@@ -216,6 +224,10 @@ handle_xdg_toplevel_map(struct wl_listener *listener, void *data)
216224
struct cg_view *view = &xdg_shell_view->view;
217225

218226
view_map(view, xdg_shell_view->xdg_toplevel->base->surface);
227+
228+
wlr_foreign_toplevel_handle_v1_set_title(view->foreign_toplevel_handle, xdg_shell_view->xdg_toplevel->title);
229+
wlr_foreign_toplevel_handle_v1_set_app_id(view->foreign_toplevel_handle, xdg_shell_view->xdg_toplevel->app_id);
230+
/* Activation state will be set by seat_set_focus */
219231
}
220232

221233
static void
@@ -258,6 +270,7 @@ static const struct cg_view_impl xdg_shell_view_impl = {
258270
.activate = activate,
259271
.maximize = maximize,
260272
.destroy = destroy,
273+
.close = close,
261274
};
262275

263276
void

xwayland.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <stdbool.h>
1010
#include <stdlib.h>
1111
#include <wayland-server-core.h>
12+
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
1213
#include <wlr/util/log.h>
1314
#include <wlr/xwayland.h>
1415

@@ -102,12 +103,21 @@ destroy(struct cg_view *view)
102103
free(xwayland_view);
103104
}
104105

106+
static void
107+
close(struct cg_view *view)
108+
{
109+
struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view);
110+
wlr_xwayland_surface_close(xwayland_view->xwayland_surface);
111+
}
112+
105113
static void
106114
handle_xwayland_surface_request_fullscreen(struct wl_listener *listener, void *data)
107115
{
108116
struct cg_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, request_fullscreen);
109117
struct wlr_xwayland_surface *xwayland_surface = xwayland_view->xwayland_surface;
110118
wlr_xwayland_surface_set_fullscreen(xwayland_view->xwayland_surface, xwayland_surface->fullscreen);
119+
wlr_foreign_toplevel_handle_v1_set_fullscreen(xwayland_view->view.foreign_toplevel_handle,
120+
xwayland_surface->fullscreen);
111121
}
112122

113123
static void
@@ -131,6 +141,10 @@ handle_xwayland_surface_map(struct wl_listener *listener, void *data)
131141
}
132142

133143
view_map(view, xwayland_view->xwayland_surface->surface);
144+
145+
wlr_foreign_toplevel_handle_v1_set_title(view->foreign_toplevel_handle, xwayland_view->xwayland_surface->title);
146+
wlr_foreign_toplevel_handle_v1_set_app_id(view->foreign_toplevel_handle,
147+
xwayland_view->xwayland_surface->class);
134148
}
135149

136150
static void
@@ -154,6 +168,7 @@ static const struct cg_view_impl xwayland_view_impl = {
154168
.activate = activate,
155169
.maximize = maximize,
156170
.destroy = destroy,
171+
.close = close,
157172
};
158173

159174
void

0 commit comments

Comments
 (0)