diff --git a/include/sway/commands.h b/include/sway/commands.h index c6f5c2e04e..2746ef28f1 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -112,6 +112,7 @@ sway_cmd cmd_border; sway_cmd cmd_client_noop; sway_cmd cmd_client_focused; sway_cmd cmd_client_focused_inactive; +sway_cmd cmd_client_focused_tab_title; sway_cmd cmd_client_unfocused; sway_cmd cmd_client_urgent; sway_cmd cmd_client_placeholder; diff --git a/include/sway/config.h b/include/sway/config.h index aa71209ddc..fda0e83f5c 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -548,12 +548,15 @@ struct sway_config { struct { struct border_colors focused; struct border_colors focused_inactive; + struct border_colors focused_tab_title; struct border_colors unfocused; struct border_colors urgent; struct border_colors placeholder; float background[4]; } border_colors; + bool has_focused_tab_title; + // floating view int32_t floating_maximum_width; int32_t floating_maximum_height; diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 97fa98c1cf..0576115084 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -117,12 +117,14 @@ struct sway_container { struct wlr_texture *title_focused; struct wlr_texture *title_focused_inactive; + struct wlr_texture *title_focused_tab_title; struct wlr_texture *title_unfocused; struct wlr_texture *title_urgent; list_t *marks; // char * struct wlr_texture *marks_focused; struct wlr_texture *marks_focused_inactive; + struct wlr_texture *marks_focused_tab_title; struct wlr_texture *marks_unfocused; struct wlr_texture *marks_urgent; diff --git a/sway/commands.c b/sway/commands.c index 205406ad2a..5a1fd32ef9 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -51,6 +51,7 @@ static const struct cmd_handler handlers[] = { { "client.background", cmd_client_noop }, { "client.focused", cmd_client_focused }, { "client.focused_inactive", cmd_client_focused_inactive }, + { "client.focused_tab_title", cmd_client_focused_tab_title }, { "client.placeholder", cmd_client_noop }, { "client.unfocused", cmd_client_unfocused }, { "client.urgent", cmd_client_urgent }, diff --git a/sway/commands/client.c b/sway/commands/client.c index dd0694df99..7726314567 100644 --- a/sway/commands/client.c +++ b/sway/commands/client.c @@ -18,6 +18,12 @@ static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name, return error; } + if (argc > 3 && strcmp(cmd_name, "client.focused_tab_title") == 0) { + sway_log(SWAY_ERROR, + "Warning: indicator and child_border colors have no effect for %s", + cmd_name); + } + struct border_colors colors = {0}; const char *ind_hex = argc > 3 ? argv[3] : default_indicator; const char *child_hex = argc > 4 ? argv[4] : argv[1]; // def to background @@ -80,3 +86,13 @@ struct cmd_results *cmd_client_noop(int argc, char **argv) { sway_log(SWAY_INFO, "Warning: %s is ignored by sway", argv[-1]); return cmd_results_new(CMD_SUCCESS, NULL); } + +struct cmd_results *cmd_client_focused_tab_title(int argc, char **argv) { + struct cmd_results *result = handle_command(argc, argv, + "client.focused_tab_title", + &config->border_colors.focused_tab_title, "#2e9ef4ff"); + if (result && result->status == CMD_SUCCESS) { + config->has_focused_tab_title = true; + } + return result; +} diff --git a/sway/config.c b/sway/config.c index 3583721244..e4745a5c7f 100644 --- a/sway/config.c +++ b/sway/config.c @@ -290,6 +290,8 @@ static void config_defaults(struct sway_config *config) { config->hide_edge_borders_smart = ESMART_OFF; config->hide_lone_tab = false; + config->has_focused_tab_title = false; + // border colors color_to_rgba(config->border_colors.focused.border, 0x4C7899FF); color_to_rgba(config->border_colors.focused.background, 0x285577FF); diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 6c8c77ed41..c088c936dc 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -762,6 +762,14 @@ static void render_containers_linear(struct sway_output *output, } } +static bool container_is_focused(struct sway_container *con, void *data) { + return con->current.focused; +} + +static bool container_has_focused_child(struct sway_container *con) { + return container_find_child(con, container_is_focused, NULL); +} + /** * Render a container's children using the L_TABBED layout. */ @@ -793,6 +801,10 @@ static void render_containers_tabbed(struct sway_output *output, colors = &config->border_colors.focused; title_texture = child->title_focused; marks_texture = child->marks_focused; + } else if (config->has_focused_tab_title && container_has_focused_child(child)) { + colors = &config->border_colors.focused_tab_title; + title_texture = child->title_focused_tab_title; + marks_texture = child->marks_focused_tab_title; } else if (child == parent->active_child) { colors = &config->border_colors.focused_inactive; title_texture = child->title_focused_inactive; @@ -858,7 +870,11 @@ static void render_containers_stacked(struct sway_output *output, colors = &config->border_colors.focused; title_texture = child->title_focused; marks_texture = child->marks_focused; - } else if (child == parent->active_child) { + } else if (config->has_focused_tab_title && container_has_focused_child(child)) { + colors = &config->border_colors.focused_tab_title; + title_texture = child->title_focused_tab_title; + marks_texture = child->marks_focused_tab_title; + } else if (child == parent->active_child) { colors = &config->border_colors.focused_inactive; title_texture = child->title_focused_inactive; marks_texture = child->marks_focused_inactive; diff --git a/sway/sway.5.scd b/sway/sway.5.scd index ec34a56caa..641d09253b 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -499,6 +499,12 @@ runtime. *client.focused_inactive* The most recently focused view within a container which is not focused. + *client.focused_tab_title* + A view that has focused descendant container. + Tab or stack container title that is the parent of the focused container + but is not directly focused. Defaults to focused_inactive if not + specified and does not use the indicator and child_border colors. + *client.placeholder* Ignored (present for i3 compatibility). @@ -554,6 +560,12 @@ The default colors are: : #ffffff : #484e50 : #5f676a +| *focused_tab_title* +: #333333 +: #5f676a +: #ffffff +: n/a +: n/a | *unfocused* : #333333 : #222222 diff --git a/sway/tree/container.c b/sway/tree/container.c index eb88b47e65..0284c9a5ef 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -64,6 +64,7 @@ void container_destroy(struct sway_container *con) { wlr_texture_destroy(con->title_focused_inactive); wlr_texture_destroy(con->title_unfocused); wlr_texture_destroy(con->title_urgent); + wlr_texture_destroy(con->title_focused_tab_title); list_free(con->pending.children); list_free(con->current.children); list_free(con->outputs); @@ -73,6 +74,7 @@ void container_destroy(struct sway_container *con) { wlr_texture_destroy(con->marks_focused_inactive); wlr_texture_destroy(con->marks_unfocused); wlr_texture_destroy(con->marks_urgent); + wlr_texture_destroy(con->marks_focused_tab_title); if (con->view) { if (con->view->container == con) { @@ -582,6 +584,8 @@ void container_update_title_textures(struct sway_container *container) { &config->border_colors.unfocused); update_title_texture(container, &container->title_urgent, &config->border_colors.urgent); + update_title_texture(container, &container->title_focused_tab_title, + &config->border_colors.focused_tab_title); container_damage_whole(container); } @@ -1635,6 +1639,8 @@ void container_update_marks_textures(struct sway_container *con) { &config->border_colors.unfocused); update_marks_texture(con, &con->marks_urgent, &config->border_colors.urgent); + update_marks_texture(con, &con->marks_focused_tab_title, + &config->border_colors.focused_tab_title); container_damage_whole(con); }