summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/config.h1
-rw-r--r--include/swaybar/bar.h1
-rw-r--r--meson.build27
-rw-r--r--sway/commands.c3
-rw-r--r--sway/commands/bar/mode.c2
-rw-r--r--sway/commands/hide_edge_borders.c10
-rw-r--r--sway/commands/output/transform.c3
-rw-r--r--sway/config.c1
-rw-r--r--sway/config/output.c2
-rw-r--r--sway/desktop/render.c8
-rw-r--r--sway/input/cursor.c6
-rw-r--r--sway/sway-bar.5.scd6
-rw-r--r--sway/sway.5.scd12
-rw-r--r--sway/tree/view.c19
-rw-r--r--swaybar/bar.c16
15 files changed, 86 insertions, 31 deletions
diff --git a/include/sway/config.h b/include/sway/config.h
index ab494e78..46ca7cee 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -465,6 +465,7 @@ struct sway_config {
465 int floating_border_thickness; 465 int floating_border_thickness;
466 enum edge_border_types hide_edge_borders; 466 enum edge_border_types hide_edge_borders;
467 enum edge_border_types saved_edge_borders; 467 enum edge_border_types saved_edge_borders;
468 bool hide_lone_tab;
468 469
469 // border colors 470 // border colors
470 struct { 471 struct {
diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h
index dfadc200..031993b5 100644
--- a/include/swaybar/bar.h
+++ b/include/swaybar/bar.h
@@ -58,6 +58,7 @@ struct swaybar_output {
58 struct zxdg_output_v1 *xdg_output; 58 struct zxdg_output_v1 *xdg_output;
59 struct wl_surface *surface; 59 struct wl_surface *surface;
60 struct zwlr_layer_surface_v1 *layer_surface; 60 struct zwlr_layer_surface_v1 *layer_surface;
61 struct wl_region *input_region;
61 uint32_t wl_name; 62 uint32_t wl_name;
62 63
63 struct wl_list workspaces; // swaybar_workspace::link 64 struct wl_list workspaces; // swaybar_workspace::link
diff --git a/meson.build b/meson.build
index 45df8799..53454cdd 100644
--- a/meson.build
+++ b/meson.build
@@ -60,17 +60,19 @@ rt = cc.find_library('rt')
60git = find_program('git', required: false) 60git = find_program('git', required: false)
61 61
62# Try first to find wlroots as a subproject, then as a system dependency 62# Try first to find wlroots as a subproject, then as a system dependency
63wlroots_version = '>=0.4.1'
63wlroots_proj = subproject( 64wlroots_proj = subproject(
64 'wlroots', 65 'wlroots',
65 default_options: ['rootston=false', 'examples=false'], 66 default_options: ['rootston=false', 'examples=false'],
66 required: false, 67 required: false,
68 version: wlroots_version,
67) 69)
68if wlroots_proj.found() 70if wlroots_proj.found()
69 wlroots = wlroots_proj.get_variable('wlroots') 71 wlroots = wlroots_proj.get_variable('wlroots')
70 wlroots_conf = wlroots_proj.get_variable('conf_data') 72 wlroots_conf = wlroots_proj.get_variable('conf_data')
71 wlroots_has_xwayland = wlroots_conf.get('WLR_HAS_XWAYLAND') == 1 73 wlroots_has_xwayland = wlroots_conf.get('WLR_HAS_XWAYLAND') == 1
72else 74else
73 wlroots = dependency('wlroots') 75 wlroots = dependency('wlroots', version: wlroots_version)
74 wlroots_has_xwayland = cc.get_define('WLR_HAS_XWAYLAND', prefix: '#include <wlr/config.h>', dependencies: wlroots) == '1' 76 wlroots_has_xwayland = cc.get_define('WLR_HAS_XWAYLAND', prefix: '#include <wlr/config.h>', dependencies: wlroots) == '1'
75endif 77endif
76 78
@@ -93,11 +95,6 @@ conf_data.set10('HAVE_SYSTEMD', systemd.found())
93conf_data.set10('HAVE_ELOGIND', elogind.found()) 95conf_data.set10('HAVE_ELOGIND', elogind.found())
94conf_data.set10('HAVE_TRAY', have_tray) 96conf_data.set10('HAVE_TRAY', have_tray)
95 97
96if not systemd.found() and not elogind.found()
97 warning('The sway binary must be setuid when compiled without (e)logind')
98 warning('You must do this manually post-install: chmod a+s /path/to/sway')
99endif
100
101scdoc = find_program('scdoc', required: get_option('man-pages')) 98scdoc = find_program('scdoc', required: get_option('man-pages'))
102if scdoc.found() 99if scdoc.found()
103 sh = find_program('sh') 100 sh = find_program('sh')
@@ -236,3 +233,21 @@ if get_option('fish-completions')
236 233
237 install_data(fish_files, install_dir: fish_install_dir) 234 install_data(fish_files, install_dir: fish_install_dir)
238endif 235endif
236
237status = [
238 '',
239 'Features:',
240 'xwayland: @0@'.format(have_xwayland),
241 'gdk-pixbuf: @0@'.format(gdk_pixbuf.found()),
242 'systemd: @0@'.format(systemd.found()),
243 'elogind: @0@'.format(elogind.found()),
244 'tray: @0@'.format(have_tray),
245 'man-pages: @0@'.format(scdoc.found()),
246 '',
247]
248message('\n'.join(status))
249
250if not systemd.found() and not elogind.found()
251 warning('The sway binary must be setuid when compiled without (e)logind')
252 warning('You must do this manually post-install: chmod a+s /path/to/sway')
253endif
diff --git a/sway/commands.c b/sway/commands.c
index 3fc4f86e..522a5fd4 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -255,7 +255,8 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
255 int argc; 255 int argc;
256 char **argv = split_args(cmd, &argc); 256 char **argv = split_args(cmd, &argc);
257 if (strcmp(argv[0], "exec") != 0 && 257 if (strcmp(argv[0], "exec") != 0 &&
258 strcmp(argv[0], "exec_always") != 0) { 258 strcmp(argv[0], "exec_always") != 0 &&
259 strcmp(argv[0], "mode") != 0) {
259 int i; 260 int i;
260 for (i = 1; i < argc; ++i) { 261 for (i = 1; i < argc; ++i) {
261 if (*argv[i] == '\"' || *argv[i] == '\'') { 262 if (*argv[i] == '\"' || *argv[i] == '\'') {
diff --git a/sway/commands/bar/mode.c b/sway/commands/bar/mode.c
index 68a80abf..1081ad4b 100644
--- a/sway/commands/bar/mode.c
+++ b/sway/commands/bar/mode.c
@@ -20,6 +20,8 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode
20 bar->mode = strdup("hide"); 20 bar->mode = strdup("hide");
21 } else if (strcasecmp("invisible", mode) == 0) { 21 } else if (strcasecmp("invisible", mode) == 0) {
22 bar->mode = strdup("invisible"); 22 bar->mode = strdup("invisible");
23 } else if (strcasecmp("overlay", mode) == 0) {
24 bar->mode = strdup("overlay");
23 } else { 25 } else {
24 return cmd_results_new(CMD_INVALID, "Invalid value %s", mode); 26 return cmd_results_new(CMD_INVALID, "Invalid value %s", mode);
25 } 27 }
diff --git a/sway/commands/hide_edge_borders.c b/sway/commands/hide_edge_borders.c
index 84a217b8..6120a17f 100644
--- a/sway/commands/hide_edge_borders.c
+++ b/sway/commands/hide_edge_borders.c
@@ -5,10 +5,16 @@
5 5
6struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) { 6struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) {
7 struct cmd_results *error = NULL; 7 struct cmd_results *error = NULL;
8 if ((error = checkarg(argc, "hide_edge_borders", EXPECTED_EQUAL_TO, 1))) { 8 if ((error = checkarg(argc, "hide_edge_borders", EXPECTED_AT_LEAST, 1))) {
9 return error; 9 return error;
10 } 10 }
11 11
12 if (strcmp(*argv, "--i3") == 0) {
13 config->hide_lone_tab = true;
14 ++argv;
15 --argc;
16 }
17
12 if (strcmp(argv[0], "none") == 0) { 18 if (strcmp(argv[0], "none") == 0) {
13 config->hide_edge_borders = E_NONE; 19 config->hide_edge_borders = E_NONE;
14 } else if (strcmp(argv[0], "vertical") == 0) { 20 } else if (strcmp(argv[0], "vertical") == 0) {
@@ -23,7 +29,7 @@ struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) {
23 config->hide_edge_borders = E_SMART_NO_GAPS; 29 config->hide_edge_borders = E_SMART_NO_GAPS;
24 } else { 30 } else {
25 return cmd_results_new(CMD_INVALID, "Expected 'hide_edge_borders " 31 return cmd_results_new(CMD_INVALID, "Expected 'hide_edge_borders "
26 "<none|vertical|horizontal|both|smart|smart_no_gaps>'"); 32 "[--i3] <none|vertical|horizontal|both|smart|smart_no_gaps>'");
27 } 33 }
28 config->saved_edge_borders = config->hide_edge_borders; 34 config->saved_edge_borders = config->hide_edge_borders;
29 35
diff --git a/sway/commands/output/transform.c b/sway/commands/output/transform.c
index 8613a8e7..8e5324ad 100644
--- a/sway/commands/output/transform.c
+++ b/sway/commands/output/transform.c
@@ -12,7 +12,8 @@ struct cmd_results *output_cmd_transform(int argc, char **argv) {
12 return cmd_results_new(CMD_INVALID, "Missing transform argument."); 12 return cmd_results_new(CMD_INVALID, "Missing transform argument.");
13 } 13 }
14 enum wl_output_transform transform; 14 enum wl_output_transform transform;
15 if (strcmp(*argv, "normal") == 0) { 15 if (strcmp(*argv, "normal") == 0 ||
16 strcmp(*argv, "0") == 0) {
16 transform = WL_OUTPUT_TRANSFORM_NORMAL; 17 transform = WL_OUTPUT_TRANSFORM_NORMAL;
17 } else if (strcmp(*argv, "90") == 0) { 18 } else if (strcmp(*argv, "90") == 0) {
18 transform = WL_OUTPUT_TRANSFORM_90; 19 transform = WL_OUTPUT_TRANSFORM_90;
diff --git a/sway/config.c b/sway/config.c
index 4cd21bbc..48bbd1ea 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -261,6 +261,7 @@ static void config_defaults(struct sway_config *config) {
261 config->floating_border_thickness = 2; 261 config->floating_border_thickness = 2;
262 config->hide_edge_borders = E_NONE; 262 config->hide_edge_borders = E_NONE;
263 config->saved_edge_borders = E_NONE; 263 config->saved_edge_borders = E_NONE;
264 config->hide_lone_tab = false;
264 265
265 // border colors 266 // border colors
266 set_color(config->border_colors.focused.border, 0x4C7899); 267 set_color(config->border_colors.focused.border, 0x4C7899);
diff --git a/sway/config/output.c b/sway/config/output.c
index e7fbad83..cb889b3e 100644
--- a/sway/config/output.c
+++ b/sway/config/output.c
@@ -378,7 +378,7 @@ static struct output_config *get_output_config(char *identifier,
378 oc_id = config->output_configs->items[i]; 378 oc_id = config->output_configs->items[i];
379 } 379 }
380 380
381 struct output_config *result = result = new_output_config("temp"); 381 struct output_config *result = new_output_config("temp");
382 if (config->reloading) { 382 if (config->reloading) {
383 default_output_config(result, sway_output->wlr_output); 383 default_output_config(result, sway_output->wlr_output);
384 } 384 }
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 92e623ef..5df16075 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -841,6 +841,14 @@ static void render_containers_stacked(struct sway_output *output,
841 841
842static void render_containers(struct sway_output *output, 842static void render_containers(struct sway_output *output,
843 pixman_region32_t *damage, struct parent_data *parent) { 843 pixman_region32_t *damage, struct parent_data *parent) {
844 if (config->hide_lone_tab && parent->children->length == 1) {
845 struct sway_container *child = parent->children->items[0];
846 if (child->view) {
847 render_containers_linear(output,damage, parent);
848 return;
849 }
850 }
851
844 switch (parent->layout) { 852 switch (parent->layout) {
845 case L_NONE: 853 case L_NONE:
846 case L_HORIZ: 854 case L_HORIZ:
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index fb4728b4..87811550 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -280,7 +280,7 @@ static void cursor_do_rebase(struct sway_cursor *cursor, uint32_t time_msec,
280void cursor_rebase(struct sway_cursor *cursor) { 280void cursor_rebase(struct sway_cursor *cursor) {
281 uint32_t time_msec = get_current_time_msec(); 281 uint32_t time_msec = get_current_time_msec();
282 struct wlr_surface *surface = NULL; 282 struct wlr_surface *surface = NULL;
283 double sx, sy; 283 double sx = 0.0, sy = 0.0;
284 cursor->previous.node = node_at_coords(cursor->seat, 284 cursor->previous.node = node_at_coords(cursor->seat,
285 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); 285 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
286 cursor_do_rebase(cursor, time_msec, cursor->previous.node, surface, sx, sy); 286 cursor_do_rebase(cursor, time_msec, cursor->previous.node, surface, sx, sy);
@@ -431,7 +431,7 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) {
431 struct sway_node *node = NULL; 431 struct sway_node *node = NULL;
432 double sx, sy; 432 double sx, sy;
433 if (cursor->active_constraint) { 433 if (cursor->active_constraint) {
434 node = node_at_coords(cursor->seat, 434 node_at_coords(cursor->seat,
435 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); 435 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
436 436
437 if (cursor->active_constraint->surface != surface) { 437 if (cursor->active_constraint->surface != surface) {
@@ -476,7 +476,7 @@ static void cursor_motion_absolute(struct sway_cursor *cursor,
476 dx, dy, dx, dy); 476 dx, dy, dx, dy);
477 477
478 struct wlr_surface *surface = NULL; 478 struct wlr_surface *surface = NULL;
479 double sx, sy; 479 double sx = 0.0, sy = 0.0;
480 struct sway_node *node = node_at_coords(cursor->seat, 480 struct sway_node *node = node_at_coords(cursor->seat,
481 lx, ly, &surface, &sx, &sy); 481 lx, ly, &surface, &sx, &sy);
482 482
diff --git a/sway/sway-bar.5.scd b/sway/sway-bar.5.scd
index 13827e5e..1f4ceaf2 100644
--- a/sway/sway-bar.5.scd
+++ b/sway/sway-bar.5.scd
@@ -84,11 +84,13 @@ Sway allows configuring swaybar in the sway configuration file.
84 debug-events`. To disable the default behavior for a button, use the 84 debug-events`. To disable the default behavior for a button, use the
85 command _nop_. 85 command _nop_.
86 86
87*mode* dock|hide|invisible 87*mode* dock|hide|invisible|overlay
88 Specifies the visibility of the bar. In _dock_ mode, it is permanently 88 Specifies the visibility of the bar. In _dock_ mode, it is permanently
89 visible at one edge of the screen. In _hide_ mode, it is hidden unless the 89 visible at one edge of the screen. In _hide_ mode, it is hidden unless the
90 modifier key is pressed, though this behaviour depends on the hidden state. 90 modifier key is pressed, though this behaviour depends on the hidden state.
91 In _invisible_ mode, it is permanently hidden. Default is _dock_. 91 In _invisible_ mode, it is permanently hidden. In _overlay_ mode, it is
92 permanently visible on top of other windows. (In _overlay_ mode the bar is
93 transparent to input events.) Default is _dock_.
92 94
93*hidden_state* hide|show 95*hidden_state* hide|show
94 Specifies the behaviour of the bar when it is in _hide_ mode. When the 96 Specifies the behaviour of the bar when it is in _hide_ mode. When the
diff --git a/sway/sway.5.scd b/sway/sway.5.scd
index 1b85a75b..8f8b7e3d 100644
--- a/sway/sway.5.scd
+++ b/sway/sway.5.scd
@@ -493,8 +493,10 @@ The default colors are:
493 This affects new workspaces only, and is used when the workspace doesn't 493 This affects new workspaces only, and is used when the workspace doesn't
494 have its own gaps settings (see: workspace <ws> gaps ...). 494 have its own gaps settings (see: workspace <ws> gaps ...).
495 495
496*hide_edge_borders* none|vertical|horizontal|both|smart|smart_no_gaps 496*hide_edge_borders* [--i3] none|vertical|horizontal|both|smart|smart_no_gaps
497 Hides window borders adjacent to the screen edges. Default is _none_. 497 Hides window borders adjacent to the screen edges. Default is _none_. The
498 _--i3_ option enables i3-compatible behavior to hide the title bar on tabbed
499 and stacked containers with one child.
498 500
499*input* <input_device> <input-subcommands...> 501*input* <input_device> <input-subcommands...>
500 For details on input subcommands, see *sway-input*(5). 502 For details on input subcommands, see *sway-input*(5).
@@ -511,9 +513,9 @@ The default colors are:
511 513
512*smart_borders* on|no_gaps|off 514*smart_borders* on|no_gaps|off
513 If smart_borders are _on_, borders will only be enabled if the workspace 515 If smart_borders are _on_, borders will only be enabled if the workspace
514 only has one visible child (identical to _hide_edge_borders_ smart). If 516 has more than one visible child (identical to _hide_edge_borders_ smart).
515 smart_borders is set to _no_gaps_, borders will only be enabled if the 517 If smart_borders is set to _no_gaps_, borders will only be enabled if the
516 workspace only has one visible child and gaps greater than zero. 518 workspace has more than one visible child and gaps equal to zero.
517 519
518*smart_gaps* on|off 520*smart_gaps* on|off
519 If smart_gaps are _on_ gaps will only be enabled if a workspace has more 521 If smart_gaps are _on_ gaps will only be enabled if a workspace has more
diff --git a/sway/tree/view.c b/sway/tree/view.c
index ca13def7..14cc07d9 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -246,14 +246,17 @@ void view_autoconfigure(struct sway_view *view) {
246 // In a tabbed or stacked container, the container's y is the top of the 246 // In a tabbed or stacked container, the container's y is the top of the
247 // title area. We have to offset the surface y by the height of the title, 247 // title area. We have to offset the surface y by the height of the title,
248 // bar, and disable any top border because we'll always have the title bar. 248 // bar, and disable any top border because we'll always have the title bar.
249 enum sway_container_layout layout = container_parent_layout(con); 249 list_t *siblings = container_get_siblings(con);
250 if (layout == L_TABBED && !container_is_floating(con)) { 250 bool show_titlebar = siblings->length > 1 || !config->hide_lone_tab;
251 y_offset = container_titlebar_height(); 251 if (show_titlebar && !container_is_floating(con)) {
252 con->border_top = false; 252 enum sway_container_layout layout = container_parent_layout(con);
253 } else if (layout == L_STACKED && !container_is_floating(con)) { 253 if (layout == L_TABBED) {
254 list_t *siblings = container_get_siblings(con); 254 y_offset = container_titlebar_height();
255 y_offset = container_titlebar_height() * siblings->length; 255 con->border_top = false;
256 con->border_top = false; 256 } else if (layout == L_STACKED) {
257 y_offset = container_titlebar_height() * siblings->length;
258 con->border_top = false;
259 }
257 } 260 }
258 261
259 double x, y, width, height; 262 double x, y, width, height;
diff --git a/swaybar/bar.c b/swaybar/bar.c
index db1c1222..ca7cd88c 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -51,6 +51,9 @@ static void swaybar_output_free(struct swaybar_output *output) {
51 if (output->surface != NULL) { 51 if (output->surface != NULL) {
52 wl_surface_destroy(output->surface); 52 wl_surface_destroy(output->surface);
53 } 53 }
54 if (output->input_region != NULL) {
55 wl_region_destroy(output->input_region);
56 }
54 zxdg_output_v1_destroy(output->xdg_output); 57 zxdg_output_v1_destroy(output->xdg_output);
55 wl_output_destroy(output->output); 58 wl_output_destroy(output->output);
56 destroy_buffer(&output->buffers[0]); 59 destroy_buffer(&output->buffers[0]);
@@ -100,16 +103,25 @@ static void add_layer_surface(struct swaybar_output *output) {
100 103
101 struct swaybar_config *config = bar->config; 104 struct swaybar_config *config = bar->config;
102 bool hidden = strcmp(config->mode, "hide") == 0; 105 bool hidden = strcmp(config->mode, "hide") == 0;
106 bool overlay = !hidden && strcmp(config->mode, "overlay") == 0;
103 output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( 107 output->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
104 bar->layer_shell, output->surface, output->output, 108 bar->layer_shell, output->surface, output->output,
105 hidden ? ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY : 109 hidden || overlay ? ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY :
106 ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); 110 ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel");
107 assert(output->layer_surface); 111 assert(output->layer_surface);
108 zwlr_layer_surface_v1_add_listener(output->layer_surface, 112 zwlr_layer_surface_v1_add_listener(output->layer_surface,
109 &layer_surface_listener, output); 113 &layer_surface_listener, output);
110 114
115 if (overlay) {
116 // Empty input region
117 output->input_region = wl_compositor_create_region(bar->compositor);
118 assert(output->input_region);
119
120 wl_surface_set_input_region(output->surface, output->input_region);
121 }
122
111 zwlr_layer_surface_v1_set_anchor(output->layer_surface, config->position); 123 zwlr_layer_surface_v1_set_anchor(output->layer_surface, config->position);
112 if (hidden) { 124 if (hidden || overlay) {
113 zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, -1); 125 zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, -1);
114 } 126 }
115} 127}