aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c158
1 files changed, 41 insertions, 117 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 5edc8f96..aa148290 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -56,26 +56,6 @@ struct sway_output *all_output_by_name_or_id(const char *name_or_id) {
56 return NULL; 56 return NULL;
57} 57}
58 58
59/**
60 * Rotate a child's position relative to a parent. The parent size is (pw, ph),
61 * the child position is (*sx, *sy) and its size is (sw, sh).
62 */
63static void rotate_child_position(double *sx, double *sy, double sw, double sh,
64 double pw, double ph, float rotation) {
65 if (rotation == 0.0f) {
66 return;
67 }
68
69 // Coordinates relative to the center of the subsurface
70 double ox = *sx - pw/2 + sw/2,
71 oy = *sy - ph/2 + sh/2;
72 // Rotated coordinates
73 double rx = cos(-rotation)*ox - sin(-rotation)*oy,
74 ry = cos(-rotation)*oy + sin(-rotation)*ox;
75 *sx = rx + pw/2 - sw/2;
76 *sy = ry + ph/2 - sh/2;
77}
78
79struct surface_iterator_data { 59struct surface_iterator_data {
80 sway_surface_iterator_func_t user_iterator; 60 sway_surface_iterator_func_t user_iterator;
81 void *user_data; 61 void *user_data;
@@ -84,7 +64,6 @@ struct surface_iterator_data {
84 struct sway_view *view; 64 struct sway_view *view;
85 double ox, oy; 65 double ox, oy;
86 int width, height; 66 int width, height;
87 float rotation;
88}; 67};
89 68
90static bool get_surface_box(struct surface_iterator_data *data, 69static bool get_surface_box(struct surface_iterator_data *data,
@@ -99,14 +78,9 @@ static bool get_surface_box(struct surface_iterator_data *data,
99 int sw = surface->current.width; 78 int sw = surface->current.width;
100 int sh = surface->current.height; 79 int sh = surface->current.height;
101 80
102 double _sx = sx + surface->sx;
103 double _sy = sy + surface->sy;
104 rotate_child_position(&_sx, &_sy, sw, sh, data->width, data->height,
105 data->rotation);
106
107 struct wlr_box box = { 81 struct wlr_box box = {
108 .x = data->ox + _sx, 82 .x = floor(data->ox + sx),
109 .y = data->oy + _sy, 83 .y = floor(data->oy + sy),
110 .width = sw, 84 .width = sw,
111 .height = sh, 85 .height = sh,
112 }; 86 };
@@ -114,16 +88,13 @@ static bool get_surface_box(struct surface_iterator_data *data,
114 memcpy(surface_box, &box, sizeof(struct wlr_box)); 88 memcpy(surface_box, &box, sizeof(struct wlr_box));
115 } 89 }
116 90
117 struct wlr_box rotated_box;
118 wlr_box_rotated_bounds(&rotated_box, &box, data->rotation);
119
120 struct wlr_box output_box = { 91 struct wlr_box output_box = {
121 .width = output->width, 92 .width = output->width,
122 .height = output->height, 93 .height = output->height,
123 }; 94 };
124 95
125 struct wlr_box intersection; 96 struct wlr_box intersection;
126 return wlr_box_intersection(&intersection, &output_box, &rotated_box); 97 return wlr_box_intersection(&intersection, &output_box, &box);
127} 98}
128 99
129static void output_for_each_surface_iterator(struct wlr_surface *surface, 100static void output_for_each_surface_iterator(struct wlr_surface *surface,
@@ -136,7 +107,7 @@ static void output_for_each_surface_iterator(struct wlr_surface *surface,
136 return; 107 return;
137 } 108 }
138 109
139 data->user_iterator(data->output, data->view, surface, &box, data->rotation, 110 data->user_iterator(data->output, data->view, surface, &box,
140 data->user_data); 111 data->user_data);
141} 112}
142 113
@@ -152,7 +123,6 @@ void output_surface_for_each_surface(struct sway_output *output,
152 .oy = oy, 123 .oy = oy,
153 .width = surface->current.width, 124 .width = surface->current.width,
154 .height = surface->current.height, 125 .height = surface->current.height,
155 .rotation = 0,
156 }; 126 };
157 127
158 wlr_surface_for_each_surface(surface, 128 wlr_surface_for_each_surface(surface,
@@ -173,7 +143,6 @@ void output_view_for_each_surface(struct sway_output *output,
173 - view->geometry.y, 143 - view->geometry.y,
174 .width = view->container->current.content_width, 144 .width = view->container->current.content_width,
175 .height = view->container->current.content_height, 145 .height = view->container->current.content_height,
176 .rotation = 0, // TODO
177 }; 146 };
178 147
179 view_for_each_surface(view, output_for_each_surface_iterator, &data); 148 view_for_each_surface(view, output_for_each_surface_iterator, &data);
@@ -193,7 +162,6 @@ void output_view_for_each_popup_surface(struct sway_output *output,
193 - view->geometry.y, 162 - view->geometry.y,
194 .width = view->container->current.content_width, 163 .width = view->container->current.content_width,
195 .height = view->container->current.content_height, 164 .height = view->container->current.content_height,
196 .rotation = 0, // TODO
197 }; 165 };
198 166
199 view_for_each_popup_surface(view, output_for_each_surface_iterator, &data); 167 view_for_each_popup_surface(view, output_for_each_surface_iterator, &data);
@@ -206,40 +174,19 @@ void output_layer_for_each_surface(struct sway_output *output,
206 wl_list_for_each(layer_surface, layer_surfaces, link) { 174 wl_list_for_each(layer_surface, layer_surfaces, link) {
207 struct wlr_layer_surface_v1 *wlr_layer_surface_v1 = 175 struct wlr_layer_surface_v1 *wlr_layer_surface_v1 =
208 layer_surface->layer_surface; 176 layer_surface->layer_surface;
209 output_surface_for_each_surface(output, wlr_layer_surface_v1->surface, 177 struct wlr_surface *surface = wlr_layer_surface_v1->surface;
210 layer_surface->geo.x, layer_surface->geo.y, iterator, 178 struct surface_iterator_data data = {
211 user_data); 179 .user_iterator = iterator,
212 180 .user_data = user_data,
213 struct wlr_xdg_popup *state; 181 .output = output,
214 wl_list_for_each(state, &wlr_layer_surface_v1->popups, link) { 182 .view = NULL,
215 struct wlr_xdg_surface *popup = state->base; 183 .ox = layer_surface->geo.x,
216 if (!popup->configured) { 184 .oy = layer_surface->geo.y,
217 continue; 185 .width = surface->current.width,
218 } 186 .height = surface->current.height,
219 187 };
220 double popup_sx, popup_sy; 188 wlr_layer_surface_v1_for_each_surface(wlr_layer_surface_v1,
221 popup_sx = layer_surface->geo.x + 189 output_for_each_surface_iterator, &data);
222 popup->popup->geometry.x - popup->geometry.x;
223 popup_sy = layer_surface->geo.y +
224 popup->popup->geometry.y - popup->geometry.y;
225
226 struct wlr_surface *surface = popup->surface;
227
228 struct surface_iterator_data data = {
229 .user_iterator = iterator,
230 .user_data = user_data,
231 .output = output,
232 .view = NULL,
233 .ox = popup_sx,
234 .oy = popup_sy,
235 .width = surface->current.width,
236 .height = surface->current.height,
237 .rotation = 0,
238 };
239
240 wlr_xdg_surface_for_each_surface(
241 popup, output_for_each_surface_iterator, &data);
242 }
243 } 190 }
244} 191}
245 192
@@ -264,37 +211,19 @@ void output_layer_for_each_popup_surface(struct sway_output *output,
264 wl_list_for_each(layer_surface, layer_surfaces, link) { 211 wl_list_for_each(layer_surface, layer_surfaces, link) {
265 struct wlr_layer_surface_v1 *wlr_layer_surface_v1 = 212 struct wlr_layer_surface_v1 *wlr_layer_surface_v1 =
266 layer_surface->layer_surface; 213 layer_surface->layer_surface;
267 214 struct wlr_surface *surface = wlr_layer_surface_v1->surface;
268 struct wlr_xdg_popup *state; 215 struct surface_iterator_data data = {
269 wl_list_for_each(state, &wlr_layer_surface_v1->popups, link) { 216 .user_iterator = iterator,
270 struct wlr_xdg_surface *popup = state->base; 217 .user_data = user_data,
271 if (!popup->configured) { 218 .output = output,
272 continue; 219 .view = NULL,
273 } 220 .ox = layer_surface->geo.x,
274 221 .oy = layer_surface->geo.y,
275 double popup_sx, popup_sy; 222 .width = surface->current.width,
276 popup_sx = layer_surface->geo.x + 223 .height = surface->current.height,
277 popup->popup->geometry.x - popup->geometry.x; 224 };
278 popup_sy = layer_surface->geo.y + 225 wlr_layer_surface_v1_for_each_popup_surface(wlr_layer_surface_v1,
279 popup->popup->geometry.y - popup->geometry.y; 226 output_for_each_surface_iterator, &data);
280
281 struct wlr_surface *surface = popup->surface;
282
283 struct surface_iterator_data data = {
284 .user_iterator = iterator,
285 .user_data = user_data,
286 .output = output,
287 .view = NULL,
288 .ox = popup_sx,
289 .oy = popup_sy,
290 .width = surface->current.width,
291 .height = surface->current.height,
292 .rotation = 0,
293 };
294
295 wlr_xdg_surface_for_each_surface(
296 popup, output_for_each_surface_iterator, &data);
297 }
298 } 227 }
299} 228}
300 229
@@ -463,9 +392,9 @@ struct send_frame_done_data {
463 int msec_until_refresh; 392 int msec_until_refresh;
464}; 393};
465 394
466static void send_frame_done_iterator(struct sway_output *output, struct sway_view *view, 395static void send_frame_done_iterator(struct sway_output *output,
467 struct wlr_surface *surface, struct wlr_box *box, float rotation, 396 struct sway_view *view, struct wlr_surface *surface,
468 void *user_data) { 397 struct wlr_box *box, void *user_data) {
469 int view_max_render_time = 0; 398 int view_max_render_time = 0;
470 if (view != NULL) { 399 if (view != NULL) {
471 view_max_render_time = view->max_render_time; 400 view_max_render_time = view->max_render_time;
@@ -488,9 +417,9 @@ static void send_frame_done(struct sway_output *output, struct send_frame_done_d
488 output_for_each_surface(output, send_frame_done_iterator, data); 417 output_for_each_surface(output, send_frame_done_iterator, data);
489} 418}
490 419
491static void count_surface_iterator(struct sway_output *output, struct sway_view *view, 420static void count_surface_iterator(struct sway_output *output,
492 struct wlr_surface *surface, struct wlr_box *_box, float rotation, 421 struct sway_view *view, struct wlr_surface *surface,
493 void *data) { 422 struct wlr_box *box, void *data) {
494 size_t *n = data; 423 size_t *n = data;
495 (*n)++; 424 (*n)++;
496} 425}
@@ -590,6 +519,7 @@ static int output_repaint_timer_handler(void *data) {
590 if (last_scanned_out && !scanned_out) { 519 if (last_scanned_out && !scanned_out) {
591 sway_log(SWAY_DEBUG, "Stopping fullscreen view scan out on %s", 520 sway_log(SWAY_DEBUG, "Stopping fullscreen view scan out on %s",
592 output->wlr_output->name); 521 output->wlr_output->name);
522 output_damage_whole(output);
593 } 523 }
594 last_scanned_out = scanned_out; 524 last_scanned_out = scanned_out;
595 525
@@ -693,18 +623,15 @@ void output_damage_whole(struct sway_output *output) {
693 } 623 }
694} 624}
695 625
696static void damage_surface_iterator(struct sway_output *output, struct sway_view *view, 626static void damage_surface_iterator(struct sway_output *output,
697 struct wlr_surface *surface, struct wlr_box *_box, float rotation, 627 struct sway_view *view, struct wlr_surface *surface,
698 void *_data) { 628 struct wlr_box *_box, void *_data) {
699 bool *data = _data; 629 bool *data = _data;
700 bool whole = *data; 630 bool whole = *data;
701 631
702 struct wlr_box box = *_box; 632 struct wlr_box box = *_box;
703 scale_box(&box, output->wlr_output->scale); 633 scale_box(&box, output->wlr_output->scale);
704 634
705 int center_x = box.x + box.width/2;
706 int center_y = box.y + box.height/2;
707
708 if (pixman_region32_not_empty(&surface->buffer_damage)) { 635 if (pixman_region32_not_empty(&surface->buffer_damage)) {
709 pixman_region32_t damage; 636 pixman_region32_t damage;
710 pixman_region32_init(&damage); 637 pixman_region32_init(&damage);
@@ -717,14 +644,11 @@ static void damage_surface_iterator(struct sway_output *output, struct sway_view
717 ceil(output->wlr_output->scale) - surface->current.scale); 644 ceil(output->wlr_output->scale) - surface->current.scale);
718 } 645 }
719 pixman_region32_translate(&damage, box.x, box.y); 646 pixman_region32_translate(&damage, box.x, box.y);
720 wlr_region_rotated_bounds(&damage, &damage, rotation,
721 center_x, center_y);
722 wlr_output_damage_add(output->damage, &damage); 647 wlr_output_damage_add(output->damage, &damage);
723 pixman_region32_fini(&damage); 648 pixman_region32_fini(&damage);
724 } 649 }
725 650
726 if (whole) { 651 if (whole) {
727 wlr_box_rotated_bounds(&box, &box, rotation);
728 wlr_output_damage_add_box(output->damage, &box); 652 wlr_output_damage_add_box(output->damage, &box);
729 } 653 }
730 654
@@ -816,7 +740,7 @@ static void update_output_manager_config(struct sway_server *server) {
816 struct wlr_box *output_box = wlr_output_layout_get_box( 740 struct wlr_box *output_box = wlr_output_layout_get_box(
817 root->output_layout, output->wlr_output); 741 root->output_layout, output->wlr_output);
818 // We mark the output enabled even if it is switched off by DPMS 742 // We mark the output enabled even if it is switched off by DPMS
819 config_head->state.enabled = output->enabled; 743 config_head->state.enabled = output->current_mode != NULL && output->enabled;
820 config_head->state.mode = output->current_mode; 744 config_head->state.mode = output->current_mode;
821 if (output_box) { 745 if (output_box) {
822 config_head->state.x = output_box->x; 746 config_head->state.x = output_box->x;