aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop
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
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')
-rw-r--r--sway/desktop/output.c73
-rw-r--r--sway/desktop/wl_shell.c38
-rw-r--r--sway/desktop/xdg_shell_v6.c46
-rw-r--r--sway/desktop/xwayland.c61
4 files changed, 96 insertions, 122 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;
diff --git a/sway/desktop/wl_shell.c b/sway/desktop/wl_shell.c
index 4fcc6317..ab969b17 100644
--- a/sway/desktop/wl_shell.c
+++ b/sway/desktop/wl_shell.c
@@ -75,15 +75,13 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
75 wl_container_of(listener, sway_surface, destroy); 75 wl_container_of(listener, sway_surface, destroy);
76 wl_list_remove(&sway_surface->commit.link); 76 wl_list_remove(&sway_surface->commit.link);
77 wl_list_remove(&sway_surface->destroy.link); 77 wl_list_remove(&sway_surface->destroy.link);
78 struct sway_container *parent = container_view_destroy(sway_surface->view->swayc); 78 view_destroy(sway_surface->view);
79 free(sway_surface->view);
80 free(sway_surface); 79 free(sway_surface);
81 arrange_windows(parent, -1, -1);
82} 80}
83 81
84void handle_wl_shell_surface(struct wl_listener *listener, void *data) { 82void handle_wl_shell_surface(struct wl_listener *listener, void *data) {
85 struct sway_server *server = wl_container_of( 83 struct sway_server *server = wl_container_of(listener, server,
86 listener, server, wl_shell_surface); 84 wl_shell_surface);
87 struct wlr_wl_shell_surface *shell_surface = data; 85 struct wlr_wl_shell_surface *shell_surface = data;
88 86
89 if (shell_surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP) { 87 if (shell_surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP) {
@@ -103,20 +101,18 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) {
103 return; 101 return;
104 } 102 }
105 103
106 struct sway_view *sway_view = calloc(1, sizeof(struct sway_view)); 104 struct sway_view *view = view_create(SWAY_WL_SHELL_VIEW);
107 if (!sway_assert(sway_view, "Failed to allocate view!")) { 105 if (!sway_assert(view, "Failed to allocate view")) {
108 return; 106 return;
109 } 107 }
110 sway_view->type = SWAY_WL_SHELL_VIEW; 108 view->iface.get_prop = get_prop;
111 sway_view->iface.get_prop = get_prop; 109 view->iface.set_size = set_size;
112 sway_view->iface.set_size = set_size; 110 view->iface.set_position = set_position;
113 sway_view->iface.set_position = set_position; 111 view->iface.set_activated = set_activated;
114 sway_view->iface.set_activated = set_activated; 112 view->iface.close = close;
115 sway_view->iface.close = close; 113 view->wlr_wl_shell_surface = shell_surface;
116 sway_view->wlr_wl_shell_surface = shell_surface; 114 view->sway_wl_shell_surface = sway_surface;
117 sway_view->sway_wl_shell_surface = sway_surface; 115 sway_surface->view = view;
118 sway_view->surface = shell_surface->surface;
119 sway_surface->view = sway_view;
120 116
121 // TODO: 117 // TODO:
122 // - Wire up listeners 118 // - Wire up listeners
@@ -132,11 +128,5 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) {
132 sway_surface->destroy.notify = handle_destroy; 128 sway_surface->destroy.notify = handle_destroy;
133 wl_signal_add(&shell_surface->events.destroy, &sway_surface->destroy); 129 wl_signal_add(&shell_surface->events.destroy, &sway_surface->destroy);
134 130
135 struct sway_seat *seat = input_manager_current_seat(input_manager); 131 view_map(view, shell_surface->surface);
136 struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container);
137 struct sway_container *cont = container_view_create(focus, sway_view);
138 sway_view->swayc = cont;
139
140 arrange_windows(cont->parent, -1, -1);
141 sway_input_manager_set_focus(input_manager, cont);
142} 132}
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index 713437f2..77a35b13 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -82,29 +82,14 @@ static void handle_commit(struct wl_listener *listener, void *data) {
82static void handle_unmap(struct wl_listener *listener, void *data) { 82static void handle_unmap(struct wl_listener *listener, void *data) {
83 struct sway_xdg_surface_v6 *sway_surface = 83 struct sway_xdg_surface_v6 *sway_surface =
84 wl_container_of(listener, sway_surface, unmap); 84 wl_container_of(listener, sway_surface, unmap);
85 view_damage_whole(sway_surface->view); 85 view_unmap(sway_surface->view);
86 container_view_destroy(sway_surface->view->swayc);
87 sway_surface->view->swayc = NULL;
88 sway_surface->view->surface = NULL;
89} 86}
90 87
91static void handle_map(struct wl_listener *listener, void *data) { 88static void handle_map(struct wl_listener *listener, void *data) {
92 struct sway_xdg_surface_v6 *sway_surface = 89 struct sway_xdg_surface_v6 *sway_surface =
93 wl_container_of(listener, sway_surface, map); 90 wl_container_of(listener, sway_surface, map);
94 struct sway_view *view = sway_surface->view; 91 struct sway_view *view = sway_surface->view;
95 92 view_map(view, view->wlr_xdg_surface_v6->surface);
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);
108} 93}
109 94
110static void handle_destroy(struct wl_listener *listener, void *data) { 95static void handle_destroy(struct wl_listener *listener, void *data) {
@@ -112,8 +97,9 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
112 wl_container_of(listener, sway_xdg_surface, destroy); 97 wl_container_of(listener, sway_xdg_surface, destroy);
113 wl_list_remove(&sway_xdg_surface->commit.link); 98 wl_list_remove(&sway_xdg_surface->commit.link);
114 wl_list_remove(&sway_xdg_surface->destroy.link); 99 wl_list_remove(&sway_xdg_surface->destroy.link);
115 container_view_destroy(sway_xdg_surface->view->swayc); 100 wl_list_remove(&sway_xdg_surface->map.link);
116 free(sway_xdg_surface->view); 101 wl_list_remove(&sway_xdg_surface->unmap.link);
102 view_destroy(sway_xdg_surface->view);
117 free(sway_xdg_surface); 103 free(sway_xdg_surface);
118} 104}
119 105
@@ -138,23 +124,21 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {
138 return; 124 return;
139 } 125 }
140 126
141 struct sway_view *sway_view = calloc(1, sizeof(struct sway_view)); 127 struct sway_view *view = view_create(SWAY_XDG_SHELL_V6_VIEW);
142 if (!sway_assert(sway_view, "Failed to allocate view!")) { 128 if (!sway_assert(view, "Failed to allocate view")) {
143 return; 129 return;
144 } 130 }
145 sway_view->type = SWAY_XDG_SHELL_V6_VIEW; 131 view->iface.get_prop = get_prop;
146 sway_view->iface.get_prop = get_prop; 132 view->iface.set_size = set_size;
147 sway_view->iface.set_size = set_size; 133 view->iface.set_position = set_position;
148 sway_view->iface.set_position = set_position; 134 view->iface.set_activated = set_activated;
149 sway_view->iface.set_activated = set_activated; 135 view->iface.close = close;
150 sway_view->iface.close = close; 136 view->wlr_xdg_surface_v6 = xdg_surface;
151 sway_view->wlr_xdg_surface_v6 = xdg_surface; 137 view->sway_xdg_surface_v6 = sway_surface;
152 sway_view->sway_xdg_surface_v6 = sway_surface; 138 sway_surface->view = view;
153 sway_surface->view = sway_view;
154 139
155 // TODO: 140 // TODO:
156 // - Look up pid and open on appropriate workspace 141 // - Look up pid and open on appropriate workspace
157 // - Set new view to maximized so it behaves nicely
158 // - Criteria 142 // - Criteria
159 143
160 sway_surface->commit.notify = handle_commit; 144 sway_surface->commit.notify = handle_commit;
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 273ca2bf..e1c2ad08 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -102,56 +102,35 @@ static void handle_commit(struct wl_listener *listener, void *data) {
102static void handle_destroy(struct wl_listener *listener, void *data) { 102static void handle_destroy(struct wl_listener *listener, void *data) {
103 struct sway_xwayland_surface *sway_surface = 103 struct sway_xwayland_surface *sway_surface =
104 wl_container_of(listener, sway_surface, destroy); 104 wl_container_of(listener, sway_surface, destroy);
105
106 wl_list_remove(&sway_surface->commit.link); 105 wl_list_remove(&sway_surface->commit.link);
107 wl_list_remove(&sway_surface->destroy.link); 106 wl_list_remove(&sway_surface->destroy.link);
108 wl_list_remove(&sway_surface->request_configure.link); 107 wl_list_remove(&sway_surface->request_configure.link);
109 wl_list_remove(&sway_surface->view->unmanaged_view_link); 108 wl_list_remove(&sway_surface->map.link);
110 container_view_destroy(sway_surface->view->swayc); 109 wl_list_remove(&sway_surface->unmap.link);
111 sway_surface->view->swayc = NULL; 110 view_destroy(sway_surface->view);
112 sway_surface->view->surface = NULL; 111 free(sway_surface);
113} 112}
114 113
115static void handle_unmap(struct wl_listener *listener, void *data) { 114static void handle_unmap(struct wl_listener *listener, void *data) {
116 struct sway_xwayland_surface *sway_surface = 115 struct sway_xwayland_surface *sway_surface =
117 wl_container_of(listener, sway_surface, unmap); 116 wl_container_of(listener, sway_surface, unmap);
118 view_damage_whole(sway_surface->view); 117 view_unmap(sway_surface->view);
119 wl_list_remove(&sway_surface->view->unmanaged_view_link);
120 wl_list_init(&sway_surface->view->unmanaged_view_link);
121 container_view_destroy(sway_surface->view->swayc);
122 sway_surface->view->swayc = NULL;
123 sway_surface->view->surface = NULL;
124} 118}
125 119
126static void handle_map(struct wl_listener *listener, void *data) { 120static void handle_map(struct wl_listener *listener, void *data) {
127 struct sway_xwayland_surface *sway_surface = 121 struct sway_xwayland_surface *sway_surface =
128 wl_container_of(listener, sway_surface, map); 122 wl_container_of(listener, sway_surface, map);
129 struct wlr_xwayland_surface *xsurface = data; 123 struct wlr_xwayland_surface *xsurface = data;
130 124 struct sway_view *view = sway_surface->view;
131 sway_surface->view->surface = xsurface->surface;
132 125
133 // put it back into the tree 126 // put it back into the tree
134 if (wlr_xwayland_surface_is_unmanaged(xsurface) || 127 if (wlr_xwayland_surface_is_unmanaged(xsurface) ||
135 xsurface->override_redirect) { 128 xsurface->override_redirect) {
136 wl_list_remove(&sway_surface->view->unmanaged_view_link); 129 view_map_unmanaged(view, xsurface->surface);
137 wl_list_insert(&root_container.sway_root->unmanaged_views,
138 &sway_surface->view->unmanaged_view_link);
139 } else { 130 } else {
140 struct sway_view *view = sway_surface->view;
141 container_view_destroy(view->swayc);
142
143 wlr_xwayland_surface_set_maximized(xsurface, true); 131 wlr_xwayland_surface_set_maximized(xsurface, true);
144 132 view_map(view, xsurface->surface);
145 struct sway_seat *seat = input_manager_current_seat(input_manager);
146 struct sway_container *focus = sway_seat_get_focus_inactive(seat,
147 &root_container);
148 struct sway_container *cont = container_view_create(focus, view);
149 view->swayc = cont;
150 arrange_windows(cont->parent, -1, -1);
151 sway_input_manager_set_focus(input_manager, cont);
152 } 133 }
153
154 view_damage_whole(sway_surface->view);
155} 134}
156 135
157static void handle_request_configure(struct wl_listener *listener, void *data) { 136static void handle_request_configure(struct wl_listener *listener, void *data) {
@@ -180,25 +159,21 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
180 return; 159 return;
181 } 160 }
182 161
183 struct sway_view *sway_view = calloc(1, sizeof(struct sway_view)); 162 struct sway_view *view = view_create(SWAY_XWAYLAND_VIEW);
184 if (!sway_assert(sway_view, "Failed to allocate view!")) { 163 if (!sway_assert(view, "Failed to allocate view")) {
185 return; 164 return;
186 } 165 }
187 sway_view->type = SWAY_XWAYLAND_VIEW; 166 view->iface.get_prop = get_prop;
188 sway_view->iface.get_prop = get_prop; 167 view->iface.set_size = set_size;
189 sway_view->iface.set_size = set_size; 168 view->iface.set_position = set_position;
190 sway_view->iface.set_position = set_position; 169 view->iface.set_activated = set_activated;
191 sway_view->iface.set_activated = set_activated; 170 view->iface.close = close_view;
192 sway_view->iface.close = close_view; 171 view->wlr_xwayland_surface = xsurface;
193 sway_view->wlr_xwayland_surface = xsurface; 172 view->sway_xwayland_surface = sway_surface;
194 sway_view->sway_xwayland_surface = sway_surface; 173 sway_surface->view = view;
195 sway_surface->view = sway_view;
196
197 wl_list_init(&sway_view->unmanaged_view_link);
198 174
199 // TODO: 175 // TODO:
200 // - Look up pid and open on appropriate workspace 176 // - Look up pid and open on appropriate workspace
201 // - Set new view to maximized so it behaves nicely
202 // - Criteria 177 // - Criteria
203 178
204 wl_signal_add(&xsurface->surface->events.commit, &sway_surface->commit); 179 wl_signal_add(&xsurface->surface->events.commit, &sway_surface->commit);