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_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;

View file

@ -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;

View file

@ -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;

View file

@ -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 },

View file

@ -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);

View file

@ -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);
}

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.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;

View file

@ -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;

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_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);