Last active
November 26, 2021 19:49
-
-
Save woodensquares/c1afc4fb56b4d9d21fa261fb4b28b092 to your computer and use it in GitHub Desktop.
Ignore specific workspaces in pager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -W 183 -duw --recursive i3.clean/i3bar/include/configuration.h i3/i3bar/include/configuration.h | |
--- i3.clean/i3bar/include/configuration.h 2021-11-17 09:55:19.357028521 -0600 | |
+++ i3/i3bar/include/configuration.h 2021-11-17 09:55:52.902415932 -0600 | |
@@ -54,6 +54,7 @@ | |
char *command; | |
char *fontname; | |
i3String *separator_symbol; | |
+ i3String *ignore_end; | |
TAILQ_HEAD(tray_outputs_head, tray_output_t) tray_outputs; | |
int tray_padding; | |
int num_outputs; | |
diff -W 183 -duw --recursive i3.clean/i3bar/include/workspaces.h i3/i3bar/include/workspaces.h | |
--- i3.clean/i3bar/include/workspaces.h 2021-11-17 09:55:19.357736554 -0600 | |
+++ i3/i3bar/include/workspaces.h 2021-11-17 09:55:52.917356007 -0600 | |
@@ -29,6 +29,12 @@ | |
*/ | |
void free_workspaces(void); | |
+/* | |
+ * check if the workspace should be skipped in the pager based on its name | |
+ * | |
+ */ | |
+bool skippable_workspace(i3String *ts); | |
+ | |
struct i3_ws { | |
uintptr_t id; /* Workspace ID - C pointer to a workspace container */ | |
int num; /* The internal number of the ws */ | |
diff -W 183 -duw --recursive i3.clean/i3bar/src/config.c i3/i3bar/src/config.c | |
--- i3.clean/i3bar/src/config.c 2021-11-17 09:55:19.358477395 -0600 | |
+++ i3/i3bar/src/config.c 2021-11-17 09:55:52.931900258 -0600 | |
@@ -202,6 +202,13 @@ | |
return 1; | |
} | |
+ if (!strcmp(cur_key, "ignore_workspaces_ending_with")) { | |
+ DLOG("ignore = %.*s\n", len, val); | |
+ I3STRING_FREE(config.ignore_end); | |
+ config.ignore_end = i3string_from_utf8_with_length((const char *)val, len); | |
+ return 1; | |
+ } | |
+ | |
if (!strcmp(cur_key, "outputs")) { | |
DLOG("+output %.*s\n", len, val); | |
int new_num_outputs = config.num_outputs + 1; | |
diff -W 183 -duw --recursive i3.clean/i3bar/src/workspaces.c i3/i3bar/src/workspaces.c | |
--- i3.clean/i3bar/src/workspaces.c 2021-11-17 09:55:19.359298224 -0600 | |
+++ i3/i3bar/src/workspaces.c 2021-11-17 09:55:52.946174683 -0600 | |
@@ -257,6 +257,41 @@ | |
} | |
/* | |
+ * check if the workspace should be skipped in the pager based on its name | |
+ * | |
+ */ | |
+bool skippable_workspace(i3String *ts) { | |
+ const char *uts, *uconf; | |
+ size_t lts, lconf; | |
+ | |
+ /* Not configured, return */ | |
+ if (config.ignore_end == NULL) | |
+ return false; | |
+ | |
+ /* For the comparison use unicode, we don't have to interpret things | |
+ just a dumb check that the bytes are the same is enough */ | |
+ uts = i3string_as_utf8(ts); | |
+ lts = i3string_get_num_bytes(ts); | |
+ uconf = i3string_as_utf8(config.ignore_end); | |
+ lconf = i3string_get_num_bytes(config.ignore_end); | |
+ | |
+ /* If the workspace name is shorter it won't match for sure */ | |
+ if (lconf > lts) | |
+ return false; | |
+ | |
+ size_t offset = lts - lconf; | |
+ bool skip = true; | |
+ for (int i=lconf-1; i >= 0; i--) { | |
+ if (uts[i + offset] != uconf[i]) { | |
+ skip = false; | |
+ break; | |
+ } | |
+ } | |
+ | |
+ return skip; | |
+} | |
+ | |
+/* | |
* free() all workspace data structures. Does not free() the heads of the tailqueues. | |
* | |
*/ | |
diff -W 183 -duw --recursive i3.clean/i3bar/src/xcb.c i3/i3bar/src/xcb.c | |
--- i3.clean/i3bar/src/xcb.c 2021-11-17 09:55:19.359654182 -0600 | |
+++ i3/i3bar/src/xcb.c 2021-11-17 09:59:54.953352726 -0600 | |
@@ -531,6 +531,14 @@ | |
i3_ws *cur_ws = NULL, *clicked_ws = NULL, *ws_walk; | |
TAILQ_FOREACH (ws_walk, walk->workspaces, tailq) { | |
+ if (skippable_workspace(ws_walk->name)) { | |
+ /* Update cur_ws if needed */ | |
+ if (ws_walk->visible) { | |
+ cur_ws = ws_walk; | |
+ } | |
+ continue; | |
+ } | |
+ | |
int w = predict_button_width(ws_walk->name_width); | |
if (x >= workspace_width && x <= workspace_width + w) | |
clicked_ws = ws_walk; | |
@@ -2017,6 +2025,8 @@ | |
if (!config.disable_ws) { | |
i3_ws *ws_walk; | |
TAILQ_FOREACH (ws_walk, outputs_walk->workspaces, tailq) { | |
+ if (skippable_workspace(ws_walk->name)) | |
+ continue; | |
DLOG("Drawing button for WS %s at x = %d, len = %d\n", | |
i3string_as_utf8(ws_walk->name), workspace_width, ws_walk->name_width); | |
color_t fg_color = colors.inactive_ws_fg; | |
diff -W 183 -duw --recursive i3.clean/include/config_directives.h i3/include/config_directives.h | |
--- i3.clean/include/config_directives.h 2021-11-17 09:55:19.360658749 -0600 | |
+++ i3/include/config_directives.h 2021-11-17 09:55:52.980286004 -0600 | |
@@ -79,6 +79,7 @@ | |
CFGFUN(bar_font, const char *font); | |
CFGFUN(bar_separator_symbol, const char *separator); | |
+CFGFUN(bar_ignore_end, const char *ignore); | |
CFGFUN(bar_mode, const char *mode); | |
CFGFUN(bar_hidden_state, const char *hidden_state); | |
CFGFUN(bar_id, const char *bar_id); | |
diff -W 183 -duw --recursive i3.clean/include/configuration.h i3/include/configuration.h | |
--- i3.clean/include/configuration.h 2021-11-17 09:55:41.829865553 -0600 | |
+++ i3/include/configuration.h 2021-11-17 09:55:52.997143422 -0600 | |
@@ -327,6 +327,9 @@ | |
/** A custom separator to use instead of a vertical line. */ | |
char *separator_symbol; | |
+ /** Do not display workspaces ending with this in i3bar. */ | |
+ char *ignore_end; | |
+ | |
/** Hide workspace buttons? Configuration option is 'workspace_buttons no' | |
* but we invert the bool to get the correct default when initializing with | |
* zero. */ | |
diff -W 183 -duw --recursive i3.clean/parser-specs/config.spec i3/parser-specs/config.spec | |
--- i3.clean/parser-specs/config.spec 2021-11-17 09:55:41.832565380 -0600 | |
+++ i3/parser-specs/config.spec 2021-11-17 09:55:53.013092073 -0600 | |
@@ -493,6 +493,7 @@ | |
'tray_padding' -> BAR_TRAY_PADDING | |
'font' -> BAR_FONT | |
'separator_symbol' -> BAR_SEPARATOR_SYMBOL | |
+ 'ignore_workspaces_ending_with' -> BAR_IGNORE_END | |
'binding_mode_indicator' -> BAR_BINDING_MODE_INDICATOR | |
'workspace_buttons' -> BAR_WORKSPACE_BUTTONS | |
'workspace_min_width' -> BAR_WORKSPACE_MIN_WIDTH | |
@@ -592,6 +593,10 @@ | |
separator = string | |
-> call cfg_bar_separator_symbol($separator); BAR | |
+state BAR_IGNORE_END: | |
+ ignore_end = string | |
+ -> call cfg_bar_ignore_end($ignore_end); BAR | |
+ | |
state BAR_BINDING_MODE_INDICATOR: | |
value = word | |
-> call cfg_bar_binding_mode_indicator($value); BAR | |
diff -W 183 -duw --recursive i3.clean/src/config_directives.c i3/src/config_directives.c | |
--- i3.clean/src/config_directives.c 2021-11-17 09:55:41.833959660 -0600 | |
+++ i3/src/config_directives.c 2021-11-17 09:55:53.031850991 -0600 | |
@@ -569,6 +569,11 @@ | |
current_bar->separator_symbol = sstrdup(separator); | |
} | |
+CFGFUN(bar_ignore_end, const char *ignore) { | |
+ FREE(current_bar->ignore_end); | |
+ current_bar->ignore_end = sstrdup(ignore); | |
+} | |
+ | |
CFGFUN(bar_mode, const char *mode) { | |
current_bar->mode = (strcmp(mode, "dock") == 0 ? M_DOCK : (strcmp(mode, "hide") == 0 ? M_HIDE : M_INVISIBLE)); | |
} | |
diff -W 183 -duw --recursive i3.clean/src/ipc.c i3/src/ipc.c | |
--- i3.clean/src/ipc.c 2021-11-17 09:55:19.378548309 -0600 | |
+++ i3/src/ipc.c 2021-11-17 09:55:53.066982387 -0600 | |
@@ -802,6 +802,11 @@ | |
ystr(config->separator_symbol); | |
} | |
+ if (config->ignore_end) { | |
+ ystr("ignore_workspaces_ending_with"); | |
+ ystr(config->ignore_end); | |
+ } | |
+ | |
ystr("workspace_buttons"); | |
y(bool, !config->hide_workspace_buttons); | |
diff -W 183 -duw --recursive i3.clean/testcases/t/201-config-parser.t i3/testcases/t/201-config-parser.t | |
--- i3.clean/testcases/t/201-config-parser.t 2021-11-17 09:55:41.838408021 -0600 | |
+++ i3/testcases/t/201-config-parser.t 2021-11-17 09:58:26.077139228 -0600 | |
@@ -769,7 +769,7 @@ | |
$expected = <<'EOT'; | |
cfg_bar_start() | |
cfg_bar_output(LVDS-1) | |
-ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'i3bar_command', 'status_command', 'socket_path', 'mode', 'hidden_state', 'id', 'modifier', 'wheel_up_cmd', 'wheel_down_cmd', 'bindsym', 'position', 'output', 'tray_output', 'tray_padding', 'font', 'separator_symbol', 'binding_mode_indicator', 'workspace_buttons', 'workspace_min_width', 'strip_workspace_numbers', 'strip_workspace_name', 'verbose', 'colors', '}' | |
+ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'i3bar_command', 'status_command', 'socket_path', 'mode', 'hidden_state', 'id', 'modifier', 'wheel_up_cmd', 'wheel_down_cmd', 'bindsym', 'position', 'output', 'tray_output', 'tray_padding', 'font', 'separator_symbol', 'ignore_workspaces_ending_with', 'binding_mode_indicator', 'workspace_buttons', 'workspace_min_width', 'strip_workspace_numbers', 'strip_workspace_name', 'verbose', 'colors', '}' | |
ERROR: CONFIG: (in file <stdin>) | |
ERROR: CONFIG: Line 1: bar { | |
ERROR: CONFIG: Line 2: output LVDS-1 | |
@@ -783,4 +783,99 @@ | |
$expected, | |
'error message (bar block) ok'); | |
+ | |
+################################################################################ | |
+# i3bar: ignore_workspaces_ending_with test | |
+################################################################################ | |
+ | |
+$config = <<'EOT'; | |
+bar { | |
+ output LVDS-1 | |
+ ignore_workspaces_ending_with "test" | |
+} | |
+EOT | |
+ | |
+$expected = <<'EOT'; | |
+cfg_bar_start() | |
+cfg_bar_output(LVDS-1) | |
+cfg_bar_ignore_end(test) | |
+cfg_bar_finish() | |
+EOT | |
+ | |
+is(parser_calls($config), | |
+ $expected, | |
+ 'ignore_workspaces_ending_with basic string ok'); | |
+ | |
+$config = <<'EOT'; | |
+bar { | |
+ output LVDS-1 | |
+ ignore_workspaces_ending_with "" | |
+} | |
+EOT | |
+ | |
+$expected = <<'EOT'; | |
+cfg_bar_start() | |
+cfg_bar_output(LVDS-1) | |
+cfg_bar_ignore_end() | |
+cfg_bar_finish() | |
+EOT | |
+ | |
+is(parser_calls($config), | |
+ $expected, | |
+ 'ignore_workspaces_ending_with unicode string ok'); | |
+ | |
+$config = <<'EOT'; | |
+bar { | |
+ output LVDS-1 | |
+ ignore_workspaces_ending_with "" | |
+} | |
+EOT | |
+ | |
+$expected = <<'EOT'; | |
+cfg_bar_start() | |
+cfg_bar_output(LVDS-1) | |
+ERROR: CONFIG: Expected one of these tokens: <string> | |
+ERROR: CONFIG: (in file <stdin>) | |
+ERROR: CONFIG: Line 1: bar { | |
+ERROR: CONFIG: Line 2: output LVDS-1 | |
+ERROR: CONFIG: Line 3: ignore_workspaces_ending_with "" | |
+ERROR: CONFIG: ^ | |
+ERROR: CONFIG: Line 4: } | |
+cfg_bar_finish() | |
+EOT | |
+ | |
+is(parser_calls($config), | |
+ $expected, | |
+ 'ignore_workspaces_ending_with empty string 1 ok'); | |
+ | |
+$config = <<'EOT'; | |
+bar { | |
+ output LVDS-1 | |
+ ignore_workspaces_ending_with | |
+} | |
+EOT | |
+ | |
+$expected = <<'EOT'; | |
+cfg_bar_start() | |
+cfg_bar_output(LVDS-1) | |
+ERROR: CONFIG: Expected one of these tokens: <string> | |
+ERROR: CONFIG: (in file <stdin>) | |
+ERROR: CONFIG: Line 1: output LVDS-1 | |
+ERROR: CONFIG: Line 2: ignore_workspaces_ending_with | |
+ERROR: CONFIG: Line 3: } | |
+ERROR: CONFIG: ^ | |
+cfg_bar_finish() | |
+EOT | |
+ | |
+is(parser_calls($config), | |
+ $expected, | |
+ 'ignore_workspaces_ending_with empty string 2 ok'); | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
done_testing; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment