diff options
-rw-r--r-- | include/sway/tree/container.h | 11 | ||||
-rw-r--r-- | sway/commands/layout.c | 2 | ||||
-rw-r--r-- | sway/desktop/output.c | 602 | ||||
-rw-r--r-- | sway/tree/arrange.c | 32 | ||||
-rw-r--r-- | sway/tree/container.c | 25 | ||||
-rw-r--r-- | sway/tree/view.c | 15 |
6 files changed, 340 insertions, 347 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 598a4f3d..493c70e2 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h | |||
@@ -11,6 +11,12 @@ extern struct sway_container root_container; | |||
11 | struct sway_view; | 11 | struct sway_view; |
12 | struct sway_seat; | 12 | struct sway_seat; |
13 | 13 | ||
14 | #define TITLEBAR_BORDER_THICKNESS 1 | ||
15 | |||
16 | // Padding includes titlebar border | ||
17 | #define TITLEBAR_H_PADDING 3 | ||
18 | #define TITLEBAR_V_PADDING 4 | ||
19 | |||
14 | /** | 20 | /** |
15 | * Different kinds of containers. | 21 | * Different kinds of containers. |
16 | * | 22 | * |
@@ -212,4 +218,9 @@ void container_calculate_title_height(struct sway_container *container); | |||
212 | 218 | ||
213 | void container_notify_child_title_changed(struct sway_container *container); | 219 | void container_notify_child_title_changed(struct sway_container *container); |
214 | 220 | ||
221 | /** | ||
222 | * Return the height of a regular title bar. | ||
223 | */ | ||
224 | size_t container_titlebar_height(void); | ||
225 | |||
215 | #endif | 226 | #endif |
diff --git a/sway/commands/layout.c b/sway/commands/layout.c index 8aa321ae..58728f16 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c | |||
@@ -41,6 +41,8 @@ struct cmd_results *cmd_layout(int argc, char **argv) { | |||
41 | parent->layout = L_VERT; | 41 | parent->layout = L_VERT; |
42 | } else if (strcasecmp(argv[0], "tabbed") == 0) { | 42 | } else if (strcasecmp(argv[0], "tabbed") == 0) { |
43 | parent->layout = L_TABBED; | 43 | parent->layout = L_TABBED; |
44 | } else if (strcasecmp(argv[0], "stacking") == 0) { | ||
45 | parent->layout = L_STACKED; | ||
44 | } else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) { | 46 | } else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) { |
45 | if (parent->layout == L_HORIZ) { | 47 | if (parent->layout == L_HORIZ) { |
46 | parent->layout = L_VERT; | 48 | parent->layout = L_VERT; |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 551e96fc..765647fd 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -269,17 +269,6 @@ static void render_unmanaged(struct sway_output *output, | |||
269 | render_surface_iterator, &data); | 269 | render_surface_iterator, &data); |
270 | } | 270 | } |
271 | 271 | ||
272 | static void render_view(struct sway_view *view, struct sway_output *output, | ||
273 | pixman_region32_t *damage) { | ||
274 | struct render_data data = { | ||
275 | .output = output, | ||
276 | .damage = damage, | ||
277 | .alpha = view->swayc->alpha, | ||
278 | }; | ||
279 | output_view_for_each_surface( | ||
280 | view, &data.root_geo, render_surface_iterator, &data); | ||
281 | } | ||
282 | |||
283 | static void render_rect(struct wlr_output *wlr_output, | 272 | static void render_rect(struct wlr_output *wlr_output, |
284 | pixman_region32_t *output_damage, const struct wlr_box *_box, | 273 | pixman_region32_t *output_damage, const struct wlr_box *_box, |
285 | float color[static 4]) { | 274 | float color[static 4]) { |
@@ -317,108 +306,161 @@ static void premultiply_alpha(float color[4], float opacity) { | |||
317 | color[2] *= color[3]; | 306 | color[2] *= color[3]; |
318 | } | 307 | } |
319 | 308 | ||
309 | static void render_view_surfaces(struct sway_view *view, | ||
310 | struct sway_output *output, pixman_region32_t *damage) { | ||
311 | struct render_data data = { | ||
312 | .output = output, | ||
313 | .damage = damage, | ||
314 | .alpha = view->swayc->alpha, | ||
315 | }; | ||
316 | output_view_for_each_surface( | ||
317 | view, &data.root_geo, render_surface_iterator, &data); | ||
318 | } | ||
319 | |||
320 | /** | 320 | /** |
321 | * Render decorations for a view with "border normal". | 321 | * Render a view's surface and left/bottom/right borders. |
322 | * | ||
323 | * Care must be taken not to render over the same pixel multiple times, | ||
324 | * otherwise the colors will be incorrect when using opacity. | ||
325 | */ | 322 | */ |
326 | static void render_container_simple_border_normal(struct sway_output *output, | 323 | static void render_view(struct sway_output *output, pixman_region32_t *damage, |
327 | pixman_region32_t *output_damage, | 324 | struct sway_container *con, struct border_colors *colors) { |
328 | struct sway_container *con, struct border_colors *colors, | ||
329 | struct wlr_texture *title_texture, struct wlr_texture *marks_texture) { | ||
330 | struct wlr_box box; | ||
331 | float color[4]; | ||
332 | struct sway_view *view = con->sway_view; | 325 | struct sway_view *view = con->sway_view; |
333 | float output_scale = output->wlr_output->scale; | 326 | render_view_surfaces(view, output, damage); |
334 | 327 | ||
335 | if (view->border_left) { | 328 | struct wlr_box box; |
336 | // Child border - left edge | 329 | float output_scale = output->wlr_output->scale; |
337 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 330 | float color[4]; |
338 | premultiply_alpha(color, con->alpha); | ||
339 | box.x = con->x; | ||
340 | box.y = con->y + 1; | ||
341 | box.width = view->border_thickness; | ||
342 | box.height = con->height - 1 | ||
343 | - view->border_thickness * view->border_bottom; | ||
344 | scale_box(&box, output_scale); | ||
345 | render_rect(output->wlr_output, output_damage, &box, color); | ||
346 | } | ||
347 | 331 | ||
348 | if (view->border_right) { | 332 | if (view->border != B_NONE) { |
349 | // Child border - right edge | 333 | if (view->border_left) { |
350 | if (con->parent->children->length == 1 | ||
351 | && con->parent->layout == L_HORIZ) { | ||
352 | memcpy(&color, colors->indicator, sizeof(float) * 4); | ||
353 | } else { | ||
354 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 334 | memcpy(&color, colors->child_border, sizeof(float) * 4); |
335 | premultiply_alpha(color, con->alpha); | ||
336 | box.x = con->x; | ||
337 | box.y = view->y; | ||
338 | box.width = view->border_thickness; | ||
339 | box.height = view->height; | ||
340 | scale_box(&box, output_scale); | ||
341 | render_rect(output->wlr_output, damage, &box, color); | ||
355 | } | 342 | } |
356 | premultiply_alpha(color, con->alpha); | ||
357 | box.x = con->x + con->width - view->border_thickness; | ||
358 | box.y = con->y + 1; | ||
359 | box.width = view->border_thickness; | ||
360 | box.height = con->height - 1 | ||
361 | - view->border_thickness * view->border_bottom; | ||
362 | scale_box(&box, output_scale); | ||
363 | render_rect(output->wlr_output, output_damage, &box, color); | ||
364 | } | ||
365 | 343 | ||
366 | if (view->border_bottom) { | 344 | if (view->border_right) { |
367 | // Child border - bottom edge | 345 | if (con->parent->children->length == 1 |
368 | if (con->parent->children->length == 1 | 346 | && con->parent->layout == L_HORIZ) { |
369 | && con->parent->layout == L_VERT) { | 347 | memcpy(&color, colors->indicator, sizeof(float) * 4); |
370 | memcpy(&color, colors->indicator, sizeof(float) * 4); | 348 | } else { |
371 | } else { | 349 | memcpy(&color, colors->child_border, sizeof(float) * 4); |
372 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 350 | } |
351 | premultiply_alpha(color, con->alpha); | ||
352 | box.x = view->x + view->width; | ||
353 | box.y = view->y; | ||
354 | box.width = view->border_thickness; | ||
355 | box.height = view->height; | ||
356 | scale_box(&box, output_scale); | ||
357 | render_rect(output->wlr_output, damage, &box, color); | ||
358 | } | ||
359 | |||
360 | if (view->border_bottom) { | ||
361 | if (con->parent->children->length == 1 | ||
362 | && con->parent->layout == L_VERT) { | ||
363 | memcpy(&color, colors->indicator, sizeof(float) * 4); | ||
364 | } else { | ||
365 | memcpy(&color, colors->child_border, sizeof(float) * 4); | ||
366 | } | ||
367 | premultiply_alpha(color, con->alpha); | ||
368 | box.x = con->x; | ||
369 | box.y = view->y + view->height; | ||
370 | box.width = con->width; | ||
371 | box.height = view->border_thickness; | ||
372 | scale_box(&box, output_scale); | ||
373 | render_rect(output->wlr_output, damage, &box, color); | ||
373 | } | 374 | } |
374 | premultiply_alpha(color, con->alpha); | ||
375 | box.x = con->x; | ||
376 | box.y = con->y + con->height - view->border_thickness; | ||
377 | box.width = con->width; | ||
378 | box.height = view->border_thickness; | ||
379 | scale_box(&box, output_scale); | ||
380 | render_rect(output->wlr_output, output_damage, &box, color); | ||
381 | } | 375 | } |
376 | } | ||
377 | |||
378 | /** | ||
379 | * Render a titlebar. | ||
380 | * | ||
381 | * Care must be taken not to render over the same pixel multiple times, | ||
382 | * otherwise the colors will be incorrect when using opacity. | ||
383 | * | ||
384 | * The height is: 1px border, 3px padding, font height, 3px padding, 1px border | ||
385 | * The left side for L_TABBED is: 1px border, 2px padding, title | ||
386 | * The left side for other layouts is: 3px padding, title | ||
387 | */ | ||
388 | static void render_titlebar(struct sway_output *output, | ||
389 | pixman_region32_t *output_damage, struct sway_container *con, | ||
390 | int x, int y, int width, | ||
391 | struct border_colors *colors, struct wlr_texture *title_texture, | ||
392 | struct wlr_texture *marks_texture) { | ||
393 | struct wlr_box box; | ||
394 | float color[4]; | ||
395 | struct sway_view *view = con->type == C_VIEW ? con->sway_view : NULL; | ||
396 | float output_scale = output->wlr_output->scale; | ||
397 | enum sway_container_layout layout = con->parent->layout; | ||
398 | bool is_last_child = | ||
399 | con->parent->children->items[con->parent->children->length - 1] == con; | ||
382 | 400 | ||
383 | // Single pixel bar above title | 401 | // Single pixel bar above title |
384 | memcpy(&color, colors->border, sizeof(float) * 4); | 402 | memcpy(&color, colors->border, sizeof(float) * 4); |
385 | premultiply_alpha(color, con->alpha); | 403 | premultiply_alpha(color, con->alpha); |
386 | box.x = con->x; | 404 | box.x = x; |
387 | box.y = con->y; | 405 | box.y = y; |
388 | box.width = con->width; | 406 | box.width = width; |
389 | box.height = 1; | 407 | box.height = TITLEBAR_BORDER_THICKNESS; |
390 | scale_box(&box, output_scale); | 408 | scale_box(&box, output_scale); |
391 | render_rect(output->wlr_output, output_damage, &box, color); | 409 | render_rect(output->wlr_output, output_damage, &box, color); |
392 | 410 | ||
393 | // Setting these makes marks and title easier | ||
394 | size_t inner_x = con->x + view->border_thickness * view->border_left; | ||
395 | size_t inner_width = con->width - view->border_thickness * view->border_left | ||
396 | - view->border_thickness * view->border_right; | ||
397 | |||
398 | // Single pixel bar below title | 411 | // Single pixel bar below title |
399 | memcpy(&color, colors->border, sizeof(float) * 4); | 412 | size_t left_offset = 0, right_offset = 0; |
400 | premultiply_alpha(color, con->alpha); | 413 | bool connects_sides = false; |
401 | box.x = inner_x; | 414 | if (layout == L_HORIZ || layout == L_VERT || |
402 | box.y = view->y - 1; | 415 | (layout == L_STACKED && is_last_child)) { |
403 | box.width = inner_width; | 416 | if (view) { |
404 | box.height = 1; | 417 | left_offset = view->border_left * view->border_thickness; |
418 | right_offset = view->border_right * view->border_thickness; | ||
419 | connects_sides = true; | ||
420 | } | ||
421 | } | ||
422 | box.x = x + left_offset; | ||
423 | box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS; | ||
424 | box.width = width - left_offset - right_offset; | ||
425 | box.height = TITLEBAR_BORDER_THICKNESS; | ||
405 | scale_box(&box, output_scale); | 426 | scale_box(&box, output_scale); |
406 | render_rect(output->wlr_output, output_damage, &box, color); | 427 | render_rect(output->wlr_output, output_damage, &box, color); |
407 | 428 | ||
429 | if (layout == L_TABBED) { | ||
430 | // Single pixel left edge | ||
431 | box.x = x; | ||
432 | box.y = y + TITLEBAR_BORDER_THICKNESS; | ||
433 | box.width = TITLEBAR_BORDER_THICKNESS; | ||
434 | box.height = | ||
435 | container_titlebar_height() - TITLEBAR_BORDER_THICKNESS * 2; | ||
436 | scale_box(&box, output_scale); | ||
437 | render_rect(output->wlr_output, output_damage, &box, color); | ||
438 | |||
439 | // Single pixel right edge | ||
440 | box.x = (x + width - TITLEBAR_BORDER_THICKNESS) * output_scale; | ||
441 | render_rect(output->wlr_output, output_damage, &box, color); | ||
442 | } | ||
443 | |||
444 | size_t inner_width = width - TITLEBAR_H_PADDING * 2; | ||
445 | |||
408 | // Marks | 446 | // Marks |
409 | size_t marks_width = 0; | 447 | size_t marks_width = 0; |
410 | if (config->show_marks && marks_texture) { | 448 | if (config->show_marks && marks_texture) { |
411 | struct wlr_box texture_box; | 449 | struct wlr_box texture_box; |
412 | wlr_texture_get_size(marks_texture, | 450 | wlr_texture_get_size(marks_texture, |
413 | &texture_box.width, &texture_box.height); | 451 | &texture_box.width, &texture_box.height); |
414 | texture_box.x = (inner_x + inner_width) * output_scale - texture_box.width; | 452 | texture_box.x = |
415 | texture_box.y = (con->y + view->border_thickness) * output_scale; | 453 | (x + width - TITLEBAR_H_PADDING) * output_scale - texture_box.width; |
454 | texture_box.y = (y + TITLEBAR_V_PADDING) * output_scale; | ||
416 | 455 | ||
417 | float matrix[9]; | 456 | float matrix[9]; |
418 | wlr_matrix_project_box(matrix, &texture_box, | 457 | wlr_matrix_project_box(matrix, &texture_box, |
419 | WL_OUTPUT_TRANSFORM_NORMAL, | 458 | WL_OUTPUT_TRANSFORM_NORMAL, |
420 | 0.0, output->wlr_output->transform_matrix); | 459 | 0.0, output->wlr_output->transform_matrix); |
421 | 460 | ||
461 | if (inner_width * output_scale < texture_box.width) { | ||
462 | texture_box.width = inner_width * output_scale; | ||
463 | } | ||
422 | render_texture(output->wlr_output, output_damage, marks_texture, | 464 | render_texture(output->wlr_output, output_damage, marks_texture, |
423 | &texture_box, matrix, con->alpha); | 465 | &texture_box, matrix, con->alpha); |
424 | marks_width = texture_box.width; | 466 | marks_width = texture_box.width; |
@@ -430,8 +472,8 @@ static void render_container_simple_border_normal(struct sway_output *output, | |||
430 | struct wlr_box texture_box; | 472 | struct wlr_box texture_box; |
431 | wlr_texture_get_size(title_texture, | 473 | wlr_texture_get_size(title_texture, |
432 | &texture_box.width, &texture_box.height); | 474 | &texture_box.width, &texture_box.height); |
433 | texture_box.x = inner_x * output_scale; | 475 | texture_box.x = (x + TITLEBAR_H_PADDING) * output_scale; |
434 | texture_box.y = (con->y + view->border_thickness) * output_scale; | 476 | texture_box.y = (y + TITLEBAR_V_PADDING) * output_scale; |
435 | 477 | ||
436 | float matrix[9]; | 478 | float matrix[9]; |
437 | wlr_matrix_project_box(matrix, &texture_box, | 479 | wlr_matrix_project_box(matrix, &texture_box, |
@@ -446,104 +488,89 @@ static void render_container_simple_border_normal(struct sway_output *output, | |||
446 | title_width = texture_box.width; | 488 | title_width = texture_box.width; |
447 | } | 489 | } |
448 | 490 | ||
449 | // Title background - above the text | 491 | // Padding above title |
450 | memcpy(&color, colors->background, sizeof(float) * 4); | 492 | memcpy(&color, colors->background, sizeof(float) * 4); |
451 | premultiply_alpha(color, con->alpha); | 493 | premultiply_alpha(color, con->alpha); |
452 | box.x = inner_x; | 494 | box.x = x + (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS; |
453 | box.y = con->y + 1; | 495 | box.y = y + TITLEBAR_BORDER_THICKNESS; |
454 | box.width = inner_width; | 496 | box.width = width - (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS * 2; |
455 | box.height = view->border_thickness - 1; | 497 | box.height = TITLEBAR_V_PADDING - TITLEBAR_BORDER_THICKNESS; |
456 | scale_box(&box, output_scale); | 498 | scale_box(&box, output_scale); |
457 | render_rect(output->wlr_output, output_damage, &box, color); | 499 | render_rect(output->wlr_output, output_damage, &box, color); |
458 | 500 | ||
459 | // Title background - below the text | 501 | // Padding below title |
460 | box.y = (con->y + view->border_thickness + config->font_height) | 502 | box.y = (y + TITLEBAR_V_PADDING + config->font_height) * output_scale; |
461 | * output_scale; | ||
462 | render_rect(output->wlr_output, output_damage, &box, color); | 503 | render_rect(output->wlr_output, output_damage, &box, color); |
463 | 504 | ||
464 | // Title background - filler between title and marks | 505 | // Filler between title and marks |
465 | box.width = inner_width * output_scale - title_width - marks_width; | 506 | box.width = inner_width * output_scale - title_width - marks_width; |
466 | if (box.width > 0) { | 507 | if (box.width > 0) { |
467 | box.x = inner_x * output_scale + title_width; | 508 | box.x = (x + TITLEBAR_H_PADDING) * output_scale + title_width; |
468 | box.y = (con->y + view->border_thickness) * output_scale; | 509 | box.y = (y + TITLEBAR_V_PADDING) * output_scale; |
469 | box.height = config->font_height * output_scale; | 510 | box.height = config->font_height * output_scale; |
470 | render_rect(output->wlr_output, output_damage, &box, color); | 511 | render_rect(output->wlr_output, output_damage, &box, color); |
471 | } | 512 | } |
472 | } | ||
473 | 513 | ||
474 | /** | 514 | // Padding left of title |
475 | * Render decorations for a view with "border pixel". | 515 | left_offset = (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS; |
476 | * | 516 | box.x = x + left_offset; |
477 | * Care must be taken not to render over the same pixel multiple times, | 517 | box.y = y + TITLEBAR_V_PADDING; |
478 | * otherwise the colors will be incorrect when using opacity. | 518 | box.width = TITLEBAR_H_PADDING - left_offset; |
479 | */ | 519 | box.height = config->font_height; |
480 | static void render_container_simple_border_pixel(struct sway_output *output, | 520 | scale_box(&box, output_scale); |
481 | pixman_region32_t *output_damage, struct sway_container *con, | 521 | render_rect(output->wlr_output, output_damage, &box, color); |
482 | struct border_colors *colors) { | ||
483 | struct wlr_box box; | ||
484 | float color[4]; | ||
485 | struct sway_view *view = con->sway_view; | ||
486 | float output_scale = output->wlr_output->scale; | ||
487 | 522 | ||
488 | if (view->border_left) { | 523 | // Padding right of marks |
489 | // Child border - left edge | 524 | right_offset = (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS; |
490 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 525 | box.x = x + width - TITLEBAR_H_PADDING; |
491 | premultiply_alpha(color, con->alpha); | 526 | box.y = y + TITLEBAR_V_PADDING; |
492 | box.x = con->x; | 527 | box.width = TITLEBAR_H_PADDING - right_offset; |
493 | box.y = con->y + view->border_thickness * view->border_top; | 528 | box.height = config->font_height; |
494 | box.width = view->border_thickness; | 529 | scale_box(&box, output_scale); |
495 | box.height = con->height - view->border_thickness | 530 | render_rect(output->wlr_output, output_damage, &box, color); |
496 | * (view->border_top + view->border_bottom); | ||
497 | scale_box(&box, output_scale); | ||
498 | render_rect(output->wlr_output, output_damage, &box, color); | ||
499 | } | ||
500 | 531 | ||
501 | if (view->border_right) { | 532 | if (connects_sides) { |
502 | // Child border - right edge | 533 | // Left pixel in line with bottom bar |
503 | if (con->parent->children->length == 1 | 534 | box.x = x; |
504 | && con->parent->layout == L_HORIZ) { | 535 | box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS; |
505 | memcpy(&color, colors->indicator, sizeof(float) * 4); | 536 | box.width = view->border_thickness * view->border_left; |
506 | } else { | 537 | box.height = TITLEBAR_BORDER_THICKNESS; |
507 | memcpy(&color, colors->child_border, sizeof(float) * 4); | ||
508 | } | ||
509 | premultiply_alpha(color, con->alpha); | ||
510 | box.x = con->x + con->width - view->border_thickness; | ||
511 | box.y = con->y + view->border_thickness * view->border_top; | ||
512 | box.width = view->border_thickness; | ||
513 | box.height = con->height - view->border_thickness | ||
514 | * (view->border_top + view->border_bottom); | ||
515 | scale_box(&box, output_scale); | 538 | scale_box(&box, output_scale); |
516 | render_rect(output->wlr_output, output_damage, &box, color); | 539 | render_rect(output->wlr_output, output_damage, &box, color); |
517 | } | ||
518 | 540 | ||
519 | if (view->border_top) { | 541 | // Right pixel in line with bottom bar |
520 | // Child border - top edge | 542 | box.x = x + width - view->border_thickness * view->border_right; |
521 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 543 | box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS; |
522 | premultiply_alpha(color, con->alpha); | 544 | box.width = view->border_thickness * view->border_right; |
523 | box.x = con->x; | 545 | box.height = TITLEBAR_BORDER_THICKNESS; |
524 | box.y = con->y; | ||
525 | box.width = con->width; | ||
526 | box.height = view->border_thickness; | ||
527 | scale_box(&box, output_scale); | 546 | scale_box(&box, output_scale); |
528 | render_rect(output->wlr_output, output_damage, &box, color); | 547 | render_rect(output->wlr_output, output_damage, &box, color); |
529 | } | 548 | } |
549 | } | ||
530 | 550 | ||
531 | if (view->border_bottom) { | 551 | /** |
532 | // Child border - bottom edge | 552 | * Render the top border line for a view using "border pixel". |
533 | if (con->parent->children->length == 1 | 553 | */ |
534 | && con->parent->layout == L_VERT) { | 554 | static void render_top_border(struct sway_output *output, |
535 | memcpy(&color, colors->indicator, sizeof(float) * 4); | 555 | pixman_region32_t *output_damage, struct sway_container *con, |
536 | } else { | 556 | struct border_colors *colors) { |
537 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 557 | struct sway_view *view = con->sway_view; |
538 | } | 558 | if (!view->border_top) { |
539 | premultiply_alpha(color, con->alpha); | 559 | return; |
540 | box.x = con->x; | ||
541 | box.y = con->y + con->height - view->border_thickness; | ||
542 | box.width = con->width; | ||
543 | box.height = view->border_thickness; | ||
544 | scale_box(&box, output_scale); | ||
545 | render_rect(output->wlr_output, output_damage, &box, color); | ||
546 | } | 560 | } |
561 | struct wlr_box box; | ||
562 | float color[4]; | ||
563 | float output_scale = output->wlr_output->scale; | ||
564 | |||
565 | // Child border - top edge | ||
566 | memcpy(&color, colors->child_border, sizeof(float) * 4); | ||
567 | premultiply_alpha(color, con->alpha); | ||
568 | box.x = con->x; | ||
569 | box.y = con->y; | ||
570 | box.width = con->width; | ||
571 | box.height = view->border_thickness; | ||
572 | scale_box(&box, output_scale); | ||
573 | render_rect(output->wlr_output, output_damage, &box, color); | ||
547 | } | 574 | } |
548 | 575 | ||
549 | static void render_container(struct sway_output *output, | 576 | static void render_container(struct sway_output *output, |
@@ -565,33 +592,30 @@ static void render_container_simple(struct sway_output *output, | |||
565 | struct sway_container *child = con->children->items[i]; | 592 | struct sway_container *child = con->children->items[i]; |
566 | 593 | ||
567 | if (child->type == C_VIEW) { | 594 | if (child->type == C_VIEW) { |
568 | if (child->sway_view->border != B_NONE) { | 595 | struct border_colors *colors; |
569 | struct border_colors *colors; | 596 | struct wlr_texture *title_texture; |
570 | struct wlr_texture *title_texture; | 597 | struct wlr_texture *marks_texture; |
571 | struct wlr_texture *marks_texture; | 598 | if (focus == child || parent_focused) { |
572 | if (focus == child || parent_focused) { | 599 | colors = &config->border_colors.focused; |
573 | colors = &config->border_colors.focused; | 600 | title_texture = child->title_focused; |
574 | title_texture = child->title_focused; | 601 | marks_texture = child->sway_view->marks_focused; |
575 | marks_texture = child->sway_view->marks_focused; | 602 | } else if (seat_get_focus_inactive(seat, con) == child) { |
576 | } else if (seat_get_focus_inactive(seat, con) == child) { | 603 | colors = &config->border_colors.focused_inactive; |
577 | colors = &config->border_colors.focused_inactive; | 604 | title_texture = child->title_focused_inactive; |
578 | title_texture = child->title_focused_inactive; | 605 | marks_texture = child->sway_view->marks_focused_inactive; |
579 | marks_texture = child->sway_view->marks_focused_inactive; | 606 | } else { |
580 | } else { | 607 | colors = &config->border_colors.unfocused; |
581 | colors = &config->border_colors.unfocused; | 608 | title_texture = child->title_unfocused; |
582 | title_texture = child->title_unfocused; | 609 | marks_texture = child->sway_view->marks_unfocused; |
583 | marks_texture = child->sway_view->marks_unfocused; | 610 | } |
584 | } | 611 | |
585 | 612 | if (child->sway_view->border == B_NORMAL) { | |
586 | if (child->sway_view->border == B_NORMAL) { | 613 | render_titlebar(output, damage, child, child->x, child->y, |
587 | render_container_simple_border_normal(output, damage, | 614 | child->width, colors, title_texture, marks_texture); |
588 | child, colors, title_texture, marks_texture); | 615 | } else { |
589 | } else { | 616 | render_top_border(output, damage, child, colors); |
590 | render_container_simple_border_pixel(output, damage, child, | ||
591 | colors); | ||
592 | } | ||
593 | } | 617 | } |
594 | render_view(child->sway_view, output, damage); | 618 | render_view(output, damage, child, colors); |
595 | } else { | 619 | } else { |
596 | render_container(output, damage, child, | 620 | render_container(output, damage, child, |
597 | parent_focused || focus == child); | 621 | parent_focused || focus == child); |
@@ -599,154 +623,71 @@ static void render_container_simple(struct sway_output *output, | |||
599 | } | 623 | } |
600 | } | 624 | } |
601 | 625 | ||
602 | static void render_tab(struct sway_output *output, pixman_region32_t *damage, | 626 | /** |
603 | struct sway_container *parent, int child_index, | 627 | * Render a container's children using the L_TABBED layout. |
604 | struct border_colors *colors, struct wlr_texture *title_texture) { | 628 | */ |
605 | struct sway_container *con = parent->children->items[child_index]; | 629 | static void render_container_tabbed(struct sway_output *output, |
606 | float output_scale = output->wlr_output->scale; | 630 | pixman_region32_t *damage, struct sway_container *con, |
607 | float color[4]; | 631 | bool parent_focused) { |
608 | struct wlr_box box; | 632 | if (!con->children->length) { |
609 | 633 | return; | |
610 | int tab_width = parent->width / parent->children->length; | ||
611 | int x = parent->x + tab_width * child_index; | ||
612 | // Make last tab use the remaining width of the parent | ||
613 | if (child_index == parent->children->length - 1) { | ||
614 | tab_width = parent->width - tab_width * child_index; | ||
615 | } | 634 | } |
635 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
636 | struct sway_container *focus = seat_get_focus(seat); | ||
637 | struct sway_container *current = seat_get_active_child(seat, con); | ||
638 | struct border_colors *current_colors = NULL; | ||
616 | 639 | ||
617 | // Single pixel bar above title | 640 | // Render tabs |
618 | memcpy(&color, colors->border, sizeof(float) * 4); | 641 | for (int i = 0; i < con->children->length; ++i) { |
619 | premultiply_alpha(color, con->alpha); | 642 | struct sway_container *child = con->children->items[i]; |
620 | box.x = x; | 643 | struct border_colors *colors; |
621 | box.y = parent->y; | 644 | struct wlr_texture *title_texture; |
622 | box.width = tab_width; | 645 | struct wlr_texture *marks_texture; |
623 | box.height = 1; | 646 | struct sway_view *view = |
624 | scale_box(&box, output_scale); | 647 | child->type == C_VIEW ? child->sway_view : NULL; |
625 | render_rect(output->wlr_output, damage, &box, color); | ||
626 | |||
627 | // Single pixel bar below title | ||
628 | box.y = (parent->y + config->border_thickness * 2 + config->font_height - 1) | ||
629 | * output_scale; | ||
630 | render_rect(output->wlr_output, damage, &box, color); | ||
631 | |||
632 | // Single pixel bar on left | ||
633 | box.x = x; | ||
634 | box.y = parent->y + 1; | ||
635 | box.width = 1; | ||
636 | box.height = config->border_thickness * 2 + config->font_height - 2; | ||
637 | scale_box(&box, output_scale); | ||
638 | render_rect(output->wlr_output, damage, &box, color); | ||
639 | |||
640 | // Single pixel bar on right | ||
641 | box.x = (x + tab_width - 1) * output_scale; | ||
642 | render_rect(output->wlr_output, damage, &box, color); | ||
643 | |||
644 | // Title text | ||
645 | size_t title_width = 0; | ||
646 | if (title_texture) { | ||
647 | struct wlr_box texture_box; | ||
648 | wlr_texture_get_size(title_texture, | ||
649 | &texture_box.width, &texture_box.height); | ||
650 | texture_box.x = (x + 1 + config->border_thickness) * output_scale; | ||
651 | texture_box.y = (parent->y + config->border_thickness) * output_scale; | ||
652 | |||
653 | float matrix[9]; | ||
654 | wlr_matrix_project_box(matrix, &texture_box, | ||
655 | WL_OUTPUT_TRANSFORM_NORMAL, | ||
656 | 0.0, output->wlr_output->transform_matrix); | ||
657 | 648 | ||
658 | int available = (tab_width - config->border_thickness * 2 - 2) | 649 | if (focus == child || parent_focused) { |
659 | * output_scale; | 650 | colors = &config->border_colors.focused; |
660 | if (texture_box.width > available) { | 651 | title_texture = child->title_focused; |
661 | texture_box.width = available; | 652 | marks_texture = view ? view->marks_focused : NULL; |
653 | } else if (child == current) { | ||
654 | colors = &config->border_colors.focused_inactive; | ||
655 | title_texture = child->title_focused_inactive; | ||
656 | marks_texture = view ? view->marks_focused : NULL; | ||
657 | } else { | ||
658 | colors = &config->border_colors.unfocused; | ||
659 | title_texture = child->title_unfocused; | ||
660 | marks_texture = view ? view->marks_unfocused : NULL; | ||
662 | } | 661 | } |
663 | render_texture(output->wlr_output, damage, title_texture, | ||
664 | &texture_box, matrix, 1.0); | ||
665 | title_width = texture_box.width; | ||
666 | } | ||
667 | |||
668 | // Title background - above the text | ||
669 | memcpy(&color, colors->background, sizeof(float) * 4); | ||
670 | premultiply_alpha(color, con->alpha); | ||
671 | box.x = x + 1; | ||
672 | box.y = parent->y + 1; | ||
673 | box.width = tab_width - 2; | ||
674 | box.height = config->border_thickness - 1; | ||
675 | scale_box(&box, output_scale); | ||
676 | render_rect(output->wlr_output, damage, &box, color); | ||
677 | 662 | ||
678 | // Title background - below the text | 663 | int tab_width = con->width / con->children->length; |
679 | box.y = (parent->y + config->border_thickness + config->font_height) | 664 | int x = con->x + tab_width * i; |
680 | * output_scale; | 665 | // Make last tab use the remaining width of the parent |
681 | render_rect(output->wlr_output, damage, &box, color); | 666 | if (i == con->children->length - 1) { |
682 | 667 | tab_width = con->width - tab_width * i; | |
683 | // Title background - left of text | ||
684 | box.x = x + 1; | ||
685 | box.y = parent->y + config->border_thickness; | ||
686 | box.width = config->border_thickness; | ||
687 | box.height = config->font_height; | ||
688 | scale_box(&box, output_scale); | ||
689 | render_rect(output->wlr_output, damage, &box, color); | ||
690 | |||
691 | // Title background - right of text | ||
692 | box.x = (x + 1 + config->border_thickness) * output_scale + title_width; | ||
693 | box.y = (parent->y + config->border_thickness) * output_scale; | ||
694 | box.width = (tab_width - config->border_thickness - 2) * output_scale | ||
695 | - title_width; | ||
696 | box.height = config->font_height * output_scale; | ||
697 | render_rect(output->wlr_output, damage, &box, color); | ||
698 | } | ||
699 | |||
700 | static void render_tab_content(struct sway_output *output, | ||
701 | pixman_region32_t *damage, struct sway_container *con, | ||
702 | struct border_colors *colors) { | ||
703 | struct sway_view *view = con->sway_view; | ||
704 | render_view(view, output, damage); | ||
705 | |||
706 | struct wlr_box box; | ||
707 | float output_scale = output->wlr_output->scale; | ||
708 | float color[4]; | ||
709 | |||
710 | if (view->border != B_NONE) { | ||
711 | if (view->border_left) { | ||
712 | memcpy(&color, colors->child_border, sizeof(float) * 4); | ||
713 | premultiply_alpha(color, con->alpha); | ||
714 | box.x = con->x; | ||
715 | box.y = con->y + config->border_thickness * 2 + config->font_height; | ||
716 | box.width = view->border_thickness; | ||
717 | box.height = view->height; | ||
718 | scale_box(&box, output_scale); | ||
719 | render_rect(output->wlr_output, damage, &box, color); | ||
720 | } | 668 | } |
721 | 669 | ||
722 | if (view->border_right) { | 670 | render_titlebar(output, damage, child, x, child->y, tab_width, colors, |
723 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 671 | title_texture, marks_texture); |
724 | premultiply_alpha(color, con->alpha); | ||
725 | box.x = view->x + view->width; | ||
726 | box.y = con->y + config->border_thickness * 2 + config->font_height; | ||
727 | box.width = view->border_thickness; | ||
728 | box.height = view->height; | ||
729 | scale_box(&box, output_scale); | ||
730 | render_rect(output->wlr_output, damage, &box, color); | ||
731 | } | ||
732 | 672 | ||
733 | if (view->border_bottom) { | 673 | if (child == current) { |
734 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 674 | current_colors = colors; |
735 | premultiply_alpha(color, con->alpha); | ||
736 | box.x = con->x; | ||
737 | box.y = view->y + view->height; | ||
738 | box.width = con->width; | ||
739 | box.height = view->border_thickness; | ||
740 | scale_box(&box, output_scale); | ||
741 | render_rect(output->wlr_output, damage, &box, color); | ||
742 | } | 675 | } |
743 | } | 676 | } |
677 | |||
678 | // Render surface and left/right/bottom borders | ||
679 | if (current->type == C_VIEW) { | ||
680 | render_view(output, damage, current, current_colors); | ||
681 | } else { | ||
682 | render_container(output, damage, current, | ||
683 | parent_focused || current == focus); | ||
684 | } | ||
744 | } | 685 | } |
745 | 686 | ||
746 | /** | 687 | /** |
747 | * Render a container's children using the L_TABBED layout. | 688 | * Render a container's children using the L_STACKED layout. |
748 | */ | 689 | */ |
749 | static void render_container_tabbed(struct sway_output *output, | 690 | static void render_container_stacked(struct sway_output *output, |
750 | pixman_region32_t *damage, struct sway_container *con, | 691 | pixman_region32_t *damage, struct sway_container *con, |
751 | bool parent_focused) { | 692 | bool parent_focused) { |
752 | if (!con->children->length) { | 693 | if (!con->children->length) { |
@@ -757,24 +698,32 @@ static void render_container_tabbed(struct sway_output *output, | |||
757 | struct sway_container *current = seat_get_active_child(seat, con); | 698 | struct sway_container *current = seat_get_active_child(seat, con); |
758 | struct border_colors *current_colors = NULL; | 699 | struct border_colors *current_colors = NULL; |
759 | 700 | ||
760 | // Render tabs | 701 | // Render titles |
761 | for (int i = 0; i < con->children->length; ++i) { | 702 | for (int i = 0; i < con->children->length; ++i) { |
762 | struct sway_container *child = con->children->items[i]; | 703 | struct sway_container *child = con->children->items[i]; |
763 | struct border_colors *colors; | 704 | struct border_colors *colors; |
764 | struct wlr_texture *title_texture; | 705 | struct wlr_texture *title_texture; |
706 | struct wlr_texture *marks_texture; | ||
707 | struct sway_view *view = | ||
708 | child->type == C_VIEW ? child->sway_view : NULL; | ||
765 | 709 | ||
766 | if (focus == child || parent_focused) { | 710 | if (focus == child || parent_focused) { |
767 | colors = &config->border_colors.focused; | 711 | colors = &config->border_colors.focused; |
768 | title_texture = child->title_focused; | 712 | title_texture = child->title_focused; |
713 | marks_texture = view ? view->marks_focused : NULL; | ||
769 | } else if (child == current) { | 714 | } else if (child == current) { |
770 | colors = &config->border_colors.focused_inactive; | 715 | colors = &config->border_colors.focused_inactive; |
771 | title_texture = child->title_focused_inactive; | 716 | title_texture = child->title_focused_inactive; |
717 | marks_texture = view ? view->marks_focused_inactive : NULL; | ||
772 | } else { | 718 | } else { |
773 | colors = &config->border_colors.unfocused; | 719 | colors = &config->border_colors.unfocused; |
774 | title_texture = child->title_unfocused; | 720 | title_texture = child->title_unfocused; |
721 | marks_texture = view ? view->marks_unfocused : NULL; | ||
775 | } | 722 | } |
776 | 723 | ||
777 | render_tab(output, damage, con, i, colors, title_texture); | 724 | int y = con->y + container_titlebar_height() * i; |
725 | render_titlebar(output, damage, child, child->x, y, child->width, | ||
726 | colors, title_texture, marks_texture); | ||
778 | 727 | ||
779 | if (child == current) { | 728 | if (child == current) { |
780 | current_colors = colors; | 729 | current_colors = colors; |
@@ -783,21 +732,13 @@ static void render_container_tabbed(struct sway_output *output, | |||
783 | 732 | ||
784 | // Render surface and left/right/bottom borders | 733 | // Render surface and left/right/bottom borders |
785 | if (current->type == C_VIEW) { | 734 | if (current->type == C_VIEW) { |
786 | render_tab_content(output, damage, current, current_colors); | 735 | render_view(output, damage, current, current_colors); |
787 | } else { | 736 | } else { |
788 | render_container(output, damage, current, | 737 | render_container(output, damage, current, |
789 | parent_focused || current == focus); | 738 | parent_focused || current == focus); |
790 | } | 739 | } |
791 | } | 740 | } |
792 | 741 | ||
793 | /** | ||
794 | * Render a container's children using the L_STACKED layout. | ||
795 | */ | ||
796 | static void render_container_stacked(struct sway_output *output, | ||
797 | pixman_region32_t *damage, struct sway_container *con) { | ||
798 | // TODO | ||
799 | } | ||
800 | |||
801 | static void render_container(struct sway_output *output, | 742 | static void render_container(struct sway_output *output, |
802 | pixman_region32_t *damage, struct sway_container *con, | 743 | pixman_region32_t *damage, struct sway_container *con, |
803 | bool parent_focused) { | 744 | bool parent_focused) { |
@@ -808,7 +749,7 @@ static void render_container(struct sway_output *output, | |||
808 | render_container_simple(output, damage, con, parent_focused); | 749 | render_container_simple(output, damage, con, parent_focused); |
809 | break; | 750 | break; |
810 | case L_STACKED: | 751 | case L_STACKED: |
811 | render_container_stacked(output, damage, con); | 752 | render_container_stacked(output, damage, con, parent_focused); |
812 | break; | 753 | break; |
813 | case L_TABBED: | 754 | case L_TABBED: |
814 | render_container_tabbed(output, damage, con, parent_focused); | 755 | render_container_tabbed(output, damage, con, parent_focused); |
@@ -868,7 +809,8 @@ static void render_output(struct sway_output *output, struct timespec *when, | |||
868 | } | 809 | } |
869 | 810 | ||
870 | // TODO: handle views smaller than the output | 811 | // TODO: handle views smaller than the output |
871 | render_view(workspace->sway_workspace->fullscreen, output, damage); | 812 | render_view_surfaces( |
813 | workspace->sway_workspace->fullscreen, output, damage); | ||
872 | 814 | ||
873 | if (workspace->sway_workspace->fullscreen->type == SWAY_VIEW_XWAYLAND) { | 815 | if (workspace->sway_workspace->fullscreen->type == SWAY_VIEW_XWAYLAND) { |
874 | render_unmanaged(output, damage, | 816 | render_unmanaged(output, damage, |
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c index 8aebc0cc..37f4a066 100644 --- a/sway/tree/arrange.c +++ b/sway/tree/arrange.c | |||
@@ -86,12 +86,14 @@ static void apply_horiz_layout(struct sway_container *parent) { | |||
86 | if (!num_children) { | 86 | if (!num_children) { |
87 | return; | 87 | return; |
88 | } | 88 | } |
89 | size_t parent_height = parent->height; | ||
90 | size_t parent_offset = 0; | 89 | size_t parent_offset = 0; |
91 | if (parent->parent->layout == L_TABBED) { | 90 | if (parent->parent->layout == L_TABBED) { |
92 | parent_offset = config->border_thickness * 2 + config->font_height; | 91 | parent_offset = container_titlebar_height(); |
93 | parent_height -= parent_offset; | 92 | } else if (parent->parent->layout == L_STACKED) { |
93 | parent_offset = | ||
94 | container_titlebar_height() * parent->parent->children->length; | ||
94 | } | 95 | } |
96 | size_t parent_height = parent->height - parent_offset; | ||
95 | 97 | ||
96 | // Calculate total width of children | 98 | // Calculate total width of children |
97 | double total_width = 0; | 99 | double total_width = 0; |
@@ -132,12 +134,14 @@ static void apply_vert_layout(struct sway_container *parent) { | |||
132 | if (!num_children) { | 134 | if (!num_children) { |
133 | return; | 135 | return; |
134 | } | 136 | } |
135 | size_t parent_height = parent->height; | ||
136 | size_t parent_offset = 0; | 137 | size_t parent_offset = 0; |
137 | if (parent->parent->layout == L_TABBED) { | 138 | if (parent->parent->layout == L_TABBED) { |
138 | parent_offset = config->border_thickness * 2 + config->font_height; | 139 | parent_offset = container_titlebar_height(); |
139 | parent_height -= parent_offset; | 140 | } else if (parent->parent->layout == L_STACKED) { |
141 | parent_offset = | ||
142 | container_titlebar_height() * parent->parent->children->length; | ||
140 | } | 143 | } |
144 | size_t parent_height = parent->height - parent_offset; | ||
141 | 145 | ||
142 | // Calculate total height of children | 146 | // Calculate total height of children |
143 | double total_height = 0; | 147 | double total_height = 0; |
@@ -186,6 +190,19 @@ static void apply_tabbed_layout(struct sway_container *parent) { | |||
186 | } | 190 | } |
187 | } | 191 | } |
188 | 192 | ||
193 | static void apply_stacked_layout(struct sway_container *parent) { | ||
194 | if (!parent->children->length) { | ||
195 | return; | ||
196 | } | ||
197 | for (int i = 0; i < parent->children->length; ++i) { | ||
198 | struct sway_container *child = parent->children->items[i]; | ||
199 | child->x = parent->x; | ||
200 | child->y = parent->y; | ||
201 | child->width = parent->width; | ||
202 | child->height = parent->height; | ||
203 | } | ||
204 | } | ||
205 | |||
189 | void arrange_children_of(struct sway_container *parent) { | 206 | void arrange_children_of(struct sway_container *parent) { |
190 | if (config->reloading) { | 207 | if (config->reloading) { |
191 | return; | 208 | return; |
@@ -219,6 +236,9 @@ void arrange_children_of(struct sway_container *parent) { | |||
219 | case L_TABBED: | 236 | case L_TABBED: |
220 | apply_tabbed_layout(parent); | 237 | apply_tabbed_layout(parent); |
221 | break; | 238 | break; |
239 | case L_STACKED: | ||
240 | apply_stacked_layout(parent); | ||
241 | break; | ||
222 | default: | 242 | default: |
223 | wlr_log(L_DEBUG, "TODO: arrange layout type %d", parent->layout); | 243 | wlr_log(L_DEBUG, "TODO: arrange layout type %d", parent->layout); |
224 | apply_horiz_layout(parent); | 244 | apply_horiz_layout(parent); |
diff --git a/sway/tree/container.c b/sway/tree/container.c index 5d88325f..9cf18f61 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -510,7 +510,7 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent, | |||
510 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 510 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
511 | 511 | ||
512 | // Tab titles | 512 | // Tab titles |
513 | int title_height = config->border_thickness * 2 + config->font_height; | 513 | int title_height = container_titlebar_height(); |
514 | if (oy < parent->y + title_height) { | 514 | if (oy < parent->y + title_height) { |
515 | int tab_width = parent->width / parent->children->length; | 515 | int tab_width = parent->width / parent->children->length; |
516 | int child_index = (ox - parent->x) / tab_width; | 516 | int child_index = (ox - parent->x) / tab_width; |
@@ -533,8 +533,23 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent, | |||
533 | static struct sway_container *container_at_stacked( | 533 | static struct sway_container *container_at_stacked( |
534 | struct sway_container *parent, double ox, double oy, | 534 | struct sway_container *parent, double ox, double oy, |
535 | struct wlr_surface **surface, double *sx, double *sy) { | 535 | struct wlr_surface **surface, double *sx, double *sy) { |
536 | // TODO | 536 | if (oy < parent->y || oy > parent->y + parent->height) { |
537 | return NULL; | 537 | return NULL; |
538 | } | ||
539 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
540 | |||
541 | // Title bars | ||
542 | int title_height = container_titlebar_height(); | ||
543 | int child_index = (oy - parent->y) / title_height; | ||
544 | if (child_index < parent->children->length) { | ||
545 | struct sway_container *child = parent->children->items[child_index]; | ||
546 | return seat_get_focus_inactive(seat, child); | ||
547 | } | ||
548 | |||
549 | // Surfaces | ||
550 | struct sway_container *current = seat_get_active_child(seat, parent); | ||
551 | |||
552 | return container_at(current, ox, oy, surface, sx, sy); | ||
538 | } | 553 | } |
539 | 554 | ||
540 | /** | 555 | /** |
@@ -847,3 +862,7 @@ void container_notify_child_title_changed(struct sway_container *container) { | |||
847 | container_update_title_textures(container); | 862 | container_update_title_textures(container); |
848 | container_notify_child_title_changed(container->parent); | 863 | container_notify_child_title_changed(container->parent); |
849 | } | 864 | } |
865 | |||
866 | size_t container_titlebar_height() { | ||
867 | return config->font_height + TITLEBAR_V_PADDING * 2; | ||
868 | } | ||
diff --git a/sway/tree/view.c b/sway/tree/view.c index c013e635..07157818 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -182,11 +182,11 @@ void view_autoconfigure(struct sway_view *view) { | |||
182 | // area. We have to offset the surface y by the height of the title bar, and | 182 | // area. We have to offset the surface y by the height of the title bar, and |
183 | // disable any top border because we'll always have the title bar. | 183 | // disable any top border because we'll always have the title bar. |
184 | if (view->swayc->parent->layout == L_TABBED) { | 184 | if (view->swayc->parent->layout == L_TABBED) { |
185 | y_offset = config->border_thickness * 2 + config->font_height; | 185 | y_offset = container_titlebar_height(); |
186 | view->border_top = 0; | 186 | view->border_top = 0; |
187 | } else if (view->swayc->parent->layout == L_STACKED) { | 187 | } else if (view->swayc->parent->layout == L_STACKED) { |
188 | y_offset = config->border_thickness * 2 + config->font_height; | 188 | y_offset = container_titlebar_height() |
189 | y_offset *= view->swayc->parent->children->length; | 189 | * view->swayc->parent->children->length; |
190 | view->border_top = 0; | 190 | view->border_top = 0; |
191 | } | 191 | } |
192 | 192 | ||
@@ -208,7 +208,7 @@ void view_autoconfigure(struct sway_view *view) { | |||
208 | - view->border_thickness * view->border_bottom; | 208 | - view->border_thickness * view->border_bottom; |
209 | break; | 209 | break; |
210 | case B_NORMAL: | 210 | case B_NORMAL: |
211 | // Height is: border + title height + border + view height + border | 211 | // Height is: 1px border + 3px pad + title height + 3px pad + 1px border |
212 | x = view->swayc->x + view->border_thickness * view->border_left; | 212 | x = view->swayc->x + view->border_thickness * view->border_left; |
213 | width = view->swayc->width | 213 | width = view->swayc->width |
214 | - view->border_thickness * view->border_left | 214 | - view->border_thickness * view->border_left |
@@ -218,10 +218,9 @@ void view_autoconfigure(struct sway_view *view) { | |||
218 | height = view->swayc->height - y_offset | 218 | height = view->swayc->height - y_offset |
219 | - view->border_thickness * view->border_bottom; | 219 | - view->border_thickness * view->border_bottom; |
220 | } else { | 220 | } else { |
221 | y = view->swayc->y + config->font_height + view->border_thickness * 2 | 221 | y = view->swayc->y + container_titlebar_height(); |
222 | + y_offset; | 222 | height = view->swayc->height - container_titlebar_height() |
223 | height = view->swayc->height - config->font_height | 223 | - view->border_thickness * view->border_bottom; |
224 | - view->border_thickness * (2 + view->border_bottom); | ||
225 | } | 224 | } |
226 | break; | 225 | break; |
227 | } | 226 | } |