diff --git a/include/sway/commands.h b/include/sway/commands.h index 27058587..eb12daad 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -144,6 +144,7 @@ sway_cmd cmd_fullscreen; sway_cmd cmd_gaps; sway_cmd cmd_hide_edge_borders; sway_cmd cmd_include; +sway_cmd cmd_include_one; sway_cmd cmd_inhibit_idle; sway_cmd cmd_input; sway_cmd cmd_seat; diff --git a/include/sway/config.h b/include/sway/config.h index 40710199..02e651ba 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -614,7 +614,10 @@ bool load_main_config(const char *path, bool is_active, bool validating); * Loads an included config. Can only be used after load_main_config. */ void load_include_configs(const char *path, struct sway_config *config, - struct swaynag_instance *swaynag); + struct swaynag_instance *swaynag, bool flag); + +void load_include_one_config(const char *paths, struct sway_config *config, + struct swaynag_instance *swaynag); /** * Reads the config from the given FILE. diff --git a/sway/commands.c b/sway/commands.c index 8d003dfa..ae6959ec 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -103,6 +103,7 @@ static const struct cmd_handler handlers[] = { static const struct cmd_handler config_handlers[] = { { "default_orientation", cmd_default_orientation }, { "include", cmd_include }, + { "include_one", cmd_include_one }, { "primary_selection", cmd_primary_selection }, { "swaybg_command", cmd_swaybg_command }, { "swaynag_command", cmd_swaynag_command }, diff --git a/sway/commands/include.c b/sway/commands/include.c index d4c14c35..1dcccbf9 100644 --- a/sway/commands/include.c +++ b/sway/commands/include.c @@ -8,7 +8,7 @@ struct cmd_results *cmd_include(int argc, char **argv) { } // We don't care if the included config(s) fails to load. - load_include_configs(argv[0], config, &config->swaynag_config_errors); + load_include_configs(argv[0], config, &config->swaynag_config_errors, false); return cmd_results_new(CMD_SUCCESS, NULL); } diff --git a/sway/commands/include_one.c b/sway/commands/include_one.c new file mode 100644 index 00000000..3f7b9bbc --- /dev/null +++ b/sway/commands/include_one.c @@ -0,0 +1,14 @@ +#include "sway/commands.h" +#include "sway/config.h" + +struct cmd_results *cmd_include_one(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "include_one", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + // We don't care if the included config(s) fails to load. + load_include_one_config(argv[0], config, &config->swaynag_config_errors); + + return cmd_results_new(CMD_SUCCESS, NULL); +} \ No newline at end of file diff --git a/sway/config.c b/sway/config.c index f9131e0f..917873d2 100644 --- a/sway/config.c +++ b/sway/config.c @@ -549,8 +549,22 @@ bool load_main_config(const char *file, bool is_active, bool validating) { return success; } +static char *extract_filename(const char *path) { + char *filename = strrchr(path, '/'); + if (filename == NULL) { + return NULL; + } + return filename; +} + +static bool same_file(const char *path1, const char *path2) { + const char *file1 = extract_filename(path1); + const char *file2 = extract_filename(path2); + return (strcmp(file1, file2) == 0); +} + static bool load_include_config(const char *path, const char *parent_dir, - struct sway_config *config, struct swaynag_instance *swaynag) { + struct sway_config *config, struct swaynag_instance *swaynag, bool flag) { // save parent config const char *parent_config = config->current_config_path; @@ -588,6 +602,14 @@ static bool load_include_config(const char *path, const char *parent_dir, free(real_path); return false; } + // check if function is called from include_one + if (flag == true && same_file(real_path, old_path) == true) { + sway_log(SWAY_DEBUG, + "%s already included once, won't be included again.", + real_path); + free(real_path); + return false; + } } config->current_config_path = real_path; @@ -607,7 +629,7 @@ static bool load_include_config(const char *path, const char *parent_dir, } void load_include_configs(const char *path, struct sway_config *config, - struct swaynag_instance *swaynag) { + struct swaynag_instance *swaynag, bool flag) { char *wd = getcwd(NULL, 0); char *parent_path = strdup(config->current_config_path); const char *parent_dir = dirname(parent_path); @@ -622,7 +644,7 @@ void load_include_configs(const char *path, struct sway_config *config, char **w = p.we_wordv; size_t i; for (i = 0; i < p.we_wordc; ++i) { - load_include_config(w[i], parent_dir, config, swaynag); + load_include_config(w[i], parent_dir, config, swaynag, flag); } wordfree(&p); } @@ -636,6 +658,21 @@ cleanup: free(wd); } + +void load_include_one_config(const char *paths, struct sway_config *config, + struct swaynag_instance *swaynag) { + char *p = strdup(paths); + char *path = strtok(p, " "); + while (path != NULL) { + load_include_configs(path, config, swaynag, true); + path = strtok(NULL, " "); + } + goto cleanup; + +cleanup: + free(p); +} + void run_deferred_commands(void) { if (!config->cmd_queue->length) { return; diff --git a/sway/meson.build b/sway/meson.build index d937e425..efe36468 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -74,6 +74,7 @@ sway_sources = files( 'commands/max_render_time.c', 'commands/opacity.c', 'commands/include.c', + 'commands/include_one.c', 'commands/input.c', 'commands/layout.c', 'commands/mode.c',