aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-04-30 21:24:13 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-04-30 21:24:13 +1000
commite67f3543332349e63b5099a241fdd85ce28ea54b (patch)
tree54bede11d48f561693d1288e0980660c644b4dc3 /sway/desktop/output.c
parentMerge pull request #1873 from RyanDwyer/remove-arrange-windows (diff)
downloadsway-e67f3543332349e63b5099a241fdd85ce28ea54b.tar.gz
sway-e67f3543332349e63b5099a241fdd85ce28ea54b.tar.zst
sway-e67f3543332349e63b5099a241fdd85ce28ea54b.zip
Implement borders
Implements rendering of borders. Title text is still to do. Implements the following configuration directives: * client.focused * client.focused_inactive * client.unfocused * client.urgent * border * default_border
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c205
1 files changed, 190 insertions, 15 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index d9ae890f..2511c610 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -116,8 +116,8 @@ static void surface_for_each_surface(struct wlr_surface *surface,
116static void output_view_for_each_surface(struct sway_view *view, 116static void output_view_for_each_surface(struct sway_view *view,
117 struct root_geometry *geo, wlr_surface_iterator_func_t iterator, 117 struct root_geometry *geo, wlr_surface_iterator_func_t iterator,
118 void *user_data) { 118 void *user_data) {
119 geo->x = view->swayc->x; 119 geo->x = view->x;
120 geo->y = view->swayc->y; 120 geo->y = view->y;
121 geo->width = view->surface->current->width; 121 geo->width = view->surface->current->width;
122 geo->height = view->surface->current->height; 122 geo->height = view->surface->current->height;
123 geo->rotation = 0; // TODO 123 geo->rotation = 0; // TODO
@@ -217,23 +217,198 @@ static void render_unmanaged(struct sway_output *output,
217 render_surface_iterator, &data); 217 render_surface_iterator, &data);
218} 218}
219 219
220static void render_container_iterator(struct sway_container *con, 220static void render_view(struct sway_view *view, struct sway_output *output) {
221 void *_data) { 221 struct render_data data = { .output = output, .alpha = view->swayc->alpha };
222 struct sway_output *output = _data; 222 output_view_for_each_surface(
223 if (!sway_assert(con->type == C_VIEW, "expected a view")) { 223 view, &data.root_geo, render_surface_iterator, &data);
224 return; 224}
225
226/**
227 * Render decorations for a view with "border normal".
228 */
229static void render_container_simple_border_normal(struct sway_output *output,
230 struct sway_container *con, struct border_colors *colors) {
231 struct wlr_renderer *renderer =
232 wlr_backend_get_renderer(output->wlr_output->backend);
233 struct wlr_box box;
234 float color[4];
235 color[3] = con->alpha;
236
237 // Child border - left edge
238 memcpy(&color, colors->child_border, sizeof(float) * 3);
239 box.x = con->x;
240 box.y = con->y + 1;
241 box.width = con->sway_view->border_thickness;
242 box.height = con->height - 1;
243 wlr_render_rect(renderer, &box, color,
244 output->wlr_output->transform_matrix);
245
246 // Child border - right edge
247 box.x = con->x + con->width - con->sway_view->border_thickness;
248 box.y = con->y + 1;
249 box.width = con->sway_view->border_thickness;
250 box.height = con->height - 1;
251 wlr_render_rect(renderer, &box, color,
252 output->wlr_output->transform_matrix);
253
254 // Child border - bottom edge
255 box.x = con->x;
256 box.y = con->y + con->height - con->sway_view->border_thickness;
257 box.width = con->width;
258 box.height = con->sway_view->border_thickness;
259 wlr_render_rect(renderer, &box, color,
260 output->wlr_output->transform_matrix);
261
262 // Single pixel bar above title
263 memcpy(&color, colors->border, sizeof(float) * 3);
264 box.x = con->x;
265 box.y = con->y;
266 box.width = con->width;
267 box.height = 1;
268 wlr_render_rect(renderer, &box, color,
269 output->wlr_output->transform_matrix);
270
271 // Single pixel bar below title
272 box.x = con->x + con->sway_view->border_thickness;
273 box.y = con->sway_view->y - 1;
274 box.width = con->width - con->sway_view->border_thickness * 2;
275 box.height = 1;
276 wlr_render_rect(renderer, &box, color,
277 output->wlr_output->transform_matrix);
278
279 // Title background
280 memcpy(&color, colors->background, sizeof(float) * 3);
281 box.x = con->x + con->sway_view->border_thickness;
282 box.y = con->y + 1;
283 box.width = con->width - con->sway_view->border_thickness * 2;
284 box.height = con->sway_view->y - con->y - 2;
285 wlr_render_rect(renderer, &box, color,
286 output->wlr_output->transform_matrix);
287
288 // Title text
289 // TODO
290}
291
292/**
293 * Render decorations for a view with "border pixel".
294 */
295static void render_container_simple_border_pixel(struct sway_output *output,
296 struct sway_container *con, struct border_colors *colors) {
297 struct wlr_renderer *renderer =
298 wlr_backend_get_renderer(output->wlr_output->backend);
299 struct wlr_box box;
300 float color[4];
301 color[3] = con->alpha;
302
303 // Child border - left edge
304 memcpy(&color, colors->child_border, sizeof(float) * 3);
305 box.x = con->x;
306 box.y = con->y;
307 box.width = con->sway_view->border_thickness;
308 box.height = con->height;
309 wlr_render_rect(renderer, &box, color,
310 output->wlr_output->transform_matrix);
311
312 // Child border - right edge
313 box.x = con->x + con->width - con->sway_view->border_thickness;
314 box.y = con->y;
315 box.width = con->sway_view->border_thickness;
316 box.height = con->height;
317 wlr_render_rect(renderer, &box, color,
318 output->wlr_output->transform_matrix);
319
320 // Child border - top edge
321 box.x = con->x;
322 box.y = con->y;
323 box.width = con->width;
324 box.height = con->sway_view->border_thickness;
325 wlr_render_rect(renderer, &box, color,
326 output->wlr_output->transform_matrix);
327
328 // Child border - bottom edge
329 box.x = con->x;
330 box.y = con->y + con->height - con->sway_view->border_thickness;
331 box.width = con->width;
332 box.height = con->sway_view->border_thickness;
333 wlr_render_rect(renderer, &box, color,
334 output->wlr_output->transform_matrix);
335}
336
337static void render_container(struct sway_output *output,
338 struct sway_container *con);
339
340/**
341 * Render a container's children using a L_HORIZ or L_VERT layout.
342 *
343 * Wrap child views in borders and leave child containers borderless because
344 * they'll apply their own borders to their children.
345 */
346static void render_container_simple(struct sway_output *output,
347 struct sway_container *con) {
348 struct sway_seat *seat = input_manager_current_seat(input_manager);
349 struct sway_container *focus = seat_get_focus(seat);
350
351 for (int i = 0; i < con->children->length; ++i) {
352 struct sway_container *child = con->children->items[i];
353
354 if (child->type == C_VIEW) {
355 if (child->sway_view->border != B_NONE) {
356 struct border_colors *colors;
357 if (focus == child) {
358 colors = &config->border_colors.focused;
359 } else if (seat_get_focus_inactive(seat, con) == child) {
360 colors = &config->border_colors.focused_inactive;
361 } else {
362 colors = &config->border_colors.unfocused;
363 }
364
365 if (child->sway_view->border == B_NORMAL) {
366 render_container_simple_border_normal(output, child,
367 colors);
368 } else {
369 render_container_simple_border_pixel(output, child, colors);
370 }
371 }
372 render_view(child->sway_view, output);
373 } else {
374 render_container(output, child);
375 }
225 } 376 }
226 struct render_data data = { .output = output, .alpha = con->alpha }; 377}
227 output_view_for_each_surface(con->sway_view, &data.root_geo, 378
228 render_surface_iterator, &data); 379/**
380 * Render a container's children using the L_TABBED layout.
381 */
382static void render_container_tabbed(struct sway_output *output,
383 struct sway_container *con) {
384 // TODO
385}
386
387/**
388 * Render a container's children using the L_STACKED layout.
389 */
390static void render_container_stacked(struct sway_output *output,
391 struct sway_container *con) {
392 // TODO
229} 393}
230 394
231static void render_container(struct sway_output *output, 395static void render_container(struct sway_output *output,
232 struct sway_container *con) { 396 struct sway_container *con) {
233 if (con->type == C_VIEW) { // Happens if a view is fullscreened 397 switch (con->layout) {
234 render_container_iterator(con, output); 398 case L_NONE:
235 } else { 399 case L_HORIZ:
236 container_descendants(con, C_VIEW, render_container_iterator, output); 400 case L_VERT:
401 render_container_simple(output, con);
402 break;
403 case L_STACKED:
404 render_container_stacked(output, con);
405 break;
406 case L_TABBED:
407 render_container_tabbed(output, con);
408 break;
409 case L_FLOATING:
410 // TODO
411 break;
237 } 412 }
238} 413}
239 414
@@ -282,7 +457,7 @@ static void render_output(struct sway_output *output, struct timespec *when,
282 float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; 457 float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
283 wlr_renderer_clear(renderer, clear_color); 458 wlr_renderer_clear(renderer, clear_color);
284 // TODO: handle views smaller than the output 459 // TODO: handle views smaller than the output
285 render_container(output, workspace->sway_workspace->fullscreen->swayc); 460 render_view(workspace->sway_workspace->fullscreen, output);
286 461
287 if (workspace->sway_workspace->fullscreen->type == SWAY_VIEW_XWAYLAND) { 462 if (workspace->sway_workspace->fullscreen->type == SWAY_VIEW_XWAYLAND) {
288 render_unmanaged(output, 463 render_unmanaged(output,