aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_surface.h8
-rw-r--r--include/wlr/types/wlr_xdg_shell_v6.h7
-rw-r--r--types/wlr_surface.c21
-rw-r--r--types/wlr_xdg_shell_v6.c15
4 files changed, 51 insertions, 0 deletions
diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h
index 0a802ea3..d76fff16 100644
--- a/include/wlr/types/wlr_surface.h
+++ b/include/wlr/types/wlr_surface.h
@@ -70,4 +70,12 @@ void wlr_surface_get_matrix(struct wlr_surface *surface,
const float (*projection)[16],
const float (*transform)[16]);
+
+/**
+ * Set the lifetime role for this surface. Returns 0 on success or -1 if the
+ * role cannot be set.
+ */
+int wlr_surface_set_role(struct wlr_surface *surface, const char *role,
+ struct wl_resource *error_resource, uint32_t error_code);
+
#endif
diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h
index 500dae87..6bc37940 100644
--- a/include/wlr/types/wlr_xdg_shell_v6.h
+++ b/include/wlr/types/wlr_xdg_shell_v6.h
@@ -10,10 +10,17 @@ struct wlr_xdg_shell_v6 {
void *data;
};
+enum wlr_xdg_surface_v6_role {
+ WLR_XDG_SURFACE_V6_ROLE_NONE,
+ WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL,
+ WLR_XDG_SURFACE_V6_ROLE_POPUP,
+};
+
struct wlr_xdg_surface_v6 {
struct wl_resource *resource;
struct wl_resource *surface;
struct wl_list link;
+ enum wlr_xdg_surface_v6_role role;
struct wl_listener surface_destroy_listener;
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index 9f329b7d..a9a54abe 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -422,3 +422,24 @@ void wlr_surface_get_matrix(struct wlr_surface *surface,
wlr_matrix_mul(matrix, &scale, matrix);
wlr_matrix_mul(projection, matrix, matrix);
}
+
+int wlr_surface_set_role(struct wlr_surface *surface, const char *role,
+ struct wl_resource *error_resource, uint32_t error_code) {
+ assert(role);
+
+ if (surface->role == NULL ||
+ surface->role == role ||
+ strcmp(surface->role, role) == 0) {
+ surface->role = role;
+
+ return 0;
+ }
+
+ wl_resource_post_error(error_resource, error_code,
+ "Cannot assign role %s to wl_surface@%d, already has role %s\n",
+ role,
+ wl_resource_get_id(surface->resource),
+ surface->role);
+
+ return -1;
+}
diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c
index 46416c4e..2fff054d 100644
--- a/types/wlr_xdg_shell_v6.c
+++ b/types/wlr_xdg_shell_v6.c
@@ -2,9 +2,12 @@
#include <stdlib.h>
#include <wayland-server.h>
#include <wlr/types/wlr_xdg_shell_v6.h>
+#include <wlr/types/wlr_surface.h>
#include <wlr/util/log.h>
#include "xdg-shell-unstable-v6-protocol.h"
+static const char *wlr_desktop_xdg_toplevel_role = "xdg_toplevel";
+
static void resource_destroy(struct wl_client *client,
struct wl_resource *resource) {
// TODO: we probably need to do more than this
@@ -114,8 +117,19 @@ static void xdg_surface_resource_destroy(struct wl_resource *resource) {
static void xdg_surface_get_toplevel(struct wl_client *client,
struct wl_resource *resource, uint32_t id) {
// TODO: Flesh out
+ struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource);
+ struct wlr_surface *wsurface = wl_resource_get_user_data(surface->surface);
+
+ if (wlr_surface_set_role(wsurface, wlr_desktop_xdg_toplevel_role,
+ resource, ZXDG_SHELL_V6_ERROR_ROLE)) {
+ return;
+ }
+
+ surface->role = WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL;
+
struct wl_resource *toplevel_resource = wl_resource_create(client,
&zxdg_toplevel_v6_interface, wl_resource_get_version(resource), id);
+
wl_resource_set_implementation(toplevel_resource,
&zxdg_toplevel_v6_implementation, NULL, NULL);
struct wl_display *display = wl_client_get_display(client);
@@ -167,6 +181,7 @@ static void xdg_shell_get_xdg_surface(struct wl_client *client,
if (!(surface = calloc(1, sizeof(struct wlr_xdg_surface_v6)))) {
return;
}
+ surface->role = WLR_XDG_SURFACE_V6_ROLE_NONE;
surface->surface = _surface;
surface->resource = wl_resource_create(client,
&zxdg_surface_v6_interface, wl_resource_get_version(_xdg_shell), id);