aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/xdg_shell.c
diff options
context:
space:
mode:
authorLibravatar Alexander Orzechowski <alex@ozal.ski>2023-12-06 14:28:59 -0500
committerLibravatar Kirill Primak <vyivel@eclair.cafe>2024-01-18 18:36:54 +0300
commitb38ed8b4792928dca3e1580e8160792ea41e25c4 (patch)
treeb080710c7a3f37de868ff4d5d96e6971f7105675 /sway/desktop/xdg_shell.c
parenttransaction: ready signals will return success bools (diff)
downloadsway-b38ed8b4792928dca3e1580e8160792ea41e25c4.tar.gz
sway-b38ed8b4792928dca3e1580e8160792ea41e25c4.tar.zst
sway-b38ed8b4792928dca3e1580e8160792ea41e25c4.zip
scene_graph: Port xdg_shell
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 @@
7#include <wlr/util/edges.h> 7#include <wlr/util/edges.h>
8#include "log.h" 8#include "log.h"
9#include "sway/decoration.h" 9#include "sway/decoration.h"
10#include "sway/desktop.h" 10#include "sway/scene_descriptor.h"
11#include "sway/desktop/transaction.h" 11#include "sway/desktop/transaction.h"
12#include "sway/input/cursor.h" 12#include "sway/input/cursor.h"
13#include "sway/input/input-manager.h" 13#include "sway/input/input-manager.h"
@@ -19,41 +19,29 @@
19#include "sway/tree/workspace.h" 19#include "sway/tree/workspace.h"
20#include "sway/xdg_decoration.h" 20#include "sway/xdg_decoration.h"
21 21
22static const struct sway_view_child_impl popup_impl; 22static struct sway_xdg_popup *popup_create(
23 23 struct wlr_xdg_popup *wlr_popup, struct sway_view *view,
24static void popup_get_view_coords(struct sway_view_child *child, 24 struct wlr_scene_tree *parent);
25 int *sx, int *sy) {
26 struct sway_xdg_popup *popup = (struct sway_xdg_popup *)child;
27 struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_popup;
28 25
29 wlr_xdg_popup_get_toplevel_coords(wlr_popup, 26static void popup_handle_new_popup(struct wl_listener *listener, void *data) {
30 wlr_popup->current.geometry.x - wlr_popup->base->current.geometry.x, 27 struct sway_xdg_popup *popup =
31 wlr_popup->current.geometry.y - wlr_popup->base->current.geometry.y, 28 wl_container_of(listener, popup, new_popup);
32 sx, sy); 29 struct wlr_xdg_popup *wlr_popup = data;
30 popup_create(wlr_popup, popup->view, popup->xdg_surface_tree);
33} 31}
34 32
35static void popup_destroy(struct sway_view_child *child) { 33static void popup_handle_destroy(struct wl_listener *listener, void *data) {
36 if (!sway_assert(child->impl == &popup_impl, 34 struct sway_xdg_popup *popup = wl_container_of(listener, popup, destroy);
37 "Expected an xdg_shell popup")) { 35
38 return;
39 }
40 struct sway_xdg_popup *popup = (struct sway_xdg_popup *)child;
41 wl_list_remove(&popup->surface_commit.link);
42 wl_list_remove(&popup->new_popup.link); 36 wl_list_remove(&popup->new_popup.link);
43 wl_list_remove(&popup->destroy.link); 37 wl_list_remove(&popup->destroy.link);
38 wl_list_remove(&popup->surface_commit.link);
39 wlr_scene_node_destroy(&popup->scene_tree->node);
44 free(popup); 40 free(popup);
45} 41}
46 42
47static const struct sway_view_child_impl popup_impl = {
48 .get_view_coords = popup_get_view_coords,
49 .destroy = popup_destroy,
50};
51
52static struct sway_xdg_popup *popup_create(
53 struct wlr_xdg_popup *wlr_popup, struct sway_view *view);
54
55static void popup_unconstrain(struct sway_xdg_popup *popup) { 43static void popup_unconstrain(struct sway_xdg_popup *popup) {
56 struct sway_view *view = popup->child.view; 44 struct sway_view *view = popup->view;
57 struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_popup; 45 struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_popup;
58 46
59 struct sway_workspace *workspace = view->container->pending.workspace; 47 struct sway_workspace *workspace = view->container->pending.workspace;
@@ -83,29 +71,44 @@ static void popup_handle_surface_commit(struct wl_listener *listener, void *data
83 } 71 }
84} 72}
85 73
86static void popup_handle_new_popup(struct wl_listener *listener, void *data) { 74static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup,
87 struct sway_xdg_popup *popup = 75 struct sway_view *view, struct wlr_scene_tree *parent) {
88 wl_container_of(listener, popup, new_popup);
89 struct wlr_xdg_popup *wlr_popup = data;
90 popup_create(wlr_popup, popup->child.view);
91}
92
93static void popup_handle_destroy(struct wl_listener *listener, void *data) {
94 struct sway_xdg_popup *popup = wl_container_of(listener, popup, destroy);
95 view_child_destroy(&popup->child);
96}
97
98static struct sway_xdg_popup *popup_create(
99 struct wlr_xdg_popup *wlr_popup, struct sway_view *view) {
100 struct wlr_xdg_surface *xdg_surface = wlr_popup->base; 76 struct wlr_xdg_surface *xdg_surface = wlr_popup->base;
101 77
102 struct sway_xdg_popup *popup = 78 struct sway_xdg_popup *popup = calloc(1, sizeof(struct sway_xdg_popup));
103 calloc(1, sizeof(struct sway_xdg_popup)); 79 if (!popup) {
104 if (popup == NULL) {
105 return NULL; 80 return NULL;
106 } 81 }
107 view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface); 82
108 popup->wlr_xdg_popup = wlr_popup; 83 popup->wlr_xdg_popup = wlr_popup;
84 popup->view = view;
85
86 popup->scene_tree = wlr_scene_tree_create(parent);
87 if (!popup->scene_tree) {
88 free(popup);
89 return NULL;
90 }
91
92 popup->xdg_surface_tree = wlr_scene_xdg_surface_create(
93 popup->scene_tree, xdg_surface);
94 if (!popup->xdg_surface_tree) {
95 wlr_scene_node_destroy(&popup->scene_tree->node);
96 free(popup);
97 return NULL;
98 }
99
100 if (!scene_descriptor_assign(&popup->scene_tree->node,
101 SWAY_SCENE_DESC_POPUP, popup)) {
102 sway_log(SWAY_ERROR, "Failed to allocate a popup scene descriptor");
103 wlr_scene_node_destroy(&popup->scene_tree->node);
104 free(popup);
105 return NULL;
106 }
107
108 popup->wlr_xdg_popup = xdg_surface->popup;
109 struct sway_xdg_shell_view *shell_view =
110 wl_container_of(view, shell_view, view);
111 xdg_surface->data = shell_view;
109 112
110 wl_signal_add(&xdg_surface->surface->events.commit, &popup->surface_commit); 113 wl_signal_add(&xdg_surface->surface->events.commit, &popup->surface_commit);
111 popup->surface_commit.notify = popup_handle_surface_commit; 114 popup->surface_commit.notify = popup_handle_surface_commit;
@@ -114,9 +117,6 @@ static struct sway_xdg_popup *popup_create(
114 wl_signal_add(&wlr_popup->events.destroy, &popup->destroy); 117 wl_signal_add(&wlr_popup->events.destroy, &popup->destroy);
115 popup->destroy.notify = popup_handle_destroy; 118 popup->destroy.notify = popup_handle_destroy;
116 119
117 wl_signal_add(&xdg_surface->surface->events.map, &popup->child.surface_map);
118 wl_signal_add(&xdg_surface->surface->events.unmap, &popup->child.surface_unmap);
119
120 return popup; 120 return popup;
121} 121}
122 122
@@ -317,7 +317,6 @@ static void handle_commit(struct wl_listener *listener, void *data) {
317 // The client changed its surface size in this commit. For floating 317 // The client changed its surface size in this commit. For floating
318 // containers, we resize the container to match. For tiling containers, 318 // containers, we resize the container to match. For tiling containers,
319 // we only recenter the surface. 319 // we only recenter the surface.
320 desktop_damage_view(view);
321 memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); 320 memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
322 if (container_is_floating(view->container)) { 321 if (container_is_floating(view->container)) {
323 view_update_size(view); 322 view_update_size(view);
@@ -330,15 +329,12 @@ static void handle_commit(struct wl_listener *listener, void *data) {
330 } else { 329 } else {
331 view_center_surface(view); 330 view_center_surface(view);
332 } 331 }
333 desktop_damage_view(view);
334 } 332 }
335 333
336 if (view->container->node.instruction) { 334 if (view->container->node.instruction) {
337 transaction_notify_view_ready_by_serial(view, 335 transaction_notify_view_ready_by_serial(view,
338 xdg_surface->current.configure_serial); 336 xdg_surface->current.configure_serial);
339 } 337 }
340
341 view_damage_from(view);
342} 338}
343 339
344static void handle_set_title(struct wl_listener *listener, void *data) { 340static 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) {
360 struct sway_xdg_shell_view *xdg_shell_view = 356 struct sway_xdg_shell_view *xdg_shell_view =
361 wl_container_of(listener, xdg_shell_view, new_popup); 357 wl_container_of(listener, xdg_shell_view, new_popup);
362 struct wlr_xdg_popup *wlr_popup = data; 358 struct wlr_xdg_popup *wlr_popup = data;
363 popup_create(wlr_popup, &xdg_shell_view->view); 359
360 struct sway_xdg_popup *popup = popup_create(wlr_popup,
361 &xdg_shell_view->view, root->layers.popup);
362 if (!popup) {
363 return;
364 }
365
366 int lx, ly;
367 wlr_scene_node_coords(&popup->view->content_tree->node, &lx, &ly);
368 wlr_scene_node_set_position(&popup->scene_tree->node, lx, ly);
364} 369}
365 370
366static void handle_request_maximize(struct wl_listener *listener, void *data) { 371static 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) {
567 xdg_shell_view->destroy.notify = handle_destroy; 572 xdg_shell_view->destroy.notify = handle_destroy;
568 wl_signal_add(&xdg_toplevel->events.destroy, &xdg_shell_view->destroy); 573 wl_signal_add(&xdg_toplevel->events.destroy, &xdg_shell_view->destroy);
569 574
575 wlr_scene_xdg_surface_create(xdg_shell_view->view.content_tree, xdg_toplevel->base);
576
570 xdg_toplevel->base->data = xdg_shell_view; 577 xdg_toplevel->base->data = xdg_shell_view;
571} 578}