]> git.sur5r.net Git - i3/i3/commitdiff
i3-nagbar: add button flag to execute action with /bin/sh directly. 2766/head
authorMax Fisher <f.mach4@gmail.com>
Sun, 7 May 2017 13:40:19 +0000 (23:40 +1000)
committerMax Fisher <f.mach4@gmail.com>
Fri, 12 May 2017 11:50:41 +0000 (21:50 +1000)
Fixes #2765.

i3-nagbar/main.c
man/i3-nagbar.man

index 7d38f73140d741c635aa0de25bd0e5809d94df75..6ec4294f0078adff6b348ee373cac913b4319a44 100644 (file)
@@ -50,6 +50,7 @@ static char *argv0 = NULL;
 typedef struct {
     i3String *label;
     char *action;
+    bool exec_in_terminal;
     int16_t x;
     uint16_t width;
 } button_t;
@@ -123,35 +124,7 @@ static void start_application(const char *command) {
     wait(0);
 }
 
-static button_t *get_button_at(int16_t x, int16_t y) {
-    for (int c = 0; c < buttoncnt; c++)
-        if (x >= (buttons[c].x) && x <= (buttons[c].x + buttons[c].width))
-            return &buttons[c];
-
-    return NULL;
-}
-
-static void handle_button_press(xcb_connection_t *conn, xcb_button_press_event_t *event) {
-    printf("button pressed on x = %d, y = %d\n",
-           event->event_x, event->event_y);
-    /* TODO: set a flag for the button, re-render */
-}
-
-/*
- * Called when the user releases the mouse button. Checks whether the
- * coordinates are over a button and executes the appropriate action.
- *
- */
-static void handle_button_release(xcb_connection_t *conn, xcb_button_release_event_t *event) {
-    printf("button released on x = %d, y = %d\n",
-           event->event_x, event->event_y);
-    /* If the user hits the close button, we exit(0) */
-    if (event->event_x >= btn_close.x && event->event_x < btn_close.x + btn_close.width)
-        exit(0);
-    button_t *button = get_button_at(event->event_x, event->event_y);
-    if (!button)
-        return;
-
+static void execute_in_terminal(const char *command) {
     /* We need to create a custom script containing our actual command
      * since not every terminal emulator which is contained in
      * i3-sensible-terminal supports -e with multiple arguments (and not
@@ -172,7 +145,7 @@ static void handle_button_release(xcb_connection_t *conn, xcb_button_release_eve
         warn("Could not fdopen() temporary script to store the nagbar command");
         return;
     }
-    fprintf(script, "#!/bin/sh\nrm %s\n%s", script_path, button->action);
+    fprintf(script, "#!/bin/sh\nrm %s\n%s", script_path, command);
     /* Also closes fd */
     fclose(script);
 
@@ -194,6 +167,43 @@ static void handle_button_release(xcb_connection_t *conn, xcb_button_release_eve
     free(terminal_cmd);
     free(script_path);
     free(exe_path);
+}
+
+static button_t *get_button_at(int16_t x, int16_t y) {
+    for (int c = 0; c < buttoncnt; c++)
+        if (x >= (buttons[c].x) && x <= (buttons[c].x + buttons[c].width))
+            return &buttons[c];
+
+    return NULL;
+}
+
+static void handle_button_press(xcb_connection_t *conn, xcb_button_press_event_t *event) {
+    printf("button pressed on x = %d, y = %d\n",
+           event->event_x, event->event_y);
+    /* TODO: set a flag for the button, re-render */
+}
+
+/*
+ * Called when the user releases the mouse button. Checks whether the
+ * coordinates are over a button and executes the appropriate action.
+ *
+ */
+static void handle_button_release(xcb_connection_t *conn, xcb_button_release_event_t *event) {
+    printf("button released on x = %d, y = %d\n",
+           event->event_x, event->event_y);
+    /* If the user hits the close button, we exit(0) */
+    if (event->event_x >= btn_close.x && event->event_x < btn_close.x + btn_close.width)
+        exit(0);
+    button_t *button = get_button_at(event->event_x, event->event_y);
+    if (!button) {
+        return;
+    }
+
+    if (button->exec_in_terminal) {
+        execute_in_terminal(button->action);
+    } else {
+        start_application(button->action);
+    }
 
     /* TODO: unset flag, re-render */
 }
@@ -358,12 +368,13 @@ int main(int argc, char *argv[]) {
         {"version", no_argument, 0, 'v'},
         {"font", required_argument, 0, 'f'},
         {"button", required_argument, 0, 'b'},
+        {"button-sh", 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.");
 
@@ -385,15 +396,26 @@ int main(int argc, char *argv[]) {
                 break;
             case 'h':
                 printf("i3-nagbar " I3_VERSION "\n");
-                printf("i3-nagbar [-m <message>] [-b <button> <action>] [-t warning|error] [-f <font>] [-v]\n");
+                printf("i3-nagbar [-m <message>] [-b <button> <terminal-action>] "
+                       "[-B <button> <shell-action> [-t warning|error] [-f <font>] [-v]\n");
                 return 0;
+            /* falls through */
+            case 'B':
             case 'b':
                 buttons = srealloc(buttons, sizeof(button_t) * (buttoncnt + 1));
                 buttons[buttoncnt].label = i3string_from_utf8(optarg);
                 buttons[buttoncnt].action = argv[optind];
-                printf("button with label *%s* and action *%s*\n",
-                       i3string_as_utf8(buttons[buttoncnt].label),
-                       buttons[buttoncnt].action);
+                if (o == 'b') {
+                    buttons[buttoncnt].exec_in_terminal = true;
+                    printf("button with label *%s* and terminal action *%s*\n",
+                           i3string_as_utf8(buttons[buttoncnt].label),
+                           buttons[buttoncnt].action);
+                } else {
+                    buttons[buttoncnt].exec_in_terminal = false;
+                    printf("button with label *%s* and shell action *%s*\n",
+                           i3string_as_utf8(buttons[buttoncnt].label),
+                           buttons[buttoncnt].action);
+                }
                 buttoncnt++;
                 printf("now %d buttons\n", buttoncnt);
                 if (optind < argc)
index 77fdd80b504ed5dd24c0f345ea1eefb2abfd086b..7dd3a238130e66ea09719d37aaa2365cfc4980f1 100644 (file)
@@ -9,7 +9,7 @@ i3-nagbar - displays an error bar on top of your screen
 
 == SYNOPSIS
 
-i3-nagbar [-m <message>] [-b <button> <action>] [-t warning|error] [-f <font>] [-v]
+i3-nagbar [-m <message>] [-b <button> <terminal-action>] [-B <button> <shell-action>] [-t warning|error] [-f <font>] [-v]
 
 == OPTIONS
 
@@ -29,9 +29,13 @@ Display 'message' as text on the left of the i3-nagbar.
 *-f, --font* 'font'::
 Select font that is being used.
 
-*-b, --button* 'button' 'action'::
-Create a button with text 'button'. The 'action' are the shell commands that
-will be executed by this button. Multiple buttons can be defined.
+*-b, --button* 'button' 'terminal-action'::
+Adds a button labelled 'button' to the bar. When pressed, the command given
+in 'terminal-action' is executed inside a terminal emulator, via i3-sensible-terminal(1).
+Multiple buttons can be defined.
+
+*-B, --button-sh* 'button' 'shell-action'::
+Same as *--button*, except that the command given in 'shell-action' is executed directly by the shell.
 
 == DESCRIPTION
 
@@ -49,7 +53,7 @@ i3-nagbar -m 'You have an error in your i3 config file!' \
 
 == SEE ALSO
 
-i3(1)
+i3(1), i3-sensible-terminal(1)
 
 == AUTHOR