diff options
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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include <stdlib.h> #include <stdio.h> #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; sway_cmd cmd_swaynag_command; sway_cmd cmd_swap; sway_cmd cmd_tiling_drag; +sway_cmd cmd_title_align; sway_cmd cmd_title_format; +sway_cmd cmd_titlebar_border_thickness; +sway_cmd cmd_titlebar_padding; sway_cmd cmd_unmark; sway_cmd cmd_urgent; sway_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 { WARP_CONTAINER }; +enum alignment { + ALIGN_LEFT, + ALIGN_CENTER, + ALIGN_RIGHT +}; + /** * The configuration struct. The result of loading a config file. */ @@ -391,6 +397,9 @@ struct sway_config { size_t font_height; size_t font_baseline; bool pango_markup; + int titlebar_border_thickness; + int titlebar_h_padding; + int titlebar_v_padding; size_t urgent_timeout; enum sway_fowa focus_on_window_activation; enum sway_popup_during_fullscreen popup_during_fullscreen; @@ -406,6 +415,7 @@ struct sway_config { bool validating; bool auto_back_and_forth; bool show_marks; + enum alignment title_align; bool tiling_drag; 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 @@ struct sway_view; struct sway_seat; -#define TITLEBAR_BORDER_THICKNESS 1 - -// Padding includes titlebar border -#define TITLEBAR_H_PADDING 3 -#define TITLEBAR_V_PADDING 4 - enum sway_container_layout { L_NONE, 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() endforeach endif -# If prefix is '/usr', sysconfdir will be explicitly set to '/etc' by Meson to -# enforce FHS compliance, so we should look for configs there as well. -if prefix == '/usr' - add_project_arguments('-DSYSCONFDIR="/@0@"'.format(sysconfdir), language : 'c') -else - add_project_arguments('-DSYSCONFDIR="/@0@/@1@"'.format(prefix, sysconfdir), language : 'c') -endif +add_project_arguments('-DSYSCONFDIR="/@0@"'.format(join_paths(prefix, sysconfdir)), language : 'c') version = get_option('sway-version') if version != '' @@ -159,14 +153,7 @@ subdir('swaylock') config = configuration_data() config.set('datadir', join_paths(prefix, datadir)) config.set('prefix', prefix) - -# If prefix is '/usr', sysconfdir will be explicitly set to '/etc' by Meson to -# enforce FHS compliance, so we should look for configs there as well. -if prefix == '/usr' - config.set('sysconfdir', sysconfdir) -else - config.set('sysconfdir', join_paths(prefix, sysconfdir)) -endif +config.set('sysconfdir', join_paths(prefix, sysconfdir)) configure_file( 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[] = { { "smart_borders", cmd_smart_borders }, { "smart_gaps", cmd_smart_gaps }, { "tiling_drag", cmd_tiling_drag }, + { "title_align", cmd_title_align }, + { "titlebar_border_thickness", cmd_titlebar_border_thickness }, + { "titlebar_padding", cmd_titlebar_padding }, { "workspace", cmd_workspace }, { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, }; 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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include <stdio.h> #include <string.h> #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 @@ -#define _XOPEN_SOURCE 500 #include <stdlib.h> #include <string.h> #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <string.h> #include <strings.h> #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 @@ -#define _XOPEN_SOURCE 500 #include <string.h> #include "sway/commands.h" 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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <string.h> #include "sway/commands.h" #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <string.h> #include <strings.h> #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <stdbool.h> #include <string.h> #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <string.h> #include "sway/commands.h" #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 @@ -#define _XOPEN_SOURCE 500 #include <string.h> #include "sway/commands.h" 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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #ifdef __linux__ #include <linux/input-event-codes.h> #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <stdlib.h> #include <stdint.h> #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 @@ -#define _XOPEN_SOURCE 500 #include <string.h> #include "sway/commands.h" #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include "sway/config.h" #include "sway/commands.h" #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include "sway/config.h" #include "sway/commands.h" #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include "sway/config.h" #include "sway/commands.h" #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include "sway/config.h" #include "sway/commands.h" #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include "sway/config.h" #include "sway/commands.h" #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <stdbool.h> #include <string.h> #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <ctype.h> #include <stdbool.h> #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 @@ -#define _XOPEN_SOURCE 500 #include <string.h> #include "sway/commands.h" #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <string.h> #include "sway/commands.h" #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 @@ -#define _XOPEN_SOURCE 500 #include <ctype.h> #include <string.h> #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, calculate_constraints(&min_width, &max_width, &min_height, &max_height); if (width->amount) { - if (width->unit == RESIZE_UNIT_PPT || - width->unit == RESIZE_UNIT_DEFAULT) { + switch (width->unit) { + case RESIZE_UNIT_PPT: // Convert to px width->amount = con->workspace->width * width->amount / 100; width->unit = RESIZE_UNIT_PX; - } - if (width->unit == RESIZE_UNIT_PX) { + // Falls through + case RESIZE_UNIT_PX: + case RESIZE_UNIT_DEFAULT: width->amount = fmax(min_width, fmin(width->amount, max_width)); grow_width = width->amount - con->width; - con->x -= grow_width / 2; con->width = width->amount; + break; + case RESIZE_UNIT_INVALID: + sway_assert(false, "invalid width unit"); + break; } } if (height->amount) { - if (height->unit == RESIZE_UNIT_PPT || - height->unit == RESIZE_UNIT_DEFAULT) { + switch (height->unit) { + case RESIZE_UNIT_PPT: // Convert to px height->amount = con->workspace->height * height->amount / 100; height->unit = RESIZE_UNIT_PX; - } - if (height->unit == RESIZE_UNIT_PX) { + // Falls through + case RESIZE_UNIT_PX: + case RESIZE_UNIT_DEFAULT: height->amount = fmax(min_height, fmin(height->amount, max_height)); grow_height = height->amount - con->height; - con->y -= grow_height / 2; con->height = height->amount; + break; + case RESIZE_UNIT_INVALID: + sway_assert(false, "invalid height unit"); + break; } } 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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include <string.h> #include <strings.h> #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #ifdef __linux__ #include <linux/input-event-codes.h> #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include <stdio.h> #include <string.h> #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 @@ +#include "sway/commands.h" +#include "sway/config.h" +#include "sway/output.h" +#include "sway/tree/container.h" +#include "sway/tree/root.h" + +struct cmd_results *cmd_title_align(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "title_align", EXPECTED_AT_LEAST, 1))) { + return error; + } + + if (strcmp(argv[0], "left") == 0) { + config->title_align = ALIGN_LEFT; + } else if (strcmp(argv[0], "center") == 0) { + config->title_align = ALIGN_CENTER; + } else if (strcmp(argv[0], "right") == 0) { + config->title_align = ALIGN_RIGHT; + } else { + return cmd_results_new(CMD_INVALID, "title_align", + "Expected 'title_align left|center|right'"); + } + + for (int i = 0; i < root->outputs->length; ++i) { + struct sway_output *output = root->outputs->items[i]; + output_damage_whole(output); + } + + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} 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 @@ +#include <string.h> +#include "sway/commands.h" +#include "sway/config.h" +#include "sway/output.h" +#include "sway/tree/arrange.h" +#include "log.h" + +struct cmd_results *cmd_titlebar_border_thickness(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "titlebar_border_thickness", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + char *inv; + int value = strtol(argv[0], &inv, 10); + if (*inv != '\0' || value < 0 || value > config->titlebar_v_padding) { + return cmd_results_new(CMD_FAILURE, "titlebar_border_thickness", + "Invalid size specified"); + } + + config->titlebar_border_thickness = value; + + for (int i = 0; i < root->outputs->length; ++i) { + struct sway_output *output = root->outputs->items[i]; + arrange_workspace(output_get_active_workspace(output)); + output_damage_whole(output); + } + + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} 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 @@ +#include <string.h> +#include "sway/commands.h" +#include "sway/config.h" +#include "sway/output.h" +#include "sway/tree/arrange.h" +#include "log.h" + +struct cmd_results *cmd_titlebar_padding(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "titlebar_padding", EXPECTED_AT_LEAST, 1))) { + return error; + } + + char *inv; + int h_value = strtol(argv[0], &inv, 10); + if (*inv != '\0' || h_value < 0 || h_value < config->titlebar_border_thickness) { + return cmd_results_new(CMD_FAILURE, "titlebar_padding", + "Invalid size specified"); + } + + int v_value; + if (argc == 1) { + v_value = h_value; + } else { + v_value = strtol(argv[1], &inv, 10); + if (*inv != '\0' || v_value < 0 || v_value < config->titlebar_border_thickness) { + return cmd_results_new(CMD_FAILURE, "titlebar_padding", + "Invalid size specified"); + } + } + + config->titlebar_v_padding = v_value; + config->titlebar_h_padding = h_value; + + for (int i = 0; i < root->outputs->length; ++i) { + struct sway_output *output = root->outputs->items[i]; + arrange_workspace(output_get_active_workspace(output)); + output_damage_whole(output); + } + + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} 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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <ctype.h> #include <limits.h> #include <string.h> @@ -38,7 +38,7 @@ void free_workspace_config(struct workspace_config *wsc) { } static void prevent_invalid_outer_gaps(struct workspace_config *wsc) { - if (wsc->gaps_outer.top != INT_MIN && + if (wsc->gaps_outer.top != INT_MIN && wsc->gaps_outer.top < -wsc->gaps_inner) { wsc->gaps_outer.top = -wsc->gaps_inner; } 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 @@ -#define _POSIX_C_SOURCE 200809L -#define _XOPEN_SOURCE 700 +#define _XOPEN_SOURCE 600 // for realpath #include <stdio.h> #include <stdbool.h> #include <stdlib.h> @@ -213,6 +212,10 @@ static void config_defaults(struct sway_config *config) { config->urgent_timeout = 500; config->popup_during_fullscreen = POPUP_SMART; + config->titlebar_border_thickness = 1; + config->titlebar_h_padding = 5; + config->titlebar_v_padding = 4; + // floating view config->floating_maximum_width = 0; config->floating_maximum_height = 0; @@ -230,6 +233,7 @@ static void config_defaults(struct sway_config *config) { config->auto_back_and_forth = false; config->reading = false; config->show_marks = true; + config->title_align = ALIGN_LEFT; config->tiling_drag = true; 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 @@ #define _POSIX_C_SOURCE 200809L -#define _XOPEN_SOURCE 700 #include <stdio.h> #include <stdbool.h> #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include <stdlib.h> #include <limits.h> #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include <assert.h> #include <stdbool.h> #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include <stdlib.h> #include <string.h> #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include <stdlib.h> #include <stdio.h> #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, children->items[children->length - 1] == con; double output_x = output->wlr_output->lx; double output_y = output->wlr_output->ly; + int titlebar_border_thickness = config->titlebar_border_thickness; + int titlebar_h_padding = config->titlebar_h_padding; + int titlebar_v_padding = config->titlebar_v_padding; + enum alignment title_align = config->title_align; // Single pixel bar above title memcpy(&color, colors->border, sizeof(float) * 4); @@ -375,7 +379,7 @@ static void render_titlebar(struct sway_output *output, box.x = x; box.y = y; box.width = width; - box.height = TITLEBAR_BORDER_THICKNESS; + box.height = titlebar_border_thickness; scale_box(&box, output_scale); render_rect(output->wlr_output, output_damage, &box, color); @@ -391,45 +395,51 @@ static void render_titlebar(struct sway_output *output, } } box.x = x + left_offset; - box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS; + box.y = y + container_titlebar_height() - titlebar_border_thickness; box.width = width - left_offset - right_offset; - box.height = TITLEBAR_BORDER_THICKNESS; + box.height = titlebar_border_thickness; scale_box(&box, output_scale); render_rect(output->wlr_output, output_damage, &box, color); if (layout == L_TABBED) { // Single pixel left edge box.x = x; - box.y = y + TITLEBAR_BORDER_THICKNESS; - box.width = TITLEBAR_BORDER_THICKNESS; + box.y = y + titlebar_border_thickness; + box.width = titlebar_border_thickness; box.height = - container_titlebar_height() - TITLEBAR_BORDER_THICKNESS * 2; + container_titlebar_height() - titlebar_border_thickness * 2; scale_box(&box, output_scale); render_rect(output->wlr_output, output_damage, &box, color); // Single pixel right edge - box.x = x + width - TITLEBAR_BORDER_THICKNESS; - box.y = y + TITLEBAR_BORDER_THICKNESS; - box.width = TITLEBAR_BORDER_THICKNESS; + box.x = x + width - titlebar_border_thickness; + box.y = y + titlebar_border_thickness; + box.width = titlebar_border_thickness; box.height = - container_titlebar_height() - TITLEBAR_BORDER_THICKNESS * 2; + container_titlebar_height() - titlebar_border_thickness * 2; scale_box(&box, output_scale); render_rect(output->wlr_output, output_damage, &box, color); } - size_t inner_width = width - TITLEBAR_H_PADDING * 2; - int bg_y = y + TITLEBAR_BORDER_THICKNESS; + int inner_x = x - output_x + titlebar_h_padding; + int bg_y = y + titlebar_border_thickness; + size_t inner_width = width - titlebar_h_padding * 2; + + // output-buffer local + int ob_inner_x = round(inner_x * output_scale); + int ob_inner_width = scale_length(inner_width, inner_x, output_scale); int ob_bg_height = scale_length( - (TITLEBAR_V_PADDING - TITLEBAR_BORDER_THICKNESS) * 2 + + (titlebar_v_padding - titlebar_border_thickness) * 2 + config->font_height, bg_y, output_scale); // Marks - int marks_ob_width = 0; // output-buffer-local + int ob_marks_x = 0; // output-buffer-local + int ob_marks_width = 0; // output-buffer-local if (config->show_marks && marks_texture) { struct wlr_box texture_box; wlr_texture_get_size(marks_texture, &texture_box.width, &texture_box.height); - marks_ob_width = texture_box.width; + ob_marks_width = texture_box.width; // The marks texture might be shorter than the config->font_height, in // 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, int ob_padding_above = floor(ob_padding_total / 2.0); int ob_padding_below = ceil(ob_padding_total / 2.0); - // Render texture - texture_box.x = round((x - output_x + width - TITLEBAR_H_PADDING) - * output_scale) - texture_box.width; + // Render texture. If the title is on the right, the marks will be on + // the left. Otherwise, they will be on the right. + if (title_align == ALIGN_RIGHT || texture_box.width > ob_inner_width) { + texture_box.x = ob_inner_x; + } else { + texture_box.x = ob_inner_x + ob_inner_width - texture_box.width; + } + ob_marks_x = texture_box.x; + texture_box.y = round((bg_y - output_y) * output_scale) + ob_padding_above; @@ -448,8 +464,8 @@ static void render_titlebar(struct sway_output *output, WL_OUTPUT_TRANSFORM_NORMAL, 0.0, output->wlr_output->transform_matrix); - if (inner_width * output_scale < texture_box.width) { - texture_box.width = inner_width * output_scale; + if (ob_inner_width < texture_box.width) { + texture_box.width = ob_inner_width; } render_texture(output->wlr_output, output_damage, marks_texture, &texture_box, matrix, con->alpha); @@ -458,7 +474,7 @@ static void render_titlebar(struct sway_output *output, memcpy(&color, colors->background, sizeof(float) * 4); premultiply_alpha(color, con->alpha); box.x = texture_box.x + round(output_x * output_scale); - box.y = round((y + TITLEBAR_BORDER_THICKNESS) * output_scale); + box.y = round((y + titlebar_border_thickness) * output_scale); box.width = texture_box.width; box.height = ob_padding_above; render_rect(output->wlr_output, output_damage, &box, color); @@ -470,24 +486,43 @@ static void render_titlebar(struct sway_output *output, } // Title text - size_t title_ob_width = 0; // output-buffer-local + int ob_title_x = 0; // output-buffer-local + int ob_title_width = 0; // output-buffer-local if (title_texture) { struct wlr_box texture_box; wlr_texture_get_size(title_texture, &texture_box.width, &texture_box.height); - title_ob_width = texture_box.width; + ob_title_width = texture_box.width; // The title texture might be shorter than the config->font_height, // in which case we need to pad it above and below. int ob_padding_above = round((config->font_baseline - - con->title_baseline + TITLEBAR_V_PADDING - - TITLEBAR_BORDER_THICKNESS) * output_scale); + con->title_baseline + titlebar_v_padding - + titlebar_border_thickness) * output_scale); int ob_padding_below = ob_bg_height - ob_padding_above - texture_box.height; // Render texture - texture_box.x = - round((x - output_x + TITLEBAR_H_PADDING) * output_scale); + if (texture_box.width > ob_inner_width - ob_marks_width) { + texture_box.x = (title_align == ALIGN_RIGHT && ob_marks_width) + ? ob_marks_x + ob_marks_width : ob_inner_x; + } else if (title_align == ALIGN_LEFT) { + texture_box.x = ob_inner_x; + } else if (title_align == ALIGN_CENTER) { + // If there are marks visible, center between the edge and marks. + // Otherwise, center in the inner area. + if (ob_marks_width) { + texture_box.x = (ob_inner_x + ob_marks_x) / 2 + - texture_box.width / 2; + } else { + texture_box.x = ob_inner_x + ob_inner_width / 2 + - texture_box.width / 2; + } + } else { + texture_box.x = ob_inner_x + ob_inner_width - texture_box.width; + } + ob_title_x = texture_box.x; + texture_box.y = round((bg_y - output_y) * output_scale) + ob_padding_above; @@ -496,11 +531,10 @@ static void render_titlebar(struct sway_output *output, WL_OUTPUT_TRANSFORM_NORMAL, 0.0, output->wlr_output->transform_matrix); - int inner_x = x - output_x + TITLEBAR_H_PADDING; - int ob_inner_width = scale_length(inner_width, inner_x, output_scale); - if (ob_inner_width - marks_ob_width < texture_box.width) { - texture_box.width = ob_inner_width - marks_ob_width; + if (ob_inner_width - ob_marks_width < texture_box.width) { + texture_box.width = ob_inner_width - ob_marks_width; } + render_texture(output->wlr_output, output_damage, title_texture, &texture_box, matrix, con->alpha); @@ -508,7 +542,7 @@ static void render_titlebar(struct sway_output *output, memcpy(&color, colors->background, sizeof(float) * 4); premultiply_alpha(color, con->alpha); box.x = texture_box.x + round(output_x * output_scale); - box.y = round((y + TITLEBAR_BORDER_THICKNESS) * output_scale); + box.y = round((y + titlebar_border_thickness) * output_scale); box.width = texture_box.width; box.height = ob_padding_above; render_rect(output->wlr_output, output_damage, &box, color); @@ -519,50 +553,78 @@ static void render_titlebar(struct sway_output *output, render_rect(output->wlr_output, output_damage, &box, color); } + // Determine the left + right extends of the textures (output-buffer local) + int ob_left_x, ob_left_width, ob_right_x, ob_right_width; + if (ob_title_x < ob_marks_x) { + ob_left_x = ob_title_x; + ob_left_width = ob_title_width; + ob_right_x = ob_marks_x; + ob_right_width = ob_marks_width; + } else { + ob_left_x = ob_marks_x; + ob_left_width = ob_marks_width; + ob_right_x = ob_title_x; + ob_right_width = ob_title_width; + } + if (ob_left_x < ob_inner_x) { + ob_left_x = ob_inner_x; + } else if (ob_left_x + ob_left_width > ob_right_x + ob_right_width) { + ob_right_x = ob_left_x; + ob_right_width = ob_left_width; + } + // Filler between title and marks - box.width = - round(inner_width * output_scale) - title_ob_width - marks_ob_width; + box.width = ob_right_x - ob_left_x - ob_left_width; if (box.width > 0) { - box.x = round((x + TITLEBAR_H_PADDING) * output_scale) + title_ob_width; + box.x = ob_left_x + ob_left_width + round(output_x * output_scale); box.y = round(bg_y * output_scale); box.height = ob_bg_height; render_rect(output->wlr_output, output_damage, &box, color); } - // Padding left of title - left_offset = (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS; + // Padding on left side + left_offset = (layout == L_TABBED) * titlebar_border_thickness; box.x = x + left_offset; - box.y = y + TITLEBAR_BORDER_THICKNESS; - box.width = TITLEBAR_H_PADDING - left_offset; - box.height = (TITLEBAR_V_PADDING - TITLEBAR_BORDER_THICKNESS) * 2 + + box.y = y + titlebar_border_thickness; + box.width = titlebar_h_padding - left_offset; + box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 + config->font_height; scale_box(&box, output_scale); + int left_x = ob_left_x + round(output_x * output_scale); + if (box.x + box.width < left_x) { + box.width += left_x - box.x - box.width; + } render_rect(output->wlr_output, output_damage, &box, color); - // Padding right of marks - right_offset = (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS; - box.x = x + width - TITLEBAR_H_PADDING; - box.y = y + TITLEBAR_BORDER_THICKNESS; - box.width = TITLEBAR_H_PADDING - right_offset; - box.height = (TITLEBAR_V_PADDING - TITLEBAR_BORDER_THICKNESS) * 2 + + // Padding on right side + right_offset = (layout == L_TABBED) * titlebar_border_thickness; + box.x = x + width - titlebar_h_padding; + box.y = y + titlebar_border_thickness; + box.width = titlebar_h_padding - right_offset; + box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 + config->font_height; scale_box(&box, output_scale); + int right_rx = ob_right_x + ob_right_width + round(output_x * output_scale); + if (right_rx < box.x) { + box.width += box.x - right_rx; + box.x = right_rx; + } render_rect(output->wlr_output, output_damage, &box, color); if (connects_sides) { // Left pixel in line with bottom bar box.x = x; - box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS; + box.y = y + container_titlebar_height() - titlebar_border_thickness; box.width = state->border_thickness * state->border_left; - box.height = TITLEBAR_BORDER_THICKNESS; + box.height = titlebar_border_thickness; scale_box(&box, output_scale); render_rect(output->wlr_output, output_damage, &box, color); // Right pixel in line with bottom bar box.x = x + width - state->border_thickness * state->border_right; - box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS; + box.y = y + container_titlebar_height() - titlebar_border_thickness; box.width = state->border_thickness * state->border_right; - box.height = TITLEBAR_BORDER_THICKNESS; + box.height = titlebar_border_thickness; scale_box(&box, output_scale); render_rect(output->wlr_output, output_damage, &box, color); } 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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include <math.h> #ifdef __linux__ #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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include <ctype.h> #include <float.h> #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 @@ -#define _XOPEN_SOURCE 700 -#define _POSIX_C_SOURCE 199309L +#define _POSIX_C_SOURCE 200809L #include <assert.h> #include <errno.h> #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 @@ #include <xkbcommon/xkbcommon.h> #include "wlr-layer-shell-unstable-v1-protocol.h" +static const int i3_output_id = INT32_MAX; +static const int i3_scratch_id = INT32_MAX - 1; + static const char *ipc_json_layout_description(enum sway_container_layout l) { switch (l) { case L_VERT: @@ -32,15 +35,66 @@ static const char *ipc_json_layout_description(enum sway_container_layout l) { } static const char *ipc_json_orientation_description(enum sway_container_layout l) { - if (l == L_VERT) { + switch (l) { + case L_VERT: return "vertical"; + case L_HORIZ: + return "horizontal"; + default: + return "none"; } +} - if (l == L_HORIZ) { - return "horizontal"; +static const char *ipc_json_border_description(enum sway_container_border border) { + switch (border) { + case B_NONE: + return "none"; + case B_PIXEL: + return "pixel"; + case B_NORMAL: + return "normal"; + case B_CSD: + return "csd"; } + return "unknown"; +} - return "none"; +static const char *ipc_json_output_transform_description(enum wl_output_transform transform) { + switch (transform) { + case WL_OUTPUT_TRANSFORM_NORMAL: + return "normal"; + case WL_OUTPUT_TRANSFORM_90: + return "90"; + case WL_OUTPUT_TRANSFORM_180: + return "180"; + case WL_OUTPUT_TRANSFORM_270: + return "270"; + case WL_OUTPUT_TRANSFORM_FLIPPED: + return "flipped"; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + return "flipped-90"; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + return "flipped-180"; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + return "flipped-270"; + } + return NULL; +} + +static const char *ipc_json_device_type_description(struct sway_input_device *device) { + switch (device->wlr_device->type) { + case WLR_INPUT_DEVICE_POINTER: + return "pointer"; + case WLR_INPUT_DEVICE_KEYBOARD: + return "keyboard"; + case WLR_INPUT_DEVICE_TOUCH: + return "touch"; + case WLR_INPUT_DEVICE_TABLET_TOOL: + return "tablet_tool"; + case WLR_INPUT_DEVICE_TABLET_PAD: + return "tablet_pad"; + } + return "unknown"; } json_object *ipc_json_get_version(void) { @@ -76,30 +130,43 @@ static json_object *ipc_json_create_empty_rect(void) { return ipc_json_create_rect(&empty); } -static void ipc_json_describe_root(struct sway_root *root, json_object *object) { - json_object_object_add(object, "type", json_object_new_string("root")); +static json_object *ipc_json_create_node(int id, char *name, + bool focused, json_object *focus, struct wlr_box *box) { + json_object *object = json_object_new_object(); + + json_object_object_add(object, "id", json_object_new_int(id)); + json_object_object_add(object, "name", + name ? json_object_new_string(name) : NULL); + json_object_object_add(object, "rect", ipc_json_create_rect(box)); + json_object_object_add(object, "focused", json_object_new_boolean(focused)); + json_object_object_add(object, "focus", focus); + + // set default values to be compatible with i3 + json_object_object_add(object, "border", + json_object_new_string( + ipc_json_border_description(B_NONE))); + json_object_object_add(object, "current_border_width", + json_object_new_int(0)); + json_object_object_add(object, "layout", + json_object_new_string( + ipc_json_layout_description(L_HORIZ))); + json_object_object_add(object, "orientation", + json_object_new_string( + ipc_json_orientation_description(L_HORIZ))); + json_object_object_add(object, "percent", NULL); + json_object_object_add(object, "window_rect", ipc_json_create_empty_rect()); + json_object_object_add(object, "deco_rect", ipc_json_create_empty_rect()); + json_object_object_add(object, "geometry", ipc_json_create_empty_rect()); + json_object_object_add(object, "window", NULL); + json_object_object_add(object, "urgent", json_object_new_boolean(false)); + json_object_object_add(object, "floating_nodes", json_object_new_array()); + json_object_object_add(object, "sticky", json_object_new_boolean(false)); + + return object; } -static const char *ipc_json_get_output_transform(enum wl_output_transform transform) { - switch (transform) { - case WL_OUTPUT_TRANSFORM_NORMAL: - return "normal"; - case WL_OUTPUT_TRANSFORM_90: - return "90"; - case WL_OUTPUT_TRANSFORM_180: - return "180"; - case WL_OUTPUT_TRANSFORM_270: - return "270"; - case WL_OUTPUT_TRANSFORM_FLIPPED: - return "flipped"; - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - return "flipped-90"; - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - return "flipped-180"; - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - return "flipped-270"; - } - return NULL; +static void ipc_json_describe_root(struct sway_root *root, json_object *object) { + json_object_object_add(object, "type", json_object_new_string("root")); } static void ipc_json_describe_output(struct sway_output *output, @@ -110,7 +177,8 @@ static void ipc_json_describe_output(struct sway_output *output, json_object_object_add(object, "primary", json_object_new_boolean(false)); json_object_object_add(object, "layout", json_object_new_string("output")); json_object_object_add(object, "orientation", - json_object_new_string(ipc_json_orientation_description(L_NONE))); + json_object_new_string( + ipc_json_orientation_description(L_NONE))); json_object_object_add(object, "make", json_object_new_string(wlr_output->make)); json_object_object_add(object, "model", @@ -121,7 +189,7 @@ static void ipc_json_describe_output(struct sway_output *output, json_object_new_double(wlr_output->scale)); json_object_object_add(object, "transform", json_object_new_string( - ipc_json_get_output_transform(wlr_output->transform))); + ipc_json_output_transform_description(wlr_output->transform))); struct sway_workspace *ws = output_get_active_workspace(output); json_object_object_add(object, "current_workspace", @@ -187,6 +255,52 @@ json_object *ipc_json_describe_disabled_output(struct sway_output *output) { return object; } +static json_object *ipc_json_describe_scratchpad_output(void) { + struct wlr_box box; + root_get_box(root, &box); + + // Create focus stack for __i3_scratch workspace + json_object *workspace_focus = json_object_new_array(); + for (int i = root->scratchpad->length - 1; i >= 0; --i) { + struct sway_container *container = root->scratchpad->items[i]; + json_object_array_add(workspace_focus, + json_object_new_int(container->node.id)); + } + + json_object *workspace = ipc_json_create_node(i3_scratch_id, + "__i3_scratch", false, workspace_focus, &box); + json_object_object_add(workspace, "type", + json_object_new_string("workspace")); + + // List all hidden scratchpad containers as floating nodes + json_object *floating_array = json_object_new_array(); + for (int i = 0; i < root->scratchpad->length; ++i) { + struct sway_container *container = root->scratchpad->items[i]; + if (!container->workspace) { + json_object_array_add(floating_array, + ipc_json_describe_node_recursive(&container->node)); + } + } + json_object_object_add(workspace, "floating_nodes", floating_array); + + // Create focus stack for __i3 output + json_object *output_focus = json_object_new_array(); + json_object_array_add(output_focus, json_object_new_int(i3_scratch_id)); + + json_object *output = ipc_json_create_node(i3_output_id, + "__i3", false, output_focus, &box); + json_object_object_add(output, "type", + json_object_new_string("output")); + json_object_object_add(output, "layout", + json_object_new_string("output")); + + json_object *nodes = json_object_new_array(); + json_object_array_add(nodes, workspace); + json_object_object_add(output, "nodes", nodes); + + return output; +} + static void ipc_json_describe_workspace(struct sway_workspace *workspace, json_object *object) { int num = isdigit(workspace->name[0]) ? atoi(workspace->name) : -1; @@ -200,11 +314,12 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace, json_object_object_add(object, "representation", workspace->representation ? json_object_new_string(workspace->representation) : NULL); - const char *layout = ipc_json_layout_description(workspace->layout); - json_object_object_add(object, "layout", json_object_new_string(layout)); - - const char *orientation = ipc_json_orientation_description(workspace->layout); - json_object_object_add(object, "orientation", json_object_new_string(orientation)); + json_object_object_add(object, "layout", + json_object_new_string( + ipc_json_layout_description(workspace->layout))); + json_object_object_add(object, "orientation", + json_object_new_string( + ipc_json_orientation_description(workspace->layout))); // Floating json_object *floating_array = json_object_new_array(); @@ -216,20 +331,6 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace, json_object_object_add(object, "floating_nodes", floating_array); } -static const char *describe_container_border(enum sway_container_border border) { - switch (border) { - case B_NONE: - return "none"; - case B_PIXEL: - return "pixel"; - case B_NORMAL: - return "normal"; - case B_CSD: - return "csd"; - } - return "unknown"; -} - static void ipc_json_describe_view(struct sway_container *c, json_object *object) { json_object_object_add(object, "pid", json_object_new_int(c->view->pid)); @@ -307,10 +408,12 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o json_object_new_string(container_is_floating(c) ? "floating_con" : "con")); json_object_object_add(object, "layout", - json_object_new_string(ipc_json_layout_description(c->layout))); + json_object_new_string( + ipc_json_layout_description(c->layout))); json_object_object_add(object, "orientation", - json_object_new_string(ipc_json_orientation_description(c->layout))); + json_object_new_string( + ipc_json_orientation_description(c->layout))); bool urgent = c->view ? 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 } json_object_object_add(object, "border", - json_object_new_string(describe_container_border(c->current.border))); + json_object_new_string( + ipc_json_border_description(c->current.border))); json_object_object_add(object, "current_border_width", json_object_new_int(c->current.border_thickness)); 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, json_object *ipc_json_describe_node(struct sway_node *node) { struct sway_seat *seat = input_manager_get_default_seat(); bool focused = seat_get_focus(seat) == node; - - json_object *object = json_object_new_object(); char *name = node_get_name(node); struct wlr_box box; node_get_box(node, &box); - json_object_object_add(object, "id", json_object_new_int((int)node->id)); - json_object_object_add(object, "name", - name ? json_object_new_string(name) : NULL); - json_object_object_add(object, "rect", ipc_json_create_rect(&box)); - json_object_object_add(object, "focused", json_object_new_boolean(focused)); json_object *focus = json_object_new_array(); struct focus_inactive_data data = { @@ -390,24 +487,9 @@ json_object *ipc_json_describe_node(struct sway_node *node) { .object = focus, }; seat_for_each_node(seat, focus_inactive_children_iterator, &data); - json_object_object_add(object, "focus", focus); - // set default values to be compatible with i3 - json_object_object_add(object, "border", - json_object_new_string(describe_container_border(B_NONE))); - json_object_object_add(object, "current_border_width", json_object_new_int(0)); - json_object_object_add(object, "layout", - json_object_new_string(ipc_json_layout_description(L_HORIZ))); - json_object_object_add(object, "orientation", - json_object_new_string(ipc_json_orientation_description(L_HORIZ))); - json_object_object_add(object, "percent", NULL); - json_object_object_add(object, "window_rect", ipc_json_create_empty_rect()); - json_object_object_add(object, "deco_rect", ipc_json_create_empty_rect()); - json_object_object_add(object, "geometry", ipc_json_create_empty_rect()); - json_object_object_add(object, "window", NULL); - json_object_object_add(object, "urgent", json_object_new_boolean(false)); - json_object_object_add(object, "floating_nodes", json_object_new_array()); - json_object_object_add(object, "sticky", json_object_new_boolean(false)); + json_object *object = ipc_json_create_node( + (int)node->id, name, focused, focus, &box); switch (node->type) { case N_ROOT: @@ -434,6 +516,8 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) { json_object *children = json_object_new_array(); switch (node->type) { case N_ROOT: + json_object_array_add(children, + ipc_json_describe_scratchpad_output()); for (i = 0; i < root->outputs->length; ++i) { struct sway_output *output = root->outputs->items[i]; json_object_array_add(children, @@ -470,22 +554,6 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) { return object; } -static const char *describe_device_type(struct sway_input_device *device) { - switch (device->wlr_device->type) { - case WLR_INPUT_DEVICE_POINTER: - return "pointer"; - case WLR_INPUT_DEVICE_KEYBOARD: - return "keyboard"; - case WLR_INPUT_DEVICE_TOUCH: - return "touch"; - case WLR_INPUT_DEVICE_TABLET_TOOL: - return "tablet_tool"; - case WLR_INPUT_DEVICE_TABLET_PAD: - return "tablet_pad"; - } - return "unknown"; -} - json_object *ipc_json_describe_input(struct sway_input_device *device) { if (!(sway_assert(device, "Device must not be null"))) { return NULL; @@ -502,7 +570,8 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { json_object_object_add(object, "product", json_object_new_int(device->wlr_device->product)); json_object_object_add(object, "type", - json_object_new_string(describe_device_type(device))); + json_object_new_string( + ipc_json_device_type_description(device))); if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) { 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) { json_object *outputs = json_object_new_array(); for (int i = 0; i < root->outputs->length; ++i) { struct sway_output *output = root->outputs->items[i]; - json_object_array_add(outputs, - ipc_json_describe_node(&output->node)); + json_object *output_json = ipc_json_describe_node(&output->node); + + // override the default focused indicator because it's set + // differently for the get_outputs reply + struct sway_seat *seat = input_manager_get_default_seat(); + struct sway_workspace *focused_ws = + seat_get_focused_workspace(seat); + bool focused = focused_ws && output == focused_ws->output; + json_object_object_del(output_json, "focused"); + json_object_object_add(output_json, "focused", + json_object_new_boolean(focused)); + + json_object_array_add(outputs, output_json); } struct sway_output *output; 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 @@ -#define _XOPEN_SOURCE 700 -#define _POSIX_C_SOURCE 200112L +#define _POSIX_C_SOURCE 200809L #include <getopt.h> #include <pango/pangocairo.h> #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( 'commands/swaynag_command.c', 'commands/swap.c', 'commands/tiling_drag.c', + 'commands/title_align.c', 'commands/title_format.c', + 'commands/titlebar_border_thickness.c', + 'commands/titlebar_padding.c', 'commands/unmark.c', 'commands/urgent.c', '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 @@ -#define _XOPEN_SOURCE 700 +#define _POSIX_C_SOURCE 200809L #include <stdlib.h> #include <string.h> #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: *font* <font> Sets font for use in title bars in Pango format. +*titlebar\_border\_thickness* <thickness> + Thickness of the titlebar border in pixels + +*titlebar\_padding* <horizontal> [<vertical>] + Padding of the text in the titlebar. _horizontal_ value affects horizontal + padding of the text while _vertical_ value affects vertical padding (space + above and below text). Padding includes titlebar borders so their value + should be greater than titlebar\_border\_thickness. If _vertical_ value is + not specified it is set to the _horizontal_ value. + *for\_window* <criteria> <command> Whenever a window that matches _criteria_ appears, run list of commands. See *CRITERIA* for more details. @@ -545,6 +555,11 @@ The default colors are: Set the opacity of the window between 0 (completely transparent) and 1 (completely opaque). +*title\_align* left|center|right + Sets the title alignment. If _right_ is selected and _show\_marks_ is set + to _yes_, the marks will be shown on the _left_ side instead of the + _right_ side. + *unmark* [<identifier>] *unmark* will remove _identifier_ from the list of current marks on a 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) { } size_t container_titlebar_height(void) { - return config->font_height + TITLEBAR_V_PADDING * 2; + return config->font_height + config->titlebar_v_padding * 2; } void 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 @@ #include <wlr/types/wlr_output_layout.h> #include "sway/desktop/transaction.h" #include "sway/input/seat.h" +#include "sway/ipc-server.h" #include "sway/output.h" #include "sway/tree/arrange.h" #include "sway/tree/container.h" @@ -75,6 +76,8 @@ void root_scratchpad_add_container(struct sway_container *con) { arrange_workspace(workspace); seat_set_focus(seat, seat_get_focus_inactive(seat, &workspace->node)); } + + ipc_event_window(con, "move"); } void root_scratchpad_remove_container(struct sway_container *con) { @@ -85,45 +88,51 @@ void root_scratchpad_remove_container(struct sway_container *con) { int index = list_find(root->scratchpad, con); if (index != -1) { list_del(root->scratchpad, index); + ipc_event_window(con, "move"); } } void root_scratchpad_show(struct sway_container *con) { struct sway_seat *seat = input_manager_current_seat(); - struct sway_workspace *ws = seat_get_focused_workspace(seat); + struct sway_workspace *new_ws = seat_get_focused_workspace(seat); + struct sway_workspace *old_ws = con->workspace; - // If the current con or any of its parents are in fullscreen mode, we - // first need to disable it before showing the scratchpad con. - if (ws->fullscreen) { - container_set_fullscreen(ws->fullscreen, false); + // If the current con or any of its parents are in fullscreen mode, we + // first need to disable it before showing the scratchpad con. + if (new_ws->fullscreen) { + container_set_fullscreen(new_ws->fullscreen, false); } // Show the container - if (con->workspace) { + if (old_ws) { container_detach(con); } - workspace_add_floating(ws, con); + workspace_add_floating(new_ws, con); // Make sure the container's center point overlaps this workspace double center_lx = con->x + con->width / 2; double center_ly = con->y + con->height / 2; struct wlr_box workspace_box; - workspace_get_box(ws, &workspace_box); + workspace_get_box(new_ws, &workspace_box); if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) { // Maybe resize it - if (con->width > ws->width || con->height > ws->height) { + if (con->width > new_ws->width || con->height > new_ws->height) { container_init_floating(con); } // Center it - double new_lx = ws->x + (ws->width - con->width) / 2; - double new_ly = ws->y + (ws->height - con->height) / 2; + double new_lx = new_ws->x + (new_ws->width - con->width) / 2; + double new_ly = new_ws->y + (new_ws->height - con->height) / 2; container_floating_move_to(con, new_lx, new_ly); } - arrange_workspace(ws); + arrange_workspace(new_ws); seat_set_focus(seat, seat_get_focus_inactive(seat, &con->node)); + + if (new_ws != old_ws) { + ipc_event_window(con, "move"); + } } void root_scratchpad_hide(struct sway_container *con) { @@ -137,6 +146,8 @@ void root_scratchpad_hide(struct sway_container *con) { seat_set_focus(seat, seat_get_focus_inactive(seat, &ws->node)); } list_move_to_end(root->scratchpad, con); + + ipc_event_window(con, "move"); } struct 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) { return NULL; } +static char *escape_pango_markup(const char *buffer) { + size_t length = escape_markup_text(buffer, NULL); + char *escaped_title = calloc(length + 1, sizeof(char)); + escape_markup_text(buffer, escaped_title); + return escaped_title; +} + static size_t append_prop(char *buffer, const char *value) { if (!value) { return 0; } - lenient_strcat(buffer, value); - return strlen(value); + // If using pango_markup in font, we need to escape all markup chars + // from values to make sure tags are not inserted by clients + if (config->pango_markup) { + char *escaped_value = escape_pango_markup(value); + lenient_strcat(buffer, escaped_value); + size_t len = strlen(escaped_value); + free(escaped_value); + return len; + } else { + lenient_strcat(buffer, value); + return strlen(value); + } } /** @@ -838,11 +855,7 @@ static size_t append_prop(char *buffer, const char *value) { */ static size_t parse_title_format(struct sway_view *view, char *buffer) { if (!view->title_format || strcmp(view->title_format, "%title") == 0) { - const char *title = view_get_title(view); - if (buffer && title) { - strcpy(buffer, title); - } - return title ? strlen(title) : 0; + return append_prop(buffer, view_get_title(view)); } size_t len = 0; @@ -882,14 +895,6 @@ static size_t parse_title_format(struct sway_view *view, char *buffer) { return len; } -static char *escape_title(char *buffer) { - size_t length = escape_markup_text(buffer, NULL); - char *escaped_title = calloc(length + 1, sizeof(char)); - escape_markup_text(buffer, escaped_title); - free(buffer); - return escaped_title; -} - void view_update_title(struct sway_view *view, bool force) { const char *title = view_get_title(view); @@ -912,10 +917,6 @@ void view_update_title(struct sway_view *view, bool force) { return; } parse_title_format(view, buffer); - // now we have the title, but needs to be escaped when using pango markup - if (config->pango_markup) { - buffer = escape_title(buffer); - } view->container->title = strdup(title); 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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <assert.h> #include <errno.h> #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <stdlib.h> #include <string.h> #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <stdio.h> #include <stdlib.h> #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 { char *resume_cmd; }; +void sway_terminate(int exit_code) { + wl_display_disconnect(state.display); + wl_event_loop_destroy(state.event_loop); + exit(exit_code); +} + static void cmd_exec(char *param) { wlr_log(WLR_DEBUG, "Cmd exec %s", param); pid_t pid = fork(); @@ -81,16 +87,16 @@ static int release_lock(void *data) { } static void acquire_sleep_lock(void) { - sd_bus_message *msg; - sd_bus_error error; + sd_bus_message *msg = NULL; + sd_bus_error error = SD_BUS_ERROR_NULL; int ret = sd_bus_call_method(bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "Inhibit", &error, &msg, "ssss", "sleep", "swayidle", "Setup Up Lock Screen", "delay"); if (ret < 0) { - wlr_log(WLR_ERROR, "Failed to send Inhibit signal: %s", - strerror(-ret)); + wlr_log(WLR_ERROR, "Failed to send Inhibit signal: %s", error.message); + sd_bus_error_free(&error); return; } @@ -98,10 +104,11 @@ static void acquire_sleep_lock(void) { if (ret < 0) { wlr_log(WLR_ERROR, "Failed to parse D-Bus response for Inhibit: %s", strerror(-ret)); - return; + } else { + wlr_log(WLR_INFO, "Got sleep lock: %d", lock_fd); } - - wlr_log(WLR_INFO, "Got sleep lock: %d", lock_fd); + sd_bus_error_free(&error); + sd_bus_message_unref(msg); } static 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, static int dbus_event(int fd, uint32_t mask, void *data) { sd_bus *bus = data; - while (sd_bus_process(bus, NULL) > 0) { - // Do nothing. + + if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) { + sway_terminate(0); + } + + int count = 0; + if (mask & WL_EVENT_READABLE) { + count = sd_bus_process(bus, NULL); } - return 1; + if (mask & WL_EVENT_WRITABLE) { + sd_bus_flush(bus); + } + if (mask == 0) { + sd_bus_flush(bus); + } + + if (count < 0) { + wlr_log_errno(WLR_ERROR, "sd_bus_process failed, exiting"); + sway_terminate(0); + } + + return count; } static void setup_sleep_listener(void) { @@ -166,8 +191,9 @@ static void setup_sleep_listener(void) { } acquire_sleep_lock(); - wl_event_loop_add_fd(state.event_loop, sd_bus_get_fd(bus), - WL_EVENT_READABLE, dbus_event, bus); + struct wl_event_source *source = wl_event_loop_add_fd(state.event_loop, + sd_bus_get_fd(bus), WL_EVENT_READABLE, dbus_event, bus); + wl_event_source_check(source); } #endif @@ -339,12 +365,6 @@ static int parse_args(int argc, char *argv[]) { return 0; } -void sway_terminate(int exit_code) { - wl_display_disconnect(state.display); - wl_event_loop_destroy(state.event_loop); - exit(exit_code); -} - static void register_zero_idle_timeout(void *item) { struct swayidle_timeout_cmd *cmd = item; register_timeout(cmd, 0); @@ -365,15 +385,28 @@ static int handle_signal(int sig, void *data) { } static int display_event(int fd, uint32_t mask, void *data) { - if (mask & WL_EVENT_HANGUP) { + if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) { sway_terminate(0); } - if (wl_display_dispatch(state.display) < 0) { + + int count = 0; + if (mask & WL_EVENT_READABLE) { + count = wl_display_dispatch(state.display); + } + if (mask & WL_EVENT_WRITABLE) { + wl_display_flush(state.display); + } + if (mask == 0) { + count = wl_display_dispatch_pending(state.display); + wl_display_flush(state.display); + } + + if (count < 0) { wlr_log_errno(WLR_ERROR, "wl_display_dispatch failed, exiting"); sway_terminate(0); } - wl_display_flush(state.display); - return 0; + + return count; } static 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 \ ``` This will lock your screen after 300 seconds of inactivity, then turn off your -displays after another 600 seconds, and turn your screens back on when resumed. +displays after another 300 seconds, and turn your screens back on when resumed. It will also lock your screen before your computer goes to sleep. # 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 @@ -#define _XOPEN_SOURCE 700 -#define _POSIX_C_SOURCE 200112L +#define _POSIX_C_SOURCE 200809L #include <assert.h> #include <ctype.h> #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <pwd.h> #include <security/pam_appl.h> #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 @@ -#define _XOPEN_SOURCE 500 #include <assert.h> #include <errno.h> #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 @@ -#define _POSIX_C_SOURCE 199506L #include <math.h> #include <stdlib.h> #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 @@ -#define _XOPEN_SOURCE +#define _XOPEN_SOURCE // for crypt #include <pwd.h> #include <shadow.h> #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <stdio.h> #include <stdlib.h> #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 @@ -#define _XOPEN_SOURCE 700 -#define _POSIX_C_SOURCE 200112L +#define _POSIX_C_SOURCE 200809L #include <getopt.h> #include <stdlib.h> #include <wordexp.h> @@ -398,4 +397,3 @@ int swaynag_load_config(char *path, struct swaynag *swaynag, list_t *types) { fclose(config); return 0; } - 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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <stdlib.h> #include <signal.h> #include "log.h" @@ -130,4 +130,3 @@ cleanup: swaynag_destroy(&swaynag); return exit_code; } - 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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <stdlib.h> #include <assert.h> #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 @@ -#define _XOPEN_SOURCE 500 +#define _POSIX_C_SOURCE 200809L #include <getopt.h> #include <stdbool.h> #include <stdlib.h> |