Skip to content

Commit

Permalink
Introduce grouped_titlebar command
Browse files Browse the repository at this point in the history
Stacking and tabbed layouts effectively override the titlebar control of
the border command, always showing the titlebar to allow navigation.

Allow users to also hide the titlebar of stacking/tabbed layouts,
through a new command that specify whether grouped titlebar
configurations should always be visible (the default) or if they should
follow the active container's border configuration.
  • Loading branch information
kennylevinsen committed Jul 14, 2024
1 parent 8c5b23e commit 6d746a3
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 1 deletion.
2 changes: 2 additions & 0 deletions include/sway/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ sway_cmd cmd_commands;
sway_cmd cmd_create_output;
sway_cmd cmd_default_border;
sway_cmd cmd_default_floating_border;
sway_cmd cmd_default_grouped_titlebar;
sway_cmd cmd_default_orientation;
sway_cmd cmd_exec;
sway_cmd cmd_exec_always;
Expand All @@ -142,6 +143,7 @@ sway_cmd cmd_force_display_urgency_hint;
sway_cmd cmd_force_focus_wrapping;
sway_cmd cmd_fullscreen;
sway_cmd cmd_gaps;
sway_cmd cmd_grouped_titlebar;
sway_cmd cmd_hide_edge_borders;
sway_cmd cmd_include;
sway_cmd cmd_inhibit_idle;
Expand Down
2 changes: 2 additions & 0 deletions include/sway/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,8 @@ struct sway_config {

bool has_focused_tab_title;

bool grouped_titlebar_follows_border;

// floating view
int32_t floating_maximum_width;
int32_t floating_maximum_height;
Expand Down
9 changes: 9 additions & 0 deletions include/sway/tree/container.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ struct sway_container_state {
bool border_left;
bool border_right;

bool grouped_titlebar_follows_border;

// These are in layout coordinates.
double content_x, content_y;
double content_width, content_height;
Expand Down Expand Up @@ -217,6 +219,13 @@ void container_set_geometry_from_content(struct sway_container *con);
*/
bool container_is_floating(struct sway_container *container);

/**
* Determine if the given container should have a titlebar.
*
* Uses pending container state.
*/
bool container_has_titlebar(struct sway_container *container);

/**
* Get a container's box in layout coordinates.
*/
Expand Down
2 changes: 2 additions & 0 deletions sway/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ static const struct cmd_handler handlers[] = {
{ "client.urgent", cmd_client_urgent },
{ "default_border", cmd_default_border },
{ "default_floating_border", cmd_default_floating_border },
{ "default_grouped_titlebar", cmd_default_grouped_titlebar },
{ "exec", cmd_exec },
{ "exec_always", cmd_exec_always },
{ "floating_maximum_size", cmd_floating_maximum_size },
Expand Down Expand Up @@ -117,6 +118,7 @@ static const struct cmd_handler command_handlers[] = {
{ "exit", cmd_exit },
{ "floating", cmd_floating },
{ "fullscreen", cmd_fullscreen },
{ "grouped_titlebar", cmd_grouped_titlebar },
{ "inhibit_idle", cmd_inhibit_idle },
{ "kill", cmd_kill },
{ "layout", cmd_layout },
Expand Down
22 changes: 22 additions & 0 deletions sway/commands/default_grouped_titlebar.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "log.h"
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/tree/container.h"

struct cmd_results *cmd_default_grouped_titlebar(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "default_grouped_titlebar", EXPECTED_EQUAL_TO, 1))) {
return error;
}

if (strcmp(argv[0], "always_visible") == 0) {
config->grouped_titlebar_follows_border = false;
} else if (strcmp(argv[0], "follows_border") == 0) {
config->grouped_titlebar_follows_border = true;
} else {
return cmd_results_new(CMD_INVALID,
"Expected 'default_grouped_titlebar <always_visible|follows_border>");
}

return cmd_results_new(CMD_SUCCESS, NULL);
}
35 changes: 35 additions & 0 deletions sway/commands/grouped_titlebar.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "log.h"
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "sway/tree/view.h"

struct cmd_results *cmd_grouped_titlebar(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "border", EXPECTED_EQUAL_TO, 1))) {
return error;
}

struct sway_container *container = config->handler_context.container;
if (!container) {
return cmd_results_new(CMD_INVALID, "No container to set");
}

if (strcmp(argv[0], "always_visible") == 0) {
container->pending.grouped_titlebar_follows_border = false;
} else if (strcmp(argv[0], "follows_border") == 0) {
container->pending.grouped_titlebar_follows_border = true;
} else {
return cmd_results_new(CMD_INVALID,
"Expected 'grouped_titlebar <always_visible|follows_border>");
}

if (container_is_floating(container)) {
container_set_geometry_from_content(container);
}

arrange_container(container);

return cmd_results_new(CMD_SUCCESS, NULL);
}
4 changes: 4 additions & 0 deletions sway/desktop/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,10 @@ static void arrange_children(enum sway_container_layout layout, list_t *children
int width, int height, int gaps) {
int title_bar_height = container_titlebar_height();

if (active && active->current.grouped_titlebar_follows_border && active->current.border != B_NORMAL) {
title_bar_height = 0;
}

if (layout == L_TABBED) {
struct sway_container *first = children->length == 1 ?
((struct sway_container *)children->items[0]) : NULL;
Expand Down
2 changes: 2 additions & 0 deletions sway/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ sway_sources = files(
'commands/create_output.c',
'commands/default_border.c',
'commands/default_floating_border.c',
'commands/default_grouped_titlebar.c',
'commands/default_orientation.c',
'commands/exit.c',
'commands/exec.c',
Expand All @@ -67,6 +68,7 @@ sway_sources = files(
'commands/fullscreen.c',
'commands/gaps.c',
'commands/gesture.c',
'commands/grouped_titlebar.c',
'commands/hide_edge_borders.c',
'commands/inhibit_idle.c',
'commands/kill.c',
Expand Down
9 changes: 9 additions & 0 deletions sway/sway.5.scd
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ They are expected to be used with *bindsym* or at runtime through *swaymsg*(1).
*border* toggle
Cycles through the available border styles.

*grouped_titlebar* always_visible|follows_border
Set whether the titlebar for stacking and tabbed layouts should always
be visible (the default) or if it should respect the border setting like
other layouts.

*exit*
Exit sway and end your Wayland session.

Expand Down Expand Up @@ -663,6 +668,10 @@ The default colors are:
windows that are spawned in floating mode, not windows that become floating
afterwards.

*default_grouped_titlebar* always_visible|follows_border
Set the default grouped titlebar setting for new windows. Config reload
won't affect existing windows, only newly created ones after the reload.

*exec* <shell command>
Executes _shell command_ with sh.

Expand Down
16 changes: 16 additions & 0 deletions sway/tree/container.c
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,22 @@ bool container_is_floating(struct sway_container *container) {
return false;
}

bool container_has_titlebar(struct sway_container *container) {
switch (container->pending.layout) {
case L_NONE:
return false;
case L_HORIZ:
case L_VERT:
return container->pending.border == B_NORMAL;
case L_STACKED:
case L_TABBED:
return container->pending.border == B_NORMAL ||
!container->pending.grouped_titlebar_follows_border;
default:
abort();
}
}

void container_get_box(struct sway_container *container, struct wlr_box *box) {
box->x = container->pending.x;
box->y = container->pending.y;
Expand Down
4 changes: 3 additions & 1 deletion sway/tree/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ void view_autoconfigure(struct sway_view *view) {
}
}

if (!container_is_floating(con)) {
if (!container_is_floating(con) && container_has_titlebar(con)) {
// In a tabbed or stacked container, the container's y is the top of the
// title area. We have to offset the surface y by the height of the title,
// bar, and disable any top border because we'll always have the title bar.
Expand Down Expand Up @@ -818,6 +818,8 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
view->container->pending.border_thickness = config->border_thickness;
view_set_tiled(view, true);
}
view->container->pending.grouped_titlebar_follows_border =
config->grouped_titlebar_follows_border;

if (config->popup_during_fullscreen == POPUP_LEAVE &&
container->pending.workspace &&
Expand Down

0 comments on commit 6d746a3

Please sign in to comment.