diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-03-30 18:53:36 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-30 18:53:36 -0400 |
commit | 1b88eaee6b14987c585fcf149cc26f665c584d77 (patch) | |
tree | 047052218c4f19701f29c4e5547856f445670c5b | |
parent | Merge pull request #1669 from emersion/workspace-pointer-events (diff) | |
parent | Handle map/unmap events in xdg-shell-v6 (diff) | |
download | sway-1b88eaee6b14987c585fcf149cc26f665c584d77.tar.gz sway-1b88eaee6b14987c585fcf149cc26f665c584d77.tar.zst sway-1b88eaee6b14987c585fcf149cc26f665c584d77.zip |
Merge pull request #1665 from emersion/damage-tracking-lite
Add lite damage tracking
-rw-r--r-- | include/sway/output.h | 14 | ||||
-rw-r--r-- | include/sway/server.h | 1 | ||||
-rw-r--r-- | include/sway/tree/view.h | 8 | ||||
-rw-r--r-- | sway/desktop/layer_shell.c | 26 | ||||
-rw-r--r-- | sway/desktop/output.c | 148 | ||||
-rw-r--r-- | sway/desktop/wl_shell.c | 1 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 49 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 15 | ||||
-rw-r--r-- | sway/tree/container.c | 2 | ||||
-rw-r--r-- | sway/tree/output.c | 5 | ||||
-rw-r--r-- | sway/tree/view.c | 18 |
11 files changed, 207 insertions, 80 deletions
diff --git a/include/sway/output.h b/include/sway/output.h index 6fb79987..b4980cd8 100644 --- a/include/sway/output.h +++ b/include/sway/output.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <wayland-server.h> | 5 | #include <wayland-server.h> |
6 | #include <wlr/types/wlr_box.h> | 6 | #include <wlr/types/wlr_box.h> |
7 | #include <wlr/types/wlr_output.h> | 7 | #include <wlr/types/wlr_output.h> |
8 | #include "sway/tree/view.h" | ||
8 | 9 | ||
9 | struct sway_server; | 10 | struct sway_server; |
10 | struct sway_container; | 11 | struct sway_container; |
@@ -13,17 +14,26 @@ struct sway_output { | |||
13 | struct wlr_output *wlr_output; | 14 | struct wlr_output *wlr_output; |
14 | struct sway_container *swayc; | 15 | struct sway_container *swayc; |
15 | struct sway_server *server; | 16 | struct sway_server *server; |
16 | struct timespec last_frame; | ||
17 | 17 | ||
18 | struct wl_list layers[4]; // sway_layer_surface::link | 18 | struct wl_list layers[4]; // sway_layer_surface::link |
19 | struct wlr_box usable_area; | 19 | struct wlr_box usable_area; |
20 | 20 | ||
21 | struct wl_listener frame; | 21 | struct timespec last_frame; |
22 | struct wlr_output_damage *damage; | ||
23 | |||
22 | struct wl_listener destroy; | 24 | struct wl_listener destroy; |
23 | struct wl_listener mode; | 25 | struct wl_listener mode; |
24 | struct wl_listener transform; | 26 | struct wl_listener transform; |
25 | 27 | ||
28 | struct wl_listener damage_destroy; | ||
29 | struct wl_listener damage_frame; | ||
30 | |||
26 | pid_t bg_pid; | 31 | pid_t bg_pid; |
27 | }; | 32 | }; |
28 | 33 | ||
34 | void output_damage_whole(struct sway_output *output); | ||
35 | |||
36 | void output_damage_whole_view(struct sway_output *output, | ||
37 | struct sway_view *view); | ||
38 | |||
29 | #endif | 39 | #endif |
diff --git a/include/sway/server.h b/include/sway/server.h index db81932f..61f21cdb 100644 --- a/include/sway/server.h +++ b/include/sway/server.h | |||
@@ -25,7 +25,6 @@ struct sway_server { | |||
25 | struct sway_input_manager *input; | 25 | struct sway_input_manager *input; |
26 | 26 | ||
27 | struct wl_listener new_output; | 27 | struct wl_listener new_output; |
28 | struct wl_listener output_frame; | ||
29 | 28 | ||
30 | struct wlr_layer_shell *layer_shell; | 29 | struct wlr_layer_shell *layer_shell; |
31 | struct wl_listener layer_shell_surface; | 30 | struct wl_listener layer_shell_surface; |
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 54f6d90e..3965d2b7 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -15,6 +15,8 @@ struct sway_xdg_surface_v6 { | |||
15 | struct wl_listener request_move; | 15 | struct wl_listener request_move; |
16 | struct wl_listener request_resize; | 16 | struct wl_listener request_resize; |
17 | struct wl_listener request_maximize; | 17 | struct wl_listener request_maximize; |
18 | struct wl_listener map; | ||
19 | struct wl_listener unmap; | ||
18 | struct wl_listener destroy; | 20 | struct wl_listener destroy; |
19 | 21 | ||
20 | int pending_width, pending_height; | 22 | int pending_width, pending_height; |
@@ -28,8 +30,8 @@ struct sway_xwayland_surface { | |||
28 | struct wl_listener request_resize; | 30 | struct wl_listener request_resize; |
29 | struct wl_listener request_maximize; | 31 | struct wl_listener request_maximize; |
30 | struct wl_listener request_configure; | 32 | struct wl_listener request_configure; |
31 | struct wl_listener unmap; | ||
32 | struct wl_listener map; | 33 | struct wl_listener map; |
34 | struct wl_listener unmap; | ||
33 | struct wl_listener destroy; | 35 | struct wl_listener destroy; |
34 | 36 | ||
35 | int pending_width, pending_height; | 37 | int pending_width, pending_height; |
@@ -113,4 +115,8 @@ void view_close(struct sway_view *view); | |||
113 | 115 | ||
114 | void view_update_outputs(struct sway_view *view, const struct wlr_box *before); | 116 | void view_update_outputs(struct sway_view *view, const struct wlr_box *before); |
115 | 117 | ||
118 | void view_damage_whole(struct sway_view *view); | ||
119 | |||
120 | void view_damage_from(struct sway_view *view); | ||
121 | |||
116 | #endif | 122 | #endif |
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index f7e5d19c..5c96659a 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -4,12 +4,13 @@ | |||
4 | #include <wayland-server.h> | 4 | #include <wayland-server.h> |
5 | #include <wlr/types/wlr_box.h> | 5 | #include <wlr/types/wlr_box.h> |
6 | #include <wlr/types/wlr_layer_shell.h> | 6 | #include <wlr/types/wlr_layer_shell.h> |
7 | #include <wlr/types/wlr_output_damage.h> | ||
7 | #include <wlr/types/wlr_output.h> | 8 | #include <wlr/types/wlr_output.h> |
8 | #include <wlr/util/log.h> | 9 | #include <wlr/util/log.h> |
9 | #include "sway/layers.h" | 10 | #include "sway/layers.h" |
10 | #include "sway/tree/layout.h" | ||
11 | #include "sway/output.h" | 11 | #include "sway/output.h" |
12 | #include "sway/server.h" | 12 | #include "sway/server.h" |
13 | #include "sway/tree/layout.h" | ||
13 | 14 | ||
14 | static void apply_exclusive(struct wlr_box *usable_area, | 15 | static void apply_exclusive(struct wlr_box *usable_area, |
15 | uint32_t anchor, int32_t exclusive, | 16 | uint32_t anchor, int32_t exclusive, |
@@ -210,20 +211,26 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { | |||
210 | } else { | 211 | } else { |
211 | // TODO DAMAGE from surface damage | 212 | // TODO DAMAGE from surface damage |
212 | } | 213 | } |
214 | wlr_output_damage_add_box(output->damage, &old_geo); | ||
215 | wlr_output_damage_add_box(output->damage, &layer->geo); | ||
213 | } | 216 | } |
214 | } | 217 | } |
215 | 218 | ||
216 | static void unmap(struct wlr_layer_surface *layer_surface) { | 219 | static void unmap(struct sway_layer_surface *sway_layer) { |
217 | // TODO DAMAGE | 220 | struct wlr_output *wlr_output = sway_layer->layer_surface->output; |
221 | if (wlr_output != NULL) { | ||
222 | struct sway_output *output = wlr_output->data; | ||
223 | wlr_output_damage_add_box(output->damage, &sway_layer->geo); | ||
224 | } | ||
218 | } | 225 | } |
219 | 226 | ||
220 | static void handle_destroy(struct wl_listener *listener, void *data) { | 227 | static void handle_destroy(struct wl_listener *listener, void *data) { |
221 | struct sway_layer_surface *sway_layer = wl_container_of( | 228 | struct sway_layer_surface *sway_layer = wl_container_of(listener, |
222 | listener, sway_layer, destroy); | 229 | sway_layer, destroy); |
223 | wlr_log(L_DEBUG, "Layer surface destroyed (%s)", | 230 | wlr_log(L_DEBUG, "Layer surface destroyed (%s)", |
224 | sway_layer->layer_surface->namespace); | 231 | sway_layer->layer_surface->namespace); |
225 | if (sway_layer->layer_surface->mapped) { | 232 | if (sway_layer->layer_surface->mapped) { |
226 | unmap(sway_layer->layer_surface); | 233 | unmap(sway_layer); |
227 | } | 234 | } |
228 | wl_list_remove(&sway_layer->link); | 235 | wl_list_remove(&sway_layer->link); |
229 | wl_list_remove(&sway_layer->destroy.link); | 236 | wl_list_remove(&sway_layer->destroy.link); |
@@ -239,13 +246,16 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
239 | } | 246 | } |
240 | 247 | ||
241 | static void handle_map(struct wl_listener *listener, void *data) { | 248 | static void handle_map(struct wl_listener *listener, void *data) { |
242 | // TODO DAMAGE | 249 | struct sway_layer_surface *sway_layer = wl_container_of(listener, |
250 | sway_layer, map); | ||
251 | struct sway_output *output = sway_layer->layer_surface->output->data; | ||
252 | wlr_output_damage_add_box(output->damage, &sway_layer->geo); | ||
243 | } | 253 | } |
244 | 254 | ||
245 | static void handle_unmap(struct wl_listener *listener, void *data) { | 255 | static void handle_unmap(struct wl_listener *listener, void *data) { |
246 | struct sway_layer_surface *sway_layer = wl_container_of( | 256 | struct sway_layer_surface *sway_layer = wl_container_of( |
247 | listener, sway_layer, unmap); | 257 | listener, sway_layer, unmap); |
248 | unmap(sway_layer->layer_surface); | 258 | unmap(sway_layer); |
249 | } | 259 | } |
250 | 260 | ||
251 | void handle_layer_shell_surface(struct wl_listener *listener, void *data) { | 261 | void handle_layer_shell_surface(struct wl_listener *listener, void *data) { |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index f3416c03..c248b29e 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -6,18 +6,19 @@ | |||
6 | #include <wlr/render/wlr_renderer.h> | 6 | #include <wlr/render/wlr_renderer.h> |
7 | #include <wlr/types/wlr_box.h> | 7 | #include <wlr/types/wlr_box.h> |
8 | #include <wlr/types/wlr_matrix.h> | 8 | #include <wlr/types/wlr_matrix.h> |
9 | #include <wlr/types/wlr_output.h> | 9 | #include <wlr/types/wlr_output_damage.h> |
10 | #include <wlr/types/wlr_output_layout.h> | 10 | #include <wlr/types/wlr_output_layout.h> |
11 | #include <wlr/types/wlr_output.h> | ||
11 | #include <wlr/types/wlr_surface.h> | 12 | #include <wlr/types/wlr_surface.h> |
12 | #include <wlr/types/wlr_wl_shell.h> | 13 | #include <wlr/types/wlr_wl_shell.h> |
13 | #include "log.h" | 14 | #include "log.h" |
14 | #include "sway/tree/container.h" | ||
15 | #include "sway/input/input-manager.h" | 15 | #include "sway/input/input-manager.h" |
16 | #include "sway/input/seat.h" | 16 | #include "sway/input/seat.h" |
17 | #include "sway/layers.h" | 17 | #include "sway/layers.h" |
18 | #include "sway/tree/layout.h" | ||
19 | #include "sway/output.h" | 18 | #include "sway/output.h" |
20 | #include "sway/server.h" | 19 | #include "sway/server.h" |
20 | #include "sway/tree/container.h" | ||
21 | #include "sway/tree/layout.h" | ||
21 | #include "sway/tree/view.h" | 22 | #include "sway/tree/view.h" |
22 | 23 | ||
23 | /** | 24 | /** |
@@ -145,13 +146,13 @@ static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, | |||
145 | 146 | ||
146 | struct render_data { | 147 | struct render_data { |
147 | struct sway_output *output; | 148 | struct sway_output *output; |
148 | struct timespec *now; | 149 | struct timespec *when; |
149 | }; | 150 | }; |
150 | 151 | ||
151 | static void output_frame_view(struct sway_container *view, void *data) { | 152 | static void render_view(struct sway_container *view, void *data) { |
152 | struct render_data *rdata = data; | 153 | struct render_data *rdata = data; |
153 | struct sway_output *output = rdata->output; | 154 | struct sway_output *output = rdata->output; |
154 | struct timespec *now = rdata->now; | 155 | struct timespec *when = rdata->when; |
155 | struct wlr_output *wlr_output = output->wlr_output; | 156 | struct wlr_output *wlr_output = output->wlr_output; |
156 | struct sway_view *sway_view = view->sway_view; | 157 | struct sway_view *sway_view = view->sway_view; |
157 | struct wlr_surface *surface = sway_view->surface; | 158 | struct wlr_surface *surface = sway_view->surface; |
@@ -164,18 +165,18 @@ static void output_frame_view(struct sway_container *view, void *data) { | |||
164 | case SWAY_XDG_SHELL_V6_VIEW: { | 165 | case SWAY_XDG_SHELL_V6_VIEW: { |
165 | int window_offset_x = view->sway_view->wlr_xdg_surface_v6->geometry.x; | 166 | int window_offset_x = view->sway_view->wlr_xdg_surface_v6->geometry.x; |
166 | int window_offset_y = view->sway_view->wlr_xdg_surface_v6->geometry.y; | 167 | int window_offset_y = view->sway_view->wlr_xdg_surface_v6->geometry.y; |
167 | render_surface(surface, wlr_output, now, | 168 | render_surface(surface, wlr_output, when, |
168 | view->x - window_offset_x, view->y - window_offset_y, 0); | 169 | view->x - window_offset_x, view->y - window_offset_y, 0); |
169 | render_xdg_v6_popups(sway_view->wlr_xdg_surface_v6, wlr_output, | 170 | render_xdg_v6_popups(sway_view->wlr_xdg_surface_v6, wlr_output, |
170 | now, view->x - window_offset_x, view->y - window_offset_y, 0); | 171 | when, view->x - window_offset_x, view->y - window_offset_y, 0); |
171 | break; | 172 | break; |
172 | } | 173 | } |
173 | case SWAY_WL_SHELL_VIEW: | 174 | case SWAY_WL_SHELL_VIEW: |
174 | render_wl_shell_surface(sway_view->wlr_wl_shell_surface, wlr_output, | 175 | render_wl_shell_surface(sway_view->wlr_wl_shell_surface, wlr_output, |
175 | now, view->x, view->y, 0, false); | 176 | when, view->x, view->y, 0, false); |
176 | break; | 177 | break; |
177 | case SWAY_XWAYLAND_VIEW: | 178 | case SWAY_XWAYLAND_VIEW: |
178 | render_surface(surface, wlr_output, now, view->x, view->y, 0); | 179 | render_surface(surface, wlr_output, when, view->x, view->y, 0); |
179 | break; | 180 | break; |
180 | default: | 181 | default: |
181 | break; | 182 | break; |
@@ -195,82 +196,132 @@ static void render_layer(struct sway_output *output, | |||
195 | } | 196 | } |
196 | } | 197 | } |
197 | 198 | ||
198 | static void handle_output_frame(struct wl_listener *listener, void *data) { | 199 | static void render_output(struct sway_output *output, struct timespec *when, |
199 | struct sway_output *soutput = wl_container_of(listener, soutput, frame); | 200 | pixman_region32_t *damage) { |
200 | struct wlr_output *wlr_output = data; | 201 | struct wlr_output *wlr_output = output->wlr_output; |
201 | struct wlr_renderer *renderer = | 202 | struct wlr_renderer *renderer = |
202 | wlr_backend_get_renderer(wlr_output->backend); | 203 | wlr_backend_get_renderer(wlr_output->backend); |
203 | 204 | ||
204 | wlr_output_make_current(wlr_output, NULL); | ||
205 | wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); | 205 | wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); |
206 | 206 | ||
207 | if (!pixman_region32_not_empty(damage)) { | ||
208 | // Output isn't damaged but needs buffer swap | ||
209 | goto renderer_end; | ||
210 | } | ||
211 | |||
212 | // TODO: don't damage the whole output here | ||
213 | int width, height; | ||
214 | wlr_output_transformed_resolution(wlr_output, &width, &height); | ||
215 | pixman_region32_union_rect(damage, damage, 0, 0, width, height); | ||
216 | |||
207 | float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; | 217 | float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; |
208 | wlr_renderer_clear(renderer, clear_color); | 218 | wlr_renderer_clear(renderer, clear_color); |
209 | 219 | ||
210 | struct timespec now; | ||
211 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
212 | |||
213 | struct wlr_output_layout *layout = root_container.sway_root->output_layout; | 220 | struct wlr_output_layout *layout = root_container.sway_root->output_layout; |
214 | const struct wlr_box *output_box = wlr_output_layout_get_box( | 221 | const struct wlr_box *output_box = |
215 | layout, wlr_output); | 222 | wlr_output_layout_get_box(layout, wlr_output); |
216 | 223 | ||
217 | render_layer(soutput, output_box, &now, | 224 | render_layer(output, output_box, when, |
218 | &soutput->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); | 225 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); |
219 | render_layer(soutput, output_box, &now, | 226 | render_layer(output, output_box, when, |
220 | &soutput->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); | 227 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); |
221 | 228 | ||
222 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 229 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
223 | struct sway_container *focus = | 230 | struct sway_container *focus = |
224 | sway_seat_get_focus_inactive(seat, soutput->swayc); | 231 | sway_seat_get_focus_inactive(seat, output->swayc); |
225 | struct sway_container *workspace = (focus->type == C_WORKSPACE ? | 232 | struct sway_container *workspace = (focus->type == C_WORKSPACE ? |
226 | focus : | 233 | focus : |
227 | container_parent(focus, C_WORKSPACE)); | 234 | container_parent(focus, C_WORKSPACE)); |
228 | 235 | ||
229 | struct render_data rdata = { | 236 | struct render_data rdata = { |
230 | .output = soutput, | 237 | .output = output, |
231 | .now = &now, | 238 | .when = when, |
232 | }; | 239 | }; |
233 | container_descendants(workspace, C_VIEW, output_frame_view, &rdata); | 240 | container_descendants(workspace, C_VIEW, render_view, &rdata); |
234 | 241 | ||
235 | // render unmanaged views on top | 242 | // render unmanaged views on top |
236 | struct sway_view *view; | 243 | struct sway_view *view; |
237 | wl_list_for_each(view, &root_container.sway_root->unmanaged_views, | 244 | wl_list_for_each(view, &root_container.sway_root->unmanaged_views, |
238 | unmanaged_view_link) { | 245 | unmanaged_view_link) { |
239 | if (view->type == SWAY_XWAYLAND_VIEW) { | 246 | if (view->type == SWAY_XWAYLAND_VIEW) { |
240 | // the only kind of unamanged view right now is xwayland override redirect | 247 | // the only kind of unamanged view right now is xwayland override |
248 | // redirect | ||
241 | int view_x = view->wlr_xwayland_surface->x; | 249 | int view_x = view->wlr_xwayland_surface->x; |
242 | int view_y = view->wlr_xwayland_surface->y; | 250 | int view_y = view->wlr_xwayland_surface->y; |
243 | render_surface(view->surface, wlr_output, &soutput->last_frame, | 251 | render_surface(view->surface, wlr_output, &output->last_frame, |
244 | view_x, view_y, 0); | 252 | view_x, view_y, 0); |
245 | } | 253 | } |
246 | } | 254 | } |
247 | 255 | ||
248 | // TODO: Consider revising this when fullscreen windows are supported | 256 | // TODO: Consider revising this when fullscreen windows are supported |
249 | render_layer(soutput, output_box, &now, | 257 | render_layer(output, output_box, when, |
250 | &soutput->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); | 258 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); |
251 | render_layer(soutput, output_box, &now, | 259 | render_layer(output, output_box, when, |
252 | &soutput->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); | 260 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); |
253 | 261 | ||
262 | renderer_end: | ||
254 | wlr_renderer_end(renderer); | 263 | wlr_renderer_end(renderer); |
255 | wlr_output_swap_buffers(wlr_output, &now, NULL); | 264 | if (!wlr_output_damage_swap_buffers(output->damage, when, damage)) { |
256 | soutput->last_frame = now; | 265 | return; |
266 | } | ||
267 | output->last_frame = *when; | ||
257 | } | 268 | } |
258 | 269 | ||
259 | static void handle_output_destroy(struct wl_listener *listener, void *data) { | 270 | static void damage_handle_frame(struct wl_listener *listener, void *data) { |
260 | struct sway_output *output = wl_container_of(listener, output, destroy); | 271 | struct sway_output *output = |
261 | struct wlr_output *wlr_output = data; | 272 | wl_container_of(listener, output, damage_frame); |
262 | wlr_log(L_DEBUG, "Output %p %s removed", wlr_output, wlr_output->name); | 273 | |
274 | if (!output->wlr_output->enabled) { | ||
275 | return; | ||
276 | } | ||
263 | 277 | ||
278 | struct timespec now; | ||
279 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
280 | |||
281 | bool needs_swap; | ||
282 | pixman_region32_t damage; | ||
283 | pixman_region32_init(&damage); | ||
284 | if (!wlr_output_damage_make_current(output->damage, &needs_swap, &damage)) { | ||
285 | return; | ||
286 | } | ||
287 | |||
288 | if (needs_swap) { | ||
289 | render_output(output, &now, &damage); | ||
290 | } | ||
291 | |||
292 | pixman_region32_fini(&damage); | ||
293 | |||
294 | // TODO: send frame done events here instead of inside render_surface | ||
295 | } | ||
296 | |||
297 | void output_damage_whole(struct sway_output *output) { | ||
298 | wlr_output_damage_add_whole(output->damage); | ||
299 | } | ||
300 | |||
301 | void output_damage_whole_view(struct sway_output *output, | ||
302 | struct sway_view *view) { | ||
303 | // TODO | ||
304 | output_damage_whole(output); | ||
305 | } | ||
306 | |||
307 | static void damage_handle_destroy(struct wl_listener *listener, void *data) { | ||
308 | struct sway_output *output = | ||
309 | wl_container_of(listener, output, damage_destroy); | ||
310 | container_output_destroy(output->swayc); | ||
311 | } | ||
312 | |||
313 | static void handle_destroy(struct wl_listener *listener, void *data) { | ||
314 | struct sway_output *output = wl_container_of(listener, output, destroy); | ||
264 | container_output_destroy(output->swayc); | 315 | container_output_destroy(output->swayc); |
265 | } | 316 | } |
266 | 317 | ||
267 | static void handle_output_mode(struct wl_listener *listener, void *data) { | 318 | static void handle_mode(struct wl_listener *listener, void *data) { |
268 | struct sway_output *output = wl_container_of(listener, output, mode); | 319 | struct sway_output *output = wl_container_of(listener, output, mode); |
269 | arrange_layers(output); | 320 | arrange_layers(output); |
270 | arrange_windows(output->swayc, -1, -1); | 321 | arrange_windows(output->swayc, -1, -1); |
271 | } | 322 | } |
272 | 323 | ||
273 | static void handle_output_transform(struct wl_listener *listener, void *data) { | 324 | static void handle_transform(struct wl_listener *listener, void *data) { |
274 | struct sway_output *output = wl_container_of(listener, output, transform); | 325 | struct sway_output *output = wl_container_of(listener, output, transform); |
275 | arrange_layers(output); | 326 | arrange_layers(output); |
276 | arrange_windows(output->swayc, -1, -1); | 327 | arrange_windows(output->swayc, -1, -1); |
@@ -295,6 +346,8 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
295 | wlr_output_set_mode(wlr_output, mode); | 346 | wlr_output_set_mode(wlr_output, mode); |
296 | } | 347 | } |
297 | 348 | ||
349 | output->damage = wlr_output_damage_create(wlr_output); | ||
350 | |||
298 | output->swayc = container_output_create(output); | 351 | output->swayc = container_output_create(output); |
299 | if (!output->swayc) { | 352 | if (!output->swayc) { |
300 | free(output); | 353 | free(output); |
@@ -308,14 +361,17 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
308 | 361 | ||
309 | sway_input_manager_configure_xcursor(input_manager); | 362 | sway_input_manager_configure_xcursor(input_manager); |
310 | 363 | ||
311 | wl_signal_add(&wlr_output->events.frame, &output->frame); | ||
312 | output->frame.notify = handle_output_frame; | ||
313 | wl_signal_add(&wlr_output->events.destroy, &output->destroy); | 364 | wl_signal_add(&wlr_output->events.destroy, &output->destroy); |
314 | output->destroy.notify = handle_output_destroy; | 365 | output->destroy.notify = handle_destroy; |
315 | wl_signal_add(&wlr_output->events.mode, &output->mode); | 366 | wl_signal_add(&wlr_output->events.mode, &output->mode); |
316 | output->mode.notify = handle_output_mode; | 367 | output->mode.notify = handle_mode; |
317 | wl_signal_add(&wlr_output->events.transform, &output->transform); | 368 | wl_signal_add(&wlr_output->events.transform, &output->transform); |
318 | output->transform.notify = handle_output_transform; | 369 | output->transform.notify = handle_transform; |
370 | |||
371 | wl_signal_add(&output->damage->events.frame, &output->damage_frame); | ||
372 | output->damage_frame.notify = damage_handle_frame; | ||
373 | wl_signal_add(&output->damage->events.destroy, &output->damage_destroy); | ||
374 | output->damage_destroy.notify = damage_handle_destroy; | ||
319 | 375 | ||
320 | arrange_layers(output); | 376 | arrange_layers(output); |
321 | arrange_windows(&root_container, -1, -1); | 377 | arrange_windows(&root_container, -1, -1); |
diff --git a/sway/desktop/wl_shell.c b/sway/desktop/wl_shell.c index 4d4d1ed7..4fcc6317 100644 --- a/sway/desktop/wl_shell.c +++ b/sway/desktop/wl_shell.c | |||
@@ -67,6 +67,7 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
67 | // TODO: Let floating views do whatever | 67 | // TODO: Let floating views do whatever |
68 | view->width = sway_surface->pending_width; | 68 | view->width = sway_surface->pending_width; |
69 | view->height = sway_surface->pending_height; | 69 | view->height = sway_surface->pending_height; |
70 | view_damage_from(view); | ||
70 | } | 71 | } |
71 | 72 | ||
72 | static void handle_destroy(struct wl_listener *listener, void *data) { | 73 | static void handle_destroy(struct wl_listener *listener, void *data) { |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 01f38d16..713437f2 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -76,6 +76,35 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
76 | // TODO: Let floating views do whatever | 76 | // TODO: Let floating views do whatever |
77 | view->width = sway_surface->pending_width; | 77 | view->width = sway_surface->pending_width; |
78 | view->height = sway_surface->pending_height; | 78 | view->height = sway_surface->pending_height; |
79 | view_damage_from(view); | ||
80 | } | ||
81 | |||
82 | static void handle_unmap(struct wl_listener *listener, void *data) { | ||
83 | struct sway_xdg_surface_v6 *sway_surface = | ||
84 | wl_container_of(listener, sway_surface, unmap); | ||
85 | view_damage_whole(sway_surface->view); | ||
86 | container_view_destroy(sway_surface->view->swayc); | ||
87 | sway_surface->view->swayc = NULL; | ||
88 | sway_surface->view->surface = NULL; | ||
89 | } | ||
90 | |||
91 | static void handle_map(struct wl_listener *listener, void *data) { | ||
92 | struct sway_xdg_surface_v6 *sway_surface = | ||
93 | wl_container_of(listener, sway_surface, map); | ||
94 | struct sway_view *view = sway_surface->view; | ||
95 | |||
96 | sway_surface->view->surface = view->wlr_xdg_surface_v6->surface; | ||
97 | |||
98 | container_view_destroy(view->swayc); | ||
99 | |||
100 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
101 | struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); | ||
102 | struct sway_container *cont = container_view_create(focus, view); | ||
103 | view->swayc = cont; | ||
104 | arrange_windows(cont->parent, -1, -1); | ||
105 | sway_input_manager_set_focus(input_manager, cont); | ||
106 | |||
107 | view_damage_whole(sway_surface->view); | ||
79 | } | 108 | } |
80 | 109 | ||
81 | static void handle_destroy(struct wl_listener *listener, void *data) { | 110 | static void handle_destroy(struct wl_listener *listener, void *data) { |
@@ -121,26 +150,22 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | |||
121 | sway_view->iface.close = close; | 150 | sway_view->iface.close = close; |
122 | sway_view->wlr_xdg_surface_v6 = xdg_surface; | 151 | sway_view->wlr_xdg_surface_v6 = xdg_surface; |
123 | sway_view->sway_xdg_surface_v6 = sway_surface; | 152 | sway_view->sway_xdg_surface_v6 = sway_surface; |
124 | sway_view->surface = xdg_surface->surface; | ||
125 | sway_surface->view = sway_view; | 153 | sway_surface->view = sway_view; |
126 | 154 | ||
127 | // TODO: | 155 | // TODO: |
128 | // - Look up pid and open on appropriate workspace | 156 | // - Look up pid and open on appropriate workspace |
129 | // - Set new view to maximized so it behaves nicely | 157 | // - Set new view to maximized so it behaves nicely |
130 | // - Criteria | 158 | // - Criteria |
131 | 159 | ||
132 | sway_surface->commit.notify = handle_commit; | 160 | sway_surface->commit.notify = handle_commit; |
133 | wl_signal_add(&xdg_surface->surface->events.commit, &sway_surface->commit); | 161 | wl_signal_add(&xdg_surface->surface->events.commit, &sway_surface->commit); |
134 | 162 | ||
135 | sway_surface->destroy.notify = handle_destroy; | 163 | sway_surface->map.notify = handle_map; |
136 | wl_signal_add(&xdg_surface->events.destroy, &sway_surface->destroy); | 164 | wl_signal_add(&xdg_surface->events.map, &sway_surface->map); |
137 | 165 | ||
138 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 166 | sway_surface->unmap.notify = handle_unmap; |
139 | struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); | 167 | wl_signal_add(&xdg_surface->events.unmap, &sway_surface->unmap); |
140 | struct sway_container *cont = container_view_create(focus, sway_view); | ||
141 | sway_view->swayc = cont; | ||
142 | |||
143 | arrange_windows(cont->parent, -1, -1); | ||
144 | 168 | ||
145 | sway_input_manager_set_focus(input_manager, cont); | 169 | sway_surface->destroy.notify = handle_destroy; |
170 | wl_signal_add(&xdg_surface->events.destroy, &sway_surface->destroy); | ||
146 | } | 171 | } |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index dfc54e86..01c993b3 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -14,10 +14,10 @@ | |||
14 | #include "sway/input/input-manager.h" | 14 | #include "sway/input/input-manager.h" |
15 | #include "log.h" | 15 | #include "log.h" |
16 | 16 | ||
17 | static bool assert_xwayland(struct sway_view *view) { | 17 | static bool assert_xwayland(struct sway_view *view) { |
18 | return sway_assert(view->type == SWAY_XWAYLAND_VIEW && view->wlr_xwayland_surface, | 18 | return sway_assert(view->type == SWAY_XWAYLAND_VIEW, |
19 | "Expected xwayland view!"); | 19 | "Expected xwayland view!"); |
20 | } | 20 | } |
21 | 21 | ||
22 | static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { | 22 | static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { |
23 | if (!assert_xwayland(view)) { | 23 | if (!assert_xwayland(view)) { |
@@ -99,6 +99,7 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
99 | // TODO: Let floating views do whatever | 99 | // TODO: Let floating views do whatever |
100 | view->width = sway_surface->pending_width; | 100 | view->width = sway_surface->pending_width; |
101 | view->height = sway_surface->pending_height; | 101 | view->height = sway_surface->pending_height; |
102 | view_damage_from(view); | ||
102 | } | 103 | } |
103 | 104 | ||
104 | static void handle_destroy(struct wl_listener *listener, void *data) { | 105 | static void handle_destroy(struct wl_listener *listener, void *data) { |
@@ -117,7 +118,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
117 | static void handle_unmap(struct wl_listener *listener, void *data) { | 118 | static void handle_unmap(struct wl_listener *listener, void *data) { |
118 | struct sway_xwayland_surface *sway_surface = | 119 | struct sway_xwayland_surface *sway_surface = |
119 | wl_container_of(listener, sway_surface, unmap); | 120 | wl_container_of(listener, sway_surface, unmap); |
120 | 121 | view_damage_whole(sway_surface->view); | |
121 | wl_list_remove(&sway_surface->view->unmanaged_view_link); | 122 | wl_list_remove(&sway_surface->view->unmanaged_view_link); |
122 | wl_list_init(&sway_surface->view->unmanaged_view_link); | 123 | wl_list_init(&sway_surface->view->unmanaged_view_link); |
123 | container_view_destroy(sway_surface->view->swayc); | 124 | container_view_destroy(sway_surface->view->swayc); |
@@ -126,7 +127,6 @@ static void handle_unmap(struct wl_listener *listener, void *data) { | |||
126 | } | 127 | } |
127 | 128 | ||
128 | static void handle_map(struct wl_listener *listener, void *data) { | 129 | static void handle_map(struct wl_listener *listener, void *data) { |
129 | // TODO put the view back into the tree | ||
130 | struct sway_xwayland_surface *sway_surface = | 130 | struct sway_xwayland_surface *sway_surface = |
131 | wl_container_of(listener, sway_surface, map); | 131 | wl_container_of(listener, sway_surface, map); |
132 | struct wlr_xwayland_surface *xsurface = data; | 132 | struct wlr_xwayland_surface *xsurface = data; |
@@ -150,6 +150,8 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
150 | arrange_windows(cont->parent, -1, -1); | 150 | arrange_windows(cont->parent, -1, -1); |
151 | sway_input_manager_set_focus(input_manager, cont); | 151 | sway_input_manager_set_focus(input_manager, cont); |
152 | } | 152 | } |
153 | |||
154 | view_damage_whole(sway_surface->view); | ||
153 | } | 155 | } |
154 | 156 | ||
155 | static void handle_configure_request(struct wl_listener *listener, void *data) { | 157 | static void handle_configure_request(struct wl_listener *listener, void *data) { |
@@ -190,7 +192,6 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
190 | sway_view->iface.close = close_view; | 192 | sway_view->iface.close = close_view; |
191 | sway_view->wlr_xwayland_surface = xsurface; | 193 | sway_view->wlr_xwayland_surface = xsurface; |
192 | sway_view->sway_xwayland_surface = sway_surface; | 194 | sway_view->sway_xwayland_surface = sway_surface; |
193 | sway_view->surface = xsurface->surface; | ||
194 | sway_surface->view = sway_view; | 195 | sway_surface->view = sway_view; |
195 | 196 | ||
196 | wl_list_init(&sway_view->unmanaged_view_link); | 197 | wl_list_init(&sway_view->unmanaged_view_link); |
diff --git a/sway/tree/container.c b/sway/tree/container.c index c3cf6c64..8705edc7 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -6,8 +6,8 @@ | |||
6 | #include <wayland-server.h> | 6 | #include <wayland-server.h> |
7 | #include <wlr/types/wlr_output_layout.h> | 7 | #include <wlr/types/wlr_output_layout.h> |
8 | #include <wlr/types/wlr_wl_shell.h> | 8 | #include <wlr/types/wlr_wl_shell.h> |
9 | #include "log.h" | ||
9 | #include "sway/config.h" | 10 | #include "sway/config.h" |
10 | #include "sway/tree/container.h" | ||
11 | #include "sway/input/input-manager.h" | 11 | #include "sway/input/input-manager.h" |
12 | #include "sway/input/seat.h" | 12 | #include "sway/input/seat.h" |
13 | #include "sway/ipc-server.h" | 13 | #include "sway/ipc-server.h" |
diff --git a/sway/tree/output.c b/sway/tree/output.c index 2246cb11..7248fd00 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -26,9 +26,12 @@ struct sway_container *container_output_destroy(struct sway_container *output) { | |||
26 | } | 26 | } |
27 | } | 27 | } |
28 | 28 | ||
29 | wl_list_remove(&output->sway_output->frame.link); | ||
30 | wl_list_remove(&output->sway_output->destroy.link); | 29 | wl_list_remove(&output->sway_output->destroy.link); |
31 | wl_list_remove(&output->sway_output->mode.link); | 30 | wl_list_remove(&output->sway_output->mode.link); |
31 | wl_list_remove(&output->sway_output->transform.link); | ||
32 | |||
33 | wl_list_remove(&output->sway_output->damage_destroy.link); | ||
34 | wl_list_remove(&output->sway_output->damage_frame.link); | ||
32 | 35 | ||
33 | wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); | 36 | wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); |
34 | container_destroy(output); | 37 | container_destroy(output); |
diff --git a/sway/tree/view.c b/sway/tree/view.c index 480ff693..b7d1a41b 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -1,9 +1,10 @@ | |||
1 | #include <wayland-server.h> | 1 | #include <wayland-server.h> |
2 | #include <wlr/types/wlr_output_layout.h> | 2 | #include <wlr/types/wlr_output_layout.h> |
3 | #include "log.h" | ||
4 | #include "sway/output.h" | ||
3 | #include "sway/tree/container.h" | 5 | #include "sway/tree/container.h" |
4 | #include "sway/tree/layout.h" | 6 | #include "sway/tree/layout.h" |
5 | #include "sway/tree/view.h" | 7 | #include "sway/tree/view.h" |
6 | #include "log.h" | ||
7 | 8 | ||
8 | const char *view_get_title(struct sway_view *view) { | 9 | const char *view_get_title(struct sway_view *view) { |
9 | if (view->iface.get_prop) { | 10 | if (view->iface.get_prop) { |
@@ -105,3 +106,18 @@ struct sway_container *container_view_destroy(struct sway_container *view) { | |||
105 | arrange_windows(parent, -1, -1); | 106 | arrange_windows(parent, -1, -1); |
106 | return parent; | 107 | return parent; |
107 | } | 108 | } |
109 | |||
110 | void view_damage_whole(struct sway_view *view) { | ||
111 | struct sway_container *cont = NULL; | ||
112 | for (int i = 0; i < root_container.children->length; ++i) { | ||
113 | cont = root_container.children->items[i]; | ||
114 | if (cont->type == C_OUTPUT) { | ||
115 | output_damage_whole_view(cont->sway_output, view); | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | |||
120 | void view_damage_from(struct sway_view *view) { | ||
121 | // TODO | ||
122 | view_damage_whole(view); | ||
123 | } | ||