summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Jones <philj56@gmail.com>2022-07-27 15:00:05 +0100
committerPhil Jones <philj56@gmail.com>2022-07-27 15:12:26 +0100
commitdf3495a160878fd28e3642b47087024429bd512f (patch)
tree2f784c35706fec01fa34e410765deed61480b921
parentcf9669976601697be36e21e3359709f09c31d9da (diff)
Fix window workspaces in drun mode.
Previously, tofi-drun would print the filename of the selected .desktop file to stdout. This could then be passed to `xargs swaymsg exec gio launch` to be executed. The problem is that this ends up defeating the purpose of passing the command to swaymsg exec, and the workspace the command was selected on may not be the one that it starts up on, if for example it takes a long time and the user switches workspaces in the meantime. The solution is to instead print the Exec= line from the .desktop file, and pass that directly to `xargs swaymsg exec --` for execution. To avoid too much breaking of configs for the few people who use tofi currently, this commit adds a new option, --drun-print-exec, to enable the fixed behaviour. A future release will change this to be the default, however.
-rw-r--r--README.md8
-rw-r--r--completions/tofi1
-rw-r--r--doc/tofi.1.md6
-rw-r--r--doc/tofi.1.scd6
-rw-r--r--doc/tofi.5.md11
-rw-r--r--doc/tofi.5.scd9
-rw-r--r--src/config.c2
-rw-r--r--src/drun.c64
-rw-r--r--src/drun.h1
-rw-r--r--src/main.c20
-rw-r--r--src/tofi.h1
11 files changed, 125 insertions, 4 deletions
diff --git a/README.md b/README.md
index b16bdcc..c5152f5 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,12 @@ executables under the user's `$PATH`.
list of applications found in desktop files as described by the [Desktop Entry
Specification](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html).
+**WARNING**: Currently, when a selection is made in drun mode, the
+filename of the selected desktop file is printed to stdout. In the next
+version of tofi, this will change to an executable command line, to be
+passed to swaymsg exec or similar. The new behaviour can be enabled now
+by passing --drun-print-exec=true to tofi-drun.
+
To use as a launcher for Sway, add something similar to the following to your
Sway config file:
```
@@ -67,7 +73,7 @@ bindsym $mod+d exec $menu
For `tofi-drun`, there are two possible methods:
```
# Launch via Sway
-set $drun tofi-drun | xargs swaymsg exec gio launch
+set $drun tofi-drun --drun-print-exec=true | xargs swaymsg exec --
bindsym $mod+Shift+d exec $drun
# Launch directly
diff --git a/completions/tofi b/completions/tofi
index 5a1d392..aa2b999 100644
--- a/completions/tofi
+++ b/completions/tofi
@@ -39,6 +39,7 @@ _tofi()
--hide-cursor
--history
--drun-launch
+ --drun-print-exec
--hint-font
--late-keyboard-init
)
diff --git a/doc/tofi.1.md b/doc/tofi.1.md
index 6de0027..4529dda 100644
--- a/doc/tofi.1.md
+++ b/doc/tofi.1.md
@@ -27,6 +27,12 @@ When invoked via the name **tofi-drun**, **tofi** will not accept items
on stdin, and will generate a list of applications from desktop files as
described in the Desktop Entry Specification.
+**WARNING**: Currently, when a selection is made in drun mode, the
+filename of the selected desktop file is printed to stdout. In the next
+version of tofi, this will change to an executable command line, to be
+passed to swaymsg exec or similar. The new behaviour can be enabled now
+by passing --drun-print-exec=true to tofi-drun.
+
**tofi-compgen** just prints the list of executables used by
**tofi-run**.
diff --git a/doc/tofi.1.scd b/doc/tofi.1.scd
index d15d394..38ed290 100644
--- a/doc/tofi.1.scd
+++ b/doc/tofi.1.scd
@@ -27,6 +27,12 @@ When invoked via the name *tofi-drun*, *tofi* will not accept items on stdin,
and will generate a list of applications from desktop files as described in the
Desktop Entry Specification.
+*WARNING*: Currently, when a selection is made in drun mode, the filename of
+the selected desktop file is printed to stdout. In the next version of tofi,
+this will change to an executable command line, to be passed to swaymsg exec or
+similar. The new behaviour can be enabled now by passing --drun-print-exec=true
+to tofi-drun.
+
*tofi-compgen* just prints the list of executables used by *tofi-run*.
# OPTIONS
diff --git a/doc/tofi.5.md b/doc/tofi.5.md
index 916fc22..9a76a5d 100644
--- a/doc/tofi.5.md
+++ b/doc/tofi.5.md
@@ -224,6 +224,17 @@ options.
>
> Default: false
+**drun-print-exec**=*true\|false*
+
+> If true, print an executable command line for the selected application
+> when in drun mode. Otherwise, just print the path of the .desktop
+> file.
+>
+> **WARNING**: In the next version of tofi, this will change to always
+> be true, as it should have been from the start.
+>
+> Default: false
+
**hint-font**=*true\|false*
> Perform font hinting. Only applies when a path to a font has been
diff --git a/doc/tofi.5.scd b/doc/tofi.5.scd
index 3ad7015..5a977d3 100644
--- a/doc/tofi.5.scd
+++ b/doc/tofi.5.scd
@@ -194,6 +194,15 @@ options.
Default: false
+*drun-print-exec*=_true|false_
+ If true, print an executable command line for the selected application
+ when in drun mode. Otherwise, just print the path of the .desktop file.
+
+ *WARNING*: In the next version of tofi, this will change to always be
+ true, as it should have been from the start.
+
+ Default: false
+
*hint-font*=_true|false_
Perform font hinting. Only applies when a path to a font has been
specified via *font-name*. Disabling font hinting speeds up text
diff --git a/src/config.c b/src/config.c
index a2e0f03..aebb8e1 100644
--- a/src/config.c
+++ b/src/config.c
@@ -293,6 +293,8 @@ bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const
tofi->use_history = parse_bool(filename, lineno, value, &err);
} else if (strcasecmp(option, "drun-launch") == 0) {
tofi->drun_launch = parse_bool(filename, lineno, value, &err);
+ } else if (strcasecmp(option, "drun-print-exec") == 0) {
+ tofi->drun_print_exec = parse_bool(filename, lineno, value, &err);
} else if (strcasecmp(option, "hint-font") == 0) {
tofi->window.entry.harfbuzz.disable_hinting = !parse_bool(filename, lineno, value, &err);
} else if (strcasecmp(option, "late-keyboard-init") == 0) {
diff --git a/src/drun.c b/src/drun.c
index 482db92..c4a32e2 100644
--- a/src/drun.c
+++ b/src/drun.c
@@ -278,6 +278,70 @@ struct desktop_vec drun_generate_cached()
return apps;
}
+void drun_print(const char *filename)
+{
+ GKeyFile *file = g_key_file_new();
+ if (!g_key_file_load_from_file(file, filename, G_KEY_FILE_NONE, NULL)) {
+ log_error("Failed to open %s.\n", filename);
+ return;
+ }
+ const char *group = "Desktop Entry";
+
+ char *exec = g_key_file_get_string(file, group, "Exec", NULL);
+ if (exec == NULL) {
+ log_error("Failed to get Exec key from %s.\n", filename);
+ g_key_file_unref(file);
+ return;
+ }
+
+ /*
+ * Build a string vector from the command line, replacing % field codes
+ * with the appropriate values.
+ */
+ struct string_vec pieces = string_vec_create();
+ char *search = exec;
+ char *last = search;
+ while ((search = strchr(search, '%')) != NULL) {
+ /* Add the string up to here to our vector. */
+ search[0] = '\0';
+ string_vec_add(&pieces, last);
+ search++;
+ last = search;
+
+ switch (search[0]) {
+ case 'i':
+ if (g_key_file_has_key(file, group, "Icon", NULL)) {
+ string_vec_add(&pieces, "--icon ");
+ string_vec_add(&pieces, g_key_file_get_string(file, group, "Icon", NULL));
+ }
+ break;
+ case 'c':
+ string_vec_add(&pieces, g_key_file_get_locale_string(file, group, "Name", NULL, NULL));
+ break;
+ case 'k':
+ string_vec_add(&pieces, filename);
+ break;
+ }
+ }
+ if (last == exec) {
+ /*
+ * We didn't find any field codes, so just use the full exec
+ * string.
+ */
+ fputs(exec, stdout);
+ } else {
+ /* Build the command line from our vector. */
+ for (size_t i = 0; i < pieces.count; i++) {
+ fputs(pieces.buf[i].string, stdout);
+ }
+ }
+ fputc('\n', stdout);
+
+ string_vec_destroy(&pieces);
+ free(exec);
+ g_key_file_unref(file);
+}
+
void drun_launch(const char *filename)
{
GDesktopAppInfo *info = g_desktop_app_info_new_from_filename(filename);
diff --git a/src/drun.h b/src/drun.h
index 8650ae6..207d384 100644
--- a/src/drun.h
+++ b/src/drun.h
@@ -8,6 +8,7 @@
struct desktop_vec drun_generate(void);
struct desktop_vec drun_generate_cached(void);
void drun_history_sort(struct desktop_vec *apps, struct history *history);
+void drun_print(const char *filename);
void drun_launch(const char *filename);
#endif /* DRUN_H */
diff --git a/src/main.c b/src/main.c
index 03dc31e..0587304 100644
--- a/src/main.c
+++ b/src/main.c
@@ -707,6 +707,8 @@ static void usage()
" --horizontal <true|false> List results horizontally.\n"
" --history <true|false> Sort results by number of usages.\n"
" --drun-launch <true|false> Launch apps directly in drun mode.\n"
+" --drun-print-exec <true|false> Print a command line in drun mode.\n"
+" This will become the default in future.\n"
" --hint-font <true|false> Perform font hinting.\n"
" --late-keyboard-init (EXPERIMENTAL) Delay keyboard\n"
" initialisation until after the first\n"
@@ -748,6 +750,7 @@ const struct option long_options[] = {
{"hide-cursor", required_argument, NULL, 0},
{"history", required_argument, NULL, 0},
{"drun-launch", required_argument, NULL, 0},
+ {"drun-print-exec", required_argument, NULL, 0},
{"hint-font", required_argument, NULL, 0},
{"output", required_argument, NULL, 'o'},
{"late-keyboard-init", no_argument, NULL, 'k'},
@@ -1257,12 +1260,23 @@ int main(int argc, char *argv[])
struct desktop_entry *app = desktop_vec_find(&tofi.window.entry.apps, res);
if (app == NULL) {
log_error("Couldn't find application file! This shouldn't happen.\n");
+ break;
} else {
res = app->path;
}
- };
- if (tofi.window.entry.drun && tofi.drun_launch) {
- drun_launch(res);
+ if (tofi.drun_launch) {
+ drun_launch(res);
+ } else if (tofi.drun_print_exec) {
+ drun_print(res);
+ } else {
+ log_warning("Using drun mode without --drun-print-exec=true is deprecated.\n"
+ " In the next version of tofi, this will become the default behaviour,\n"
+ " so fix your compositor configs now e.g. by replacing\n"
+ " tofi-drun | xargs swaymsg exec gio launch\n"
+ " with\n"
+ " tofi-drun --drun-print-exec=true | xargs swaymsg exec --\n");
+ printf("%s\n", res);
+ }
} else {
printf("%s\n", res);
}
diff --git a/src/tofi.h b/src/tofi.h
index deea1a2..0b63363 100644
--- a/src/tofi.h
+++ b/src/tofi.h
@@ -67,6 +67,7 @@ struct tofi {
bool use_history;
bool late_keyboard_init;
bool drun_launch;
+ bool drun_print_exec;
char target_output_name[MAX_OUTPUT_NAME_LEN];
};