diff --git a/src/battery/battery.c b/src/battery/battery.c index 4ecff73..ccc6975 100644 --- a/src/battery/battery.c +++ b/src/battery/battery.c @@ -227,14 +227,14 @@ void update_battery_tick(void *arg) if (old_ac_connected != battery_state.ac_connected) { if (battery_state.ac_connected) - tint_exec(ac_connected_cmd); + tint_exec_no_sn(ac_connected_cmd); else - tint_exec(ac_disconnected_cmd); + tint_exec_no_sn(ac_disconnected_cmd); } if (battery_state.percentage < battery_low_status && battery_state.state == BATTERY_DISCHARGING && !battery_low_cmd_sent) { - tint_exec(battery_low_cmd); + tint_exec_no_sn(battery_low_cmd); battery_low_cmd_sent = TRUE; } if (battery_state.percentage > battery_low_status && battery_state.state == BATTERY_CHARGING && @@ -437,7 +437,7 @@ char *battery_get_tooltip(void *obj) return battery_os_tooltip(); } -void battery_action(int button) +void battery_action(int button, Time time) { char *command = NULL; switch (button) { @@ -457,5 +457,5 @@ void battery_action(int button) command = battery_dwheel_command; break; } - tint_exec(command); + tint_exec(command, NULL, NULL, time); } diff --git a/src/battery/battery.h b/src/battery/battery.h index 04664d3..831413c 100644 --- a/src/battery/battery.h +++ b/src/battery/battery.h @@ -108,7 +108,7 @@ void battery_default_font_changed(); gboolean resize_battery(void *obj); -void battery_action(int button); +void battery_action(int button, Time time); /* operating system specific functions */ gboolean battery_os_init(); diff --git a/src/button/button.c b/src/button/button.c index 85c056a..c5c9e4f 100644 --- a/src/button/button.c +++ b/src/button/button.c @@ -513,7 +513,7 @@ void button_dump_geometry(void *obj, int indent) button->backend->text); } -void button_action(void *obj, int mouse_button, int x, int y) +void button_action(void *obj, int mouse_button, int x, int y, Time time) { Button *button = (Button *)obj; Panel *panel = (Panel *)button->area.panel; @@ -626,18 +626,8 @@ void button_action(void *obj, int mouse_button, int x, int y) panel_x2, panel_y2, command); - pid_t pid = fork(); - if (pid < 0) { - fprintf(stderr, "Could not fork\n"); - } else if (pid == 0) { - // Child process - // Allow children to exist after parent destruction - setsid(); - // Run the command - execl("/bin/sh", "/bin/sh", "-c", full_cmd, NULL); - fprintf(stderr, "Failed to execlp %s\n", full_cmd); - exit(1); - } + tint_exec(full_cmd, NULL, NULL, time); + g_free(full_cmd); } } diff --git a/src/button/button.h b/src/button/button.h index 92f6280..1b1d58e 100644 --- a/src/button/button.h +++ b/src/button/button.h @@ -103,7 +103,7 @@ void draw_button(void *obj, cairo_t *c); gboolean resize_button(void *obj); // Called on mouse click event. -void button_action(void *obj, int button, int x, int y); +void button_action(void *obj, int button, int x, int y, Time time); void button_default_font_changed(); void button_default_icon_theme_changed(); diff --git a/src/clock/clock.c b/src/clock/clock.c index 5f2be44..818b1e3 100644 --- a/src/clock/clock.c +++ b/src/clock/clock.c @@ -393,7 +393,7 @@ char *clock_get_tooltip(void *obj) return strdup(buf_tooltip); } -void clock_action(int button) +void clock_action(int button, Time time) { char *command = NULL; switch (button) { @@ -413,5 +413,5 @@ void clock_action(int button) command = clock_dwheel_command; break; } - tint_exec(command); + tint_exec(command, NULL, NULL, time); } diff --git a/src/clock/clock.h b/src/clock/clock.h index e433405..47851d2 100644 --- a/src/clock/clock.h +++ b/src/clock/clock.h @@ -54,6 +54,6 @@ void draw_clock(void *obj, cairo_t *c); gboolean resize_clock(void *obj); -void clock_action(int button); +void clock_action(int button, Time time); #endif diff --git a/src/config.c b/src/config.c index dd071ac..297aaa1 100644 --- a/src/config.c +++ b/src/config.c @@ -62,8 +62,8 @@ #endif // global path -char *config_path; -char *snapshot_path; +char *config_path = NULL; +char *snapshot_path = NULL; #ifndef TINT2CONF diff --git a/src/execplugin/execplugin.c b/src/execplugin/execplugin.c index fcef081..e7656d1 100644 --- a/src/execplugin/execplugin.c +++ b/src/execplugin/execplugin.c @@ -557,7 +557,7 @@ void execp_force_update(Execp *execp) } } -void execp_action(void *obj, int button, int x, int y) +void execp_action(void *obj, int button, int x, int y, Time time) { Execp *execp = obj; char *command = NULL; @@ -588,20 +588,7 @@ void execp_action(void *obj, int button, int x, int y) execp->area.width, execp->area.height, command); - pid_t pid = fork(); - if (pid < 0) { - fprintf(stderr, "Could not fork\n"); - } else if (pid == 0) { - // Child process - // Allow children to exist after parent destruction - setsid(); - // Run the command - execl("/bin/sh", "/bin/sh", "-c", full_cmd, NULL); - fprintf(stderr, "Failed to execlp %s\n", full_cmd); - exit(1); - } - // Parent process - g_tree_insert(execp->backend->cmd_pids, GINT_TO_POINTER(pid), GINT_TO_POINTER(1)); + tint_exec(full_cmd, NULL, NULL, time); g_free(full_cmd); } else { execp_force_update(execp); diff --git a/src/execplugin/execplugin.h b/src/execplugin/execplugin.h index ac78f64..23cb4aa 100644 --- a/src/execplugin/execplugin.h +++ b/src/execplugin/execplugin.h @@ -129,7 +129,7 @@ void draw_execp(void *obj, cairo_t *c); gboolean resize_execp(void *obj); // Called on mouse click event. -void execp_action(void *obj, int button, int x, int y); +void execp_action(void *obj, int button, int x, int y, Time time); void execp_cmd_completed(Execp *obj, pid_t pid); diff --git a/src/launcher/launcher.c b/src/launcher/launcher.c index 7a56ad1..897fd83 100644 --- a/src/launcher/launcher.c +++ b/src/launcher/launcher.c @@ -50,7 +50,6 @@ int launcher_brightness; char *icon_theme_name_config; char *icon_theme_name_xsettings; int launcher_icon_theme_override; -int startup_notifications; Background *launcher_icon_bg; GList *launcher_icon_gradients; @@ -420,60 +419,9 @@ void launcher_action(LauncherIcon *icon, XEvent *evt) { launcher_reload_icon((Launcher *)icon->area.parent, icon); launcher_reload_hidden_icons((Launcher *)icon->area.parent); - char *cmd = calloc(strlen(icon->cmd) + 10, 1); - sprintf(cmd, "(%s&)", icon->cmd); -#if HAVE_SN - SnLauncherContext *ctx = 0; - Time time; - if (startup_notifications) { - ctx = sn_launcher_context_new(server.sn_display, server.screen); - sn_launcher_context_set_name(ctx, icon->icon_tooltip); - sn_launcher_context_set_description(ctx, "Application launched from tint2"); - sn_launcher_context_set_binary_name(ctx, icon->cmd); - // Get a timestamp from the X event - if (evt->type == ButtonPress || evt->type == ButtonRelease) { - time = evt->xbutton.time; - } else { - fprintf(stderr, "Unknown X event: %d\n", evt->type); - free(cmd); - return; - } - sn_launcher_context_initiate(ctx, "tint2", icon->cmd, time); - } -#endif /* HAVE_SN */ - pid_t pid; - pid = fork(); - if (pid < 0) { - fprintf(stderr, "Could not fork\n"); - } else if (pid == 0) { -// Child process -#if HAVE_SN - if (startup_notifications) { - sn_launcher_context_setup_child_process(ctx); - } -#endif // HAVE_SN - // Allow children to exist after parent destruction - setsid(); - // Run the command - if (icon->cwd) - chdir(icon->cwd); - execl("/bin/sh", "/bin/sh", "-c", icon->cmd, NULL); - fprintf(stderr, "Failed to execlp %s\n", icon->cmd); -#if HAVE_SN - if (startup_notifications) { - sn_launcher_context_unref(ctx); - } -#endif // HAVE_SN - exit(1); - } else { -// Parent process -#if HAVE_SN - if (startup_notifications) { - g_tree_insert(server.pids, GINT_TO_POINTER(pid), ctx); - } -#endif // HAVE_SN - } - free(cmd); + + if (evt->type == ButtonPress || evt->type == ButtonRelease) + tint_exec(icon->cmd, icon->cwd, icon->icon_tooltip, evt->xbutton.time); } // Populates the list_icons list from the list_apps list diff --git a/src/launcher/launcher.h b/src/launcher/launcher.h index 7c479e3..6b44dc3 100644 --- a/src/launcher/launcher.h +++ b/src/launcher/launcher.h @@ -49,7 +49,6 @@ extern int launcher_brightness; extern char *icon_theme_name_xsettings; // theme name extern char *icon_theme_name_config; extern int launcher_icon_theme_override; -extern int startup_notifications; extern Background *launcher_icon_bg; extern GList *launcher_icon_gradients; diff --git a/src/panel.c b/src/panel.c index 64bcc97..cb7afa3 100644 --- a/src/panel.c +++ b/src/panel.c @@ -57,6 +57,7 @@ gboolean task_dragged; char *panel_window_name = NULL; gboolean debug_geometry; gboolean debug_gradients; +gboolean startup_notifications; gboolean panel_autohide; int panel_autohide_show_timeout; diff --git a/src/panel.h b/src/panel.h index 707351c..11033a9 100644 --- a/src/panel.h +++ b/src/panel.h @@ -90,6 +90,7 @@ extern Imlib_Image default_icon; #define DEFAULT_FONT "sans 10" extern char *default_font; extern XSettingsClient *xsettings_client; +extern gboolean startup_notifications; extern gboolean debug_geometry; extern gboolean debug_fps; extern gboolean debug_frames; diff --git a/src/tint.c b/src/tint.c index 4458e9a..7791d07 100644 --- a/src/tint.c +++ b/src/tint.c @@ -968,7 +968,7 @@ void event_button_release(XEvent *e) } if (click_clock(panel, e->xbutton.x, e->xbutton.y)) { - clock_action(e->xbutton.button); + clock_action(e->xbutton.button, e->xbutton.time); if (panel_layer == BOTTOM_LAYER) XLowerWindow(server.display, panel->main_win); task_drag = 0; @@ -977,7 +977,7 @@ void event_button_release(XEvent *e) #ifdef ENABLE_BATTERY if (click_battery(panel, e->xbutton.x, e->xbutton.y)) { - battery_action(e->xbutton.button); + battery_action(e->xbutton.button, e->xbutton.time); if (panel_layer == BOTTOM_LAYER) XLowerWindow(server.display, panel->main_win); task_drag = 0; @@ -987,7 +987,7 @@ void event_button_release(XEvent *e) Execp *execp = click_execp(panel, e->xbutton.x, e->xbutton.y); if (execp) { - execp_action(execp, e->xbutton.button, e->xbutton.x - execp->area.posx, e->xbutton.y - execp->area.posy); + execp_action(execp, e->xbutton.button, e->xbutton.x - execp->area.posx, e->xbutton.y - execp->area.posy, e->xbutton.time); if (panel_layer == BOTTOM_LAYER) XLowerWindow(server.display, panel->main_win); task_drag = 0; @@ -996,7 +996,7 @@ void event_button_release(XEvent *e) Button *button = click_button(panel, e->xbutton.x, e->xbutton.y); if (button) { - button_action(button, e->xbutton.button, e->xbutton.x - button->area.posx, e->xbutton.y - button->area.posy); + button_action(button, e->xbutton.button, e->xbutton.x - button->area.posx, e->xbutton.y - button->area.posy, e->xbutton.time); if (panel_layer == BOTTOM_LAYER) XLowerWindow(server.display, panel->main_win); task_drag = 0; @@ -2131,7 +2131,7 @@ start: strcat(cmd, "\""); strcat(cmd, "&)"); fprintf(stderr, "DnD %s:%d: Running command: %s\n", __FILE__, __LINE__, cmd); - tint_exec(cmd); + tint_exec(cmd, NULL, NULL, e.xselection.time); free(cmd); // Reply OK. diff --git a/src/tint2conf/main.c b/src/tint2conf/main.c index 05d2b67..90a8b27 100644 --- a/src/tint2conf/main.c +++ b/src/tint2conf/main.c @@ -340,6 +340,10 @@ int main(int argc, char **argv) if (argc > 0) { load_specific_themes(argv, argc); g_timeout_add(SNAPSHOT_TICK, edit_theme, NULL); + } else if (getenv("TINT2_CONFIG")) { + char *themes[2] = {getenv("TINT2_CONFIG"), NULL}; + load_specific_themes(themes, 1); + g_timeout_add(SNAPSHOT_TICK, edit_theme, NULL); } gtk_widget_show_all(g_window); diff --git a/src/util/common.c b/src/util/common.c index fbda54c..09f34d7 100644 --- a/src/util/common.c +++ b/src/util/common.c @@ -44,6 +44,8 @@ #include #endif +#include "../panel.h" + void copy_file(const char *path_src, const char *path_dest) { if (g_str_equal(path_src, path_dest)) @@ -99,18 +101,70 @@ gboolean parse_line(const char *line, char **key, char **value) return TRUE; } -void tint_exec(const char *command) +extern char *config_path; + +void tint_exec(const char *command, const char *dir, const char *tooltip, Time time) { - if (command) { - if (fork() == 0) { - // change for the fork the signal mask - // sigset_t sigset; - // sigprocmask(SIG_SETMASK, &sigset, 0); - // sigprocmask(SIG_UNBLOCK, &sigset, 0); - execl("/bin/sh", "/bin/sh", "-c", command, NULL); - _exit(0); - } + if (!command || strlen(command) == 0) + return; + + command = g_strdup_printf("export TINT2_CONFIG=%s;" + "%s", + config_path, + command); + if (!command) + return; + + if (!tooltip) + tooltip = command; + +#if HAVE_SN && !defined TINT2CONF + SnLauncherContext *ctx = 0; + if (startup_notifications && time) { + ctx = sn_launcher_context_new(server.sn_display, server.screen); + sn_launcher_context_set_name(ctx, tooltip); + sn_launcher_context_set_description(ctx, "Application launched from tint2"); + sn_launcher_context_set_binary_name(ctx, command); + sn_launcher_context_initiate(ctx, "tint2", command, time); } +#endif /* HAVE_SN */ + pid_t pid; + pid = fork(); + if (pid < 0) { + fprintf(stderr, "Could not fork\n"); + } else if (pid == 0) { +// Child process +#if HAVE_SN && !defined TINT2CONF + if (startup_notifications && time) { + sn_launcher_context_setup_child_process(ctx); + } +#endif // HAVE_SN + // Allow children to exist after parent destruction + setsid(); + // Run the command + if (dir) + chdir(dir); + execl("/bin/sh", "/bin/sh", "-c", command, NULL); + fprintf(stderr, "Failed to execlp %s\n", command); +#if HAVE_SN && !defined TINT2CONF + if (startup_notifications && time) { + sn_launcher_context_unref(ctx); + } +#endif // HAVE_SN + _exit(1); + } else { +// Parent process +#if HAVE_SN && !defined TINT2CONF + if (startup_notifications && time) { + g_tree_insert(server.pids, GINT_TO_POINTER(pid), ctx); + } +#endif // HAVE_SN + } +} + +void tint_exec_no_sn(const char *command) +{ + tint_exec(command, NULL, NULL, 0); } char *expand_tilde(const char *s) diff --git a/src/util/common.h b/src/util/common.h index 6567f30..b4f34f1 100644 --- a/src/util/common.h +++ b/src/util/common.h @@ -54,7 +54,8 @@ void extract_values(const char *value, char **value1, char **value2, char **valu void extract_values_4(const char *value, char **value1, char **value2, char **value3, char **value4); // Executes a command in a shell. -void tint_exec(const char *command); +void tint_exec(const char *command, const char *dir, const char *tooltip, Time time); +void tint_exec_no_sn(const char *command); // Returns a copy of s in which "~" is expanded to the path to the user's home directory. // The caller takes ownership of the string.