summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/stringop.c2
-rw-r--r--include/sway/commands.h3
-rw-r--r--include/sway/config.h10
-rw-r--r--include/sway/tree/container.h6
-rw-r--r--meson.build17
-rw-r--r--sway/commands.c3
-rw-r--r--sway/commands/assign.c2
-rw-r--r--sway/commands/bar/bindsym.c1
-rw-r--r--sway/commands/bar/hidden_state.c2
-rw-r--r--sway/commands/bar/icon_theme.c1
-rw-r--r--sway/commands/bar/id.c2
-rw-r--r--sway/commands/bar/mode.c2
-rw-r--r--sway/commands/bar/output.c2
-rw-r--r--sway/commands/bar/separator_symbol.c2
-rw-r--r--sway/commands/bar/tray_output.c1
-rw-r--r--sway/commands/bind.c2
-rw-r--r--sway/commands/exec_always.c2
-rw-r--r--sway/commands/for_window.c1
-rw-r--r--sway/commands/input/xkb_layout.c2
-rw-r--r--sway/commands/input/xkb_model.c2
-rw-r--r--sway/commands/input/xkb_options.c2
-rw-r--r--sway/commands/input/xkb_rules.c2
-rw-r--r--sway/commands/input/xkb_variant.c2
-rw-r--r--sway/commands/mode.c2
-rw-r--r--sway/commands/move.c2
-rw-r--r--sway/commands/no_focus.c1
-rw-r--r--sway/commands/reload.c2
-rw-r--r--sway/commands/rename.c1
-rw-r--r--sway/commands/resize.c28
-rw-r--r--sway/commands/seat/attach.c2
-rw-r--r--sway/commands/seat/cursor.c2
-rw-r--r--sway/commands/set.c2
-rw-r--r--sway/commands/title_align.c30
-rw-r--r--sway/commands/titlebar_border_thickness.c30
-rw-r--r--sway/commands/titlebar_padding.c42
-rw-r--r--sway/commands/workspace.c4
-rw-r--r--sway/config.c8
-rw-r--r--sway/config/bar.c1
-rw-r--r--sway/config/input.c2
-rw-r--r--sway/config/output.c2
-rw-r--r--sway/config/seat.c2
-rw-r--r--sway/criteria.c2
-rw-r--r--sway/desktop/render.c162
-rw-r--r--sway/input/cursor.c2
-rw-r--r--sway/input/input-manager.c2
-rw-r--r--sway/input/seat.c3
-rw-r--r--sway/ipc-json.c251
-rw-r--r--sway/ipc-server.c15
-rw-r--r--sway/main.c3
-rw-r--r--sway/meson.build3
-rw-r--r--sway/security.c2
-rw-r--r--sway/sway.5.scd15
-rw-r--r--sway/tree/container.c2
-rw-r--r--sway/tree/root.c35
-rw-r--r--sway/tree/view.c39
-rw-r--r--swaybar/bar.c2
-rw-r--r--swaybar/config.c2
-rw-r--r--swaybar/main.c2
-rw-r--r--swayidle/main.c77
-rw-r--r--swayidle/swayidle.1.scd2
-rw-r--r--swaylock/main.c3
-rw-r--r--swaylock/pam.c2
-rw-r--r--swaylock/password.c1
-rw-r--r--swaylock/render.c1
-rw-r--r--swaylock/shadow.c2
-rw-r--r--swaymsg/main.c2
-rw-r--r--swaynag/config.c4
-rw-r--r--swaynag/main.c3
-rw-r--r--swaynag/swaynag.c2
-rw-r--r--swaynag/types.c2
70 files changed, 589 insertions, 288 deletions
diff --git a/common/stringop.c b/common/stringop.c
index d2c91c24..df016e9d 100644
--- a/common/stringop.c
+++ b/common/stringop.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include <stdlib.h> 2#include <stdlib.h>
3#include <stdio.h> 3#include <stdio.h>
4#include <string.h> 4#include <string.h>
diff --git a/include/sway/commands.h b/include/sway/commands.h
index b0339313..eb446eae 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -172,7 +172,10 @@ 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;
177sway_cmd cmd_titlebar_border_thickness;
178sway_cmd cmd_titlebar_padding;
176sway_cmd cmd_unmark; 179sway_cmd cmd_unmark;
177sway_cmd cmd_urgent; 180sway_cmd cmd_urgent;
178sway_cmd cmd_workspace; 181sway_cmd cmd_workspace;
diff --git a/include/sway/config.h b/include/sway/config.h
index 4927b8e0..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 */
@@ -391,6 +397,9 @@ struct sway_config {
391 size_t font_height; 397 size_t font_height;
392 size_t font_baseline; 398 size_t font_baseline;
393 bool pango_markup; 399 bool pango_markup;
400 int titlebar_border_thickness;
401 int titlebar_h_padding;
402 int titlebar_v_padding;
394 size_t urgent_timeout; 403 size_t urgent_timeout;
395 enum sway_fowa focus_on_window_activation; 404 enum sway_fowa focus_on_window_activation;
396 enum sway_popup_during_fullscreen popup_during_fullscreen; 405 enum sway_popup_during_fullscreen popup_during_fullscreen;
@@ -406,6 +415,7 @@ struct sway_config {
406 bool validating; 415 bool validating;
407 bool auto_back_and_forth; 416 bool auto_back_and_forth;
408 bool show_marks; 417 bool show_marks;
418 enum alignment title_align;
409 bool tiling_drag; 419 bool tiling_drag;
410 420
411 bool smart_gaps; 421 bool smart_gaps;
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index f907aad2..1d0a0ad1 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -10,12 +10,6 @@
10struct sway_view; 10struct sway_view;
11struct sway_seat; 11struct sway_seat;
12 12
13#define TITLEBAR_BORDER_THICKNESS 1
14
15// Padding includes titlebar border
16#define TITLEBAR_H_PADDING 3
17#define TITLEBAR_V_PADDING 4
18
19enum sway_container_layout { 13enum sway_container_layout {
20 L_NONE, 14 L_NONE,
21 L_HORIZ, 15 L_HORIZ,
diff --git a/meson.build b/meson.build
index bb60bc89..810a657e 100644
--- a/meson.build
+++ b/meson.build
@@ -108,13 +108,7 @@ if scdoc.found()
108 endforeach 108 endforeach
109endif 109endif
110 110
111# If prefix is '/usr', sysconfdir will be explicitly set to '/etc' by Meson to 111add_project_arguments('-DSYSCONFDIR="/@0@"'.format(join_paths(prefix, sysconfdir)), language : 'c')
112# enforce FHS compliance, so we should look for configs there as well.
113if prefix == '/usr'
114 add_project_arguments('-DSYSCONFDIR="/@0@"'.format(sysconfdir), language : 'c')
115else
116 add_project_arguments('-DSYSCONFDIR="/@0@/@1@"'.format(prefix, sysconfdir), language : 'c')
117endif
118 112
119version = get_option('sway-version') 113version = get_option('sway-version')
120if version != '' 114if version != ''
@@ -159,14 +153,7 @@ subdir('swaylock')
159config = configuration_data() 153config = configuration_data()
160config.set('datadir', join_paths(prefix, datadir)) 154config.set('datadir', join_paths(prefix, datadir))
161config.set('prefix', prefix) 155config.set('prefix', prefix)
162 156config.set('sysconfdir', join_paths(prefix, sysconfdir))
163# If prefix is '/usr', sysconfdir will be explicitly set to '/etc' by Meson to
164# enforce FHS compliance, so we should look for configs there as well.
165if prefix == '/usr'
166 config.set('sysconfdir', sysconfdir)
167else
168 config.set('sysconfdir', join_paths(prefix, sysconfdir))
169endif
170 157
171configure_file( 158configure_file(
172 configuration: config, 159 configuration: config,
diff --git a/sway/commands.c b/sway/commands.c
index 4b86c2fa..bffc18f6 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -103,6 +103,9 @@ 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 },
107 { "titlebar_border_thickness", cmd_titlebar_border_thickness },
108 { "titlebar_padding", cmd_titlebar_padding },
106 { "workspace", cmd_workspace }, 109 { "workspace", cmd_workspace },
107 { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, 110 { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth },
108}; 111};
diff --git a/sway/commands/assign.c b/sway/commands/assign.c
index 04582e88..716d70cf 100644
--- a/sway/commands/assign.c
+++ b/sway/commands/assign.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include <stdio.h> 2#include <stdio.h>
3#include <string.h> 3#include <string.h>
4#include "sway/commands.h" 4#include "sway/commands.h"
diff --git a/sway/commands/bar/bindsym.c b/sway/commands/bar/bindsym.c
index 965c8903..e6d6220e 100644
--- a/sway/commands/bar/bindsym.c
+++ b/sway/commands/bar/bindsym.c
@@ -1,4 +1,3 @@
1#define _XOPEN_SOURCE 500
2#include <stdlib.h> 1#include <stdlib.h>
3#include <string.h> 2#include <string.h>
4#include <strings.h> 3#include <strings.h>
diff --git a/sway/commands/bar/hidden_state.c b/sway/commands/bar/hidden_state.c
index 5be6c2dc..79eaf01c 100644
--- a/sway/commands/bar/hidden_state.c
+++ b/sway/commands/bar/hidden_state.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <string.h> 2#include <string.h>
3#include <strings.h> 3#include <strings.h>
4#include "sway/commands.h" 4#include "sway/commands.h"
diff --git a/sway/commands/bar/icon_theme.c b/sway/commands/bar/icon_theme.c
index 44cd3076..0e30409b 100644
--- a/sway/commands/bar/icon_theme.c
+++ b/sway/commands/bar/icon_theme.c
@@ -1,4 +1,3 @@
1#define _XOPEN_SOURCE 500
2#include <string.h> 1#include <string.h>
3#include "sway/commands.h" 2#include "sway/commands.h"
4 3
diff --git a/sway/commands/bar/id.c b/sway/commands/bar/id.c
index 7690a852..35509459 100644
--- a/sway/commands/bar/id.c
+++ b/sway/commands/bar/id.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <string.h> 2#include <string.h>
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "log.h" 4#include "log.h"
diff --git a/sway/commands/bar/mode.c b/sway/commands/bar/mode.c
index 2cba785e..dcaf6da9 100644
--- a/sway/commands/bar/mode.c
+++ b/sway/commands/bar/mode.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <string.h> 2#include <string.h>
3#include <strings.h> 3#include <strings.h>
4#include "sway/commands.h" 4#include "sway/commands.h"
diff --git a/sway/commands/bar/output.c b/sway/commands/bar/output.c
index 72754e05..930d779d 100644
--- a/sway/commands/bar/output.c
+++ b/sway/commands/bar/output.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <stdbool.h> 2#include <stdbool.h>
3#include <string.h> 3#include <string.h>
4#include "sway/commands.h" 4#include "sway/commands.h"
diff --git a/sway/commands/bar/separator_symbol.c b/sway/commands/bar/separator_symbol.c
index 392ab730..060b8f52 100644
--- a/sway/commands/bar/separator_symbol.c
+++ b/sway/commands/bar/separator_symbol.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <string.h> 2#include <string.h>
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "log.h" 4#include "log.h"
diff --git a/sway/commands/bar/tray_output.c b/sway/commands/bar/tray_output.c
index 6ab16731..e6c77128 100644
--- a/sway/commands/bar/tray_output.c
+++ b/sway/commands/bar/tray_output.c
@@ -1,4 +1,3 @@
1#define _XOPEN_SOURCE 500
2#include <string.h> 1#include <string.h>
3#include "sway/commands.h" 2#include "sway/commands.h"
4 3
diff --git a/sway/commands/bind.c b/sway/commands/bind.c
index a9de227f..08acbe7a 100644
--- a/sway/commands/bind.c
+++ b/sway/commands/bind.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#ifdef __linux__ 2#ifdef __linux__
3#include <linux/input-event-codes.h> 3#include <linux/input-event-codes.h>
4#elif __FreeBSD__ 4#elif __FreeBSD__
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c
index 7a15709b..9ec28d81 100644
--- a/sway/commands/exec_always.c
+++ b/sway/commands/exec_always.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <stdlib.h> 2#include <stdlib.h>
3#include <stdint.h> 3#include <stdint.h>
4#include <string.h> 4#include <string.h>
diff --git a/sway/commands/for_window.c b/sway/commands/for_window.c
index ac4d6563..7c0f7d7f 100644
--- a/sway/commands/for_window.c
+++ b/sway/commands/for_window.c
@@ -1,4 +1,3 @@
1#define _XOPEN_SOURCE 500
2#include <string.h> 1#include <string.h>
3#include "sway/commands.h" 2#include "sway/commands.h"
4#include "sway/criteria.h" 3#include "sway/criteria.h"
diff --git a/sway/commands/input/xkb_layout.c b/sway/commands/input/xkb_layout.c
index 5fccd4a3..43166401 100644
--- a/sway/commands/input/xkb_layout.c
+++ b/sway/commands/input/xkb_layout.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include "sway/config.h" 2#include "sway/config.h"
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "sway/input/input-manager.h" 4#include "sway/input/input-manager.h"
diff --git a/sway/commands/input/xkb_model.c b/sway/commands/input/xkb_model.c
index c4d04638..066f632b 100644
--- a/sway/commands/input/xkb_model.c
+++ b/sway/commands/input/xkb_model.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include "sway/config.h" 2#include "sway/config.h"
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "sway/input/input-manager.h" 4#include "sway/input/input-manager.h"
diff --git a/sway/commands/input/xkb_options.c b/sway/commands/input/xkb_options.c
index 794ab6e9..09dc4a5c 100644
--- a/sway/commands/input/xkb_options.c
+++ b/sway/commands/input/xkb_options.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include "sway/config.h" 2#include "sway/config.h"
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "sway/input/input-manager.h" 4#include "sway/input/input-manager.h"
diff --git a/sway/commands/input/xkb_rules.c b/sway/commands/input/xkb_rules.c
index 257c3288..d3e576e6 100644
--- a/sway/commands/input/xkb_rules.c
+++ b/sway/commands/input/xkb_rules.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include "sway/config.h" 2#include "sway/config.h"
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "sway/input/input-manager.h" 4#include "sway/input/input-manager.h"
diff --git a/sway/commands/input/xkb_variant.c b/sway/commands/input/xkb_variant.c
index 3832dc8e..2d7581d1 100644
--- a/sway/commands/input/xkb_variant.c
+++ b/sway/commands/input/xkb_variant.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include "sway/config.h" 2#include "sway/config.h"
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "sway/input/input-manager.h" 4#include "sway/input/input-manager.h"
diff --git a/sway/commands/mode.c b/sway/commands/mode.c
index 637ca45e..189e3c1a 100644
--- a/sway/commands/mode.c
+++ b/sway/commands/mode.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <stdbool.h> 2#include <stdbool.h>
3#include <string.h> 3#include <string.h>
4#include <strings.h> 4#include <strings.h>
diff --git a/sway/commands/move.c b/sway/commands/move.c
index 7d8c1f1a..240b9f04 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <ctype.h> 2#include <ctype.h>
3#include <stdbool.h> 3#include <stdbool.h>
4#include <string.h> 4#include <string.h>
diff --git a/sway/commands/no_focus.c b/sway/commands/no_focus.c
index 61a8de7e..cb81a445 100644
--- a/sway/commands/no_focus.c
+++ b/sway/commands/no_focus.c
@@ -1,4 +1,3 @@
1#define _XOPEN_SOURCE 500
2#include <string.h> 1#include <string.h>
3#include "sway/commands.h" 2#include "sway/commands.h"
4#include "sway/criteria.h" 3#include "sway/criteria.h"
diff --git a/sway/commands/reload.c b/sway/commands/reload.c
index 62105cdc..c64de4bd 100644
--- a/sway/commands/reload.c
+++ b/sway/commands/reload.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <string.h> 2#include <string.h>
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "sway/config.h" 4#include "sway/config.h"
diff --git a/sway/commands/rename.c b/sway/commands/rename.c
index 0cee9293..29f90d81 100644
--- a/sway/commands/rename.c
+++ b/sway/commands/rename.c
@@ -1,4 +1,3 @@
1#define _XOPEN_SOURCE 500
2#include <ctype.h> 1#include <ctype.h>
3#include <string.h> 2#include <string.h>
4#include <strings.h> 3#include <strings.h>
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/seat/attach.c b/sway/commands/seat/attach.c
index 6b4bcf1f..8d646c2d 100644
--- a/sway/commands/seat/attach.c
+++ b/sway/commands/seat/attach.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include <string.h> 2#include <string.h>
3#include <strings.h> 3#include <strings.h>
4#include "sway/input/input-manager.h" 4#include "sway/input/input-manager.h"
diff --git a/sway/commands/seat/cursor.c b/sway/commands/seat/cursor.c
index 1d41a94e..495c2338 100644
--- a/sway/commands/seat/cursor.c
+++ b/sway/commands/seat/cursor.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#ifdef __linux__ 2#ifdef __linux__
3#include <linux/input-event-codes.h> 3#include <linux/input-event-codes.h>
4#elif __FreeBSD__ 4#elif __FreeBSD__
diff --git a/sway/commands/set.c b/sway/commands/set.c
index be51230b..d912e4fd 100644
--- a/sway/commands/set.c
+++ b/sway/commands/set.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include <stdio.h> 2#include <stdio.h>
3#include <string.h> 3#include <string.h>
4#include <strings.h> 4#include <strings.h>
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/commands/titlebar_border_thickness.c b/sway/commands/titlebar_border_thickness.c
new file mode 100644
index 00000000..c1e9bb52
--- /dev/null
+++ b/sway/commands/titlebar_border_thickness.c
@@ -0,0 +1,30 @@
1#include <string.h>
2#include "sway/commands.h"
3#include "sway/config.h"
4#include "sway/output.h"
5#include "sway/tree/arrange.h"
6#include "log.h"
7
8struct cmd_results *cmd_titlebar_border_thickness(int argc, char **argv) {
9 struct cmd_results *error = NULL;
10 if ((error = checkarg(argc, "titlebar_border_thickness", EXPECTED_EQUAL_TO, 1))) {
11 return error;
12 }
13
14 char *inv;
15 int value = strtol(argv[0], &inv, 10);
16 if (*inv != '\0' || value < 0 || value > config->titlebar_v_padding) {
17 return cmd_results_new(CMD_FAILURE, "titlebar_border_thickness",
18 "Invalid size specified");
19 }
20
21 config->titlebar_border_thickness = value;
22
23 for (int i = 0; i < root->outputs->length; ++i) {
24 struct sway_output *output = root->outputs->items[i];
25 arrange_workspace(output_get_active_workspace(output));
26 output_damage_whole(output);
27 }
28
29 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
30}
diff --git a/sway/commands/titlebar_padding.c b/sway/commands/titlebar_padding.c
new file mode 100644
index 00000000..a642e945
--- /dev/null
+++ b/sway/commands/titlebar_padding.c
@@ -0,0 +1,42 @@
1#include <string.h>
2#include "sway/commands.h"
3#include "sway/config.h"
4#include "sway/output.h"
5#include "sway/tree/arrange.h"
6#include "log.h"
7
8struct cmd_results *cmd_titlebar_padding(int argc, char **argv) {
9 struct cmd_results *error = NULL;
10 if ((error = checkarg(argc, "titlebar_padding", EXPECTED_AT_LEAST, 1))) {
11 return error;
12 }
13
14 char *inv;
15 int h_value = strtol(argv[0], &inv, 10);
16 if (*inv != '\0' || h_value < 0 || h_value < config->titlebar_border_thickness) {
17 return cmd_results_new(CMD_FAILURE, "titlebar_padding",
18 "Invalid size specified");
19 }
20
21 int v_value;
22 if (argc == 1) {
23 v_value = h_value;
24 } else {
25 v_value = strtol(argv[1], &inv, 10);
26 if (*inv != '\0' || v_value < 0 || v_value < config->titlebar_border_thickness) {
27 return cmd_results_new(CMD_FAILURE, "titlebar_padding",
28 "Invalid size specified");
29 }
30 }
31
32 config->titlebar_v_padding = v_value;
33 config->titlebar_h_padding = h_value;
34
35 for (int i = 0; i < root->outputs->length; ++i) {
36 struct sway_output *output = root->outputs->items[i];
37 arrange_workspace(output_get_active_workspace(output));
38 output_damage_whole(output);
39 }
40
41 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
42}
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c
index 92118ecf..7d32e65b 100644
--- a/sway/commands/workspace.c
+++ b/sway/commands/workspace.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <ctype.h> 2#include <ctype.h>
3#include <limits.h> 3#include <limits.h>
4#include <string.h> 4#include <string.h>
@@ -38,7 +38,7 @@ void free_workspace_config(struct workspace_config *wsc) {
38} 38}
39 39
40static void prevent_invalid_outer_gaps(struct workspace_config *wsc) { 40static void prevent_invalid_outer_gaps(struct workspace_config *wsc) {
41 if (wsc->gaps_outer.top != INT_MIN && 41 if (wsc->gaps_outer.top != INT_MIN &&
42 wsc->gaps_outer.top < -wsc->gaps_inner) { 42 wsc->gaps_outer.top < -wsc->gaps_inner) {
43 wsc->gaps_outer.top = -wsc->gaps_inner; 43 wsc->gaps_outer.top = -wsc->gaps_inner;
44 } 44 }
diff --git a/sway/config.c b/sway/config.c
index c1320acf..ed288060 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -1,5 +1,4 @@
1#define _POSIX_C_SOURCE 200809L 1#define _XOPEN_SOURCE 600 // for realpath
2#define _XOPEN_SOURCE 700
3#include <stdio.h> 2#include <stdio.h>
4#include <stdbool.h> 3#include <stdbool.h>
5#include <stdlib.h> 4#include <stdlib.h>
@@ -213,6 +212,10 @@ static void config_defaults(struct sway_config *config) {
213 config->urgent_timeout = 500; 212 config->urgent_timeout = 500;
214 config->popup_during_fullscreen = POPUP_SMART; 213 config->popup_during_fullscreen = POPUP_SMART;
215 214
215 config->titlebar_border_thickness = 1;
216 config->titlebar_h_padding = 5;
217 config->titlebar_v_padding = 4;
218
216 // floating view 219 // floating view
217 config->floating_maximum_width = 0; 220 config->floating_maximum_width = 0;
218 config->floating_maximum_height = 0; 221 config->floating_maximum_height = 0;
@@ -230,6 +233,7 @@ static void config_defaults(struct sway_config *config) {
230 config->auto_back_and_forth = false; 233 config->auto_back_and_forth = false;
231 config->reading = false; 234 config->reading = false;
232 config->show_marks = true; 235 config->show_marks = true;
236 config->title_align = ALIGN_LEFT;
233 config->tiling_drag = true; 237 config->tiling_drag = true;
234 238
235 config->smart_gaps = false; 239 config->smart_gaps = false;
diff --git a/sway/config/bar.c b/sway/config/bar.c
index 7009d0a0..36e10527 100644
--- a/sway/config/bar.c
+++ b/sway/config/bar.c
@@ -1,5 +1,4 @@
1#define _POSIX_C_SOURCE 200809L 1#define _POSIX_C_SOURCE 200809L
2#define _XOPEN_SOURCE 700
3#include <stdio.h> 2#include <stdio.h>
4#include <stdbool.h> 3#include <stdbool.h>
5#include <stdlib.h> 4#include <stdlib.h>
diff --git a/sway/config/input.c b/sway/config/input.c
index d5d2d90b..d649d34d 100644
--- a/sway/config/input.c
+++ b/sway/config/input.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include <stdlib.h> 2#include <stdlib.h>
3#include <limits.h> 3#include <limits.h>
4#include <float.h> 4#include <float.h>
diff --git a/sway/config/output.c b/sway/config/output.c
index 07543e3c..75309289 100644
--- a/sway/config/output.c
+++ b/sway/config/output.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include <assert.h> 2#include <assert.h>
3#include <stdbool.h> 3#include <stdbool.h>
4#include <string.h> 4#include <string.h>
diff --git a/sway/config/seat.c b/sway/config/seat.c
index 46456caf..56fa6095 100644
--- a/sway/config/seat.c
+++ b/sway/config/seat.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include <stdlib.h> 2#include <stdlib.h>
3#include <string.h> 3#include <string.h>
4#include "sway/config.h" 4#include "sway/config.h"
diff --git a/sway/criteria.c b/sway/criteria.c
index 3393852c..54583b04 100644
--- a/sway/criteria.c
+++ b/sway/criteria.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include <stdlib.h> 2#include <stdlib.h>
3#include <stdio.h> 3#include <stdio.h>
4#include <stdbool.h> 4#include <stdbool.h>
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 8d4a701b..eeda496c 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -368,6 +368,10 @@ static void render_titlebar(struct sway_output *output,
368 children->items[children->length - 1] == con; 368 children->items[children->length - 1] == con;
369 double output_x = output->wlr_output->lx; 369 double output_x = output->wlr_output->lx;
370 double output_y = output->wlr_output->ly; 370 double output_y = output->wlr_output->ly;
371 int titlebar_border_thickness = config->titlebar_border_thickness;
372 int titlebar_h_padding = config->titlebar_h_padding;
373 int titlebar_v_padding = config->titlebar_v_padding;
374 enum alignment title_align = config->title_align;
371 375
372 // Single pixel bar above title 376 // Single pixel bar above title
373 memcpy(&color, colors->border, sizeof(float) * 4); 377 memcpy(&color, colors->border, sizeof(float) * 4);
@@ -375,7 +379,7 @@ static void render_titlebar(struct sway_output *output,
375 box.x = x; 379 box.x = x;
376 box.y = y; 380 box.y = y;
377 box.width = width; 381 box.width = width;
378 box.height = TITLEBAR_BORDER_THICKNESS; 382 box.height = titlebar_border_thickness;
379 scale_box(&box, output_scale); 383 scale_box(&box, output_scale);
380 render_rect(output->wlr_output, output_damage, &box, color); 384 render_rect(output->wlr_output, output_damage, &box, color);
381 385
@@ -391,45 +395,51 @@ static void render_titlebar(struct sway_output *output,
391 } 395 }
392 } 396 }
393 box.x = x + left_offset; 397 box.x = x + left_offset;
394 box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS; 398 box.y = y + container_titlebar_height() - titlebar_border_thickness;
395 box.width = width - left_offset - right_offset; 399 box.width = width - left_offset - right_offset;
396 box.height = TITLEBAR_BORDER_THICKNESS; 400 box.height = titlebar_border_thickness;
397 scale_box(&box, output_scale); 401 scale_box(&box, output_scale);
398 render_rect(output->wlr_output, output_damage, &box, color); 402 render_rect(output->wlr_output, output_damage, &box, color);
399 403
400 if (layout == L_TABBED) { 404 if (layout == L_TABBED) {
401 // Single pixel left edge 405 // Single pixel left edge
402 box.x = x; 406 box.x = x;
403 box.y = y + TITLEBAR_BORDER_THICKNESS; 407 box.y = y + titlebar_border_thickness;
404 box.width = TITLEBAR_BORDER_THICKNESS; 408 box.width = titlebar_border_thickness;
405 box.height = 409 box.height =
406 container_titlebar_height() - TITLEBAR_BORDER_THICKNESS * 2; 410 container_titlebar_height() - titlebar_border_thickness * 2;
407 scale_box(&box, output_scale); 411 scale_box(&box, output_scale);
408 render_rect(output->wlr_output, output_damage, &box, color); 412 render_rect(output->wlr_output, output_damage, &box, color);
409 413
410 // Single pixel right edge 414 // Single pixel right edge
411 box.x = x + width - TITLEBAR_BORDER_THICKNESS; 415 box.x = x + width - titlebar_border_thickness;
412 box.y = y + TITLEBAR_BORDER_THICKNESS; 416 box.y = y + titlebar_border_thickness;
413 box.width = TITLEBAR_BORDER_THICKNESS; 417 box.width = titlebar_border_thickness;
414 box.height = 418 box.height =
415 container_titlebar_height() - TITLEBAR_BORDER_THICKNESS * 2; 419 container_titlebar_height() - titlebar_border_thickness * 2;
416 scale_box(&box, output_scale); 420 scale_box(&box, output_scale);
417 render_rect(output->wlr_output, output_damage, &box, color); 421 render_rect(output->wlr_output, output_damage, &box, color);
418 } 422 }
419 423
420 size_t inner_width = width - TITLEBAR_H_PADDING * 2; 424 int inner_x = x - output_x + titlebar_h_padding;
421 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);
422 int ob_bg_height = scale_length( 431 int ob_bg_height = scale_length(
423 (TITLEBAR_V_PADDING - TITLEBAR_BORDER_THICKNESS) * 2 + 432 (titlebar_v_padding - titlebar_border_thickness) * 2 +
424 config->font_height, bg_y, output_scale); 433 config->font_height, bg_y, output_scale);
425 434
426 // Marks 435 // Marks
427 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
428 if (config->show_marks && marks_texture) { 438 if (config->show_marks && marks_texture) {
429 struct wlr_box texture_box; 439 struct wlr_box texture_box;
430 wlr_texture_get_size(marks_texture, 440 wlr_texture_get_size(marks_texture,
431 &texture_box.width, &texture_box.height); 441 &texture_box.width, &texture_box.height);
432 marks_ob_width = texture_box.width; 442 ob_marks_width = texture_box.width;
433 443
434 // 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
435 // 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.
@@ -437,9 +447,15 @@ static void render_titlebar(struct sway_output *output,
437 int ob_padding_above = floor(ob_padding_total / 2.0); 447 int ob_padding_above = floor(ob_padding_total / 2.0);
438 int ob_padding_below = ceil(ob_padding_total / 2.0); 448 int ob_padding_below = ceil(ob_padding_total / 2.0);
439 449
440 // Render texture 450 // Render texture. If the title is on the right, the marks will be on
441 texture_box.x = round((x - output_x + width - TITLEBAR_H_PADDING) 451 // the left. Otherwise, they will be on the right.
442 * 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
443 texture_box.y = round((bg_y - output_y) * output_scale) + 459 texture_box.y = round((bg_y - output_y) * output_scale) +
444 ob_padding_above; 460 ob_padding_above;
445 461
@@ -448,8 +464,8 @@ static void render_titlebar(struct sway_output *output,
448 WL_OUTPUT_TRANSFORM_NORMAL, 464 WL_OUTPUT_TRANSFORM_NORMAL,
449 0.0, output->wlr_output->transform_matrix); 465 0.0, output->wlr_output->transform_matrix);
450 466
451 if (inner_width * output_scale < texture_box.width) { 467 if (ob_inner_width < texture_box.width) {
452 texture_box.width = inner_width * output_scale; 468 texture_box.width = ob_inner_width;
453 } 469 }
454 render_texture(output->wlr_output, output_damage, marks_texture, 470 render_texture(output->wlr_output, output_damage, marks_texture,
455 &texture_box, matrix, con->alpha); 471 &texture_box, matrix, con->alpha);
@@ -458,7 +474,7 @@ static void render_titlebar(struct sway_output *output,
458 memcpy(&color, colors->background, sizeof(float) * 4); 474 memcpy(&color, colors->background, sizeof(float) * 4);
459 premultiply_alpha(color, con->alpha); 475 premultiply_alpha(color, con->alpha);
460 box.x = texture_box.x + round(output_x * output_scale); 476 box.x = texture_box.x + round(output_x * output_scale);
461 box.y = round((y + TITLEBAR_BORDER_THICKNESS) * output_scale); 477 box.y = round((y + titlebar_border_thickness) * output_scale);
462 box.width = texture_box.width; 478 box.width = texture_box.width;
463 box.height = ob_padding_above; 479 box.height = ob_padding_above;
464 render_rect(output->wlr_output, output_damage, &box, color); 480 render_rect(output->wlr_output, output_damage, &box, color);
@@ -470,24 +486,43 @@ static void render_titlebar(struct sway_output *output,
470 } 486 }
471 487
472 // Title text 488 // Title text
473 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
474 if (title_texture) { 491 if (title_texture) {
475 struct wlr_box texture_box; 492 struct wlr_box texture_box;
476 wlr_texture_get_size(title_texture, 493 wlr_texture_get_size(title_texture,
477 &texture_box.width, &texture_box.height); 494 &texture_box.width, &texture_box.height);
478 title_ob_width = texture_box.width; 495 ob_title_width = texture_box.width;
479 496
480 // The title texture might be shorter than the config->font_height, 497 // The title texture might be shorter than the config->font_height,
481 // in which case we need to pad it above and below. 498 // in which case we need to pad it above and below.
482 int ob_padding_above = round((config->font_baseline - 499 int ob_padding_above = round((config->font_baseline -
483 con->title_baseline + TITLEBAR_V_PADDING - 500 con->title_baseline + titlebar_v_padding -
484 TITLEBAR_BORDER_THICKNESS) * output_scale); 501 titlebar_border_thickness) * output_scale);
485 int ob_padding_below = ob_bg_height - ob_padding_above - 502 int ob_padding_below = ob_bg_height - ob_padding_above -
486 texture_box.height; 503 texture_box.height;
487 504
488 // Render texture 505 // Render texture
489 texture_box.x = 506 if (texture_box.width > ob_inner_width - ob_marks_width) {
490 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
491 texture_box.y = 526 texture_box.y =
492 round((bg_y - output_y) * output_scale) + ob_padding_above; 527 round((bg_y - output_y) * output_scale) + ob_padding_above;
493 528
@@ -496,11 +531,10 @@ static void render_titlebar(struct sway_output *output,
496 WL_OUTPUT_TRANSFORM_NORMAL, 531 WL_OUTPUT_TRANSFORM_NORMAL,
497 0.0, output->wlr_output->transform_matrix); 532 0.0, output->wlr_output->transform_matrix);
498 533
499 int inner_x = x - output_x + TITLEBAR_H_PADDING; 534 if (ob_inner_width - ob_marks_width < texture_box.width) {
500 int ob_inner_width = scale_length(inner_width, inner_x, output_scale); 535 texture_box.width = ob_inner_width - ob_marks_width;
501 if (ob_inner_width - marks_ob_width < texture_box.width) {
502 texture_box.width = ob_inner_width - marks_ob_width;
503 } 536 }
537
504 render_texture(output->wlr_output, output_damage, title_texture, 538 render_texture(output->wlr_output, output_damage, title_texture,
505 &texture_box, matrix, con->alpha); 539 &texture_box, matrix, con->alpha);
506 540
@@ -508,7 +542,7 @@ static void render_titlebar(struct sway_output *output,
508 memcpy(&color, colors->background, sizeof(float) * 4); 542 memcpy(&color, colors->background, sizeof(float) * 4);
509 premultiply_alpha(color, con->alpha); 543 premultiply_alpha(color, con->alpha);
510 box.x = texture_box.x + round(output_x * output_scale); 544 box.x = texture_box.x + round(output_x * output_scale);
511 box.y = round((y + TITLEBAR_BORDER_THICKNESS) * output_scale); 545 box.y = round((y + titlebar_border_thickness) * output_scale);
512 box.width = texture_box.width; 546 box.width = texture_box.width;
513 box.height = ob_padding_above; 547 box.height = ob_padding_above;
514 render_rect(output->wlr_output, output_damage, &box, color); 548 render_rect(output->wlr_output, output_damage, &box, color);
@@ -519,50 +553,78 @@ static void render_titlebar(struct sway_output *output,
519 render_rect(output->wlr_output, output_damage, &box, color); 553 render_rect(output->wlr_output, output_damage, &box, color);
520 } 554 }
521 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
522 // Filler between title and marks 576 // Filler between title and marks
523 box.width = 577 box.width = ob_right_x - ob_left_x - ob_left_width;
524 round(inner_width * output_scale) - title_ob_width - marks_ob_width;
525 if (box.width > 0) { 578 if (box.width > 0) {
526 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);
527 box.y = round(bg_y * output_scale); 580 box.y = round(bg_y * output_scale);
528 box.height = ob_bg_height; 581 box.height = ob_bg_height;
529 render_rect(output->wlr_output, output_damage, &box, color); 582 render_rect(output->wlr_output, output_damage, &box, color);
530 } 583 }
531 584
532 // Padding left of title 585 // Padding on left side
533 left_offset = (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS; 586 left_offset = (layout == L_TABBED) * titlebar_border_thickness;
534 box.x = x + left_offset; 587 box.x = x + left_offset;
535 box.y = y + TITLEBAR_BORDER_THICKNESS; 588 box.y = y + titlebar_border_thickness;
536 box.width = TITLEBAR_H_PADDING - left_offset; 589 box.width = titlebar_h_padding - left_offset;
537 box.height = (TITLEBAR_V_PADDING - TITLEBAR_BORDER_THICKNESS) * 2 + 590 box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 +
538 config->font_height; 591 config->font_height;
539 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 }
540 render_rect(output->wlr_output, output_damage, &box, color); 597 render_rect(output->wlr_output, output_damage, &box, color);
541 598
542 // Padding right of marks 599 // Padding on right side
543 right_offset = (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS; 600 right_offset = (layout == L_TABBED) * titlebar_border_thickness;
544 box.x = x + width - TITLEBAR_H_PADDING; 601 box.x = x + width - titlebar_h_padding;
545 box.y = y + TITLEBAR_BORDER_THICKNESS; 602 box.y = y + titlebar_border_thickness;
546 box.width = TITLEBAR_H_PADDING - right_offset; 603 box.width = titlebar_h_padding - right_offset;
547 box.height = (TITLEBAR_V_PADDING - TITLEBAR_BORDER_THICKNESS) * 2 + 604 box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 +
548 config->font_height; 605 config->font_height;
549 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 }
550 render_rect(output->wlr_output, output_damage, &box, color); 612 render_rect(output->wlr_output, output_damage, &box, color);
551 613
552 if (connects_sides) { 614 if (connects_sides) {
553 // Left pixel in line with bottom bar 615 // Left pixel in line with bottom bar
554 box.x = x; 616 box.x = x;
555 box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS; 617 box.y = y + container_titlebar_height() - titlebar_border_thickness;
556 box.width = state->border_thickness * state->border_left; 618 box.width = state->border_thickness * state->border_left;
557 box.height = TITLEBAR_BORDER_THICKNESS; 619 box.height = titlebar_border_thickness;
558 scale_box(&box, output_scale); 620 scale_box(&box, output_scale);
559 render_rect(output->wlr_output, output_damage, &box, color); 621 render_rect(output->wlr_output, output_damage, &box, color);
560 622
561 // Right pixel in line with bottom bar 623 // Right pixel in line with bottom bar
562 box.x = x + width - state->border_thickness * state->border_right; 624 box.x = x + width - state->border_thickness * state->border_right;
563 box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS; 625 box.y = y + container_titlebar_height() - titlebar_border_thickness;
564 box.width = state->border_thickness * state->border_right; 626 box.width = state->border_thickness * state->border_right;
565 box.height = TITLEBAR_BORDER_THICKNESS; 627 box.height = titlebar_border_thickness;
566 scale_box(&box, output_scale); 628 scale_box(&box, output_scale);
567 render_rect(output->wlr_output, output_damage, &box, color); 629 render_rect(output->wlr_output, output_damage, &box, color);
568 } 630 }
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index d89f64d8..14e25726 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include <math.h> 2#include <math.h>
3#ifdef __linux__ 3#ifdef __linux__
4#include <linux/input-event-codes.h> 4#include <linux/input-event-codes.h>
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index 68445d68..89146d5b 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include <ctype.h> 2#include <ctype.h>
3#include <float.h> 3#include <float.h>
4#include <limits.h> 4#include <limits.h>
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 663c5140..53fb2ed7 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -1,5 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#define _POSIX_C_SOURCE 199309L
3#include <assert.h> 2#include <assert.h>
4#include <errno.h> 3#include <errno.h>
5#ifdef __linux__ 4#ifdef __linux__
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
index 05e453ec..40fbd3e7 100644
--- a/sway/ipc-json.c
+++ b/sway/ipc-json.c
@@ -15,6 +15,9 @@
15#include <xkbcommon/xkbcommon.h> 15#include <xkbcommon/xkbcommon.h>
16#include "wlr-layer-shell-unstable-v1-protocol.h" 16#include "wlr-layer-shell-unstable-v1-protocol.h"
17 17
18static const int i3_output_id = INT32_MAX;
19static const int i3_scratch_id = INT32_MAX - 1;
20
18static const char *ipc_json_layout_description(enum sway_container_layout l) { 21static const char *ipc_json_layout_description(enum sway_container_layout l) {
19 switch (l) { 22 switch (l) {
20 case L_VERT: 23 case L_VERT:
@@ -32,15 +35,66 @@ static const char *ipc_json_layout_description(enum sway_container_layout l) {
32} 35}
33 36
34static const char *ipc_json_orientation_description(enum sway_container_layout l) { 37static const char *ipc_json_orientation_description(enum sway_container_layout l) {
35 if (l == L_VERT) { 38 switch (l) {
39 case L_VERT:
36 return "vertical"; 40 return "vertical";
41 case L_HORIZ:
42 return "horizontal";
43 default:
44 return "none";
37 } 45 }
46}
38 47
39 if (l == L_HORIZ) { 48static const char *ipc_json_border_description(enum sway_container_border border) {
40 return "horizontal"; 49 switch (border) {
50 case B_NONE:
51 return "none";
52 case B_PIXEL:
53 return "pixel";
54 case B_NORMAL:
55 return "normal";
56 case B_CSD:
57 return "csd";
41 } 58 }
59 return "unknown";
60}
42 61
43 return "none"; 62static const char *ipc_json_output_transform_description(enum wl_output_transform transform) {
63 switch (transform) {
64 case WL_OUTPUT_TRANSFORM_NORMAL:
65 return "normal";
66 case WL_OUTPUT_TRANSFORM_90:
67 return "90";
68 case WL_OUTPUT_TRANSFORM_180:
69 return "180";
70 case WL_OUTPUT_TRANSFORM_270:
71 return "270";
72 case WL_OUTPUT_TRANSFORM_FLIPPED:
73 return "flipped";
74 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
75 return "flipped-90";
76 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
77 return "flipped-180";
78 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
79 return "flipped-270";
80 }
81 return NULL;
82}
83
84static const char *ipc_json_device_type_description(struct sway_input_device *device) {
85 switch (device->wlr_device->type) {
86 case WLR_INPUT_DEVICE_POINTER:
87 return "pointer";
88 case WLR_INPUT_DEVICE_KEYBOARD:
89 return "keyboard";
90 case WLR_INPUT_DEVICE_TOUCH:
91 return "touch";
92 case WLR_INPUT_DEVICE_TABLET_TOOL:
93 return "tablet_tool";
94 case WLR_INPUT_DEVICE_TABLET_PAD:
95 return "tablet_pad";
96 }
97 return "unknown";
44} 98}
45 99
46json_object *ipc_json_get_version(void) { 100json_object *ipc_json_get_version(void) {
@@ -76,30 +130,43 @@ static json_object *ipc_json_create_empty_rect(void) {
76 return ipc_json_create_rect(&empty); 130 return ipc_json_create_rect(&empty);
77} 131}
78 132
79static void ipc_json_describe_root(struct sway_root *root, json_object *object) { 133static json_object *ipc_json_create_node(int id, char *name,
80 json_object_object_add(object, "type", json_object_new_string("root")); 134 bool focused, json_object *focus, struct wlr_box *box) {
135 json_object *object = json_object_new_object();
136
137 json_object_object_add(object, "id", json_object_new_int(id));
138 json_object_object_add(object, "name",
139 name ? json_object_new_string(name) : NULL);
140 json_object_object_add(object, "rect", ipc_json_create_rect(box));
141 json_object_object_add(object, "focused", json_object_new_boolean(focused));
142 json_object_object_add(object, "focus", focus);
143
144 // set default values to be compatible with i3
145 json_object_object_add(object, "border",
146 json_object_new_string(
147 ipc_json_border_description(B_NONE)));
148 json_object_object_add(object, "current_border_width",
149 json_object_new_int(0));
150 json_object_object_add(object, "layout",
151 json_object_new_string(
152 ipc_json_layout_description(L_HORIZ)));
153 json_object_object_add(object, "orientation",
154 json_object_new_string(
155 ipc_json_orientation_description(L_HORIZ)));
156 json_object_object_add(object, "percent", NULL);
157 json_object_object_add(object, "window_rect", ipc_json_create_empty_rect());
158 json_object_object_add(object, "deco_rect", ipc_json_create_empty_rect());
159 json_object_object_add(object, "geometry", ipc_json_create_empty_rect());
160 json_object_object_add(object, "window", NULL);
161 json_object_object_add(object, "urgent", json_object_new_boolean(false));
162 json_object_object_add(object, "floating_nodes", json_object_new_array());
163 json_object_object_add(object, "sticky", json_object_new_boolean(false));
164
165 return object;
81} 166}
82 167
83static const char *ipc_json_get_output_transform(enum wl_output_transform transform) { 168static void ipc_json_describe_root(struct sway_root *root, json_object *object) {
84 switch (transform) { 169 json_object_object_add(object, "type", json_object_new_string("root"));
85 case WL_OUTPUT_TRANSFORM_NORMAL:
86 return "normal";
87 case WL_OUTPUT_TRANSFORM_90:
88 return "90";
89 case WL_OUTPUT_TRANSFORM_180:
90 return "180";
91 case WL_OUTPUT_TRANSFORM_270:
92 return "270";
93 case WL_OUTPUT_TRANSFORM_FLIPPED:
94 return "flipped";
95 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
96 return "flipped-90";
97 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
98 return "flipped-180";
99 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
100 return "flipped-270";
101 }
102 return NULL;
103} 170}
104 171
105static void ipc_json_describe_output(struct sway_output *output, 172static void ipc_json_describe_output(struct sway_output *output,
@@ -110,7 +177,8 @@ static void ipc_json_describe_output(struct sway_output *output,
110 json_object_object_add(object, "primary", json_object_new_boolean(false)); 177 json_object_object_add(object, "primary", json_object_new_boolean(false));
111 json_object_object_add(object, "layout", json_object_new_string("output")); 178 json_object_object_add(object, "layout", json_object_new_string("output"));
112 json_object_object_add(object, "orientation", 179 json_object_object_add(object, "orientation",
113 json_object_new_string(ipc_json_orientation_description(L_NONE))); 180 json_object_new_string(
181 ipc_json_orientation_description(L_NONE)));
114 json_object_object_add(object, "make", 182 json_object_object_add(object, "make",
115 json_object_new_string(wlr_output->make)); 183 json_object_new_string(wlr_output->make));
116 json_object_object_add(object, "model", 184 json_object_object_add(object, "model",
@@ -121,7 +189,7 @@ static void ipc_json_describe_output(struct sway_output *output,
121 json_object_new_double(wlr_output->scale)); 189 json_object_new_double(wlr_output->scale));
122 json_object_object_add(object, "transform", 190 json_object_object_add(object, "transform",
123 json_object_new_string( 191 json_object_new_string(
124 ipc_json_get_output_transform(wlr_output->transform))); 192 ipc_json_output_transform_description(wlr_output->transform)));
125 193
126 struct sway_workspace *ws = output_get_active_workspace(output); 194 struct sway_workspace *ws = output_get_active_workspace(output);
127 json_object_object_add(object, "current_workspace", 195 json_object_object_add(object, "current_workspace",
@@ -187,6 +255,52 @@ json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
187 return object; 255 return object;
188} 256}
189 257
258static json_object *ipc_json_describe_scratchpad_output(void) {
259 struct wlr_box box;
260 root_get_box(root, &box);
261
262 // Create focus stack for __i3_scratch workspace
263 json_object *workspace_focus = json_object_new_array();
264 for (int i = root->scratchpad->length - 1; i >= 0; --i) {
265 struct sway_container *container = root->scratchpad->items[i];
266 json_object_array_add(workspace_focus,
267 json_object_new_int(container->node.id));
268 }
269
270 json_object *workspace = ipc_json_create_node(i3_scratch_id,
271 "__i3_scratch", false, workspace_focus, &box);
272 json_object_object_add(workspace, "type",
273 json_object_new_string("workspace"));
274
275 // List all hidden scratchpad containers as floating nodes
276 json_object *floating_array = json_object_new_array();
277 for (int i = 0; i < root->scratchpad->length; ++i) {
278 struct sway_container *container = root->scratchpad->items[i];
279 if (!container->workspace) {
280 json_object_array_add(floating_array,
281 ipc_json_describe_node_recursive(&container->node));
282 }
283 }
284 json_object_object_add(workspace, "floating_nodes", floating_array);
285
286 // Create focus stack for __i3 output
287 json_object *output_focus = json_object_new_array();
288 json_object_array_add(output_focus, json_object_new_int(i3_scratch_id));
289
290 json_object *output = ipc_json_create_node(i3_output_id,
291 "__i3", false, output_focus, &box);
292 json_object_object_add(output, "type",
293 json_object_new_string("output"));
294 json_object_object_add(output, "layout",
295 json_object_new_string("output"));
296
297 json_object *nodes = json_object_new_array();
298 json_object_array_add(nodes, workspace);
299 json_object_object_add(output, "nodes", nodes);
300
301 return output;
302}
303
190static void ipc_json_describe_workspace(struct sway_workspace *workspace, 304static void ipc_json_describe_workspace(struct sway_workspace *workspace,
191 json_object *object) { 305 json_object *object) {
192 int num = isdigit(workspace->name[0]) ? atoi(workspace->name) : -1; 306 int num = isdigit(workspace->name[0]) ? atoi(workspace->name) : -1;
@@ -200,11 +314,12 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace,
200 json_object_object_add(object, "representation", workspace->representation ? 314 json_object_object_add(object, "representation", workspace->representation ?
201 json_object_new_string(workspace->representation) : NULL); 315 json_object_new_string(workspace->representation) : NULL);
202 316
203 const char *layout = ipc_json_layout_description(workspace->layout); 317 json_object_object_add(object, "layout",
204 json_object_object_add(object, "layout", json_object_new_string(layout)); 318 json_object_new_string(
205 319 ipc_json_layout_description(workspace->layout)));
206 const char *orientation = ipc_json_orientation_description(workspace->layout); 320 json_object_object_add(object, "orientation",
207 json_object_object_add(object, "orientation", json_object_new_string(orientation)); 321 json_object_new_string(
322 ipc_json_orientation_description(workspace->layout)));
208 323
209 // Floating 324 // Floating
210 json_object *floating_array = json_object_new_array(); 325 json_object *floating_array = json_object_new_array();
@@ -216,20 +331,6 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace,
216 json_object_object_add(object, "floating_nodes", floating_array); 331 json_object_object_add(object, "floating_nodes", floating_array);
217} 332}
218 333
219static const char *describe_container_border(enum sway_container_border border) {
220 switch (border) {
221 case B_NONE:
222 return "none";
223 case B_PIXEL:
224 return "pixel";
225 case B_NORMAL:
226 return "normal";
227 case B_CSD:
228 return "csd";
229 }
230 return "unknown";
231}
232
233static void ipc_json_describe_view(struct sway_container *c, json_object *object) { 334static void ipc_json_describe_view(struct sway_container *c, json_object *object) {
234 json_object_object_add(object, "pid", json_object_new_int(c->view->pid)); 335 json_object_object_add(object, "pid", json_object_new_int(c->view->pid));
235 336
@@ -307,10 +408,12 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o
307 json_object_new_string(container_is_floating(c) ? "floating_con" : "con")); 408 json_object_new_string(container_is_floating(c) ? "floating_con" : "con"));
308 409
309 json_object_object_add(object, "layout", 410 json_object_object_add(object, "layout",
310 json_object_new_string(ipc_json_layout_description(c->layout))); 411 json_object_new_string(
412 ipc_json_layout_description(c->layout)));
311 413
312 json_object_object_add(object, "orientation", 414 json_object_object_add(object, "orientation",
313 json_object_new_string(ipc_json_orientation_description(c->layout))); 415 json_object_new_string(
416 ipc_json_orientation_description(c->layout)));
314 417
315 bool urgent = c->view ? 418 bool urgent = c->view ?
316 view_is_urgent(c->view) : container_has_urgent_child(c); 419 view_is_urgent(c->view) : container_has_urgent_child(c);
@@ -331,7 +434,8 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o
331 } 434 }
332 435
333 json_object_object_add(object, "border", 436 json_object_object_add(object, "border",
334 json_object_new_string(describe_container_border(c->current.border))); 437 json_object_new_string(
438 ipc_json_border_description(c->current.border)));
335 json_object_object_add(object, "current_border_width", 439 json_object_object_add(object, "current_border_width",
336 json_object_new_int(c->current.border_thickness)); 440 json_object_new_int(c->current.border_thickness));
337 json_object_object_add(object, "floating_nodes", json_object_new_array()); 441 json_object_object_add(object, "floating_nodes", json_object_new_array());
@@ -372,17 +476,10 @@ static void focus_inactive_children_iterator(struct sway_node *node,
372json_object *ipc_json_describe_node(struct sway_node *node) { 476json_object *ipc_json_describe_node(struct sway_node *node) {
373 struct sway_seat *seat = input_manager_get_default_seat(); 477 struct sway_seat *seat = input_manager_get_default_seat();
374 bool focused = seat_get_focus(seat) == node; 478 bool focused = seat_get_focus(seat) == node;
375
376 json_object *object = json_object_new_object();
377 char *name = node_get_name(node); 479 char *name = node_get_name(node);
378 480
379 struct wlr_box box; 481 struct wlr_box box;
380 node_get_box(node, &box); 482 node_get_box(node, &box);
381 json_object_object_add(object, "id", json_object_new_int((int)node->id));
382 json_object_object_add(object, "name",
383 name ? json_object_new_string(name) : NULL);
384 json_object_object_add(object, "rect", ipc_json_create_rect(&box));
385 json_object_object_add(object, "focused", json_object_new_boolean(focused));
386 483
387 json_object *focus = json_object_new_array(); 484 json_object *focus = json_object_new_array();
388 struct focus_inactive_data data = { 485 struct focus_inactive_data data = {
@@ -390,24 +487,9 @@ json_object *ipc_json_describe_node(struct sway_node *node) {
390 .object = focus, 487 .object = focus,
391 }; 488 };
392 seat_for_each_node(seat, focus_inactive_children_iterator, &data); 489 seat_for_each_node(seat, focus_inactive_children_iterator, &data);
393 json_object_object_add(object, "focus", focus);
394 490
395 // set default values to be compatible with i3 491 json_object *object = ipc_json_create_node(
396 json_object_object_add(object, "border", 492 (int)node->id, name, focused, focus, &box);
397 json_object_new_string(describe_container_border(B_NONE)));
398 json_object_object_add(object, "current_border_width", json_object_new_int(0));
399 json_object_object_add(object, "layout",
400 json_object_new_string(ipc_json_layout_description(L_HORIZ)));
401 json_object_object_add(object, "orientation",
402 json_object_new_string(ipc_json_orientation_description(L_HORIZ)));
403 json_object_object_add(object, "percent", NULL);
404 json_object_object_add(object, "window_rect", ipc_json_create_empty_rect());
405 json_object_object_add(object, "deco_rect", ipc_json_create_empty_rect());
406 json_object_object_add(object, "geometry", ipc_json_create_empty_rect());
407 json_object_object_add(object, "window", NULL);
408 json_object_object_add(object, "urgent", json_object_new_boolean(false));
409 json_object_object_add(object, "floating_nodes", json_object_new_array());
410 json_object_object_add(object, "sticky", json_object_new_boolean(false));
411 493
412 switch (node->type) { 494 switch (node->type) {
413 case N_ROOT: 495 case N_ROOT:
@@ -434,6 +516,8 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) {
434 json_object *children = json_object_new_array(); 516 json_object *children = json_object_new_array();
435 switch (node->type) { 517 switch (node->type) {
436 case N_ROOT: 518 case N_ROOT:
519 json_object_array_add(children,
520 ipc_json_describe_scratchpad_output());
437 for (i = 0; i < root->outputs->length; ++i) { 521 for (i = 0; i < root->outputs->length; ++i) {
438 struct sway_output *output = root->outputs->items[i]; 522 struct sway_output *output = root->outputs->items[i];
439 json_object_array_add(children, 523 json_object_array_add(children,
@@ -470,22 +554,6 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) {
470 return object; 554 return object;
471} 555}
472 556
473static const char *describe_device_type(struct sway_input_device *device) {
474 switch (device->wlr_device->type) {
475 case WLR_INPUT_DEVICE_POINTER:
476 return "pointer";
477 case WLR_INPUT_DEVICE_KEYBOARD:
478 return "keyboard";
479 case WLR_INPUT_DEVICE_TOUCH:
480 return "touch";
481 case WLR_INPUT_DEVICE_TABLET_TOOL:
482 return "tablet_tool";
483 case WLR_INPUT_DEVICE_TABLET_PAD:
484 return "tablet_pad";
485 }
486 return "unknown";
487}
488
489json_object *ipc_json_describe_input(struct sway_input_device *device) { 557json_object *ipc_json_describe_input(struct sway_input_device *device) {
490 if (!(sway_assert(device, "Device must not be null"))) { 558 if (!(sway_assert(device, "Device must not be null"))) {
491 return NULL; 559 return NULL;
@@ -502,7 +570,8 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
502 json_object_object_add(object, "product", 570 json_object_object_add(object, "product",
503 json_object_new_int(device->wlr_device->product)); 571 json_object_new_int(device->wlr_device->product));
504 json_object_object_add(object, "type", 572 json_object_object_add(object, "type",
505 json_object_new_string(describe_device_type(device))); 573 json_object_new_string(
574 ipc_json_device_type_description(device)));
506 575
507 if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) { 576 if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) {
508 struct wlr_keyboard *keyboard = device->wlr_device->keyboard; 577 struct wlr_keyboard *keyboard = device->wlr_device->keyboard;
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index 6466d263..aa0f0fad 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -619,8 +619,19 @@ void ipc_client_handle_command(struct ipc_client *client) {
619 json_object *outputs = json_object_new_array(); 619 json_object *outputs = json_object_new_array();
620 for (int i = 0; i < root->outputs->length; ++i) { 620 for (int i = 0; i < root->outputs->length; ++i) {
621 struct sway_output *output = root->outputs->items[i]; 621 struct sway_output *output = root->outputs->items[i];
622 json_object_array_add(outputs, 622 json_object *output_json = ipc_json_describe_node(&output->node);
623 ipc_json_describe_node(&output->node)); 623
624 // override the default focused indicator because it's set
625 // differently for the get_outputs reply
626 struct sway_seat *seat = input_manager_get_default_seat();
627 struct sway_workspace *focused_ws =
628 seat_get_focused_workspace(seat);
629 bool focused = focused_ws && output == focused_ws->output;
630 json_object_object_del(output_json, "focused");
631 json_object_object_add(output_json, "focused",
632 json_object_new_boolean(focused));
633
634 json_object_array_add(outputs, output_json);
624 } 635 }
625 struct sway_output *output; 636 struct sway_output *output;
626 wl_list_for_each(output, &root->all_outputs, link) { 637 wl_list_for_each(output, &root->all_outputs, link) {
diff --git a/sway/main.c b/sway/main.c
index 920cea11..a21970e2 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -1,5 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#define _POSIX_C_SOURCE 200112L
3#include <getopt.h> 2#include <getopt.h>
4#include <pango/pangocairo.h> 3#include <pango/pangocairo.h>
5#include <signal.h> 4#include <signal.h>
diff --git a/sway/meson.build b/sway/meson.build
index 14822dbd..75131891 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -88,7 +88,10 @@ 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',
93 'commands/titlebar_border_thickness.c',
94 'commands/titlebar_padding.c',
92 'commands/unmark.c', 95 'commands/unmark.c',
93 'commands/urgent.c', 96 'commands/urgent.c',
94 'commands/workspace.c', 97 'commands/workspace.c',
diff --git a/sway/security.c b/sway/security.c
index cc0d3f66..6a00229e 100644
--- a/sway/security.c
+++ b/sway/security.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#include <stdlib.h> 2#include <stdlib.h>
3#include <string.h> 3#include <string.h>
4#include "sway/security.h" 4#include "sway/security.h"
diff --git a/sway/sway.5.scd b/sway/sway.5.scd
index 1a11015f..4edd16bf 100644
--- a/sway/sway.5.scd
+++ b/sway/sway.5.scd
@@ -436,6 +436,16 @@ The default colors are:
436*font* <font> 436*font* <font>
437 Sets font for use in title bars in Pango format. 437 Sets font for use in title bars in Pango format.
438 438
439*titlebar\_border\_thickness* <thickness>
440 Thickness of the titlebar border in pixels
441
442*titlebar\_padding* <horizontal> [<vertical>]
443 Padding of the text in the titlebar. _horizontal_ value affects horizontal
444 padding of the text while _vertical_ value affects vertical padding (space
445 above and below text). Padding includes titlebar borders so their value
446 should be greater than titlebar\_border\_thickness. If _vertical_ value is
447 not specified it is set to the _horizontal_ value.
448
439*for\_window* <criteria> <command> 449*for\_window* <criteria> <command>
440 Whenever a window that matches _criteria_ appears, run list of commands. 450 Whenever a window that matches _criteria_ appears, run list of commands.
441 See *CRITERIA* for more details. 451 See *CRITERIA* for more details.
@@ -545,6 +555,11 @@ The default colors are:
545 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
546 (completely opaque). 556 (completely opaque).
547 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
548*unmark* [<identifier>] 563*unmark* [<identifier>]
549 *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
550 window. If _identifier_ is omitted, all marks are removed. 565 window. If _identifier_ is omitted, all marks are removed.
diff --git a/sway/tree/container.c b/sway/tree/container.c
index cf6f5b54..91e8dd7f 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -594,7 +594,7 @@ void container_update_representation(struct sway_container *con) {
594} 594}
595 595
596size_t container_titlebar_height(void) { 596size_t container_titlebar_height(void) {
597 return config->font_height + TITLEBAR_V_PADDING * 2; 597 return config->font_height + config->titlebar_v_padding * 2;
598} 598}
599 599
600void container_init_floating(struct sway_container *con) { 600void container_init_floating(struct sway_container *con) {
diff --git a/sway/tree/root.c b/sway/tree/root.c
index 544d666a..9f6bf607 100644
--- a/sway/tree/root.c
+++ b/sway/tree/root.c
@@ -5,6 +5,7 @@
5#include <wlr/types/wlr_output_layout.h> 5#include <wlr/types/wlr_output_layout.h>
6#include "sway/desktop/transaction.h" 6#include "sway/desktop/transaction.h"
7#include "sway/input/seat.h" 7#include "sway/input/seat.h"
8#include "sway/ipc-server.h"
8#include "sway/output.h" 9#include "sway/output.h"
9#include "sway/tree/arrange.h" 10#include "sway/tree/arrange.h"
10#include "sway/tree/container.h" 11#include "sway/tree/container.h"
@@ -75,6 +76,8 @@ void root_scratchpad_add_container(struct sway_container *con) {
75 arrange_workspace(workspace); 76 arrange_workspace(workspace);
76 seat_set_focus(seat, seat_get_focus_inactive(seat, &workspace->node)); 77 seat_set_focus(seat, seat_get_focus_inactive(seat, &workspace->node));
77 } 78 }
79
80 ipc_event_window(con, "move");
78} 81}
79 82
80void root_scratchpad_remove_container(struct sway_container *con) { 83void root_scratchpad_remove_container(struct sway_container *con) {
@@ -85,45 +88,51 @@ void root_scratchpad_remove_container(struct sway_container *con) {
85 int index = list_find(root->scratchpad, con); 88 int index = list_find(root->scratchpad, con);
86 if (index != -1) { 89 if (index != -1) {
87 list_del(root->scratchpad, index); 90 list_del(root->scratchpad, index);
91 ipc_event_window(con, "move");
88 } 92 }
89} 93}
90 94
91void root_scratchpad_show(struct sway_container *con) { 95void root_scratchpad_show(struct sway_container *con) {
92 struct sway_seat *seat = input_manager_current_seat(); 96 struct sway_seat *seat = input_manager_current_seat();
93 struct sway_workspace *ws = seat_get_focused_workspace(seat); 97 struct sway_workspace *new_ws = seat_get_focused_workspace(seat);
98 struct sway_workspace *old_ws = con->workspace;
94 99
95 // If the current con or any of its parents are in fullscreen mode, we 100 // If the current con or any of its parents are in fullscreen mode, we
96 // first need to disable it before showing the scratchpad con. 101 // first need to disable it before showing the scratchpad con.
97 if (ws->fullscreen) { 102 if (new_ws->fullscreen) {
98 container_set_fullscreen(ws->fullscreen, false); 103 container_set_fullscreen(new_ws->fullscreen, false);
99 } 104 }
100 105
101 // Show the container 106 // Show the container
102 if (con->workspace) { 107 if (old_ws) {
103 container_detach(con); 108 container_detach(con);
104 } 109 }
105 workspace_add_floating(ws, con); 110 workspace_add_floating(new_ws, con);
106 111
107 // Make sure the container's center point overlaps this workspace 112 // Make sure the container's center point overlaps this workspace
108 double center_lx = con->x + con->width / 2; 113 double center_lx = con->x + con->width / 2;
109 double center_ly = con->y + con->height / 2; 114 double center_ly = con->y + con->height / 2;
110 115
111 struct wlr_box workspace_box; 116 struct wlr_box workspace_box;
112 workspace_get_box(ws, &workspace_box); 117 workspace_get_box(new_ws, &workspace_box);
113 if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) { 118 if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) {
114 // Maybe resize it 119 // Maybe resize it
115 if (con->width > ws->width || con->height > ws->height) { 120 if (con->width > new_ws->width || con->height > new_ws->height) {
116 container_init_floating(con); 121 container_init_floating(con);
117 } 122 }
118 123
119 // Center it 124 // Center it
120 double new_lx = ws->x + (ws->width - con->width) / 2; 125 double new_lx = new_ws->x + (new_ws->width - con->width) / 2;
121 double new_ly = ws->y + (ws->height - con->height) / 2; 126 double new_ly = new_ws->y + (new_ws->height - con->height) / 2;
122 container_floating_move_to(con, new_lx, new_ly); 127 container_floating_move_to(con, new_lx, new_ly);
123 } 128 }
124 129
125 arrange_workspace(ws); 130 arrange_workspace(new_ws);
126 seat_set_focus(seat, seat_get_focus_inactive(seat, &con->node)); 131 seat_set_focus(seat, seat_get_focus_inactive(seat, &con->node));
132
133 if (new_ws != old_ws) {
134 ipc_event_window(con, "move");
135 }
127} 136}
128 137
129void root_scratchpad_hide(struct sway_container *con) { 138void root_scratchpad_hide(struct sway_container *con) {
@@ -137,6 +146,8 @@ void root_scratchpad_hide(struct sway_container *con) {
137 seat_set_focus(seat, seat_get_focus_inactive(seat, &ws->node)); 146 seat_set_focus(seat, seat_get_focus_inactive(seat, &ws->node));
138 } 147 }
139 list_move_to_end(root->scratchpad, con); 148 list_move_to_end(root->scratchpad, con);
149
150 ipc_event_window(con, "move");
140} 151}
141 152
142struct pid_workspace { 153struct pid_workspace {
diff --git a/sway/tree/view.c b/sway/tree/view.c
index d7110619..febba3b9 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -824,12 +824,29 @@ struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) {
824 return NULL; 824 return NULL;
825} 825}
826 826
827static char *escape_pango_markup(const char *buffer) {
828 size_t length = escape_markup_text(buffer, NULL);
829 char *escaped_title = calloc(length + 1, sizeof(char));
830 escape_markup_text(buffer, escaped_title);
831 return escaped_title;
832}
833
827static size_t append_prop(char *buffer, const char *value) { 834static size_t append_prop(char *buffer, const char *value) {
828 if (!value) { 835 if (!value) {
829 return 0; 836 return 0;
830 } 837 }
831 lenient_strcat(buffer, value); 838 // If using pango_markup in font, we need to escape all markup chars
832 return strlen(value); 839 // from values to make sure tags are not inserted by clients
840 if (config->pango_markup) {
841 char *escaped_value = escape_pango_markup(value);
842 lenient_strcat(buffer, escaped_value);
843 size_t len = strlen(escaped_value);
844 free(escaped_value);
845 return len;
846 } else {
847 lenient_strcat(buffer, value);
848 return strlen(value);
849 }
833} 850}
834 851
835/** 852/**
@@ -838,11 +855,7 @@ static size_t append_prop(char *buffer, const char *value) {
838 */ 855 */
839static size_t parse_title_format(struct sway_view *view, char *buffer) { 856static size_t parse_title_format(struct sway_view *view, char *buffer) {
840 if (!view->title_format || strcmp(view->title_format, "%title") == 0) { 857 if (!view->title_format || strcmp(view->title_format, "%title") == 0) {
841 const char *title = view_get_title(view); 858 return append_prop(buffer, view_get_title(view));
842 if (buffer && title) {
843 strcpy(buffer, title);
844 }
845 return title ? strlen(title) : 0;
846 } 859 }
847 860
848 size_t len = 0; 861 size_t len = 0;
@@ -882,14 +895,6 @@ static size_t parse_title_format(struct sway_view *view, char *buffer) {
882 return len; 895 return len;
883} 896}
884 897
885static char *escape_title(char *buffer) {
886 size_t length = escape_markup_text(buffer, NULL);
887 char *escaped_title = calloc(length + 1, sizeof(char));
888 escape_markup_text(buffer, escaped_title);
889 free(buffer);
890 return escaped_title;
891}
892
893void view_update_title(struct sway_view *view, bool force) { 898void view_update_title(struct sway_view *view, bool force) {
894 const char *title = view_get_title(view); 899 const char *title = view_get_title(view);
895 900
@@ -912,10 +917,6 @@ void view_update_title(struct sway_view *view, bool force) {
912 return; 917 return;
913 } 918 }
914 parse_title_format(view, buffer); 919 parse_title_format(view, buffer);
915 // now we have the title, but needs to be escaped when using pango markup
916 if (config->pango_markup) {
917 buffer = escape_title(buffer);
918 }
919 920
920 view->container->title = strdup(title); 921 view->container->title = strdup(title);
921 view->container->formatted_title = buffer; 922 view->container->formatted_title = buffer;
diff --git a/swaybar/bar.c b/swaybar/bar.c
index 2178f542..47c89a39 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <assert.h> 2#include <assert.h>
3#include <errno.h> 3#include <errno.h>
4#include <fcntl.h> 4#include <fcntl.h>
diff --git a/swaybar/config.c b/swaybar/config.c
index 0ab346b1..16febb2e 100644
--- a/swaybar/config.c
+++ b/swaybar/config.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <stdlib.h> 2#include <stdlib.h>
3#include <string.h> 3#include <string.h>
4#include <wlr/util/log.h> 4#include <wlr/util/log.h>
diff --git a/swaybar/main.c b/swaybar/main.c
index 2672abef..06238c62 100644
--- a/swaybar/main.c
+++ b/swaybar/main.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <stdio.h> 2#include <stdio.h>
3#include <stdlib.h> 3#include <stdlib.h>
4#include <string.h> 4#include <string.h>
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) {
diff --git a/swayidle/swayidle.1.scd b/swayidle/swayidle.1.scd
index 3083163f..0e3b5c3c 100644
--- a/swayidle/swayidle.1.scd
+++ b/swayidle/swayidle.1.scd
@@ -49,7 +49,7 @@ swayidle \
49``` 49```
50 50
51This will lock your screen after 300 seconds of inactivity, then turn off your 51This will lock your screen after 300 seconds of inactivity, then turn off your
52displays after another 600 seconds, and turn your screens back on when resumed. 52displays after another 300 seconds, and turn your screens back on when resumed.
53It will also lock your screen before your computer goes to sleep. 53It will also lock your screen before your computer goes to sleep.
54 54
55# AUTHORS 55# AUTHORS
diff --git a/swaylock/main.c b/swaylock/main.c
index 9b74b671..50f145e3 100644
--- a/swaylock/main.c
+++ b/swaylock/main.c
@@ -1,5 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#define _POSIX_C_SOURCE 200112L
3#include <assert.h> 2#include <assert.h>
4#include <ctype.h> 3#include <ctype.h>
5#include <errno.h> 4#include <errno.h>
diff --git a/swaylock/pam.c b/swaylock/pam.c
index cac95a85..b90d9e87 100644
--- a/swaylock/pam.c
+++ b/swaylock/pam.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <pwd.h> 2#include <pwd.h>
3#include <security/pam_appl.h> 3#include <security/pam_appl.h>
4#include <stdbool.h> 4#include <stdbool.h>
diff --git a/swaylock/password.c b/swaylock/password.c
index 6138e1fe..db8ecaeb 100644
--- a/swaylock/password.c
+++ b/swaylock/password.c
@@ -1,4 +1,3 @@
1#define _XOPEN_SOURCE 500
2#include <assert.h> 1#include <assert.h>
3#include <errno.h> 2#include <errno.h>
4#include <pwd.h> 3#include <pwd.h>
diff --git a/swaylock/render.c b/swaylock/render.c
index fa8832bd..cbd5d01d 100644
--- a/swaylock/render.c
+++ b/swaylock/render.c
@@ -1,4 +1,3 @@
1#define _POSIX_C_SOURCE 199506L
2#include <math.h> 1#include <math.h>
3#include <stdlib.h> 2#include <stdlib.h>
4#include <wayland-client.h> 3#include <wayland-client.h>
diff --git a/swaylock/shadow.c b/swaylock/shadow.c
index f928eaa3..b7b10a67 100644
--- a/swaylock/shadow.c
+++ b/swaylock/shadow.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 1#define _XOPEN_SOURCE // for crypt
2#include <pwd.h> 2#include <pwd.h>
3#include <shadow.h> 3#include <shadow.h>
4#include <stdbool.h> 4#include <stdbool.h>
diff --git a/swaymsg/main.c b/swaymsg/main.c
index 243b5fdc..e640cadf 100644
--- a/swaymsg/main.c
+++ b/swaymsg/main.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <stdio.h> 2#include <stdio.h>
3#include <stdlib.h> 3#include <stdlib.h>
4#include <string.h> 4#include <string.h>
diff --git a/swaynag/config.c b/swaynag/config.c
index cd34dcc2..63808ce4 100644
--- a/swaynag/config.c
+++ b/swaynag/config.c
@@ -1,5 +1,4 @@
1#define _XOPEN_SOURCE 700 1#define _POSIX_C_SOURCE 200809L
2#define _POSIX_C_SOURCE 200112L
3#include <getopt.h> 2#include <getopt.h>
4#include <stdlib.h> 3#include <stdlib.h>
5#include <wordexp.h> 4#include <wordexp.h>
@@ -398,4 +397,3 @@ int swaynag_load_config(char *path, struct swaynag *swaynag, list_t *types) {
398 fclose(config); 397 fclose(config);
399 return 0; 398 return 0;
400} 399}
401
diff --git a/swaynag/main.c b/swaynag/main.c
index bae3c0e2..9f00ac7e 100644
--- a/swaynag/main.c
+++ b/swaynag/main.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <stdlib.h> 2#include <stdlib.h>
3#include <signal.h> 3#include <signal.h>
4#include "log.h" 4#include "log.h"
@@ -130,4 +130,3 @@ cleanup:
130 swaynag_destroy(&swaynag); 130 swaynag_destroy(&swaynag);
131 return exit_code; 131 return exit_code;
132} 132}
133
diff --git a/swaynag/swaynag.c b/swaynag/swaynag.c
index 06185f20..74e127b6 100644
--- a/swaynag/swaynag.c
+++ b/swaynag/swaynag.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <stdlib.h> 2#include <stdlib.h>
3#include <assert.h> 3#include <assert.h>
4#include <sys/stat.h> 4#include <sys/stat.h>
diff --git a/swaynag/types.c b/swaynag/types.c
index 1e0a138b..129644b7 100644
--- a/swaynag/types.c
+++ b/swaynag/types.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <getopt.h> 2#include <getopt.h>
3#include <stdbool.h> 3#include <stdbool.h>
4#include <stdlib.h> 4#include <stdlib.h>