summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/commands.h1
-rw-r--r--include/sway/config.h7
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/resize.c28
-rw-r--r--sway/commands/title_align.c30
-rw-r--r--sway/config.c1
-rw-r--r--sway/desktop/render.c101
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway.5.scd5
-rw-r--r--sway/tree/view.c13
-rw-r--r--swayidle/main.c77
11 files changed, 203 insertions, 62 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h
index e6036e51..eb446eae 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -172,6 +172,7 @@ sway_cmd cmd_swaybg_command;
172sway_cmd cmd_swaynag_command; 172sway_cmd cmd_swaynag_command;
173sway_cmd cmd_swap; 173sway_cmd cmd_swap;
174sway_cmd cmd_tiling_drag; 174sway_cmd cmd_tiling_drag;
175sway_cmd cmd_title_align;
175sway_cmd cmd_title_format; 176sway_cmd cmd_title_format;
176sway_cmd cmd_titlebar_border_thickness; 177sway_cmd cmd_titlebar_border_thickness;
177sway_cmd cmd_titlebar_padding; 178sway_cmd cmd_titlebar_padding;
diff --git a/include/sway/config.h b/include/sway/config.h
index a6920835..1ff9a104 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -357,6 +357,12 @@ enum mouse_warping_mode {
357 WARP_CONTAINER 357 WARP_CONTAINER
358}; 358};
359 359
360enum alignment {
361 ALIGN_LEFT,
362 ALIGN_CENTER,
363 ALIGN_RIGHT
364};
365
360/** 366/**
361 * The configuration struct. The result of loading a config file. 367 * The configuration struct. The result of loading a config file.
362 */ 368 */
@@ -409,6 +415,7 @@ struct sway_config {
409 bool validating; 415 bool validating;
410 bool auto_back_and_forth; 416 bool auto_back_and_forth;
411 bool show_marks; 417 bool show_marks;
418 enum alignment title_align;
412 bool tiling_drag; 419 bool tiling_drag;
413 420
414 bool smart_gaps; 421 bool smart_gaps;
diff --git a/sway/commands.c b/sway/commands.c
index d35658d5..bffc18f6 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -103,6 +103,7 @@ static struct cmd_handler handlers[] = {
103 { "smart_borders", cmd_smart_borders }, 103 { "smart_borders", cmd_smart_borders },
104 { "smart_gaps", cmd_smart_gaps }, 104 { "smart_gaps", cmd_smart_gaps },
105 { "tiling_drag", cmd_tiling_drag }, 105 { "tiling_drag", cmd_tiling_drag },
106 { "title_align", cmd_title_align },
106 { "titlebar_border_thickness", cmd_titlebar_border_thickness }, 107 { "titlebar_border_thickness", cmd_titlebar_border_thickness },
107 { "titlebar_padding", cmd_titlebar_padding }, 108 { "titlebar_padding", cmd_titlebar_padding },
108 { "workspace", cmd_workspace }, 109 { "workspace", cmd_workspace },
diff --git a/sway/commands/resize.c b/sway/commands/resize.c
index a90d578e..cf5dea02 100644
--- a/sway/commands/resize.c
+++ b/sway/commands/resize.c
@@ -512,34 +512,42 @@ static struct cmd_results *resize_set_floating(struct sway_container *con,
512 calculate_constraints(&min_width, &max_width, &min_height, &max_height); 512 calculate_constraints(&min_width, &max_width, &min_height, &max_height);
513 513
514 if (width->amount) { 514 if (width->amount) {
515 if (width->unit == RESIZE_UNIT_PPT || 515 switch (width->unit) {
516 width->unit == RESIZE_UNIT_DEFAULT) { 516 case RESIZE_UNIT_PPT:
517 // Convert to px 517 // Convert to px
518 width->amount = con->workspace->width * width->amount / 100; 518 width->amount = con->workspace->width * width->amount / 100;
519 width->unit = RESIZE_UNIT_PX; 519 width->unit = RESIZE_UNIT_PX;
520 } 520 // Falls through
521 if (width->unit == RESIZE_UNIT_PX) { 521 case RESIZE_UNIT_PX:
522 case RESIZE_UNIT_DEFAULT:
522 width->amount = fmax(min_width, fmin(width->amount, max_width)); 523 width->amount = fmax(min_width, fmin(width->amount, max_width));
523 grow_width = width->amount - con->width; 524 grow_width = width->amount - con->width;
524
525 con->x -= grow_width / 2; 525 con->x -= grow_width / 2;
526 con->width = width->amount; 526 con->width = width->amount;
527 break;
528 case RESIZE_UNIT_INVALID:
529 sway_assert(false, "invalid width unit");
530 break;
527 } 531 }
528 } 532 }
529 533
530 if (height->amount) { 534 if (height->amount) {
531 if (height->unit == RESIZE_UNIT_PPT || 535 switch (height->unit) {
532 height->unit == RESIZE_UNIT_DEFAULT) { 536 case RESIZE_UNIT_PPT:
533 // Convert to px 537 // Convert to px
534 height->amount = con->workspace->height * height->amount / 100; 538 height->amount = con->workspace->height * height->amount / 100;
535 height->unit = RESIZE_UNIT_PX; 539 height->unit = RESIZE_UNIT_PX;
536 } 540 // Falls through
537 if (height->unit == RESIZE_UNIT_PX) { 541 case RESIZE_UNIT_PX:
542 case RESIZE_UNIT_DEFAULT:
538 height->amount = fmax(min_height, fmin(height->amount, max_height)); 543 height->amount = fmax(min_height, fmin(height->amount, max_height));
539 grow_height = height->amount - con->height; 544 grow_height = height->amount - con->height;
540
541 con->y -= grow_height / 2; 545 con->y -= grow_height / 2;
542 con->height = height->amount; 546 con->height = height->amount;
547 break;
548 case RESIZE_UNIT_INVALID:
549 sway_assert(false, "invalid height unit");
550 break;
543 } 551 }
544 } 552 }
545 553
diff --git a/sway/commands/title_align.c b/sway/commands/title_align.c
new file mode 100644
index 00000000..82578186
--- /dev/null
+++ b/sway/commands/title_align.c
@@ -0,0 +1,30 @@
1#include "sway/commands.h"
2#include "sway/config.h"
3#include "sway/output.h"
4#include "sway/tree/container.h"
5#include "sway/tree/root.h"
6
7struct cmd_results *cmd_title_align(int argc, char **argv) {
8 struct cmd_results *error = NULL;
9 if ((error = checkarg(argc, "title_align", EXPECTED_AT_LEAST, 1))) {
10 return error;
11 }
12
13 if (strcmp(argv[0], "left") == 0) {
14 config->title_align = ALIGN_LEFT;
15 } else if (strcmp(argv[0], "center") == 0) {
16 config->title_align = ALIGN_CENTER;
17 } else if (strcmp(argv[0], "right") == 0) {
18 config->title_align = ALIGN_RIGHT;
19 } else {
20 return cmd_results_new(CMD_INVALID, "title_align",
21 "Expected 'title_align left|center|right'");
22 }
23
24 for (int i = 0; i < root->outputs->length; ++i) {
25 struct sway_output *output = root->outputs->items[i];
26 output_damage_whole(output);
27 }
28
29 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
30}
diff --git a/sway/config.c b/sway/config.c
index da40ace6..ed288060 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -233,6 +233,7 @@ static void config_defaults(struct sway_config *config) {
233 config->auto_back_and_forth = false; 233 config->auto_back_and_forth = false;
234 config->reading = false; 234 config->reading = false;
235 config->show_marks = true; 235 config->show_marks = true;
236 config->title_align = ALIGN_LEFT;
236 config->tiling_drag = true; 237 config->tiling_drag = true;
237 238
238 config->smart_gaps = false; 239 config->smart_gaps = false;
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 51cb8980..eeda496c 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -371,6 +371,7 @@ static void render_titlebar(struct sway_output *output,
371 int titlebar_border_thickness = config->titlebar_border_thickness; 371 int titlebar_border_thickness = config->titlebar_border_thickness;
372 int titlebar_h_padding = config->titlebar_h_padding; 372 int titlebar_h_padding = config->titlebar_h_padding;
373 int titlebar_v_padding = config->titlebar_v_padding; 373 int titlebar_v_padding = config->titlebar_v_padding;
374 enum alignment title_align = config->title_align;
374 375
375 // Single pixel bar above title 376 // Single pixel bar above title
376 memcpy(&color, colors->border, sizeof(float) * 4); 377 memcpy(&color, colors->border, sizeof(float) * 4);
@@ -420,19 +421,25 @@ static void render_titlebar(struct sway_output *output,
420 render_rect(output->wlr_output, output_damage, &box, color); 421 render_rect(output->wlr_output, output_damage, &box, color);
421 } 422 }
422 423
423 size_t inner_width = width - titlebar_h_padding * 2; 424 int inner_x = x - output_x + titlebar_h_padding;
424 int bg_y = y + titlebar_border_thickness; 425 int bg_y = y + titlebar_border_thickness;
426 size_t inner_width = width - titlebar_h_padding * 2;
427
428 // output-buffer local
429 int ob_inner_x = round(inner_x * output_scale);
430 int ob_inner_width = scale_length(inner_width, inner_x, output_scale);
425 int ob_bg_height = scale_length( 431 int ob_bg_height = scale_length(
426 (titlebar_v_padding - titlebar_border_thickness) * 2 + 432 (titlebar_v_padding - titlebar_border_thickness) * 2 +
427 config->font_height, bg_y, output_scale); 433 config->font_height, bg_y, output_scale);
428 434
429 // Marks 435 // Marks
430 int marks_ob_width = 0; // output-buffer-local 436 int ob_marks_x = 0; // output-buffer-local
437 int ob_marks_width = 0; // output-buffer-local
431 if (config->show_marks && marks_texture) { 438 if (config->show_marks && marks_texture) {
432 struct wlr_box texture_box; 439 struct wlr_box texture_box;
433 wlr_texture_get_size(marks_texture, 440 wlr_texture_get_size(marks_texture,
434 &texture_box.width, &texture_box.height); 441 &texture_box.width, &texture_box.height);
435 marks_ob_width = texture_box.width; 442 ob_marks_width = texture_box.width;
436 443
437 // The marks texture might be shorter than the config->font_height, in 444 // The marks texture might be shorter than the config->font_height, in
438 // which case we need to pad it as evenly as possible above and below. 445 // which case we need to pad it as evenly as possible above and below.
@@ -440,9 +447,15 @@ static void render_titlebar(struct sway_output *output,
440 int ob_padding_above = floor(ob_padding_total / 2.0); 447 int ob_padding_above = floor(ob_padding_total / 2.0);
441 int ob_padding_below = ceil(ob_padding_total / 2.0); 448 int ob_padding_below = ceil(ob_padding_total / 2.0);
442 449
443 // Render texture 450 // Render texture. If the title is on the right, the marks will be on
444 texture_box.x = round((x - output_x + width - titlebar_h_padding) 451 // the left. Otherwise, they will be on the right.
445 * output_scale) - texture_box.width; 452 if (title_align == ALIGN_RIGHT || texture_box.width > ob_inner_width) {
453 texture_box.x = ob_inner_x;
454 } else {
455 texture_box.x = ob_inner_x + ob_inner_width - texture_box.width;
456 }
457 ob_marks_x = texture_box.x;
458
446 texture_box.y = round((bg_y - output_y) * output_scale) + 459 texture_box.y = round((bg_y - output_y) * output_scale) +
447 ob_padding_above; 460 ob_padding_above;
448 461
@@ -451,8 +464,8 @@ static void render_titlebar(struct sway_output *output,
451 WL_OUTPUT_TRANSFORM_NORMAL, 464 WL_OUTPUT_TRANSFORM_NORMAL,
452 0.0, output->wlr_output->transform_matrix); 465 0.0, output->wlr_output->transform_matrix);
453 466
454 if (inner_width * output_scale < texture_box.width) { 467 if (ob_inner_width < texture_box.width) {
455 texture_box.width = inner_width * output_scale; 468 texture_box.width = ob_inner_width;
456 } 469 }
457 render_texture(output->wlr_output, output_damage, marks_texture, 470 render_texture(output->wlr_output, output_damage, marks_texture,
458 &texture_box, matrix, con->alpha); 471 &texture_box, matrix, con->alpha);
@@ -473,12 +486,13 @@ static void render_titlebar(struct sway_output *output,
473 } 486 }
474 487
475 // Title text 488 // Title text
476 size_t title_ob_width = 0; // output-buffer-local 489 int ob_title_x = 0; // output-buffer-local
490 int ob_title_width = 0; // output-buffer-local
477 if (title_texture) { 491 if (title_texture) {
478 struct wlr_box texture_box; 492 struct wlr_box texture_box;
479 wlr_texture_get_size(title_texture, 493 wlr_texture_get_size(title_texture,
480 &texture_box.width, &texture_box.height); 494 &texture_box.width, &texture_box.height);
481 title_ob_width = texture_box.width; 495 ob_title_width = texture_box.width;
482 496
483 // The title texture might be shorter than the config->font_height, 497 // The title texture might be shorter than the config->font_height,
484 // in which case we need to pad it above and below. 498 // in which case we need to pad it above and below.
@@ -489,8 +503,26 @@ static void render_titlebar(struct sway_output *output,
489 texture_box.height; 503 texture_box.height;
490 504
491 // Render texture 505 // Render texture
492 texture_box.x = 506 if (texture_box.width > ob_inner_width - ob_marks_width) {
493 round((x - output_x + titlebar_h_padding) * output_scale); 507 texture_box.x = (title_align == ALIGN_RIGHT && ob_marks_width)
508 ? ob_marks_x + ob_marks_width : ob_inner_x;
509 } else if (title_align == ALIGN_LEFT) {
510 texture_box.x = ob_inner_x;
511 } else if (title_align == ALIGN_CENTER) {
512 // If there are marks visible, center between the edge and marks.
513 // Otherwise, center in the inner area.
514 if (ob_marks_width) {
515 texture_box.x = (ob_inner_x + ob_marks_x) / 2
516 - texture_box.width / 2;
517 } else {
518 texture_box.x = ob_inner_x + ob_inner_width / 2
519 - texture_box.width / 2;
520 }
521 } else {
522 texture_box.x = ob_inner_x + ob_inner_width - texture_box.width;
523 }
524 ob_title_x = texture_box.x;
525
494 texture_box.y = 526 texture_box.y =
495 round((bg_y - output_y) * output_scale) + ob_padding_above; 527 round((bg_y - output_y) * output_scale) + ob_padding_above;
496 528
@@ -499,11 +531,10 @@ static void render_titlebar(struct sway_output *output,
499 WL_OUTPUT_TRANSFORM_NORMAL, 531 WL_OUTPUT_TRANSFORM_NORMAL,
500 0.0, output->wlr_output->transform_matrix); 532 0.0, output->wlr_output->transform_matrix);
501 533
502 int inner_x = x - output_x + titlebar_h_padding; 534 if (ob_inner_width - ob_marks_width < texture_box.width) {
503 int ob_inner_width = scale_length(inner_width, inner_x, output_scale); 535 texture_box.width = ob_inner_width - ob_marks_width;
504 if (ob_inner_width - marks_ob_width < texture_box.width) {
505 texture_box.width = ob_inner_width - marks_ob_width;
506 } 536 }
537
507 render_texture(output->wlr_output, output_damage, title_texture, 538 render_texture(output->wlr_output, output_damage, title_texture,
508 &texture_box, matrix, con->alpha); 539 &texture_box, matrix, con->alpha);
509 540
@@ -522,17 +553,36 @@ static void render_titlebar(struct sway_output *output,
522 render_rect(output->wlr_output, output_damage, &box, color); 553 render_rect(output->wlr_output, output_damage, &box, color);
523 } 554 }
524 555
556 // Determine the left + right extends of the textures (output-buffer local)
557 int ob_left_x, ob_left_width, ob_right_x, ob_right_width;
558 if (ob_title_x < ob_marks_x) {
559 ob_left_x = ob_title_x;
560 ob_left_width = ob_title_width;
561 ob_right_x = ob_marks_x;
562 ob_right_width = ob_marks_width;
563 } else {
564 ob_left_x = ob_marks_x;
565 ob_left_width = ob_marks_width;
566 ob_right_x = ob_title_x;
567 ob_right_width = ob_title_width;
568 }
569 if (ob_left_x < ob_inner_x) {
570 ob_left_x = ob_inner_x;
571 } else if (ob_left_x + ob_left_width > ob_right_x + ob_right_width) {
572 ob_right_x = ob_left_x;
573 ob_right_width = ob_left_width;
574 }
575
525 // Filler between title and marks 576 // Filler between title and marks
526 box.width = 577 box.width = ob_right_x - ob_left_x - ob_left_width;
527 round(inner_width * output_scale) - title_ob_width - marks_ob_width;
528 if (box.width > 0) { 578 if (box.width > 0) {
529 box.x = round((x + titlebar_h_padding) * output_scale) + title_ob_width; 579 box.x = ob_left_x + ob_left_width + round(output_x * output_scale);
530 box.y = round(bg_y * output_scale); 580 box.y = round(bg_y * output_scale);
531 box.height = ob_bg_height; 581 box.height = ob_bg_height;
532 render_rect(output->wlr_output, output_damage, &box, color); 582 render_rect(output->wlr_output, output_damage, &box, color);
533 } 583 }
534 584
535 // Padding left of title 585 // Padding on left side
536 left_offset = (layout == L_TABBED) * titlebar_border_thickness; 586 left_offset = (layout == L_TABBED) * titlebar_border_thickness;
537 box.x = x + left_offset; 587 box.x = x + left_offset;
538 box.y = y + titlebar_border_thickness; 588 box.y = y + titlebar_border_thickness;
@@ -540,9 +590,13 @@ static void render_titlebar(struct sway_output *output,
540 box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 + 590 box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 +
541 config->font_height; 591 config->font_height;
542 scale_box(&box, output_scale); 592 scale_box(&box, output_scale);
593 int left_x = ob_left_x + round(output_x * output_scale);
594 if (box.x + box.width < left_x) {
595 box.width += left_x - box.x - box.width;
596 }
543 render_rect(output->wlr_output, output_damage, &box, color); 597 render_rect(output->wlr_output, output_damage, &box, color);
544 598
545 // Padding right of marks 599 // Padding on right side
546 right_offset = (layout == L_TABBED) * titlebar_border_thickness; 600 right_offset = (layout == L_TABBED) * titlebar_border_thickness;
547 box.x = x + width - titlebar_h_padding; 601 box.x = x + width - titlebar_h_padding;
548 box.y = y + titlebar_border_thickness; 602 box.y = y + titlebar_border_thickness;
@@ -550,6 +604,11 @@ static void render_titlebar(struct sway_output *output,
550 box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 + 604 box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 +
551 config->font_height; 605 config->font_height;
552 scale_box(&box, output_scale); 606 scale_box(&box, output_scale);
607 int right_rx = ob_right_x + ob_right_width + round(output_x * output_scale);
608 if (right_rx < box.x) {
609 box.width += box.x - right_rx;
610 box.x = right_rx;
611 }
553 render_rect(output->wlr_output, output_damage, &box, color); 612 render_rect(output->wlr_output, output_damage, &box, color);
554 613
555 if (connects_sides) { 614 if (connects_sides) {
diff --git a/sway/meson.build b/sway/meson.build
index c8c95a96..75131891 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -88,6 +88,7 @@ sway_sources = files(
88 'commands/swaynag_command.c', 88 'commands/swaynag_command.c',
89 'commands/swap.c', 89 'commands/swap.c',
90 'commands/tiling_drag.c', 90 'commands/tiling_drag.c',
91 'commands/title_align.c',
91 'commands/title_format.c', 92 'commands/title_format.c',
92 'commands/titlebar_border_thickness.c', 93 'commands/titlebar_border_thickness.c',
93 'commands/titlebar_padding.c', 94 'commands/titlebar_padding.c',
diff --git a/sway/sway.5.scd b/sway/sway.5.scd
index 6ccb1acf..4edd16bf 100644
--- a/sway/sway.5.scd
+++ b/sway/sway.5.scd
@@ -555,6 +555,11 @@ The default colors are:
555 Set the opacity of the window between 0 (completely transparent) and 1 555 Set the opacity of the window between 0 (completely transparent) and 1
556 (completely opaque). 556 (completely opaque).
557 557
558*title\_align* left|center|right
559 Sets the title alignment. If _right_ is selected and _show\_marks_ is set
560 to _yes_, the marks will be shown on the _left_ side instead of the
561 _right_ side.
562
558*unmark* [<identifier>] 563*unmark* [<identifier>]
559 *unmark* will remove _identifier_ from the list of current marks on a 564 *unmark* will remove _identifier_ from the list of current marks on a
560 window. If _identifier_ is omitted, all marks are removed. 565 window. If _identifier_ is omitted, all marks are removed.
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 63bb8e26..febba3b9 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -835,11 +835,10 @@ static size_t append_prop(char *buffer, const char *value) {
835 if (!value) { 835 if (!value) {
836 return 0; 836 return 0;
837 } 837 }
838 // if using pango_markup in font, we need to escape all markup char 838 // If using pango_markup in font, we need to escape all markup chars
839 // from values to avoid messing with pango markup 839 // from values to make sure tags are not inserted by clients
840 if (!config->pango_markup) { 840 if (config->pango_markup) {
841 char *escaped_value = escape_pango_markup(value); 841 char *escaped_value = escape_pango_markup(value);
842
843 lenient_strcat(buffer, escaped_value); 842 lenient_strcat(buffer, escaped_value);
844 size_t len = strlen(escaped_value); 843 size_t len = strlen(escaped_value);
845 free(escaped_value); 844 free(escaped_value);
@@ -856,11 +855,7 @@ static size_t append_prop(char *buffer, const char *value) {
856 */ 855 */
857static size_t parse_title_format(struct sway_view *view, char *buffer) { 856static size_t parse_title_format(struct sway_view *view, char *buffer) {
858 if (!view->title_format || strcmp(view->title_format, "%title") == 0) { 857 if (!view->title_format || strcmp(view->title_format, "%title") == 0) {
859 const char *title = view_get_title(view); 858 return append_prop(buffer, view_get_title(view));
860 if (buffer && title) {
861 strcpy(buffer, title);
862 }
863 return title ? strlen(title) : 0;
864 } 859 }
865 860
866 size_t len = 0; 861 size_t len = 0;
diff --git a/swayidle/main.c b/swayidle/main.c
index 2b185949..dd7d9de3 100644
--- a/swayidle/main.c
+++ b/swayidle/main.c
@@ -43,6 +43,12 @@ struct swayidle_timeout_cmd {
43 char *resume_cmd; 43 char *resume_cmd;
44}; 44};
45 45
46void sway_terminate(int exit_code) {
47 wl_display_disconnect(state.display);
48 wl_event_loop_destroy(state.event_loop);
49 exit(exit_code);
50}
51
46static void cmd_exec(char *param) { 52static void cmd_exec(char *param) {
47 wlr_log(WLR_DEBUG, "Cmd exec %s", param); 53 wlr_log(WLR_DEBUG, "Cmd exec %s", param);
48 pid_t pid = fork(); 54 pid_t pid = fork();
@@ -81,16 +87,16 @@ static int release_lock(void *data) {
81} 87}
82 88
83static void acquire_sleep_lock(void) { 89static void acquire_sleep_lock(void) {
84 sd_bus_message *msg; 90 sd_bus_message *msg = NULL;
85 sd_bus_error error; 91 sd_bus_error error = SD_BUS_ERROR_NULL;
86 int ret = sd_bus_call_method(bus, "org.freedesktop.login1", 92 int ret = sd_bus_call_method(bus, "org.freedesktop.login1",
87 "/org/freedesktop/login1", 93 "/org/freedesktop/login1",
88 "org.freedesktop.login1.Manager", "Inhibit", 94 "org.freedesktop.login1.Manager", "Inhibit",
89 &error, &msg, "ssss", "sleep", "swayidle", 95 &error, &msg, "ssss", "sleep", "swayidle",
90 "Setup Up Lock Screen", "delay"); 96 "Setup Up Lock Screen", "delay");
91 if (ret < 0) { 97 if (ret < 0) {
92 wlr_log(WLR_ERROR, "Failed to send Inhibit signal: %s", 98 wlr_log(WLR_ERROR, "Failed to send Inhibit signal: %s", error.message);
93 strerror(-ret)); 99 sd_bus_error_free(&error);
94 return; 100 return;
95 } 101 }
96 102
@@ -98,10 +104,11 @@ static void acquire_sleep_lock(void) {
98 if (ret < 0) { 104 if (ret < 0) {
99 wlr_log(WLR_ERROR, "Failed to parse D-Bus response for Inhibit: %s", 105 wlr_log(WLR_ERROR, "Failed to parse D-Bus response for Inhibit: %s",
100 strerror(-ret)); 106 strerror(-ret));
101 return; 107 } else {
108 wlr_log(WLR_INFO, "Got sleep lock: %d", lock_fd);
102 } 109 }
103 110 sd_bus_error_free(&error);
104 wlr_log(WLR_INFO, "Got sleep lock: %d", lock_fd); 111 sd_bus_message_unref(msg);
105} 112}
106 113
107static int prepare_for_sleep(sd_bus_message *msg, void *userdata, 114static int prepare_for_sleep(sd_bus_message *msg, void *userdata,
@@ -137,10 +144,28 @@ static int prepare_for_sleep(sd_bus_message *msg, void *userdata,
137 144
138static int dbus_event(int fd, uint32_t mask, void *data) { 145static int dbus_event(int fd, uint32_t mask, void *data) {
139 sd_bus *bus = data; 146 sd_bus *bus = data;
140 while (sd_bus_process(bus, NULL) > 0) { 147
141 // Do nothing. 148 if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
149 sway_terminate(0);
150 }
151
152 int count = 0;
153 if (mask & WL_EVENT_READABLE) {
154 count = sd_bus_process(bus, NULL);
142 } 155 }
143 return 1; 156 if (mask & WL_EVENT_WRITABLE) {
157 sd_bus_flush(bus);
158 }
159 if (mask == 0) {
160 sd_bus_flush(bus);
161 }
162
163 if (count < 0) {
164 wlr_log_errno(WLR_ERROR, "sd_bus_process failed, exiting");
165 sway_terminate(0);
166 }
167
168 return count;
144} 169}
145 170
146static void setup_sleep_listener(void) { 171static void setup_sleep_listener(void) {
@@ -166,8 +191,9 @@ static void setup_sleep_listener(void) {
166 } 191 }
167 acquire_sleep_lock(); 192 acquire_sleep_lock();
168 193
169 wl_event_loop_add_fd(state.event_loop, sd_bus_get_fd(bus), 194 struct wl_event_source *source = wl_event_loop_add_fd(state.event_loop,
170 WL_EVENT_READABLE, dbus_event, bus); 195 sd_bus_get_fd(bus), WL_EVENT_READABLE, dbus_event, bus);
196 wl_event_source_check(source);
171} 197}
172#endif 198#endif
173 199
@@ -339,12 +365,6 @@ static int parse_args(int argc, char *argv[]) {
339 return 0; 365 return 0;
340} 366}
341 367
342void sway_terminate(int exit_code) {
343 wl_display_disconnect(state.display);
344 wl_event_loop_destroy(state.event_loop);
345 exit(exit_code);
346}
347
348static void register_zero_idle_timeout(void *item) { 368static void register_zero_idle_timeout(void *item) {
349 struct swayidle_timeout_cmd *cmd = item; 369 struct swayidle_timeout_cmd *cmd = item;
350 register_timeout(cmd, 0); 370 register_timeout(cmd, 0);
@@ -365,15 +385,28 @@ static int handle_signal(int sig, void *data) {
365} 385}
366 386
367static int display_event(int fd, uint32_t mask, void *data) { 387static int display_event(int fd, uint32_t mask, void *data) {
368 if (mask & WL_EVENT_HANGUP) { 388 if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
369 sway_terminate(0); 389 sway_terminate(0);
370 } 390 }
371 if (wl_display_dispatch(state.display) < 0) { 391
392 int count = 0;
393 if (mask & WL_EVENT_READABLE) {
394 count = wl_display_dispatch(state.display);
395 }
396 if (mask & WL_EVENT_WRITABLE) {
397 wl_display_flush(state.display);
398 }
399 if (mask == 0) {
400 count = wl_display_dispatch_pending(state.display);
401 wl_display_flush(state.display);
402 }
403
404 if (count < 0) {
372 wlr_log_errno(WLR_ERROR, "wl_display_dispatch failed, exiting"); 405 wlr_log_errno(WLR_ERROR, "wl_display_dispatch failed, exiting");
373 sway_terminate(0); 406 sway_terminate(0);
374 } 407 }
375 wl_display_flush(state.display); 408
376 return 0; 409 return count;
377} 410}
378 411
379static void register_idle_timeout(void *item) { 412static void register_idle_timeout(void *item) {