sway: Implement client.sticky colorclass

This commit is contained in:
qiu-x 2022-10-08 16:30:36 +02:00
parent 78b5c0a77e
commit 62c1fdc4bf
9 changed files with 127 additions and 8 deletions

View file

@ -114,9 +114,12 @@ sway_cmd cmd_client_noop;
sway_cmd cmd_client_focused; sway_cmd cmd_client_focused;
sway_cmd cmd_client_focused_inactive; sway_cmd cmd_client_focused_inactive;
sway_cmd cmd_client_focused_tab_title; 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_unfocused;
sway_cmd cmd_client_urgent; sway_cmd cmd_client_urgent;
sway_cmd cmd_client_placeholder;
sway_cmd cmd_client_background; sway_cmd cmd_client_background;
sway_cmd cmd_commands; sway_cmd cmd_commands;
sway_cmd cmd_create_output; sway_cmd cmd_create_output;

View file

@ -560,6 +560,12 @@ struct sway_config {
struct border_colors unfocused; struct border_colors unfocused;
struct border_colors urgent; struct border_colors urgent;
struct border_colors placeholder; 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]; float background[4];
} border_colors; } border_colors;

View file

@ -120,6 +120,9 @@ struct sway_container {
struct wlr_texture *title_focused_tab_title; struct wlr_texture *title_focused_tab_title;
struct wlr_texture *title_unfocused; struct wlr_texture *title_unfocused;
struct wlr_texture *title_urgent; 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 * list_t *marks; // char *
struct wlr_texture *marks_focused; struct wlr_texture *marks_focused;

View file

@ -54,6 +54,9 @@ static const struct cmd_handler handlers[] = {
{ "client.focused_inactive", cmd_client_focused_inactive }, { "client.focused_inactive", cmd_client_focused_inactive },
{ "client.focused_tab_title", cmd_client_focused_tab_title }, { "client.focused_tab_title", cmd_client_focused_tab_title },
{ "client.placeholder", cmd_client_noop }, { "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.unfocused", cmd_client_unfocused },
{ "client.urgent", cmd_client_urgent }, { "client.urgent", cmd_client_urgent },
{ "default_border", cmd_default_border }, { "default_border", cmd_default_border },

View file

@ -82,6 +82,24 @@ struct cmd_results *cmd_client_urgent(int argc, char **argv) {
&config->border_colors.urgent, "#900000ff"); &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) { struct cmd_results *cmd_client_noop(int argc, char **argv) {
sway_log(SWAY_INFO, "Warning: %s is ignored by sway", argv[-1]); sway_log(SWAY_INFO, "Warning: %s is ignored by sway", argv[-1]);
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);

View file

@ -44,6 +44,7 @@ struct cmd_results *cmd_sticky(int argc, char **argv) {
workspace_consider_destroy(old_workspace); workspace_consider_destroy(old_workspace);
} }
} }
container_update_representation(container);
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);
} }

View file

@ -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.indicator, 0x000000FF);
color_to_rgba(config->border_colors.placeholder.child_border, 0x0C0C0CFF); 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); color_to_rgba(config->border_colors.background, 0xFFFFFFFF);
// The keysym to keycode translation // The keysym to keycode translation
@ -343,6 +347,24 @@ cleanup:
sway_abort("Unable to allocate config structures"); 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) { static bool file_exists(const char *path) {
return path && access(path, R_OK) != -1; 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, success = success && load_config(path, config,
&config->swaynag_config_errors); &config->swaynag_config_errors);
// Needed for compatibility with i3
config_copy_missing(config);
if (validating) { if (validating) {
free_config(config); free_config(config);
config = old_config; config = old_config;

View file

@ -705,6 +705,7 @@ struct parent_data {
struct wlr_box box; struct wlr_box box;
list_t *children; list_t *children;
bool focused; bool focused;
bool sticky;
struct sway_container *active_child; 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 *title_texture;
struct wlr_texture *marks_texture; struct wlr_texture *marks_texture;
struct sway_container_state *state = &child->current; struct sway_container_state *state = &child->current;
bool is_sticky = parent->sticky;
if (view_is_urgent(view)) { if (view_is_urgent(view)) {
colors = &config->border_colors.urgent; colors = &config->border_colors.urgent;
title_texture = child->title_urgent; title_texture = child->title_urgent;
marks_texture = child->marks_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; colors = &config->border_colors.focused;
title_texture = child->title_focused; title_texture = child->title_focused;
marks_texture = child->marks_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; colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive; title_texture = child->title_focused_inactive;
marks_texture = child->marks_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 { } else {
colors = &config->border_colors.unfocused; colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused; title_texture = child->title_unfocused;
@ -792,23 +806,36 @@ static void render_containers_tabbed(struct sway_output *output,
struct wlr_texture *marks_texture; struct wlr_texture *marks_texture;
bool urgent = view ? bool urgent = view ?
view_is_urgent(view) : container_has_urgent_child(child); view_is_urgent(view) : container_has_urgent_child(child);
bool is_sticky = parent->sticky;
if (urgent) { if (urgent) {
colors = &config->border_colors.urgent; colors = &config->border_colors.urgent;
title_texture = child->title_urgent; title_texture = child->title_urgent;
marks_texture = child->marks_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; colors = &config->border_colors.focused;
title_texture = child->title_focused; title_texture = child->title_focused;
marks_texture = child->marks_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)) { } else if (config->has_focused_tab_title && container_has_focused_child(child)) {
colors = &config->border_colors.focused_tab_title; colors = &config->border_colors.focused_tab_title;
title_texture = child->title_focused_tab_title; title_texture = child->title_focused_tab_title;
marks_texture = child->marks_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; colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive; title_texture = child->title_focused_inactive;
marks_texture = child->marks_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 { } else {
colors = &config->border_colors.unfocused; colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused; title_texture = child->title_unfocused;
@ -861,23 +888,36 @@ static void render_containers_stacked(struct sway_output *output,
struct wlr_texture *marks_texture; struct wlr_texture *marks_texture;
bool urgent = view ? bool urgent = view ?
view_is_urgent(view) : container_has_urgent_child(child); view_is_urgent(view) : container_has_urgent_child(child);
bool is_sticky = parent->sticky;
if (urgent) { if (urgent) {
colors = &config->border_colors.urgent; colors = &config->border_colors.urgent;
title_texture = child->title_urgent; title_texture = child->title_urgent;
marks_texture = child->marks_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; colors = &config->border_colors.focused;
title_texture = child->title_focused; title_texture = child->title_focused;
marks_texture = child->marks_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)) { } else if (config->has_focused_tab_title && container_has_focused_child(child)) {
colors = &config->border_colors.focused_tab_title; colors = &config->border_colors.focused_tab_title;
title_texture = child->title_focused_tab_title; title_texture = child->title_focused_tab_title;
marks_texture = child->marks_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; colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive; title_texture = child->title_focused_inactive;
marks_texture = child->marks_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 { } else {
colors = &config->border_colors.unfocused; colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused; title_texture = child->title_unfocused;
@ -939,6 +979,7 @@ static void render_container(struct sway_output *output,
}, },
.children = con->current.children, .children = con->current.children,
.focused = focused, .focused = focused,
.sticky = container_is_sticky(con),
.active_child = con->current.focused_inactive_child, .active_child = con->current.focused_inactive_child,
}; };
render_containers(output, damage, &data); render_containers(output, damage, &data);
@ -956,6 +997,7 @@ static void render_workspace(struct sway_output *output,
}, },
.children = ws->current.tiling, .children = ws->current.tiling,
.focused = focused, .focused = focused,
.sticky = false,
.active_child = ws->current.focused_inactive_child, .active_child = ws->current.focused_inactive_child,
}; };
render_containers(output, damage, &data); render_containers(output, damage, &data);
@ -968,15 +1010,24 @@ static void render_floating_container(struct sway_output *soutput,
struct border_colors *colors; struct border_colors *colors;
struct wlr_texture *title_texture; struct wlr_texture *title_texture;
struct wlr_texture *marks_texture; struct wlr_texture *marks_texture;
bool is_sticky = container_is_sticky(con);
if (view_is_urgent(view)) { if (view_is_urgent(view)) {
colors = &config->border_colors.urgent; colors = &config->border_colors.urgent;
title_texture = con->title_urgent; title_texture = con->title_urgent;
marks_texture = con->marks_urgent; marks_texture = con->marks_urgent;
} else if (con->current.focused) { } else if (con->current.focused && !is_sticky) {
colors = &config->border_colors.focused; colors = &config->border_colors.focused;
title_texture = con->title_focused; title_texture = con->title_focused;
marks_texture = con->marks_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 { } else {
colors = &config->border_colors.unfocused; colors = &config->border_colors.unfocused;
title_texture = con->title_unfocused; title_texture = con->title_unfocused;

View file

@ -69,6 +69,9 @@ void container_destroy(struct sway_container *con) {
wlr_texture_destroy(con->title_focused_inactive); wlr_texture_destroy(con->title_focused_inactive);
wlr_texture_destroy(con->title_unfocused); wlr_texture_destroy(con->title_unfocused);
wlr_texture_destroy(con->title_urgent); 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); wlr_texture_destroy(con->title_focused_tab_title);
list_free(con->pending.children); list_free(con->pending.children);
list_free(con->current.children); list_free(con->current.children);
@ -594,6 +597,12 @@ void container_update_title_textures(struct sway_container *container) {
&config->border_colors.unfocused); &config->border_colors.unfocused);
update_title_texture(container, &container->title_urgent, update_title_texture(container, &container->title_urgent,
&config->border_colors.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, update_title_texture(container, &container->title_focused_tab_title,
&config->border_colors.focused_tab_title); &config->border_colors.focused_tab_title);
container_damage_whole(container); container_damage_whole(container);