]> git.sur5r.net Git - i3/i3/blobdiff - i3-nagbar/main.c
i3-nagbar: add button flag to execute action with /bin/sh directly.
[i3/i3] / i3-nagbar / main.c
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)