aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/xwayland.c
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2018-04-05 11:38:14 -0400
committerLibravatar emersion <contact@emersion.fr>2018-04-05 11:40:39 -0400
commitdcd15a2d3dd93e057fe702238eb21dd70331b44f (patch)
treed3fb74ee77369ad52edeba7bac1f3ada907d3099 /sway/desktop/xwayland.c
parentError handling in swaylock daemonize() (diff)
downloadsway-dcd15a2d3dd93e057fe702238eb21dd70331b44f.tar.gz
sway-dcd15a2d3dd93e057fe702238eb21dd70331b44f.tar.zst
sway-dcd15a2d3dd93e057fe702238eb21dd70331b44f.zip
Implement shell views
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r--sway/desktop/xwayland.c123
1 files changed, 66 insertions, 57 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index a793928c..384f4236 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -41,13 +41,17 @@ static void create_unmanaged(struct wlr_xwayland_surface *xsurface) {
41} 41}
42 42
43 43
44static bool assert_xwayland(struct sway_view *view) { 44static struct sway_xwayland_view *xwayland_view_from_view(
45 return sway_assert(view->type == SWAY_VIEW_XWAYLAND, 45 struct sway_view *view) {
46 "Expected xwayland view!"); 46 if (!sway_assert(view->type == SWAY_VIEW_XWAYLAND,
47 "Expected xwayland view")) {
48 return NULL;
49 }
50 return (struct sway_xwayland_view *)view;
47} 51}
48 52
49static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { 53static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) {
50 if (!assert_xwayland(view)) { 54 if (xwayland_view_from_view(view) == NULL) {
51 return NULL; 55 return NULL;
52 } 56 }
53 switch (prop) { 57 switch (prop) {
@@ -62,7 +66,8 @@ static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) {
62 66
63static void configure(struct sway_view *view, double ox, double oy, int width, 67static void configure(struct sway_view *view, double ox, double oy, int width,
64 int height) { 68 int height) {
65 if (!assert_xwayland(view)) { 69 struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view);
70 if (xwayland_view == NULL) {
66 return; 71 return;
67 } 72 }
68 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; 73 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
@@ -84,14 +89,14 @@ static void configure(struct sway_view *view, double ox, double oy, int width,
84 89
85 view_update_position(view, ox, oy); 90 view_update_position(view, ox, oy);
86 91
87 view->sway_xwayland_surface->pending_width = width; 92 xwayland_view->pending_width = width;
88 view->sway_xwayland_surface->pending_height = height; 93 xwayland_view->pending_height = height;
89 wlr_xwayland_surface_configure(xsurface, ox + loutput->x, oy + loutput->y, 94 wlr_xwayland_surface_configure(xsurface, ox + loutput->x, oy + loutput->y,
90 width, height); 95 width, height);
91} 96}
92 97
93static void set_activated(struct sway_view *view, bool activated) { 98static void set_activated(struct sway_view *view, bool activated) {
94 if (!assert_xwayland(view)) { 99 if (xwayland_view_from_view(view) == NULL) {
95 return; 100 return;
96 } 101 }
97 struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; 102 struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface;
@@ -99,12 +104,24 @@ static void set_activated(struct sway_view *view, bool activated) {
99} 104}
100 105
101static void _close(struct sway_view *view) { 106static void _close(struct sway_view *view) {
102 if (!assert_xwayland(view)) { 107 if (xwayland_view_from_view(view) == NULL) {
103 return; 108 return;
104 } 109 }
105 wlr_xwayland_surface_close(view->wlr_xwayland_surface); 110 wlr_xwayland_surface_close(view->wlr_xwayland_surface);
106} 111}
107 112
113static void destroy(struct sway_view *view) {
114 struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view);
115 if (xwayland_view == NULL) {
116 return;
117 }
118 wl_list_remove(&xwayland_view->destroy.link);
119 wl_list_remove(&xwayland_view->request_configure.link);
120 wl_list_remove(&xwayland_view->map.link);
121 wl_list_remove(&xwayland_view->unmap.link);
122 free(xwayland_view);
123}
124
108static const struct sway_view_impl view_impl = { 125static const struct sway_view_impl view_impl = {
109 .get_prop = get_prop, 126 .get_prop = get_prop,
110 .configure = configure, 127 .configure = configure,
@@ -113,50 +130,50 @@ static const struct sway_view_impl view_impl = {
113}; 130};
114 131
115static void handle_commit(struct wl_listener *listener, void *data) { 132static void handle_commit(struct wl_listener *listener, void *data) {
116 struct sway_xwayland_surface *sway_surface = 133 struct sway_xwayland_view *xwayland_view =
117 wl_container_of(listener, sway_surface, commit); 134 wl_container_of(listener, xwayland_view, commit);
118 struct sway_view *view = sway_surface->view; 135 struct sway_view *view = &xwayland_view->view;
119 // NOTE: We intentionally discard the view's desired width here 136 // NOTE: We intentionally discard the view's desired width here
120 // TODO: Let floating views do whatever 137 // TODO: Let floating views do whatever
121 view_update_size(view, sway_surface->pending_width, 138 view_update_size(view, xwayland_view->pending_width,
122 sway_surface->pending_height); 139 xwayland_view->pending_height);
123 view_damage_from(view); 140 view_damage_from(view);
124} 141}
125 142
126static void handle_destroy(struct wl_listener *listener, void *data) { 143static void handle_destroy(struct wl_listener *listener, void *data) {
127 struct sway_xwayland_surface *sway_surface = 144 struct sway_xwayland_view *xwayland_view =
128 wl_container_of(listener, sway_surface, destroy); 145 wl_container_of(listener, xwayland_view, destroy);
129 wl_list_remove(&sway_surface->commit.link); 146 view_destroy(&xwayland_view->view);
130 wl_list_remove(&sway_surface->destroy.link);
131 wl_list_remove(&sway_surface->request_configure.link);
132 wl_list_remove(&sway_surface->map.link);
133 wl_list_remove(&sway_surface->unmap.link);
134 view_destroy(sway_surface->view);
135 free(sway_surface);
136} 147}
137 148
138static void handle_unmap(struct wl_listener *listener, void *data) { 149static void handle_unmap(struct wl_listener *listener, void *data) {
139 struct sway_xwayland_surface *sway_surface = 150 struct sway_xwayland_view *xwayland_view =
140 wl_container_of(listener, sway_surface, unmap); 151 wl_container_of(listener, xwayland_view, unmap);
141 view_unmap(sway_surface->view); 152 wl_list_remove(&xwayland_view->commit.link);
153 view_unmap(&xwayland_view->view);
142} 154}
143 155
144static void handle_map(struct wl_listener *listener, void *data) { 156static void handle_map(struct wl_listener *listener, void *data) {
145 struct sway_xwayland_surface *sway_surface = 157 struct sway_xwayland_view *xwayland_view =
146 wl_container_of(listener, sway_surface, map); 158 wl_container_of(listener, xwayland_view, map);
147 struct wlr_xwayland_surface *xsurface = data; 159 struct wlr_xwayland_surface *xsurface = data;
148 struct sway_view *view = sway_surface->view; 160 struct sway_view *view = &xwayland_view->view;
161
162 // Wire up the commit listener here, because xwayland map/unmap can change
163 // the underlying wlr_surface
164 wl_signal_add(&xsurface->surface->events.commit, &xwayland_view->commit);
165 xwayland_view->commit.notify = handle_commit;
149 166
150 // put it back into the tree 167 // Put it back into the tree
151 wlr_xwayland_surface_set_maximized(xsurface, true); 168 wlr_xwayland_surface_set_maximized(xsurface, true);
152 view_map(view, xsurface->surface); 169 view_map(view, xsurface->surface);
153} 170}
154 171
155static void handle_request_configure(struct wl_listener *listener, void *data) { 172static void handle_request_configure(struct wl_listener *listener, void *data) {
156 struct sway_xwayland_surface *sway_surface = 173 struct sway_xwayland_view *xwayland_view =
157 wl_container_of(listener, sway_surface, request_configure); 174 wl_container_of(listener, xwayland_view, request_configure);
158 struct wlr_xwayland_surface_configure_event *ev = data; 175 struct wlr_xwayland_surface_configure_event *ev = data;
159 struct sway_view *view = sway_surface->view; 176 struct sway_view *view = &xwayland_view->view;
160 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; 177 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
161 // TODO: floating windows are allowed to move around like this, but make 178 // TODO: floating windows are allowed to move around like this, but make
162 // sure tiling windows always stay in place. 179 // sure tiling windows always stay in place.
@@ -165,8 +182,8 @@ static void handle_request_configure(struct wl_listener *listener, void *data) {
165} 182}
166 183
167void handle_xwayland_surface(struct wl_listener *listener, void *data) { 184void handle_xwayland_surface(struct wl_listener *listener, void *data) {
168 struct sway_server *server = wl_container_of( 185 struct sway_server *server = wl_container_of(listener, server,
169 listener, server, xwayland_surface); 186 xwayland_surface);
170 struct wlr_xwayland_surface *xsurface = data; 187 struct wlr_xwayland_surface *xsurface = data;
171 188
172 if (wlr_xwayland_surface_is_unmanaged(xsurface) || 189 if (wlr_xwayland_surface_is_unmanaged(xsurface) ||
@@ -179,39 +196,31 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
179 wlr_log(L_DEBUG, "New xwayland surface title='%s' class='%s'", 196 wlr_log(L_DEBUG, "New xwayland surface title='%s' class='%s'",
180 xsurface->title, xsurface->class); 197 xsurface->title, xsurface->class);
181 198
182 struct sway_xwayland_surface *sway_surface = 199 struct sway_xwayland_view *xwayland_view =
183 calloc(1, sizeof(struct sway_xwayland_surface)); 200 calloc(1, sizeof(struct sway_xwayland_view));
184 if (!sway_assert(sway_surface, "Failed to allocate surface")) { 201 if (!sway_assert(xwayland_view, "Failed to allocate view")) {
185 return; 202 return;
186 } 203 }
187 204
188 struct sway_view *view = view_create(SWAY_VIEW_XWAYLAND, &view_impl); 205 view_init(&xwayland_view->view, SWAY_VIEW_XWAYLAND, &view_impl);
189 if (!sway_assert(view, "Failed to allocate view")) { 206 xwayland_view->view.wlr_xwayland_surface = xsurface;
190 return;
191 }
192 view->wlr_xwayland_surface = xsurface;
193 view->sway_xwayland_surface = sway_surface;
194 sway_surface->view = view;
195 207
196 // TODO: 208 // TODO:
197 // - Look up pid and open on appropriate workspace 209 // - Look up pid and open on appropriate workspace
198 // - Criteria 210 // - Criteria
199 211
200 wl_signal_add(&xsurface->surface->events.commit, &sway_surface->commit); 212 wl_signal_add(&xsurface->events.destroy, &xwayland_view->destroy);
201 sway_surface->commit.notify = handle_commit; 213 xwayland_view->destroy.notify = handle_destroy;
202
203 wl_signal_add(&xsurface->events.destroy, &sway_surface->destroy);
204 sway_surface->destroy.notify = handle_destroy;
205 214
206 wl_signal_add(&xsurface->events.request_configure, 215 wl_signal_add(&xsurface->events.request_configure,
207 &sway_surface->request_configure); 216 &xwayland_view->request_configure);
208 sway_surface->request_configure.notify = handle_request_configure; 217 xwayland_view->request_configure.notify = handle_request_configure;
209 218
210 wl_signal_add(&xsurface->events.unmap, &sway_surface->unmap); 219 wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap);
211 sway_surface->unmap.notify = handle_unmap; 220 xwayland_view->unmap.notify = handle_unmap;
212 221
213 wl_signal_add(&xsurface->events.map, &sway_surface->map); 222 wl_signal_add(&xsurface->events.map, &xwayland_view->map);
214 sway_surface->map.notify = handle_map; 223 xwayland_view->map.notify = handle_map;
215 224
216 handle_map(&sway_surface->map, xsurface); 225 handle_map(&xwayland_view->map, xsurface);
217} 226}