diff --git a/src/main.c b/src/main.c index 66f57fa..4ba3cb8 100644 --- a/src/main.c +++ b/src/main.c @@ -14,6 +14,8 @@ #define DEFAULT_LAYOUT 0 // Default ignored time between layout change and focus lost events #define DEFAULT_TIMEOUT 50 +// Default list of tab-enabled app IDs +#define DEFAULT_TABAPPS "firefox,chrome" // Convert timespec to milliseconds #define TIMESPEC_MS(ts) (ts.tv_sec * 1000 + ts.tv_nsec / 1000000) @@ -25,6 +27,8 @@ struct context { int current_layout; ///< Current layout index int switch_timeout; ///< Ignored time between layout change and focus lost struct timespec switch_timestamp; ///< Timestamp of the last layout change + char** tabapps; + size_t tabapps_num; }; static struct context ctx = { .last_window = INVALID_WINDOW, @@ -40,12 +44,14 @@ static unsigned long window_id(int wnd_id, const char* app_id, const char* title // check if the current container belongs to the web browser, we will // use window title (which is a tab name) to generate unique id - if (app_id && title && - (strcmp(app_id, "firefox") == 0 || strcmp(app_id, "chromium") == 0)) { - // djb2 hash - id = 5381; - while (*title) { - id = ((id << 5) + id) + *title++; + for (size_t i = 0; i < ctx.tabapps_num; ++i) { + if (strcmp(app_id, ctx.tabapps[i]) == 0) { + // djb2 hash + id = 5381; + while (*title) { + id = ((id << 5) + id) + *title++; + } + break; } } @@ -114,6 +120,36 @@ static void on_layout_change(int layout) clock_gettime(CLOCK_MONOTONIC, &ctx.switch_timestamp); } +/** Set list of tab-enabled app IDs from command line arument. */ +static void set_tabapps(const char* ids) +{ + size_t size; + + // get number of app ids + size = 1; + for(const char* ptr = ids; *ptr; ++ptr) { + if (*ptr == ',') { + ++size; + } + } + + // split into array + ctx.tabapps = malloc(size * sizeof(char*)); + for(const char* ptr = ids; ; ++ptr) { + if (!*ptr || *ptr == ',') { + const size_t len = ptr - ids; + char* id = malloc(len + 1 /* last null */); + memcpy(id, ids, len); + id[len] = 0; + ids = ptr + 1; + ctx.tabapps[ctx.tabapps_num++] = id; + if (!*ptr) { + break; + } + } + } +} + /** * Application entry point. */ @@ -122,11 +158,12 @@ int main(int argc, char* argv[]) const struct option long_opts[] = { { "default", required_argument, NULL, 'd' }, { "timeout", required_argument, NULL, 't' }, + { "tabapps", required_argument, NULL, 'a' }, { "version", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } }; - const char* short_opts = "d:t:vh"; + const char* short_opts = "d:t:a:vh"; opterr = 0; // prevent native error messages @@ -137,29 +174,32 @@ int main(int argc, char* argv[]) case 'd': ctx.default_layout = atoi(optarg); if (ctx.default_layout < -1 || ctx.default_layout > 0xffff) { - fprintf(stderr, "Invalid default layout: %s\n", - argv[optind - 1]); + fprintf(stderr, "Invalid default layout: %s\n", optarg); return EXIT_FAILURE; } break; case 't': ctx.switch_timeout = atoi(optarg); if (ctx.switch_timeout < 0) { - fprintf(stderr, "Invalid timeout value: %s\n", - argv[optind - 1]); + fprintf(stderr, "Invalid timeout value: %s\n", optarg); return EXIT_FAILURE; } break; + case 'a': + set_tabapps(optarg); + break; case 'v': printf("swaykbdd version " VERSION ".\n"); return EXIT_SUCCESS; case 'h': printf("Keyboard layout switcher for Sway.\n"); printf("Usage: %s [OPTION]\n", argv[0]); - printf(" -d, --default ID Default layout for new windows " + printf(" -d, --default=ID Default layout for new windows " "[%i]\n", DEFAULT_LAYOUT); - printf(" -t, --timeout MS Delay between switching and " + printf(" -t, --timeout=MS Delay between switching and " "saving layout [%i ms]\n", DEFAULT_TIMEOUT); + printf(" -a, --tabapps=IDS List of tab-enabled app IDs " + "[" DEFAULT_TABAPPS "]\n"); printf(" -v, --version Print version info and exit\n"); printf(" -h, --help Print this help and exit\n"); return EXIT_SUCCESS; @@ -173,5 +213,9 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; } + if (ctx.tabapps_num == 0) { + set_tabapps(DEFAULT_TABAPPS); + } + return sway_monitor(on_focus_change, on_window_close, on_layout_change); } diff --git a/swaykbdd.1 b/swaykbdd.1 index 4d6ddbc..5cc0365 100644 --- a/swaykbdd.1 +++ b/swaykbdd.1 @@ -23,6 +23,9 @@ windows (currently active layout will be used instead). .IP "\fB\-t\fR, \fB\-\-timeout\fR\fB=\fR\fIMS\fR" Ignored time between layout change and focus lost events, in milliseconds. The default value is 50. +.IP "\fB\-a\fR, \fB\-\-tabapps\fR\fB=\fR\fIIDS\fR" +A comma-separated list of tab-enabled application IDs, for which each tab will +have its own keyboard layout. The default value is "firefox,chrome" .SH ENVIRONMENT .IP \fISWAYSOCK\fR Path to the socket file used for Sway IPC.