This commit is contained in:
33KK 2025-02-10 10:35:21 -05:00 committed by GitHub
commit ff032a4bed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 110 additions and 1 deletions

View file

@ -245,6 +245,7 @@ sway_cmd bar_colors_cmd_focused_separator;
sway_cmd bar_colors_cmd_statusline; sway_cmd bar_colors_cmd_statusline;
sway_cmd bar_colors_cmd_focused_statusline; sway_cmd bar_colors_cmd_focused_statusline;
sway_cmd bar_colors_cmd_urgent_workspace; sway_cmd bar_colors_cmd_urgent_workspace;
sway_cmd bar_colors_cmd_empty_workspace;
sway_cmd input_cmd_seat; sway_cmd input_cmd_seat;
sway_cmd input_cmd_accel_profile; sway_cmd input_cmd_accel_profile;

View file

@ -394,6 +394,9 @@ struct bar_config {
char *urgent_workspace_border; char *urgent_workspace_border;
char *urgent_workspace_bg; char *urgent_workspace_bg;
char *urgent_workspace_text; char *urgent_workspace_text;
char *empty_workspace_border;
char *empty_workspace_bg;
char *empty_workspace_text;
char *binding_mode_border; char *binding_mode_border;
char *binding_mode_bg; char *binding_mode_bg;
char *binding_mode_text; char *binding_mode_text;

View file

@ -49,6 +49,7 @@ struct sway_workspace {
list_t *tiling; // struct sway_container list_t *tiling; // struct sway_container
list_t *output_priority; list_t *output_priority;
bool urgent; bool urgent;
bool persistent;
struct sway_workspace_state current; struct sway_workspace_state current;
}; };

View file

@ -88,6 +88,7 @@ struct swaybar_workspace {
bool focused; bool focused;
bool visible; bool visible;
bool urgent; bool urgent;
bool empty;
}; };
bool bar_setup(struct swaybar *bar, const char *socket_path); bool bar_setup(struct swaybar *bar, const char *socket_path);

View file

@ -65,6 +65,7 @@ struct swaybar_config {
struct box_colors active_workspace; struct box_colors active_workspace;
struct box_colors inactive_workspace; struct box_colors inactive_workspace;
struct box_colors urgent_workspace; struct box_colors urgent_workspace;
struct box_colors empty_workspace;
struct box_colors binding_mode; struct box_colors binding_mode;
} colors; } colors;

View file

@ -8,6 +8,7 @@ static const struct cmd_handler bar_colors_handlers[] = {
{ "active_workspace", bar_colors_cmd_active_workspace }, { "active_workspace", bar_colors_cmd_active_workspace },
{ "background", bar_colors_cmd_background }, { "background", bar_colors_cmd_background },
{ "binding_mode", bar_colors_cmd_binding_mode }, { "binding_mode", bar_colors_cmd_binding_mode },
{ "empty_workspace", bar_colors_cmd_empty_workspace },
{ "focused_background", bar_colors_cmd_focused_background }, { "focused_background", bar_colors_cmd_focused_background },
{ "focused_separator", bar_colors_cmd_focused_separator }, { "focused_separator", bar_colors_cmd_focused_separator },
{ "focused_statusline", bar_colors_cmd_focused_statusline }, { "focused_statusline", bar_colors_cmd_focused_statusline },
@ -150,3 +151,12 @@ struct cmd_results *bar_colors_cmd_urgent_workspace(int argc, char **argv) {
}; };
return parse_three_colors(colors, "urgent_workspace", argc, argv); return parse_three_colors(colors, "urgent_workspace", argc, argv);
} }
struct cmd_results *bar_colors_cmd_empty_workspace(int argc, char **argv) {
char **colors[3] = {
&(config->current_bar->colors.empty_workspace_border),
&(config->current_bar->colors.empty_workspace_bg),
&(config->current_bar->colors.empty_workspace_text)
};
return parse_three_colors(colors, "empty_workspace", argc, argv);
}

View file

@ -9,6 +9,7 @@
#include "list.h" #include "list.h"
#include "log.h" #include "log.h"
#include "stringop.h" #include "stringop.h"
#include "util.h"
static struct workspace_config *workspace_config_find_or_create(char *ws_name) { static struct workspace_config *workspace_config_find_or_create(char *ws_name) {
struct workspace_config *wsc = workspace_find_config(ws_name); struct workspace_config *wsc = workspace_find_config(ws_name);
@ -129,6 +130,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
int output_location = -1; int output_location = -1;
int gaps_location = -1; int gaps_location = -1;
int persistent_location = -1;
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
if (strcasecmp(argv[i], "output") == 0) { if (strcasecmp(argv[i], "output") == 0) {
@ -142,6 +144,13 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
break; break;
} }
} }
for (int i = 0; i < argc; ++i) {
if (strcasecmp(argv[i], "persistent") == 0) {
persistent_location = i;
break;
}
}
if (output_location == 0) { if (output_location == 0) {
return cmd_results_new(CMD_INVALID, return cmd_results_new(CMD_INVALID,
"Expected 'workspace <name> output <output>'"); "Expected 'workspace <name> output <output>'");
@ -164,6 +173,24 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
if ((error = cmd_workspace_gaps(argc, argv, gaps_location))) { if ((error = cmd_workspace_gaps(argc, argv, gaps_location))) {
return error; return error;
} }
} else if (persistent_location == 0) {
return cmd_results_new(CMD_INVALID,
"Expected 'workspace <name> persistent yes|no'");
} else if (persistent_location > 0) {
if ((error = checkarg(argc, "workspace", EXPECTED_AT_LEAST,
persistent_location + 2))) {
return error;
}
struct sway_workspace *ws = NULL;
char *ws_name = join_args(argv, persistent_location);
if (!(ws = workspace_by_name(ws_name))) {
ws = workspace_create(NULL, ws_name);
}
free(ws_name);
ws->persistent = parse_boolean(argv[persistent_location + 1], ws->persistent);
workspace_consider_destroy(ws);
} else { } else {
if (config->reading || !config->active) { if (config->reading || !config->active) {
return cmd_results_new(CMD_DEFER, NULL); return cmd_results_new(CMD_DEFER, NULL);

View file

@ -67,6 +67,9 @@ void free_bar_config(struct bar_config *bar) {
free(bar->colors.urgent_workspace_border); free(bar->colors.urgent_workspace_border);
free(bar->colors.urgent_workspace_bg); free(bar->colors.urgent_workspace_bg);
free(bar->colors.urgent_workspace_text); free(bar->colors.urgent_workspace_text);
free(bar->colors.empty_workspace_border);
free(bar->colors.empty_workspace_bg);
free(bar->colors.empty_workspace_text);
free(bar->colors.binding_mode_border); free(bar->colors.binding_mode_border);
free(bar->colors.binding_mode_bg); free(bar->colors.binding_mode_bg);
free(bar->colors.binding_mode_text); free(bar->colors.binding_mode_text);
@ -161,6 +164,15 @@ struct bar_config *default_bar_config(void) {
if (!(bar->colors.urgent_workspace_text = strndup("#ffffffff", 9))) { if (!(bar->colors.urgent_workspace_text = strndup("#ffffffff", 9))) {
goto cleanup; goto cleanup;
} }
if (!(bar->colors.empty_workspace_border = strndup("#000000ff", 9))) {
goto cleanup;
}
if (!(bar->colors.empty_workspace_bg = strndup("#000000ff", 9))) {
goto cleanup;
}
if (!(bar->colors.empty_workspace_text = strndup("#666666FF", 9))) {
goto cleanup;
}
// if the following colors stay undefined, they fall back to background, // if the following colors stay undefined, they fall back to background,
// statusline, separator and urgent_workspace_*. // statusline, separator and urgent_workspace_*.
bar->colors.focused_background = NULL; bar->colors.focused_background = NULL;

View file

@ -511,6 +511,8 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace,
json_object_new_string(workspace->output->wlr_output->name) : NULL); json_object_new_string(workspace->output->wlr_output->name) : NULL);
json_object_object_add(object, "urgent", json_object_object_add(object, "urgent",
json_object_new_boolean(workspace->urgent)); json_object_new_boolean(workspace->urgent));
json_object_object_add(object, "empty",
json_object_new_boolean(workspace_is_empty(workspace)));
json_object_object_add(object, "representation", workspace->representation ? json_object_object_add(object, "representation", workspace->representation ?
json_object_new_string(workspace->representation) : NULL); json_object_new_string(workspace->representation) : NULL);
@ -1364,6 +1366,13 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
json_object_object_add(colors, "urgent_workspace_text", json_object_object_add(colors, "urgent_workspace_text",
json_object_new_string(bar->colors.urgent_workspace_text)); json_object_new_string(bar->colors.urgent_workspace_text));
json_object_object_add(colors, "empty_workspace_border",
json_object_new_string(bar->colors.empty_workspace_border));
json_object_object_add(colors, "empty_workspace_bg",
json_object_new_string(bar->colors.empty_workspace_bg));
json_object_object_add(colors, "empty_workspace_text",
json_object_new_string(bar->colors.empty_workspace_text));
if (bar->colors.binding_mode_border) { if (bar->colors.binding_mode_border) {
json_object_object_add(colors, "binding_mode_border", json_object_object_add(colors, "binding_mode_border",
json_object_new_string(bar->colors.binding_mode_border)); json_object_new_string(bar->colors.binding_mode_border));

View file

@ -228,6 +228,10 @@ must be defined in hex: _#RRGGBB_ or _#RRGGBBAA_.
Border, background and text color for a workspace button when the workspace Border, background and text color for a workspace button when the workspace
contains a window with the urgency hint set. contains a window with the urgency hint set.
*empty_workspace* <border> <background> <text>
Border, background and text color for a workspace button when the workspace
contains no windows and is not active.
*binding_mode* <border> <background> <text> *binding_mode* <border> <background> <text>
Border, background and text color for the binding mode indicator. If not used, Border, background and text color for the binding mode indicator. If not used,
the colors will be taken from _urgent_workspace_. the colors will be taken from _urgent_workspace_.

View file

@ -139,6 +139,9 @@ has the following properties:
|- urgent |- urgent
: boolean : boolean
: Whether a view on the workspace has the urgent flag set : Whether a view on the workspace has the urgent flag set
|- empty
: boolean
: Whether the workspace is empty
|- rect |- rect
: object : object
: The bounds of the workspace. It consists of _x_, _y_, _width_, and _height_ : The bounds of the workspace. It consists of _x_, _y_, _width_, and _height_
@ -931,6 +934,15 @@ containing the _#RRGGBBAA_ representation of the color:
|- urgent_workspace_border |- urgent_workspace_border
: The color to use for the border of the workspace buttons for workspaces that : The color to use for the border of the workspace buttons for workspaces that
contain an urgent view contain an urgent view
|- empty_workspace_text
: The color to use for the text of the workspace buttons for workspaces that
are empty
|- empty_workspace_bg
: The color to use for the background of the workspace buttons for workspaces
that are empty
|- empty_workspace_border
: The color to use for the border of the workspace buttons for workspaces that
are empty
|- binding_mode_text |- binding_mode_text
: The color to use for the text of the binding mode indicator : The color to use for the text of the binding mode indicator
|- binding_mode_bg |- binding_mode_bg
@ -980,6 +992,9 @@ containing the _#RRGGBBAA_ representation of the color:
"urgent_workspace_border": "#2f343aff", "urgent_workspace_border": "#2f343aff",
"urgent_workspace_bg": "#900000ff", "urgent_workspace_bg": "#900000ff",
"urgent_workspace_text": "#ffffffff", "urgent_workspace_text": "#ffffffff",
"empty_workspace_border": "#000000ff",
"empty_workspace_bg": "#000000ff",
"empty_workspace_text": "#666666ff",
"binding_mode_border": "#2f343aff", "binding_mode_border": "#2f343aff",
"binding_mode_bg": "#900000ff", "binding_mode_bg": "#900000ff",
"binding_mode_text": "#ffffffff" "binding_mode_text": "#ffffffff"
@ -1585,6 +1600,7 @@ The following change types are currently available:
"num": 2, "num": 2,
"output": "eDP-1", "output": "eDP-1",
"type": "workspace", "type": "workspace",
"empty": true,
"representation": null, "representation": null,
"nodes": [ "nodes": [
] ]

View file

@ -961,6 +961,13 @@ The default colors are:
criteria (non-empty workspaces only) or _workspace_ command (to switch criteria (non-empty workspaces only) or _workspace_ command (to switch
to the workspace before moving). to the workspace before moving).
*workspace* <name> persistent yes|no
Specifies that workspace _name_ should not be destroyed when it is empty and
inactive.
This command will apply to an existing workspace or create it if it doesn't
exist.
*workspace_auto_back_and_forth* yes|no *workspace_auto_back_and_forth* yes|no
When _yes_, repeating a workspace switch command will switch back to the When _yes_, repeating a workspace switch command will switch back to the
prior workspace. For example, if you are currently on workspace 1, prior workspace. For example, if you are currently on workspace 1,

View file

@ -89,6 +89,7 @@ struct sway_workspace *workspace_create(struct sway_output *output,
ws->floating = create_list(); ws->floating = create_list();
ws->tiling = create_list(); ws->tiling = create_list();
ws->output_priority = create_list(); ws->output_priority = create_list();
ws->persistent = false;
ws->gaps_outer = config->gaps_outer; ws->gaps_outer = config->gaps_outer;
ws->gaps_inner = config->gaps_inner; ws->gaps_inner = config->gaps_inner;
@ -187,6 +188,11 @@ void workspace_consider_destroy(struct sway_workspace *ws) {
} }
} }
if (ws->persistent) {
ipc_event_workspace(NULL, ws, "empty");
return;
}
workspace_begin_destroy(ws); workspace_begin_destroy(ws);
} }

View file

@ -72,6 +72,10 @@ struct swaybar_config *init_config(void) {
config->colors.urgent_workspace.background = 0x900000FF; config->colors.urgent_workspace.background = 0x900000FF;
config->colors.urgent_workspace.text = 0xFFFFFFFF; config->colors.urgent_workspace.text = 0xFFFFFFFF;
config->colors.empty_workspace.border = 0x000000FF;
config->colors.empty_workspace.background = 0x000000FF;
config->colors.empty_workspace.text = 0x666666FF;
config->colors.binding_mode.border = 0x2F343AFF; config->colors.binding_mode.border = 0x2F343AFF;
config->colors.binding_mode.background = 0x900000FF; config->colors.binding_mode.background = 0x900000FF;
config->colors.binding_mode.text = 0xFFFFFFFF; config->colors.binding_mode.text = 0xFFFFFFFF;

View file

@ -77,6 +77,9 @@ static void ipc_parse_colors(
{ "urgent_workspace_border", &config->colors.urgent_workspace.border }, { "urgent_workspace_border", &config->colors.urgent_workspace.border },
{ "urgent_workspace_bg", &config->colors.urgent_workspace.background }, { "urgent_workspace_bg", &config->colors.urgent_workspace.background },
{ "urgent_workspace_text", &config->colors.urgent_workspace.text }, { "urgent_workspace_text", &config->colors.urgent_workspace.text },
{ "empty_workspace_border", &config->colors.empty_workspace.border },
{ "empty_workspace_bg", &config->colors.empty_workspace.background },
{ "empty_workspace_text", &config->colors.empty_workspace.text },
{ "binding_mode_border", &config->colors.binding_mode.border }, { "binding_mode_border", &config->colors.binding_mode.border },
{ "binding_mode_bg", &config->colors.binding_mode.background }, { "binding_mode_bg", &config->colors.binding_mode.background },
{ "binding_mode_text", &config->colors.binding_mode.text }, { "binding_mode_text", &config->colors.binding_mode.text },
@ -355,7 +358,7 @@ bool ipc_get_workspaces(struct swaybar *bar) {
bar->visible_by_urgency = false; bar->visible_by_urgency = false;
size_t length = json_object_array_length(results); size_t length = json_object_array_length(results);
json_object *ws_json; json_object *ws_json;
json_object *num, *name, *visible, *focused, *out, *urgent; json_object *num, *name, *visible, *focused, *out, *urgent, *empty;
for (size_t i = 0; i < length; ++i) { for (size_t i = 0; i < length; ++i) {
ws_json = json_object_array_get_idx(results, i); ws_json = json_object_array_get_idx(results, i);
@ -365,6 +368,7 @@ bool ipc_get_workspaces(struct swaybar *bar) {
json_object_object_get_ex(ws_json, "focused", &focused); json_object_object_get_ex(ws_json, "focused", &focused);
json_object_object_get_ex(ws_json, "output", &out); json_object_object_get_ex(ws_json, "output", &out);
json_object_object_get_ex(ws_json, "urgent", &urgent); json_object_object_get_ex(ws_json, "urgent", &urgent);
json_object_object_get_ex(ws_json, "empty", &empty);
wl_list_for_each(output, &bar->outputs, link) { wl_list_for_each(output, &bar->outputs, link) {
const char *ws_output = json_object_get_string(out); const char *ws_output = json_object_get_string(out);
@ -399,6 +403,7 @@ bool ipc_get_workspaces(struct swaybar *bar) {
if (ws->urgent) { if (ws->urgent) {
bar->visible_by_urgency = true; bar->visible_by_urgency = true;
} }
ws->empty = json_object_get_boolean(empty);
wl_list_insert(output->workspaces.prev, &ws->link); wl_list_insert(output->workspaces.prev, &ws->link);
} }
} }

View file

@ -625,6 +625,8 @@ static uint32_t render_workspace_button(struct render_context *ctx,
box_colors = config->colors.focused_workspace; box_colors = config->colors.focused_workspace;
} else if (ws->visible) { } else if (ws->visible) {
box_colors = config->colors.active_workspace; box_colors = config->colors.active_workspace;
} else if (ws->empty) {
box_colors = config->colors.empty_workspace;
} else { } else {
box_colors = config->colors.inactive_workspace; box_colors = config->colors.inactive_workspace;
} }