aboutsummaryrefslogtreecommitdiff
path: root/sway/desktop/xdg_shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/xdg_shell.c')
-rw-r--r--sway/desktop/xdg_shell.c113
1 files changed, 60 insertions, 53 deletions
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index 11c112be..fed820cf 100644
--- a/sway/desktop/xdg_shell.c
+++ b/sway/desktop/xdg_shell.c
@@ -7,7 +7,7 @@
#include <wlr/util/edges.h>
#include "log.h"
#include "sway/decoration.h"
-#include "sway/desktop.h"
+#include "sway/scene_descriptor.h"
#include "sway/desktop/transaction.h"
#include "sway/input/cursor.h"
#include "sway/input/input-manager.h"
@@ -19,41 +19,29 @@
#include "sway/tree/workspace.h"
#include "sway/xdg_decoration.h"
-static const struct sway_view_child_impl popup_impl;
-
-static void popup_get_view_coords(struct sway_view_child *child,
- int *sx, int *sy) {
- struct sway_xdg_popup *popup = (struct sway_xdg_popup *)child;
- struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_popup;
+static struct sway_xdg_popup *popup_create(
+ struct wlr_xdg_popup *wlr_popup, struct sway_view *view,
+ struct wlr_scene_tree *parent);
- wlr_xdg_popup_get_toplevel_coords(wlr_popup,
- wlr_popup->current.geometry.x - wlr_popup->base->current.geometry.x,
- wlr_popup->current.geometry.y - wlr_popup->base->current.geometry.y,
- sx, sy);
+static void popup_handle_new_popup(struct wl_listener *listener, void *data) {
+ struct sway_xdg_popup *popup =
+ wl_container_of(listener, popup, new_popup);
+ struct wlr_xdg_popup *wlr_popup = data;
+ popup_create(wlr_popup, popup->view, popup->xdg_surface_tree);
}
-static void popup_destroy(struct sway_view_child *child) {
- if (!sway_assert(child->impl == &popup_impl,
- "Expected an xdg_shell popup")) {
- return;
- }
- struct sway_xdg_popup *popup = (struct sway_xdg_popup *)child;
- wl_list_remove(&popup->surface_commit.link);
+static void popup_handle_destroy(struct wl_listener *listener, void *data) {
+ struct sway_xdg_popup *popup = wl_container_of(listener, popup, destroy);
+
wl_list_remove(&popup->new_popup.link);
wl_list_remove(&popup->destroy.link);
+ wl_list_remove(&popup->surface_commit.link);
+ wlr_scene_node_destroy(&popup->scene_tree->node);
free(popup);
}
-static const struct sway_view_child_impl popup_impl = {
- .get_view_coords = popup_get_view_coords,
- .destroy = popup_destroy,
-};
-
-static struct sway_xdg_popup *popup_create(
- struct wlr_xdg_popup *wlr_popup, struct sway_view *view);
-
static void popup_unconstrain(struct sway_xdg_popup *popup) {
- struct sway_view *view = popup->child.view;
+ struct sway_view *view = popup->view;
struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_popup;
struct sway_workspace *workspace = view->container->pending.workspace;
@@ -83,29 +71,44 @@ static void popup_handle_surface_commit(struct wl_listener *listener, void *data
}
}
-static void popup_handle_new_popup(struct wl_listener *listener, void *data) {
- struct sway_xdg_popup *popup =
- wl_container_of(listener, popup, new_popup);
- struct wlr_xdg_popup *wlr_popup = data;
- popup_create(wlr_popup, popup->child.view);
-}
-
-static void popup_handle_destroy(struct wl_listener *listener, void *data) {
- struct sway_xdg_popup *popup = wl_container_of(listener, popup, destroy);
- view_child_destroy(&popup->child);
-}
-
-static struct sway_xdg_popup *popup_create(
- struct wlr_xdg_popup *wlr_popup, struct sway_view *view) {
+static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup,
+ struct sway_view *view, struct wlr_scene_tree *parent) {
struct wlr_xdg_surface *xdg_surface = wlr_popup->base;
- struct sway_xdg_popup *popup =
- calloc(1, sizeof(struct sway_xdg_popup));
- if (popup == NULL) {
+ struct sway_xdg_popup *popup = calloc(1, sizeof(struct sway_xdg_popup));
+ if (!popup) {
return NULL;
}
- view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface);
+
popup->wlr_xdg_popup = wlr_popup;
+ popup->view = view;
+
+ popup->scene_tree = wlr_scene_tree_create(parent);
+ if (!popup->scene_tree) {
+ free(popup);
+ return NULL;
+ }
+
+ popup->xdg_surface_tree = wlr_scene_xdg_surface_create(
+ popup->scene_tree, xdg_surface);
+ if (!popup->xdg_surface_tree) {
+ wlr_scene_node_destroy(&popup->scene_tree->node);
+ free(popup);
+ return NULL;
+ }
+
+ if (!scene_descriptor_assign(&popup->scene_tree->node,
+ SWAY_SCENE_DESC_POPUP, popup)) {
+ sway_log(SWAY_ERROR, "Failed to allocate a popup scene descriptor");
+ wlr_scene_node_destroy(&popup->scene_tree->node);
+ free(popup);
+ return NULL;
+ }
+
+ popup->wlr_xdg_popup = xdg_surface->popup;
+ struct sway_xdg_shell_view *shell_view =
+ wl_container_of(view, shell_view, view);
+ xdg_surface->data = shell_view;
wl_signal_add(&xdg_surface->surface->events.commit, &popup->surface_commit);
popup->surface_commit.notify = popup_handle_surface_commit;
@@ -114,9 +117,6 @@ static struct sway_xdg_popup *popup_create(
wl_signal_add(&wlr_popup->events.destroy, &popup->destroy);
popup->destroy.notify = popup_handle_destroy;
- wl_signal_add(&xdg_surface->surface->events.map, &popup->child.surface_map);
- wl_signal_add(&xdg_surface->surface->events.unmap, &popup->child.surface_unmap);
-
return popup;
}
@@ -317,7 +317,6 @@ static void handle_commit(struct wl_listener *listener, void *data) {
// The client changed its surface size in this commit. For floating
// containers, we resize the container to match. For tiling containers,
// we only recenter the surface.
- desktop_damage_view(view);
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
if (container_is_floating(view->container)) {
view_update_size(view);
@@ -330,15 +329,12 @@ static void handle_commit(struct wl_listener *listener, void *data) {
} else {
view_center_surface(view);
}
- desktop_damage_view(view);
}
if (view->container->node.instruction) {
transaction_notify_view_ready_by_serial(view,
xdg_surface->current.configure_serial);
}
-
- view_damage_from(view);
}
static void handle_set_title(struct wl_listener *listener, void *data) {
@@ -360,7 +356,16 @@ static void handle_new_popup(struct wl_listener *listener, void *data) {
struct sway_xdg_shell_view *xdg_shell_view =
wl_container_of(listener, xdg_shell_view, new_popup);
struct wlr_xdg_popup *wlr_popup = data;
- popup_create(wlr_popup, &xdg_shell_view->view);
+
+ struct sway_xdg_popup *popup = popup_create(wlr_popup,
+ &xdg_shell_view->view, root->layers.popup);
+ if (!popup) {
+ return;
+ }
+
+ int lx, ly;
+ wlr_scene_node_coords(&popup->view->content_tree->node, &lx, &ly);
+ wlr_scene_node_set_position(&popup->scene_tree->node, lx, ly);
}
static void handle_request_maximize(struct wl_listener *listener, void *data) {
@@ -567,5 +572,7 @@ void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) {
xdg_shell_view->destroy.notify = handle_destroy;
wl_signal_add(&xdg_toplevel->events.destroy, &xdg_shell_view->destroy);
+ wlr_scene_xdg_surface_create(xdg_shell_view->view.content_tree, xdg_toplevel->base);
+
xdg_toplevel->base->data = xdg_shell_view;
}