From aa8215194cecd6e791f1b560799e9bd641b431f4 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Thu, 20 Sep 2018 13:02:54 +0300 Subject: [PATCH 01/16] Fix typo: terminaison -> termination --- include/libi3.h | 2 +- libi3/string.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/libi3.h b/include/libi3.h index 913953289..9a276571b 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -196,7 +196,7 @@ i3String *i3string_from_markup(const char *from_markup); /** * Build an i3String from an UTF-8 encoded string with fixed length. - * To be used when no proper NUL-terminaison is available. + * To be used when no proper NULL-termination is available. * Returns the newly-allocated i3String. * */ diff --git a/libi3/string.c b/libi3/string.c index f78a140f9..a078b33e2 100644 --- a/libi3/string.c +++ b/libi3/string.c @@ -48,7 +48,7 @@ i3String *i3string_from_markup(const char *from_markup) { /* * Build an i3String from an UTF-8 encoded string with fixed length. - * To be used when no proper NUL-terminaison is available. + * To be used when no proper NULL-termination is available. * Returns the newly-allocated i3String. * */ From daf5ca111f59e3fda32fd938cf8750886be977a1 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Fri, 21 Sep 2018 01:50:51 +0300 Subject: [PATCH 02/16] Provide g_utf8_make_valid if not available See #3415 for licensing discussion. Fixes Airblader/i3#236 --- Makefile.am | 1 + include/libi3.h | 5 +++ libi3/g_utf8_make_valid.c | 93 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 libi3/g_utf8_make_valid.c diff --git a/Makefile.am b/Makefile.am index 09bbb6d50..7ca32506b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -301,6 +301,7 @@ libi3_a_SOURCES = \ libi3/fake_configure_notify.c \ libi3/font.c \ libi3/format_placeholders.c \ + libi3/g_utf8_make_valid.c \ libi3/get_colorpixel.c \ libi3/get_config_path.c \ libi3/get_exe_path.c \ diff --git a/include/libi3.h b/include/libi3.h index 9a276571b..d27437ba2 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -320,6 +320,11 @@ int ipc_recv_message(int sockfd, uint32_t *message_type, */ void fake_configure_notify(xcb_connection_t *conn, xcb_rectangle_t r, xcb_window_t window, int border_width); +#define HAS_G_UTF8_MAKE_VALID GLIB_CHECK_VERSION(2, 52, 0) +#if !HAS_G_UTF8_MAKE_VALID +gchar *g_utf8_make_valid(const gchar *str, gssize len); +#endif + /** * Returns the colorpixel to use for the given hex color (think of HTML). Only * works for true-color (vast majority of cases) at the moment, avoiding a diff --git a/libi3/g_utf8_make_valid.c b/libi3/g_utf8_make_valid.c new file mode 100644 index 000000000..b15873b37 --- /dev/null +++ b/libi3/g_utf8_make_valid.c @@ -0,0 +1,93 @@ +/* g_utf8_make_valid.c - Coerce string into UTF-8 + * + * Copyright (C) 1999 Tom Tromey + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "libi3.h" + +#include +#include + +/* Copied from: + * https://gitlab.gnome.org/GNOME/glib/blob/f928dfdf57bf92c883b53b16d7a9d49add504f52/glib/gutf8.c#L1752-1815 */ +/* clang-format off */ +#if !HAS_G_UTF8_MAKE_VALID +/** + * g_utf8_make_valid: + * @str: string to coerce into UTF-8 + * @len: the maximum length of @str to use, in bytes. If @len < 0, + * then the string is nul-terminated. + * + * If the provided string is valid UTF-8, return a copy of it. If not, + * return a copy in which bytes that could not be interpreted as valid Unicode + * are replaced with the Unicode replacement character (U+FFFD). + * + * For example, this is an appropriate function to use if you have received + * a string that was incorrectly declared to be UTF-8, and you need a valid + * UTF-8 version of it that can be logged or displayed to the user, with the + * assumption that it is close enough to ASCII or UTF-8 to be mostly + * readable as-is. + * + * Returns: (transfer full): a valid UTF-8 string whose content resembles @str + * + * Since: 2.52 + */ +gchar * +g_utf8_make_valid (const gchar *str, + gssize len) +{ + GString *string; + const gchar *remainder, *invalid; + gsize remaining_bytes, valid_bytes; + + g_return_val_if_fail (str != NULL, NULL); + + if (len < 0) + len = strlen (str); + + string = NULL; + remainder = str; + remaining_bytes = len; + + while (remaining_bytes != 0) + { + if (g_utf8_validate (remainder, remaining_bytes, &invalid)) + break; + valid_bytes = invalid - remainder; + + if (string == NULL) + string = g_string_sized_new (remaining_bytes); + + g_string_append_len (string, remainder, valid_bytes); + /* append U+FFFD REPLACEMENT CHARACTER */ + g_string_append (string, "\357\277\275"); + + remaining_bytes -= valid_bytes + 1; + remainder = invalid + 1; + } + + if (string == NULL) + return g_strndup (str, len); + + g_string_append_len (string, remainder, remaining_bytes); + g_string_append_c (string, '\0'); + + g_assert (g_utf8_validate (string->str, -1, NULL)); + + return g_string_free (string, FALSE); +} +#endif From 0ede8b9365ead4785172cdbb8a95b9795ea7867f Mon Sep 17 00:00:00 2001 From: Thomas Fischer Date: Fri, 28 Sep 2018 17:34:18 -0700 Subject: [PATCH 03/16] Correctly calculate max_aspect --- src/handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handlers.c b/src/handlers.c index 2cd45b797..c76f1935d 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -1072,7 +1072,7 @@ static bool handle_normal_hints(void *data, xcb_connection_t *conn, uint8_t stat /* Convert numerator/denominator to a double */ double min_aspect = (double)size_hints.min_aspect_num / size_hints.min_aspect_den; - double max_aspect = (double)size_hints.max_aspect_num / size_hints.min_aspect_den; + double max_aspect = (double)size_hints.max_aspect_num / size_hints.max_aspect_den; DLOG("Aspect ratio set: minimum %f, maximum %f\n", min_aspect, max_aspect); DLOG("width = %f, height = %f\n", width, height); From d722d1b0e605be6b84f37053d05d43d40fe6d88c Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 2 Oct 2018 18:13:06 -0400 Subject: [PATCH 04/16] i3-msg: check reply in quiet mode i3-msg currently exits right after sending the IPC message if the quiet flag is set. This means that if an error occurred when issuing a command, e.g. "i3-msg -q foobar", it gets silently ignored. What we really want is to just skip printing but still check the reply. At the same time, explicitly print the reply when we need to, instead of using an exit label. --- i3-msg/main.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/i3-msg/main.c b/i3-msg/main.c index 96edb2c3a..9b34b0629 100644 --- a/i3-msg/main.c +++ b/i3-msg/main.c @@ -246,9 +246,6 @@ int main(int argc, char *argv[]) { err(EXIT_FAILURE, "IPC: write()"); free(payload); - if (quiet) - return 0; - uint32_t reply_length; uint32_t reply_type; uint8_t *reply; @@ -275,8 +272,9 @@ int main(int argc, char *argv[]) { errx(EXIT_FAILURE, "IPC: Could not parse JSON reply."); } - /* NB: We still fall-through and print the reply, because even if one - * command failed, that doesn’t mean that all commands failed. */ + if (!quiet) { + printf("%.*s\n", reply_length, reply); + } } else if (reply_type == I3_IPC_REPLY_TYPE_CONFIG) { yajl_handle handle = yajl_alloc(&config_callbacks, NULL, NULL); yajl_status state = yajl_parse(handle, (const unsigned char *)reply, reply_length); @@ -289,12 +287,12 @@ int main(int argc, char *argv[]) { case yajl_status_error: errx(EXIT_FAILURE, "IPC: Could not parse JSON reply."); } - - goto exit; + } else { + if (!quiet) { + printf("%.*s\n", reply_length, reply); + } } - printf("%.*s\n", reply_length, reply); -exit: free(reply); close(sockfd); From cff4fadd7275dd20b9de383c2f83e1e06a27b7a4 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 5 Sep 2014 16:47:27 -0400 Subject: [PATCH 05/16] i3-msg: add support for SUBSCRIBE message type If i3-msg is invoked with -t subscribe, it will wait for the first event matching the given payload, before exiting. For instance, get the number of the next focused workspace with: i3-msg -t subscribe '[ "workspace" ]' | jshon -e current -e num Like inotifywait, the -m flag allows to wait indefinitely for events, instead of exiting right after receiving the first one. For example, continuously monitor the names of focused windows with: i3-msg -t subscribe -m '[ "window" ]' | jq .container.name --- i3-msg/main.c | 35 ++++++++++++++++++++++++++++++++--- man/i3-msg.man | 13 +++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/i3-msg/main.c b/i3-msg/main.c index 9b34b0629..fe1114168 100644 --- a/i3-msg/main.c +++ b/i3-msg/main.c @@ -166,16 +166,18 @@ int main(int argc, char *argv[]) { uint32_t message_type = I3_IPC_MESSAGE_TYPE_RUN_COMMAND; char *payload = NULL; bool quiet = false; + bool monitor = false; static struct option long_options[] = { {"socket", required_argument, 0, 's'}, {"type", required_argument, 0, 't'}, {"version", no_argument, 0, 'v'}, {"quiet", no_argument, 0, 'q'}, + {"monitor", no_argument, 0, 'm'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - char *options_string = "s:t:vhq"; + char *options_string = "s:t:vhqm"; while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) { if (o == 's') { @@ -204,25 +206,34 @@ int main(int argc, char *argv[]) { message_type = I3_IPC_MESSAGE_TYPE_GET_CONFIG; } else if (strcasecmp(optarg, "send_tick") == 0) { message_type = I3_IPC_MESSAGE_TYPE_SEND_TICK; + } else if (strcasecmp(optarg, "subscribe") == 0) { + message_type = I3_IPC_MESSAGE_TYPE_SUBSCRIBE; } else { printf("Unknown message type\n"); - printf("Known types: run_command, get_workspaces, get_outputs, get_tree, get_marks, get_bar_config, get_binding_modes, get_version, get_config, send_tick\n"); + printf("Known types: run_command, get_workspaces, get_outputs, get_tree, get_marks, get_bar_config, get_binding_modes, get_version, get_config, send_tick, subscribe\n"); exit(EXIT_FAILURE); } } else if (o == 'q') { quiet = true; + } else if (o == 'm') { + monitor = true; } else if (o == 'v') { printf("i3-msg " I3_VERSION "\n"); return 0; } else if (o == 'h') { printf("i3-msg " I3_VERSION "\n"); - printf("i3-msg [-s ] [-t ] \n"); + printf("i3-msg [-s ] [-t ] [-m] \n"); return 0; } else if (o == '?') { exit(EXIT_FAILURE); } } + if (monitor && message_type != I3_IPC_MESSAGE_TYPE_SUBSCRIBE) { + fprintf(stderr, "The monitor option -m is used with -t SUBSCRIBE exclusively.\n"); + exit(EXIT_FAILURE); + } + /* Use all arguments, separated by whitespace, as payload. * This way, you don’t have to do i3-msg 'mark foo', you can use * i3-msg mark foo */ @@ -287,6 +298,24 @@ int main(int argc, char *argv[]) { case yajl_status_error: errx(EXIT_FAILURE, "IPC: Could not parse JSON reply."); } + } else if (reply_type == I3_IPC_REPLY_TYPE_SUBSCRIBE) { + do { + free(reply); + if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) { + if (ret == -1) + err(EXIT_FAILURE, "IPC: read()"); + exit(1); + } + + if (!(reply_type & I3_IPC_EVENT_MASK)) { + errx(EXIT_FAILURE, "IPC: Received reply of type %d but expected an event", reply_type); + } + + if (!quiet) { + fprintf(stdout, "%.*s\n", reply_length, reply); + fflush(stdout); + } + } while (monitor); } else { if (!quiet) { printf("%.*s\n", reply_length, reply); diff --git a/man/i3-msg.man b/man/i3-msg.man index 04c719007..625131de5 100644 --- a/man/i3-msg.man +++ b/man/i3-msg.man @@ -31,6 +31,11 @@ with an error. *-t* 'type':: Send ipc message, see below. This option defaults to "command". +*-m*, *--monitor*:: +Instead of exiting right after receiving the first subscribed event, +wait indefinitely for all of them. Can only be used with "-t subscribe". +See the "subscribe" IPC message type below for details. + *message*:: Send ipc message, see below. @@ -75,6 +80,11 @@ Gets the currently loaded i3 configuration. send_tick:: Sends a tick to all IPC connections which subscribe to tick events. +subscribe:: +The payload of the message describes the events to subscribe to. +Upon reception, each event will be dumped as a JSON-encoded object. +See the -m option for continuous monitoring. + == DESCRIPTION i3-msg is a sample implementation for a client using the unix socket IPC @@ -91,6 +101,9 @@ i3-msg border normal # Dump the layout tree i3-msg -t get_tree + +# Monitor window changes +i3-msg -t subscribe -m '[ "window" ]' ------------------------------------------------ == ENVIRONMENT From acea46e16a9d840b95397127cfb18d2bca93aee9 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 7 Oct 2018 20:09:35 +0200 Subject: [PATCH 06/16] configure.ac: add conditionals for building docs/mans fixes #3378 --- configure.ac | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 1784fa83d..5cc9d4a69 100644 --- a/configure.ac +++ b/configure.ac @@ -110,12 +110,27 @@ AC_PROG_MAKE_SET AC_PROG_RANLIB AC_PROG_LN_S -AC_PATH_PROG([PATH_ASCIIDOC], [asciidoc]) -AC_PATH_PROG([PATH_XMLTO], [xmlto]) -AC_PATH_PROG([PATH_POD2MAN], [pod2man]) - -AM_CONDITIONAL([BUILD_MANS], [test x$PATH_ASCIIDOC != x && test x$PATH_XMLTO != x && test x$PATH_POD2MAN != x]) -AM_CONDITIONAL([BUILD_DOCS], [test x$PATH_ASCIIDOC != x]) +AC_ARG_ENABLE(docs, + AS_HELP_STRING( + [--disable-docs], + [disable building documentation]), + [ax_docs=$enableval], + [ax_docs=yes]) +AC_ARG_ENABLE(mans, + AS_HELP_STRING( + [--disable-mans], + [disable building manual pages]), + [ax_mans=$enableval], + [ax_mans=yes]) +AS_IF([test x$ax_docs = xyes || test x$ax_mans = xyes], [ + AC_PATH_PROG([PATH_ASCIIDOC], [asciidoc]) +]) +AS_IF([test x$ax_mans = xyes], [ + AC_PATH_PROG([PATH_XMLTO], [xmlto]) + AC_PATH_PROG([PATH_POD2MAN], [pod2man]) +]) +AM_CONDITIONAL([BUILD_MANS], [test x$ax_mans = xyes && test x$PATH_ASCIIDOC != x && test x$PATH_XMLTO != x && test x$PATH_POD2MAN != x]) +AM_CONDITIONAL([BUILD_DOCS], [test x$ax_docs = xyes && test x$PATH_ASCIIDOC != x]) AM_PROG_AR From 18dbfe699a61b64239f7397246e015c9ebfb36ce Mon Sep 17 00:00:00 2001 From: Orestis Date: Sun, 7 Oct 2018 21:24:09 +0300 Subject: [PATCH 07/16] userguide: Mention know issues for assign (#3434) Fixes #3222 Fixes #3293 Related to #2060 --- docs/userguide | 25 +++++++++++++++++-------- src/config_directives.c | 10 ++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/docs/userguide b/docs/userguide index 9c601e886..da5d98737 100644 --- a/docs/userguide +++ b/docs/userguide @@ -755,14 +755,23 @@ set_from_resource $black i3wm.color0 #000000 To automatically make a specific window show up on a specific workspace, you can use an *assignment*. You can match windows by using any criteria, -see <>. It is recommended that you match on window classes -(and instances, when appropriate) instead of window titles whenever possible -because some applications first create their window, and then worry about -setting the correct title. Firefox with Vimperator comes to mind. The window -starts up being named Firefox, and only when Vimperator is loaded does the -title change. As i3 will get the title as soon as the application maps the -window (mapping means actually displaying it on the screen), you’d need to have -to match on 'Firefox' in this case. +see <>. The difference between +assign+ and ++for_window move to workspace+ is that the former will only be +executed when the application maps the window (mapping means actually displaying +it on the screen) but the latter will be executed whenever a window changes its +properties to something that matches the specified criteria. + +Thus, it is recommended that you match on window classes (and instances, when +appropriate) instead of window titles whenever possible because some +applications first create their window, and then worry about setting the correct +title. Firefox with Vimperator comes to mind. The window starts up being named +Firefox, and only when Vimperator is loaded does the title change. As i3 will +get the title as soon as the application maps the window, you’d need to have to +match on 'Firefox' in this case. +Another known issue is with Spotify, which doesn't set the class hints when +mapping the window, meaning you'll have to use a +for_window+ rule to assign +Spotify to a specific workspace. +Finally, using +assign [tiling]+ and +assign [floating]+ is not supported. You can also assign a window to show up on a specific output. You can use RandR names such as +VGA1+ or names relative to the output with the currently focused diff --git a/src/config_directives.c b/src/config_directives.c index dfbb52d85..5c85197f6 100644 --- a/src/config_directives.c +++ b/src/config_directives.c @@ -406,6 +406,11 @@ CFGFUN(assign_output, const char *output) { return; } + if (current_match->window_mode != WM_ANY) { + ELOG("Assignments using window mode (floating/tiling) is not supported\n"); + return; + } + DLOG("New assignment, using above criteria, to output \"%s\".\n", output); Assignment *assignment = scalloc(1, sizeof(Assignment)); match_copy(&(assignment->match), current_match); @@ -420,6 +425,11 @@ CFGFUN(assign, const char *workspace, bool is_number) { return; } + if (current_match->window_mode != WM_ANY) { + ELOG("Assignments using window mode (floating/tiling) is not supported\n"); + return; + } + if (is_number && ws_name_to_number(workspace) == -1) { ELOG("Could not parse initial part of \"%s\" as a number.\n", workspace); return; From 2be4975f18f6e49b53ae683a30b11e435a5515dd Mon Sep 17 00:00:00 2001 From: Orestis Date: Sun, 7 Oct 2018 21:26:37 +0300 Subject: [PATCH 08/16] resolve_tilde: strncpy + strlen is pointless (#3436) strlen already assumes that the string is NULL-terminated. Like in https://github.com/i3/i3status/pull/312 but for whatever reason gcc didn't warn about this here. --- libi3/resolve_tilde.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libi3/resolve_tilde.c b/libi3/resolve_tilde.c index 51d642db3..6dbf132fa 100644 --- a/libi3/resolve_tilde.c +++ b/libi3/resolve_tilde.c @@ -35,9 +35,10 @@ char *resolve_tilde(const char *path) { } else { head = globbuf.gl_pathv[0]; result = scalloc(strlen(head) + (tail ? strlen(tail) : 0) + 1, 1); - strncpy(result, head, strlen(head)); - if (tail) - strncat(result, tail, strlen(tail)); + strcpy(result, head); + if (tail) { + strcat(result, tail); + } } globfree(&globbuf); From 824d6916400e83d6b4dd93940238ca75dee4ef82 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 7 Oct 2018 20:41:42 +0200 Subject: [PATCH 09/16] add specific GitHub issue templates I learnt about this from the GitHub blog: https://blog.github.com/2018-05-02-issue-template-improvements/ --- .github/ISSUE_TEMPLATE.md | 10 +++- .github/ISSUE_TEMPLATE/bug_report.md | 71 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 47 +++++++++++++++ 3 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 96f68d90a..f2c55972e 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -12,10 +12,16 @@ PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATI ## Current Behavior - + ## Expected Behavior - + ## Reproduction Instructions + +## I'm submitting a… + +
+[x] Bug
+[ ] Feature Request
+[ ] Documentation Request
+[ ] Other (Please describe in detail)
+
+ +## Current Behavior + + +## Expected Behavior + + +## Reproduction Instructions + + +## Environment + +Output of `i3 --moreversion 2>&-`: +
+i3 version: 
+
+ + +
+
+ + +
+Logfile URL:
+
+ + +
+- Linux Distribution & Version:
+- Are you using a compositor (e.g., xcompmgr or compton):
+
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..e1c169a58 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,47 @@ +--- +name: Feature request +about: Suggest an idea for this project +--- + + + +## I'm submitting a… + +
+[ ] Bug
+[x] Feature Request
+[ ] Documentation Request
+[ ] Other (Please describe in detail)
+
+ +## Current Behavior + + +## Desired Behavior + + +## Environment + +Output of `i3 --moreversion 2>&-`: +
+i3 version: 
+
+ + +
+- Linux Distribution & Version:
+- Are you using a compositor (e.g., xcompmgr or compton):
+
From dfe89cc4f1706a6fae0ae3816787d0fb22dadd7d Mon Sep 17 00:00:00 2001 From: Orestis Date: Sun, 7 Oct 2018 23:43:24 +0300 Subject: [PATCH 10/16] i3-nagbar: add option for button that runs commands without a terminal (#3258) Fixes #2199. --- etc/config | 2 +- etc/config.keycodes | 2 +- i3-nagbar/main.c | 14 +++++++++++--- man/i3-nagbar.man | 8 +++++++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/etc/config b/etc/config index 3be9831dd..da51d5703 100644 --- a/etc/config +++ b/etc/config @@ -147,7 +147,7 @@ bindsym Mod1+Shift+c reload # restart i3 inplace (preserves your layout/session, can be used to upgrade i3) bindsym Mod1+Shift+r restart # exit i3 (logs you out of your X session) -bindsym Mod1+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'" +bindsym Mod1+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'" # resize window (you can also use the mouse for that) mode "resize" { diff --git a/etc/config.keycodes b/etc/config.keycodes index 2d56876c2..6fc19426a 100644 --- a/etc/config.keycodes +++ b/etc/config.keycodes @@ -133,7 +133,7 @@ bindcode $mod+Shift+54 reload # restart i3 inplace (preserves your layout/session, can be used to upgrade i3) bindcode $mod+Shift+27 restart # exit i3 (logs you out of your X session) -bindcode $mod+Shift+26 exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'" +bindcode $mod+Shift+26 exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'" # resize window (you can also use the mouse for that) mode "resize" { diff --git a/i3-nagbar/main.c b/i3-nagbar/main.c index 1d600c023..fd7acd6e7 100644 --- a/i3-nagbar/main.c +++ b/i3-nagbar/main.c @@ -55,6 +55,7 @@ typedef struct { char *action; int16_t x; uint16_t width; + bool terminal; } button_t; static xcb_window_t win; @@ -187,7 +188,11 @@ static void handle_button_release(xcb_connection_t *conn, xcb_button_release_eve } char *terminal_cmd; - sasprintf(&terminal_cmd, "i3-sensible-terminal -e %s", link_path); + if (button->terminal) { + sasprintf(&terminal_cmd, "i3-sensible-terminal -e %s", link_path); + } else { + terminal_cmd = sstrdup(link_path); + } printf("argv0 = %s\n", argv0); printf("terminal_cmd = %s\n", terminal_cmd); @@ -361,12 +366,13 @@ int main(int argc, char *argv[]) { {"version", no_argument, 0, 'v'}, {"font", required_argument, 0, 'f'}, {"button", required_argument, 0, 'b'}, + {"button-no-terminal", required_argument, 0, 'B'}, {"help", no_argument, 0, 'h'}, {"message", required_argument, 0, 'm'}, {"type", required_argument, 0, 't'}, {0, 0, 0, 0}}; - char *options_string = "b:f:m:t:vh"; + char *options_string = "b:B:f:m:t:vh"; prompt = i3string_from_utf8("Please do not run this program."); @@ -388,12 +394,14 @@ int main(int argc, char *argv[]) { break; case 'h': printf("i3-nagbar " I3_VERSION "\n"); - printf("i3-nagbar [-m ] [-b