From 62c1fdc4bf26327a83e153e2b5c30ec1c0119139 Mon Sep 17 00:00:00 2001 From: qiu-x Date: Sat, 8 Oct 2022 16:30:36 +0200 Subject: [PATCH] sway: Implement `client.sticky` colorclass --- include/sway/commands.h | 5 ++- include/sway/config.h | 6 ++++ include/sway/tree/container.h | 3 ++ sway/commands.c | 3 ++ sway/commands/client.c | 18 ++++++++++ sway/commands/sticky.c | 1 + sway/config.c | 25 ++++++++++++++ sway/desktop/render.c | 65 +++++++++++++++++++++++++++++++---- sway/tree/container.c | 9 +++++ 9 files changed, 127 insertions(+), 8 deletions(-) diff --git a/include/sway/commands.h b/include/sway/commands.h index 013a7b826..22c3d978b 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -114,9 +114,12 @@ 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_placeholder; +sway_cmd cmd_client_sticky; +sway_cmd cmd_client_sticky_inactive; +sway_cmd cmd_client_sticky_unfocused; sway_cmd cmd_client_unfocused; sway_cmd cmd_client_urgent; -sway_cmd cmd_client_placeholder; sway_cmd cmd_client_background; sway_cmd cmd_commands; sway_cmd cmd_create_output; diff --git a/include/sway/config.h b/include/sway/config.h index 68c068462..b6968a5bb 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -560,6 +560,12 @@ struct sway_config { struct border_colors unfocused; struct border_colors urgent; struct border_colors placeholder; + struct border_colors sticky; + bool sticky_is_set; + struct border_colors sticky_inactive; + bool sticky_inactive_is_set; + struct border_colors sticky_unfocused; + bool sticky_unfocused_is_set; float background[4]; } border_colors; diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 751612e2c..9c86599e8 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -120,6 +120,9 @@ struct sway_container { struct wlr_texture *title_focused_tab_title; struct wlr_texture *title_unfocused; struct wlr_texture *title_urgent; + struct wlr_texture *title_sticky; + struct wlr_texture *title_sticky_inactive; + struct wlr_texture *title_sticky_unfocused; list_t *marks; // char * struct wlr_texture *marks_focused; diff --git a/sway/commands.c b/sway/commands.c index 2160a970f..99f53a0e7 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -54,6 +54,9 @@ static const struct cmd_handler handlers[] = { { "client.focused_inactive", cmd_client_focused_inactive }, { "client.focused_tab_title", cmd_client_focused_tab_title }, { "client.placeholder", cmd_client_noop }, + { "client.sticky", cmd_client_sticky }, + { "client.sticky_inactive", cmd_client_sticky_inactive }, + { "client.sticky_unfocused", cmd_client_sticky_unfocused }, { "client.unfocused", cmd_client_unfocused }, { "client.urgent", cmd_client_urgent }, { "default_border", cmd_default_border }, diff --git a/sway/commands/client.c b/sway/commands/client.c index 772631456..f1d34a6b5 100644 --- a/sway/commands/client.c +++ b/sway/commands/client.c @@ -82,6 +82,24 @@ struct cmd_results *cmd_client_urgent(int argc, char **argv) { &config->border_colors.urgent, "#900000ff"); } +struct cmd_results *cmd_client_sticky(int argc, char **argv) { + config->border_colors.sticky_is_set = true; + return handle_command(argc, argv, "client.sticky", + &config->border_colors.sticky, "#2e9ef4ff"); +} + +struct cmd_results *cmd_client_sticky_inactive(int argc, char **argv) { + config->border_colors.sticky_inactive_is_set = true; + return handle_command(argc, argv, "client.sticky_inactive", + &config->border_colors.sticky_inactive, "#484e50ff"); +} + +struct cmd_results *cmd_client_sticky_unfocused(int argc, char **argv) { + config->border_colors.sticky_unfocused_is_set = true; + return handle_command(argc, argv, "client.sticky_unfocused", + &config->border_colors.sticky_unfocused, "#292d2eff"); +} + 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); diff --git a/sway/commands/sticky.c b/sway/commands/sticky.c index 9b09a0f9d..200995539 100644 --- a/sway/commands/sticky.c +++ b/sway/commands/sticky.c @@ -44,6 +44,7 @@ struct cmd_results *cmd_sticky(int argc, char **argv) { workspace_consider_destroy(old_workspace); } } + container_update_representation(container); return cmd_results_new(CMD_SUCCESS, NULL); } diff --git a/sway/config.c b/sway/config.c index b41dd871b..f1644d7ed 100644 --- a/sway/config.c +++ b/sway/config.c @@ -331,6 +331,10 @@ static void config_defaults(struct sway_config *config) { color_to_rgba(config->border_colors.placeholder.indicator, 0x000000FF); color_to_rgba(config->border_colors.placeholder.child_border, 0x0C0C0CFF); + config->border_colors.sticky_is_set = false; + config->border_colors.sticky_inactive_is_set = false; + config->border_colors.sticky_inactive_is_set = false; + color_to_rgba(config->border_colors.background, 0xFFFFFFFF); // The keysym to keycode translation @@ -343,6 +347,24 @@ cleanup: sway_abort("Unable to allocate config structures"); } +static void config_copy_missing(struct sway_config *config) { + if (!config->border_colors.sticky_is_set) { + memcpy(&config->border_colors.sticky, + &config->border_colors.focused, + sizeof(struct border_colors)); + } + if (!config->border_colors.sticky_inactive_is_set) { + memcpy(&config->border_colors.sticky_inactive, + &config->border_colors.focused_inactive, + sizeof(struct border_colors)); + } + if (!config->border_colors.sticky_inactive_is_set) { + memcpy(&config->border_colors.sticky_unfocused, + &config->border_colors.unfocused, + sizeof(struct border_colors)); + } +} + static bool file_exists(const char *path) { return path && access(path, R_OK) != -1; } @@ -544,6 +566,9 @@ bool load_main_config(const char *file, bool is_active, bool validating) { success = success && load_config(path, config, &config->swaynag_config_errors); + // Needed for compatibility with i3 + config_copy_missing(config); + if (validating) { free_config(config); config = old_config; diff --git a/sway/desktop/render.c b/sway/desktop/render.c index ed9ad4906..a51fc181b 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -705,6 +705,7 @@ struct parent_data { struct wlr_box box; list_t *children; bool focused; + bool sticky; struct sway_container *active_child; }; @@ -728,19 +729,32 @@ static void render_containers_linear(struct sway_output *output, struct wlr_texture *title_texture; struct wlr_texture *marks_texture; struct sway_container_state *state = &child->current; + bool is_sticky = parent->sticky; if (view_is_urgent(view)) { colors = &config->border_colors.urgent; title_texture = child->title_urgent; marks_texture = child->marks_urgent; - } else if (state->focused || parent->focused) { + } else if ((state->focused || parent->focused) && !is_sticky) { colors = &config->border_colors.focused; title_texture = child->title_focused; marks_texture = child->marks_focused; - } else if (child == parent->active_child) { + } else if ((state->focused || parent->focused) && is_sticky) { + colors = &config->border_colors.sticky; + title_texture = child->title_sticky; + marks_texture = child->marks_focused; + } else if (child == parent->active_child && !is_sticky) { colors = &config->border_colors.focused_inactive; title_texture = child->title_focused_inactive; marks_texture = child->marks_focused_inactive; + } else if (child == parent->active_child && is_sticky) { + colors = &config->border_colors.sticky_inactive; + title_texture = child->title_sticky_inactive; + marks_texture = child->marks_focused_inactive; + } else if (is_sticky) { + colors = &config->border_colors.sticky_unfocused; + title_texture = child->title_sticky_unfocused; + marks_texture = child->marks_unfocused; } else { colors = &config->border_colors.unfocused; title_texture = child->title_unfocused; @@ -792,23 +806,36 @@ static void render_containers_tabbed(struct sway_output *output, struct wlr_texture *marks_texture; bool urgent = view ? view_is_urgent(view) : container_has_urgent_child(child); + bool is_sticky = parent->sticky; if (urgent) { colors = &config->border_colors.urgent; title_texture = child->title_urgent; marks_texture = child->marks_urgent; - } else if (cstate->focused || parent->focused) { + } else if ((cstate->focused || parent->focused) && !is_sticky) { colors = &config->border_colors.focused; title_texture = child->title_focused; marks_texture = child->marks_focused; + } else if ((cstate->focused || parent->focused) && is_sticky) { + colors = &config->border_colors.sticky; + title_texture = child->title_sticky; + 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) { + } else if (child == parent->active_child && !is_sticky) { colors = &config->border_colors.focused_inactive; title_texture = child->title_focused_inactive; marks_texture = child->marks_focused_inactive; + } else if (child == parent->active_child && is_sticky) { + colors = &config->border_colors.sticky_inactive; + title_texture = child->title_sticky_inactive; + marks_texture = child->marks_focused_inactive; + } else if (is_sticky) { + colors = &config->border_colors.sticky_unfocused; + title_texture = child->title_sticky_unfocused; + marks_texture = child->marks_unfocused; } else { colors = &config->border_colors.unfocused; title_texture = child->title_unfocused; @@ -861,23 +888,36 @@ static void render_containers_stacked(struct sway_output *output, struct wlr_texture *marks_texture; bool urgent = view ? view_is_urgent(view) : container_has_urgent_child(child); + bool is_sticky = parent->sticky; if (urgent) { colors = &config->border_colors.urgent; title_texture = child->title_urgent; marks_texture = child->marks_urgent; - } else if (cstate->focused || parent->focused) { + } else if ((cstate->focused || parent->focused) && !is_sticky) { colors = &config->border_colors.focused; title_texture = child->title_focused; marks_texture = child->marks_focused; + } else if ((cstate->focused || parent->focused) && is_sticky) { + colors = &config->border_colors.sticky; + title_texture = child->title_sticky; + 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) { + } else if (child == parent->active_child && !is_sticky) { colors = &config->border_colors.focused_inactive; title_texture = child->title_focused_inactive; marks_texture = child->marks_focused_inactive; + } else if (child == parent->active_child && is_sticky) { + colors = &config->border_colors.sticky_inactive; + title_texture = child->title_sticky_inactive; + marks_texture = child->marks_focused_inactive; + } else if (is_sticky) { + colors = &config->border_colors.sticky_unfocused; + title_texture = child->title_sticky_unfocused; + marks_texture = child->marks_unfocused; } else { colors = &config->border_colors.unfocused; title_texture = child->title_unfocused; @@ -939,6 +979,7 @@ static void render_container(struct sway_output *output, }, .children = con->current.children, .focused = focused, + .sticky = container_is_sticky(con), .active_child = con->current.focused_inactive_child, }; render_containers(output, damage, &data); @@ -956,6 +997,7 @@ static void render_workspace(struct sway_output *output, }, .children = ws->current.tiling, .focused = focused, + .sticky = false, .active_child = ws->current.focused_inactive_child, }; render_containers(output, damage, &data); @@ -968,15 +1010,24 @@ static void render_floating_container(struct sway_output *soutput, struct border_colors *colors; struct wlr_texture *title_texture; struct wlr_texture *marks_texture; + bool is_sticky = container_is_sticky(con); if (view_is_urgent(view)) { colors = &config->border_colors.urgent; title_texture = con->title_urgent; marks_texture = con->marks_urgent; - } else if (con->current.focused) { + } else if (con->current.focused && !is_sticky) { colors = &config->border_colors.focused; title_texture = con->title_focused; marks_texture = con->marks_focused; + } else if (con->current.focused && is_sticky) { + colors = &config->border_colors.sticky; + title_texture = con->title_sticky; + marks_texture = con->marks_focused; + } else if (is_sticky) { + colors = &config->border_colors.sticky_unfocused; + title_texture = con->title_sticky_unfocused; + marks_texture = con->marks_unfocused; } else { colors = &config->border_colors.unfocused; title_texture = con->title_unfocused; diff --git a/sway/tree/container.c b/sway/tree/container.c index 04ef965f8..6f039deda 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -69,6 +69,9 @@ 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_sticky); + wlr_texture_destroy(con->title_sticky_inactive); + wlr_texture_destroy(con->title_sticky_unfocused); wlr_texture_destroy(con->title_focused_tab_title); list_free(con->pending.children); list_free(con->current.children); @@ -594,6 +597,12 @@ 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_sticky, + &config->border_colors.sticky); + update_title_texture(container, &container->title_sticky_inactive, + &config->border_colors.sticky_inactive); + update_title_texture(container, &container->title_sticky_unfocused, + &config->border_colors.sticky_unfocused); update_title_texture(container, &container->title_focused_tab_title, &config->border_colors.focused_tab_title); container_damage_whole(container);