diff options
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r-- | sway/desktop/output.c | 115 |
1 files changed, 41 insertions, 74 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index a650665f..63420d0c 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -46,57 +46,22 @@ static void render_surface(struct wlr_surface *surface, | |||
46 | int height = surface->current->height; | 46 | int height = surface->current->height; |
47 | int render_width = width * wlr_output->scale; | 47 | int render_width = width * wlr_output->scale; |
48 | int render_height = height * wlr_output->scale; | 48 | int render_height = height * wlr_output->scale; |
49 | double ox = lx, oy = ly; | 49 | int owidth, oheight; |
50 | wlr_output_layout_output_coords(layout, wlr_output, &ox, &oy); | 50 | wlr_output_effective_resolution(wlr_output, &owidth, &oheight); |
51 | ox *= wlr_output->scale; | ||
52 | oy *= wlr_output->scale; | ||
53 | 51 | ||
54 | struct wlr_box render_box = { | 52 | // FIXME: view coords are inconsistently assumed to be in output or layout coords |
55 | .x = lx, .y = ly, | 53 | struct wlr_box layout_box = { |
54 | .x = lx + wlr_output->lx, .y = ly + wlr_output->ly, | ||
56 | .width = render_width, .height = render_height, | 55 | .width = render_width, .height = render_height, |
57 | }; | 56 | }; |
58 | if (wlr_output_layout_intersects(layout, wlr_output, &render_box)) { | 57 | if (wlr_output_layout_intersects(layout, wlr_output, &layout_box)) { |
58 | struct wlr_box render_box = { | ||
59 | .x = lx, .y = ly, | ||
60 | .width = render_width, .height = render_height | ||
61 | }; | ||
59 | float matrix[16]; | 62 | float matrix[16]; |
60 | 63 | wlr_matrix_project_box(&matrix, &render_box, | |
61 | float translate_center[16]; | 64 | surface->current->transform, 0, &wlr_output->transform_matrix); |
62 | wlr_matrix_translate(&translate_center, | ||
63 | (int)ox + render_width / 2, (int)oy + render_height / 2, 0); | ||
64 | |||
65 | float rotate[16]; | ||
66 | wlr_matrix_rotate(&rotate, rotation); | ||
67 | |||
68 | float translate_origin[16]; | ||
69 | wlr_matrix_translate(&translate_origin, -render_width / 2, | ||
70 | -render_height / 2, 0); | ||
71 | |||
72 | float scale[16]; | ||
73 | wlr_matrix_scale(&scale, render_width, render_height, 1); | ||
74 | |||
75 | float transform[16]; | ||
76 | wlr_matrix_mul(&translate_center, &rotate, &transform); | ||
77 | wlr_matrix_mul(&transform, &translate_origin, &transform); | ||
78 | wlr_matrix_mul(&transform, &scale, &transform); | ||
79 | |||
80 | if (surface->current->transform != WL_OUTPUT_TRANSFORM_NORMAL) { | ||
81 | float surface_translate_center[16]; | ||
82 | wlr_matrix_translate(&surface_translate_center, 0.5, 0.5, 0); | ||
83 | |||
84 | float surface_transform[16]; | ||
85 | wlr_matrix_transform(surface_transform, | ||
86 | wlr_output_transform_invert(surface->current->transform)); | ||
87 | |||
88 | float surface_translate_origin[16]; | ||
89 | wlr_matrix_translate(&surface_translate_origin, -0.5, -0.5, 0); | ||
90 | |||
91 | wlr_matrix_mul(&transform, &surface_translate_center, | ||
92 | &transform); | ||
93 | wlr_matrix_mul(&transform, &surface_transform, &transform); | ||
94 | wlr_matrix_mul(&transform, &surface_translate_origin, | ||
95 | &transform); | ||
96 | } | ||
97 | |||
98 | wlr_matrix_mul(&wlr_output->transform_matrix, &transform, &matrix); | ||
99 | |||
100 | wlr_render_with_matrix(server.renderer, surface->texture, | 65 | wlr_render_with_matrix(server.renderer, surface->texture, |
101 | &matrix); | 66 | &matrix); |
102 | 67 | ||
@@ -125,8 +90,9 @@ static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, | |||
125 | double width = surface->surface->current->width; | 90 | double width = surface->surface->current->width; |
126 | double height = surface->surface->current->height; | 91 | double height = surface->surface->current->height; |
127 | 92 | ||
128 | struct wlr_xdg_surface_v6 *popup; | 93 | struct wlr_xdg_popup_v6 *popup_state; |
129 | wl_list_for_each(popup, &surface->popups, popup_link) { | 94 | wl_list_for_each(popup_state, &surface->popups, link) { |
95 | struct wlr_xdg_surface_v6 *popup = popup_state->base; | ||
130 | if (!popup->configured) { | 96 | if (!popup->configured) { |
131 | continue; | 97 | continue; |
132 | } | 98 | } |
@@ -215,11 +181,20 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { | |||
215 | struct sway_output *soutput = wl_container_of(listener, soutput, frame); | 181 | struct sway_output *soutput = wl_container_of(listener, soutput, frame); |
216 | struct wlr_output *wlr_output = data; | 182 | struct wlr_output *wlr_output = data; |
217 | struct sway_server *server = soutput->server; | 183 | struct sway_server *server = soutput->server; |
184 | float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; | ||
185 | struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend); | ||
186 | wlr_renderer_clear(renderer, &clear_color); | ||
218 | 187 | ||
219 | wlr_output_make_current(wlr_output); | 188 | int buffer_age = -1; |
189 | wlr_output_make_current(wlr_output, &buffer_age); | ||
220 | wlr_renderer_begin(server->renderer, wlr_output); | 190 | wlr_renderer_begin(server->renderer, wlr_output); |
221 | 191 | ||
222 | swayc_t *workspace = soutput->swayc->focused; | 192 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
193 | swayc_t *focus = sway_seat_get_focus_inactive(seat, soutput->swayc); | ||
194 | swayc_t *workspace = (focus->type == C_WORKSPACE ? | ||
195 | focus : | ||
196 | swayc_parent_by_type(focus, C_WORKSPACE)); | ||
197 | |||
223 | swayc_descendants_of_type(workspace, C_VIEW, output_frame_view, soutput); | 198 | swayc_descendants_of_type(workspace, C_VIEW, output_frame_view, soutput); |
224 | 199 | ||
225 | // render unmanaged views on top | 200 | // render unmanaged views on top |
@@ -236,15 +211,23 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { | |||
236 | } | 211 | } |
237 | 212 | ||
238 | wlr_renderer_end(server->renderer); | 213 | wlr_renderer_end(server->renderer); |
239 | wlr_output_swap_buffers(wlr_output); | 214 | wlr_output_swap_buffers(wlr_output, &soutput->last_frame, NULL); |
240 | 215 | ||
241 | struct timespec now; | 216 | struct timespec now; |
242 | clock_gettime(CLOCK_MONOTONIC, &now); | 217 | clock_gettime(CLOCK_MONOTONIC, &now); |
243 | soutput->last_frame = now; | 218 | soutput->last_frame = now; |
244 | } | 219 | } |
245 | 220 | ||
246 | void output_add_notify(struct wl_listener *listener, void *data) { | 221 | static void handle_output_destroy(struct wl_listener *listener, void *data) { |
247 | struct sway_server *server = wl_container_of(listener, server, output_add); | 222 | struct sway_output *output = wl_container_of(listener, output, output_destroy); |
223 | struct wlr_output *wlr_output = data; | ||
224 | wlr_log(L_DEBUG, "Output %p %s removed", wlr_output, wlr_output->name); | ||
225 | |||
226 | destroy_output(output->swayc); | ||
227 | } | ||
228 | |||
229 | void handle_new_output(struct wl_listener *listener, void *data) { | ||
230 | struct sway_server *server = wl_container_of(listener, server, new_output); | ||
248 | struct wlr_output *wlr_output = data; | 231 | struct wlr_output *wlr_output = data; |
249 | wlr_log(L_DEBUG, "New output %p: %s", wlr_output, wlr_output->name); | 232 | wlr_log(L_DEBUG, "New output %p: %s", wlr_output, wlr_output->name); |
250 | 233 | ||
@@ -269,27 +252,11 @@ void output_add_notify(struct wl_listener *listener, void *data) { | |||
269 | 252 | ||
270 | sway_input_manager_configure_xcursor(input_manager); | 253 | sway_input_manager_configure_xcursor(input_manager); |
271 | 254 | ||
272 | output->frame.notify = output_frame_notify; | ||
273 | wl_signal_add(&wlr_output->events.frame, &output->frame); | 255 | wl_signal_add(&wlr_output->events.frame, &output->frame); |
274 | } | 256 | output->frame.notify = output_frame_notify; |
275 | |||
276 | void output_remove_notify(struct wl_listener *listener, void *data) { | ||
277 | struct sway_server *server = wl_container_of(listener, server, output_remove); | ||
278 | struct wlr_output *wlr_output = data; | ||
279 | wlr_log(L_DEBUG, "Output %p %s removed", wlr_output, wlr_output->name); | ||
280 | 257 | ||
281 | swayc_t *output_container = NULL; | 258 | wl_signal_add(&wlr_output->events.destroy, &output->output_destroy); |
282 | for (int i = 0 ; i < root_container.children->length; ++i) { | 259 | output->output_destroy.notify = handle_output_destroy; |
283 | swayc_t *child = root_container.children->items[i]; | ||
284 | if (child->type == C_OUTPUT && | ||
285 | child->sway_output->wlr_output == wlr_output) { | ||
286 | output_container = child; | ||
287 | break; | ||
288 | } | ||
289 | } | ||
290 | if (!output_container) { | ||
291 | return; | ||
292 | } | ||
293 | 260 | ||
294 | destroy_output(output_container); | 261 | arrange_windows(&root_container, -1, -1); |
295 | } | 262 | } |