aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2018-03-31 17:49:40 -0400
committerLibravatar emersion <contact@emersion.fr>2018-03-31 17:49:40 -0400
commitb2c2ee693b6f1cdaeb204a1469c0fa1b775a498c (patch)
tree1fd4a806d0ab7ba780d5fb93acb741b9b1dc3f85 /sway/desktop/output.c
parentMerge pull request #1684 from swaywm/follow-warp (diff)
downloadsway-b2c2ee693b6f1cdaeb204a1469c0fa1b775a498c.tar.gz
sway-b2c2ee693b6f1cdaeb204a1469c0fa1b775a498c.tar.zst
sway-b2c2ee693b6f1cdaeb204a1469c0fa1b775a498c.zip
Introduce common functions to create, map, unmap, destroy views
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c73
1 files changed, 49 insertions, 24 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 0d706c52..6c97ac37 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -39,6 +39,32 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh,
39 } 39 }
40} 40}
41 41
42/**
43 * Checks whether a surface at (lx, ly) intersects an output. If `box` is not
44 * NULL, it populates it with the surface box in the output, in output-local
45 * coordinates.
46 */
47static bool surface_intersect_output(struct wlr_surface *surface,
48 struct wlr_output_layout *output_layout, struct wlr_output *wlr_output,
49 double lx, double ly, float rotation, struct wlr_box *box) {
50 double ox = lx, oy = ly;
51 wlr_output_layout_output_coords(output_layout, wlr_output, &ox, &oy);
52
53 if (box != NULL) {
54 box->x = ox * wlr_output->scale;
55 box->y = oy * wlr_output->scale;
56 box->width = surface->current->width * wlr_output->scale;
57 box->height = surface->current->height * wlr_output->scale;
58 }
59
60 struct wlr_box layout_box = {
61 .x = lx, .y = ly,
62 .width = surface->current->width, .height = surface->current->height,
63 };
64 wlr_box_rotated_bounds(&layout_box, rotation, &layout_box);
65 return wlr_output_layout_intersects(output_layout, wlr_output, &layout_box);
66}
67
42static void render_surface(struct wlr_surface *surface, 68static void render_surface(struct wlr_surface *surface,
43 struct wlr_output *wlr_output, struct timespec *when, 69 struct wlr_output *wlr_output, struct timespec *when,
44 double lx, double ly, float rotation) { 70 double lx, double ly, float rotation) {
@@ -48,29 +74,21 @@ static void render_surface(struct wlr_surface *surface,
48 if (!wlr_surface_has_buffer(surface)) { 74 if (!wlr_surface_has_buffer(surface)) {
49 return; 75 return;
50 } 76 }
77
51 struct wlr_output_layout *layout = root_container.sway_root->output_layout; 78 struct wlr_output_layout *layout = root_container.sway_root->output_layout;
52 int width = surface->current->width; 79
53 int height = surface->current->height; 80 struct wlr_box box;
54 int render_width = width * wlr_output->scale; 81 bool intersects = surface_intersect_output(surface, layout, wlr_output,
55 int render_height = height * wlr_output->scale; 82 lx, ly, rotation, &box);
56 int owidth, oheight; 83 if (intersects) {
57 wlr_output_effective_resolution(wlr_output, &owidth, &oheight);
58
59 // FIXME: view coords are inconsistently assumed to be in output or layout coords
60 struct wlr_box layout_box = {
61 .x = lx + wlr_output->lx, .y = ly + wlr_output->ly,
62 .width = render_width, .height = render_height,
63 };
64 if (wlr_output_layout_intersects(layout, wlr_output, &layout_box)) {
65 struct wlr_box render_box = {
66 .x = lx, .y = ly,
67 .width = render_width, .height = render_height
68 };
69 float matrix[9]; 84 float matrix[9];
70 wlr_matrix_project_box(matrix, &render_box, surface->current->transform, 85 enum wl_output_transform transform =
71 0, wlr_output->transform_matrix); 86 wlr_output_transform_invert(surface->current->transform);
72 wlr_render_texture_with_matrix(renderer, surface->texture, matrix, 87 wlr_matrix_project_box(matrix, &box, transform, rotation,
73 1.0f); // TODO: configurable alpha 88 wlr_output->transform_matrix);
89
90 // TODO: configurable alpha
91 wlr_render_texture_with_matrix(renderer, surface->texture, matrix, 1.0f);
74 92
75 wlr_surface_send_frame_done(surface, when); 93 wlr_surface_send_frame_done(surface, when);
76 } 94 }
@@ -80,9 +98,8 @@ static void render_surface(struct wlr_surface *surface,
80 struct wlr_surface_state *state = subsurface->surface->current; 98 struct wlr_surface_state *state = subsurface->surface->current;
81 double sx = state->subsurface_position.x; 99 double sx = state->subsurface_position.x;
82 double sy = state->subsurface_position.y; 100 double sy = state->subsurface_position.y;
83 double sw = state->buffer_width / state->scale; 101 rotate_child_position(&sx, &sy, state->width, state->height,
84 double sh = state->buffer_height / state->scale; 102 surface->current->width, surface->current->height, rotation);
85 rotate_child_position(&sx, &sy, sw, sh, width, height, rotation);
86 103
87 render_surface(subsurface->surface, wlr_output, when, 104 render_surface(subsurface->surface, wlr_output, when,
88 lx + sx, ly + sy, rotation); 105 lx + sx, ly + sy, rotation);
@@ -338,6 +355,12 @@ static void handle_transform(struct wl_listener *listener, void *data) {
338 arrange_windows(output->swayc, -1, -1); 355 arrange_windows(output->swayc, -1, -1);
339} 356}
340 357
358static void handle_scale(struct wl_listener *listener, void *data) {
359 struct sway_output *output = wl_container_of(listener, output, scale);
360 arrange_layers(output);
361 arrange_windows(output->swayc, -1, -1);
362}
363
341void handle_new_output(struct wl_listener *listener, void *data) { 364void handle_new_output(struct wl_listener *listener, void *data) {
342 struct sway_server *server = wl_container_of(listener, server, new_output); 365 struct sway_server *server = wl_container_of(listener, server, new_output);
343 struct wlr_output *wlr_output = data; 366 struct wlr_output *wlr_output = data;
@@ -378,6 +401,8 @@ void handle_new_output(struct wl_listener *listener, void *data) {
378 output->mode.notify = handle_mode; 401 output->mode.notify = handle_mode;
379 wl_signal_add(&wlr_output->events.transform, &output->transform); 402 wl_signal_add(&wlr_output->events.transform, &output->transform);
380 output->transform.notify = handle_transform; 403 output->transform.notify = handle_transform;
404 wl_signal_add(&wlr_output->events.scale, &output->scale);
405 output->scale.notify = handle_scale;
381 406
382 wl_signal_add(&output->damage->events.frame, &output->damage_frame); 407 wl_signal_add(&output->damage->events.frame, &output->damage_frame);
383 output->damage_frame.notify = damage_handle_frame; 408 output->damage_frame.notify = damage_handle_frame;