wlserver: Initial hookup of xdg-shell

This commit is contained in:
Joshua Ashton 2023-01-23 11:59:46 +00:00 committed by Joshie
parent f14dc8cfb8
commit b167dfbf94
4 changed files with 1445 additions and 0 deletions

View file

@ -7,6 +7,7 @@ protocols = [
'gamescope-pipewire',
'gamescope-input-method',
'gamescope-tearing-control-unstable-v1',
'xdg-shell',
]
protocols_client_src = []

1351
protocol/xdg-shell.xml Normal file

File diff suppressed because it is too large Load diff

View file

@ -31,6 +31,7 @@ extern "C" {
#include <wlr/types/wlr_touch.h>
#include <wlr/util/log.h>
#include <wlr/xwayland/server.h>
#include <wlr/types/wlr_xdg_shell.h>
#undef static
#undef class
}
@ -929,6 +930,69 @@ void gamescope_xwayland_server_t::update_output_info()
wlr_output_set_description(output, info->description);
}
static void xdg_toplevel_map(struct wl_listener *listener, void *data) {
struct wlserver_xdg_surface_info* info =
wl_container_of(listener, info, map);
wl_list_insert(&wlserver.mapped_xdg_views, &info->link);
}
static void xdg_toplevel_unmap(struct wl_listener *listener, void *data) {
struct wlserver_xdg_surface_info* info =
wl_container_of(listener, info, unmap);
wl_list_remove(&info->link);
}
static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) {
struct wlserver_xdg_surface_info* info =
wl_container_of(listener, info, destroy);
wl_list_remove(&info->map.link);
wl_list_remove(&info->unmap.link);
wl_list_remove(&info->destroy.link);
wlserver_wl_surface_info *wlserver_surface = get_wl_surface_info(info->xdg_toplevel->base->surface);
if (!wlserver_surface)
{
wl_log.infof("No base surface info. (destroy)");
return;
}
wlserver_surface->xdg_surface = nullptr;
delete info;
}
void xdg_surface_new(struct wl_listener *listener, void *data)
{
struct wlr_xdg_surface *xdg_surface = (struct wlr_xdg_surface *)data;
if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
{
wl_log.infof("Not top level surface.");
return;
}
wlserver_wl_surface_info *wlserver_surface = get_wl_surface_info(xdg_surface->surface);
if (!wlserver_surface)
{
wl_log.infof("No base surface info. (new)");
return;
}
wlserver_xdg_surface_info *xdg_surface_info = new wlserver_xdg_surface_info;
wlserver_surface->xdg_surface = xdg_surface_info;
xdg_surface_info->xdg_toplevel = xdg_surface->toplevel;
xdg_surface_info->map.notify = xdg_toplevel_map;
wl_signal_add(&xdg_surface->events.map, &xdg_surface_info->map);
xdg_surface_info->unmap.notify = xdg_toplevel_unmap;
wl_signal_add(&xdg_surface->events.unmap, &xdg_surface_info->unmap);
xdg_surface_info->destroy.notify = xdg_toplevel_destroy;
wl_signal_add(&xdg_surface->events.destroy, &xdg_surface_info->destroy);
}
bool wlserver_init( void ) {
assert( wlserver.display != nullptr );
@ -980,6 +1044,17 @@ bool wlserver_init( void ) {
create_gamescope_tearing();
wlserver.xdg_shell = wlr_xdg_shell_create(wlserver.display, 3);
if (!wlserver.xdg_shell)
{
wl_log.infof("Unable to create XDG shell interface");
return false;
}
wlserver.new_xdg_surface.notify = xdg_surface_new;
wl_signal_add(&wlserver.xdg_shell->events.new_surface, &wlserver.new_xdg_surface);
wl_list_init(&wlserver.mapped_xdg_views);
int result = -1;
int display_slot = 0;

View file

@ -127,6 +127,10 @@ struct wlserver_t {
struct wl_listener session_active;
struct wl_listener new_input_method;
struct wlr_xdg_shell *xdg_shell;
struct wl_listener new_xdg_surface;
struct wl_list mapped_xdg_views;
};
struct wlserver_keyboard {
@ -225,9 +229,23 @@ struct wlserver_x11_surface_info
gamescope_xwayland_server_t *xwayland_server;
};
struct wlserver_xdg_surface_info
{
struct wlr_xdg_toplevel *xdg_toplevel = nullptr;
struct wl_list link;
struct wl_listener map;
struct wl_listener unmap;
struct wl_listener destroy;
};
struct wlserver_wl_surface_info
{
wlserver_x11_surface_info *x11_surface = nullptr;
wlserver_xdg_surface_info *xdg_surface = nullptr;
struct wlr_surface *wlr = nullptr;
struct wl_listener commit;
struct wl_listener destroy;