mirror of
https://github.com/cage-kiosk/cage.git
synced 2025-10-29 05:40:19 -04:00
xdg_shell: add support for wlr-foreign-toplevel-management
This commit is contained in:
parent
2e593fe5a8
commit
b35d0afae4
6 changed files with 129 additions and 9 deletions
8
cage.c
8
cage.c
|
|
@ -24,6 +24,7 @@
|
|||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_idle_notify_v1.h>
|
||||
|
|
@ -527,6 +528,13 @@ main(int argc, char *argv[])
|
|||
goto end;
|
||||
}
|
||||
|
||||
server.foreign_toplevel_manager = wlr_foreign_toplevel_manager_v1_create(server.wl_display);
|
||||
if (!server.foreign_toplevel_manager) {
|
||||
wlr_log(WLR_ERROR, "Unable to create the foreign toplevel manager");
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
#if CAGE_HAS_XWAYLAND
|
||||
struct wlr_xcursor_manager *xcursor_manager = NULL;
|
||||
struct wlr_xwayland *xwayland = wlr_xwayland_create(server.wl_display, compositor, true);
|
||||
|
|
|
|||
6
seat.c
6
seat.c
|
|
@ -945,6 +945,8 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view)
|
|||
|
||||
if (prev_view) {
|
||||
view_activate(prev_view, false);
|
||||
if (prev_view->foreign_toplevel_handle)
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(prev_view->foreign_toplevel_handle, false);
|
||||
}
|
||||
|
||||
/* Move the view to the front, but only if it isn't a
|
||||
|
|
@ -955,6 +957,10 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view)
|
|||
}
|
||||
|
||||
view_activate(view, true);
|
||||
|
||||
if (view->foreign_toplevel_handle)
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(view->foreign_toplevel_handle, true);
|
||||
|
||||
char *title = view_get_title(view);
|
||||
struct cg_output *output;
|
||||
wl_list_for_each (output, &server->outputs, link) {
|
||||
|
|
|
|||
3
server.h
3
server.h
|
|
@ -4,6 +4,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
||||
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_idle_notify_v1.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
|
|
@ -61,6 +62,8 @@ struct cg_server {
|
|||
|
||||
struct wlr_relative_pointer_manager_v1 *relative_pointer_manager;
|
||||
|
||||
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
|
||||
|
||||
bool xdg_decoration;
|
||||
bool allow_vt_switch;
|
||||
bool return_app_code;
|
||||
|
|
|
|||
2
view.h
2
view.h
|
|
@ -32,6 +32,8 @@ struct cg_view {
|
|||
|
||||
enum cg_view_type type;
|
||||
const struct cg_view_impl *impl;
|
||||
|
||||
struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel_handle;
|
||||
};
|
||||
|
||||
struct cg_view_impl {
|
||||
|
|
|
|||
109
xdg_shell.c
109
xdg_shell.c
|
|
@ -10,10 +10,12 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
#include "seat.h"
|
||||
#include "server.h"
|
||||
#include "view.h"
|
||||
#include "xdg_shell.h"
|
||||
|
|
@ -183,21 +185,61 @@ destroy(struct cg_view *view)
|
|||
free(xdg_shell_view);
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_toplevel_set_fullscreen(struct cg_xdg_shell_view *xdg_shell_view, bool fullscreen)
|
||||
{
|
||||
struct wlr_box layout_box;
|
||||
wlr_output_layout_get_box(xdg_shell_view->view.server->output_layout, NULL, &layout_box);
|
||||
wlr_xdg_toplevel_set_size(xdg_shell_view->xdg_toplevel, layout_box.width, layout_box.height);
|
||||
wlr_xdg_toplevel_set_fullscreen(xdg_shell_view->xdg_toplevel, fullscreen);
|
||||
|
||||
if (xdg_shell_view->view.foreign_toplevel_handle) {
|
||||
wlr_foreign_toplevel_handle_v1_set_fullscreen(xdg_shell_view->view.foreign_toplevel_handle, fullscreen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_xdg_toplevel_request_fullscreen(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, request_fullscreen);
|
||||
|
||||
/**
|
||||
* Certain clients do not like figuring out their own window geometry if they
|
||||
* display in fullscreen mode, so we set it here.
|
||||
*/
|
||||
struct wlr_box layout_box;
|
||||
wlr_output_layout_get_box(xdg_shell_view->view.server->output_layout, NULL, &layout_box);
|
||||
wlr_xdg_toplevel_set_size(xdg_shell_view->xdg_toplevel, layout_box.width, layout_box.height);
|
||||
xdg_toplevel_set_fullscreen(xdg_shell_view, xdg_shell_view->xdg_toplevel->requested.fullscreen);
|
||||
}
|
||||
|
||||
wlr_xdg_toplevel_set_fullscreen(xdg_shell_view->xdg_toplevel,
|
||||
xdg_shell_view->xdg_toplevel->requested.fullscreen);
|
||||
static void
|
||||
handle_foreign_toplevel_request_activate(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct cg_foreign_toplevel_handle *foreign_toplevel =
|
||||
wl_container_of(listener, foreign_toplevel, request_activate);
|
||||
struct cg_xdg_shell_view *xdg_shell_view = foreign_toplevel->view;
|
||||
struct cg_view *view = &xdg_shell_view->view;
|
||||
|
||||
if (view->scene_tree) {
|
||||
wlr_scene_node_raise_to_top(&view->scene_tree->node);
|
||||
}
|
||||
|
||||
seat_set_focus(view->server->seat, view);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_foreign_toplevel_request_close(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct cg_foreign_toplevel_handle *foreign_toplevel =
|
||||
wl_container_of(listener, foreign_toplevel, request_close);
|
||||
struct cg_xdg_shell_view *xdg_shell_view = foreign_toplevel->view;
|
||||
|
||||
wlr_xdg_toplevel_send_close(xdg_shell_view->xdg_toplevel);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_foreign_toplevel_request_fullscreen(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct cg_foreign_toplevel_handle *foreign_toplevel =
|
||||
wl_container_of(listener, foreign_toplevel, request_fullscreen);
|
||||
struct cg_xdg_shell_view *xdg_shell_view = foreign_toplevel->view;
|
||||
struct wlr_foreign_toplevel_handle_v1_fullscreen_event *event = data;
|
||||
|
||||
xdg_toplevel_set_fullscreen(xdg_shell_view, event->fullscreen);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -206,6 +248,10 @@ handle_xdg_toplevel_unmap(struct wl_listener *listener, void *data)
|
|||
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, unmap);
|
||||
struct cg_view *view = &xdg_shell_view->view;
|
||||
|
||||
if (view->foreign_toplevel_handle) {
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(view->foreign_toplevel_handle, false);
|
||||
}
|
||||
|
||||
view_unmap(view);
|
||||
}
|
||||
|
||||
|
|
@ -216,6 +262,14 @@ handle_xdg_toplevel_map(struct wl_listener *listener, void *data)
|
|||
struct cg_view *view = &xdg_shell_view->view;
|
||||
|
||||
view_map(view, xdg_shell_view->xdg_toplevel->base->surface);
|
||||
|
||||
if (view->foreign_toplevel_handle) {
|
||||
wlr_foreign_toplevel_handle_v1_set_title(view->foreign_toplevel_handle,
|
||||
xdg_shell_view->xdg_toplevel->title);
|
||||
wlr_foreign_toplevel_handle_v1_set_app_id(view->foreign_toplevel_handle,
|
||||
xdg_shell_view->xdg_toplevel->app_id);
|
||||
/* Activation state will be set by seat_set_focus */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -240,6 +294,19 @@ handle_xdg_toplevel_destroy(struct wl_listener *listener, void *data)
|
|||
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, destroy);
|
||||
struct cg_view *view = &xdg_shell_view->view;
|
||||
|
||||
if (xdg_shell_view->foreign_toplevel) {
|
||||
wl_list_remove(&xdg_shell_view->foreign_toplevel->request_activate.link);
|
||||
wl_list_remove(&xdg_shell_view->foreign_toplevel->request_close.link);
|
||||
wl_list_remove(&xdg_shell_view->foreign_toplevel->request_fullscreen.link);
|
||||
free(xdg_shell_view->foreign_toplevel);
|
||||
xdg_shell_view->foreign_toplevel = NULL;
|
||||
}
|
||||
|
||||
if (view->foreign_toplevel_handle) {
|
||||
wlr_foreign_toplevel_handle_v1_destroy(view->foreign_toplevel_handle);
|
||||
view->foreign_toplevel_handle = NULL;
|
||||
}
|
||||
|
||||
wl_list_remove(&xdg_shell_view->commit.link);
|
||||
wl_list_remove(&xdg_shell_view->map.link);
|
||||
wl_list_remove(&xdg_shell_view->unmap.link);
|
||||
|
|
@ -275,6 +342,9 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data)
|
|||
view_init(&xdg_shell_view->view, server, CAGE_XDG_SHELL_VIEW, &xdg_shell_view_impl);
|
||||
xdg_shell_view->xdg_toplevel = toplevel;
|
||||
|
||||
xdg_shell_view->view.foreign_toplevel_handle =
|
||||
wlr_foreign_toplevel_handle_v1_create(server->foreign_toplevel_manager);
|
||||
|
||||
xdg_shell_view->commit.notify = handle_xdg_toplevel_commit;
|
||||
wl_signal_add(&toplevel->base->surface->events.commit, &xdg_shell_view->commit);
|
||||
xdg_shell_view->map.notify = handle_xdg_toplevel_map;
|
||||
|
|
@ -286,6 +356,27 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data)
|
|||
xdg_shell_view->request_fullscreen.notify = handle_xdg_toplevel_request_fullscreen;
|
||||
wl_signal_add(&toplevel->events.request_fullscreen, &xdg_shell_view->request_fullscreen);
|
||||
|
||||
if (xdg_shell_view->view.foreign_toplevel_handle) {
|
||||
struct cg_foreign_toplevel_handle *foreign_toplevel =
|
||||
calloc(1, sizeof(struct cg_foreign_toplevel_handle));
|
||||
if (!foreign_toplevel) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate foreign toplevel handle");
|
||||
} else {
|
||||
foreign_toplevel->view = xdg_shell_view;
|
||||
xdg_shell_view->foreign_toplevel = foreign_toplevel;
|
||||
|
||||
foreign_toplevel->request_activate.notify = handle_foreign_toplevel_request_activate;
|
||||
wl_signal_add(&xdg_shell_view->view.foreign_toplevel_handle->events.request_activate,
|
||||
&foreign_toplevel->request_activate);
|
||||
foreign_toplevel->request_close.notify = handle_foreign_toplevel_request_close;
|
||||
wl_signal_add(&xdg_shell_view->view.foreign_toplevel_handle->events.request_close,
|
||||
&foreign_toplevel->request_close);
|
||||
foreign_toplevel->request_fullscreen.notify = handle_foreign_toplevel_request_fullscreen;
|
||||
wl_signal_add(&xdg_shell_view->view.foreign_toplevel_handle->events.request_fullscreen,
|
||||
&foreign_toplevel->request_fullscreen);
|
||||
}
|
||||
}
|
||||
|
||||
toplevel->base->data = xdg_shell_view;
|
||||
}
|
||||
|
||||
|
|
|
|||
10
xdg_shell.h
10
xdg_shell.h
|
|
@ -7,6 +7,14 @@
|
|||
|
||||
#include "view.h"
|
||||
|
||||
struct cg_foreign_toplevel_handle {
|
||||
struct cg_xdg_shell_view *view;
|
||||
|
||||
struct wl_listener request_activate;
|
||||
struct wl_listener request_close;
|
||||
struct wl_listener request_fullscreen;
|
||||
};
|
||||
|
||||
struct cg_xdg_shell_view {
|
||||
struct cg_view view;
|
||||
struct wlr_xdg_toplevel *xdg_toplevel;
|
||||
|
|
@ -16,6 +24,8 @@ struct cg_xdg_shell_view {
|
|||
struct wl_listener unmap;
|
||||
struct wl_listener map;
|
||||
struct wl_listener request_fullscreen;
|
||||
|
||||
struct cg_foreign_toplevel_handle *foreign_toplevel;
|
||||
};
|
||||
|
||||
struct cg_xdg_decoration {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue