all repos — tint2 @ 14c3824632f6e654e60a8510a9aa3a0cec9c6c72

fork of the tint2 desktop panel for my custom setup - only minimized windows across all desktops for the taskbar

Launcher: Add support for Terminal=true
o9000 mrovi9000@gmail.com
commit

14c3824632f6e654e60a8510a9aa3a0cec9c6c72

parent

eb93af362248a5355e544b6827f26cf4ab6bf7bf

M src/battery/battery.csrc/battery/battery.c

@@ -464,5 +464,5 @@ case 5:

command = battery_dwheel_command; break; } - tint_exec(command, NULL, NULL, time, obj, x, y); + tint_exec(command, NULL, NULL, time, obj, x, y, FALSE, TRUE); }
M src/button/button.csrc/button/button.c

@@ -530,7 +530,7 @@ case 5:

command = button->backend->dwheel_command; break; } - tint_exec(command, NULL, NULL, time, obj, x, y); + tint_exec(command, NULL, NULL, time, obj, x, y, FALSE, TRUE); } char *button_get_tooltip(void *obj)
M src/clock/clock.csrc/clock/clock.c

@@ -353,5 +353,5 @@ case 5:

command = clock_dwheel_command; break; } - tint_exec(command, NULL, NULL, time, obj, x, y); + tint_exec(command, NULL, NULL, time, obj, x, y, FALSE, TRUE); }
M src/drag_and_drop.csrc/drag_and_drop.c

@@ -30,7 +30,7 @@ static int dnd_version;

static Atom dnd_selection; static Atom dnd_atom; static int dnd_sent_request; -static char *dnd_launcher_exec; +static LauncherIcon *dnd_launcher_icon; static gboolean dnd_debug = FALSE; gboolean hidden_panel_shown_for_dnd;

@@ -43,7 +43,7 @@ dnd_version = 0;

dnd_selection = XInternAtom(server.display, "PRIMARY", 0); dnd_atom = None; dnd_sent_request = 0; - dnd_launcher_exec = 0; + dnd_launcher_icon = NULL; hidden_panel_shown_for_dnd = FALSE; }

@@ -62,9 +62,21 @@ __FILE__,

__LINE__, more_than_3 ? "yes" : "no"); fprintf(stderr, "tint2: DnD %s:%d: Protocol version = %d\n", __FILE__, __LINE__, dnd_version); - fprintf(stderr, "tint2: DnD %s:%d: Type 1 = %s\n", __FILE__, __LINE__, GetAtomName(server.display, e->data.l[2])); - fprintf(stderr, "tint2: DnD %s:%d: Type 2 = %s\n", __FILE__, __LINE__, GetAtomName(server.display, e->data.l[3])); - fprintf(stderr, "tint2: DnD %s:%d: Type 3 = %s\n", __FILE__, __LINE__, GetAtomName(server.display, e->data.l[4])); + fprintf(stderr, + "tint2: DnD %s:%d: Type 1 = %s\n", + __FILE__, + __LINE__, + GetAtomName(server.display, e->data.l[2])); + fprintf(stderr, + "tint2: DnD %s:%d: Type 2 = %s\n", + __FILE__, + __LINE__, + GetAtomName(server.display, e->data.l[3])); + fprintf(stderr, + "tint2: DnD %s:%d: Type 3 = %s\n", + __FILE__, + __LINE__, + GetAtomName(server.display, e->data.l[4])); } // Query which conversions are available and pick the best

@@ -80,7 +92,11 @@ dnd_atom = pick_target_from_atoms(server.display, e->data.l[2], e->data.l[3], e->data.l[4]);

} if (dnd_debug) - fprintf(stderr, "tint2: DnD %s:%d: Requested type = %s\n", __FILE__, __LINE__, GetAtomName(server.display, dnd_atom)); + fprintf(stderr, + "tint2: DnD %s:%d: Requested type = %s\n", + __FILE__, + __LINE__, + GetAtomName(server.display, dnd_atom)); } void handle_dnd_position(XClientMessageEvent *e)

@@ -102,9 +118,9 @@ } else {

LauncherIcon *icon = click_launcher_icon(panel, mapX, mapY); if (icon) { accept = 1; - dnd_launcher_exec = icon->cmd; + dnd_launcher_icon = icon; } else { - dnd_launcher_exec = 0; + dnd_launcher_icon = NULL; } }

@@ -129,7 +145,7 @@ }

void handle_dnd_drop(XClientMessageEvent *e) { - if (dnd_target_window && dnd_launcher_exec) { + if (dnd_target_window && dnd_launcher_icon) { if (dnd_version >= 1) { XConvertSelection(server.display, server.atom.XdndSelection,

@@ -173,7 +189,11 @@ "DnD %s:%d: Selection atom = %s\n",

__FILE__, __LINE__, GetAtomName(server.display, e->selection)); - fprintf(stderr, "tint2: DnD %s:%d: Target atom = %s\n", __FILE__, __LINE__, GetAtomName(server.display, target)); + fprintf(stderr, + "tint2: DnD %s:%d: Target atom = %s\n", + __FILE__, + __LINE__, + GetAtomName(server.display, target)); fprintf(stderr, "DnD %s:%d: Property atom = %s\n", __FILE__,

@@ -181,7 +201,7 @@ __LINE__,

GetAtomName(server.display, e->property)); } - if (e->property != None && dnd_launcher_exec) { + if (e->property != None && dnd_launcher_icon) { Property prop = read_property(server.display, dnd_target_window, dnd_selection); // If we're being given a list of targets (possible conversions)

@@ -213,10 +233,12 @@ fprintf(stderr, "tint2: %c", ((char *)prop.data)[i]);

fprintf(stderr, "tint2: --------\n"); } + // TODO replace this with exec*(...) + int cmd_length = 0; - cmd_length += 1; // ( - cmd_length += strlen(dnd_launcher_exec) + 1; // exec + space - cmd_length += 1; // open double quotes + cmd_length += 1; // ( + cmd_length += strlen(dnd_launcher_icon->cmd) + 1; // exec + space + cmd_length += 1; // open double quotes for (int i = 0; i < prop.nitems * prop.format / 8; i++) { char c = ((char *)prop.data)[i]; if (c == '\n') {

@@ -239,7 +261,7 @@

char *cmd = (char *)calloc(cmd_length, 1); cmd[0] = '\0'; strcat(cmd, "("); - strcat(cmd, dnd_launcher_exec); + strcat(cmd, dnd_launcher_icon->cmd); strcat(cmd, " \""); for (int i = 0; i < prop.nitems * prop.format / 8; i++) { char c = ((char *)prop.data)[i];

@@ -263,7 +285,15 @@ strcat(cmd, "\"");

strcat(cmd, "&)"); if (dnd_debug) fprintf(stderr, "tint2: DnD %s:%d: Running command: %s\n", __FILE__, __LINE__, cmd); - tint_exec(cmd, NULL, NULL, e->time, NULL, 0, 0); + tint_exec(cmd, + NULL, + NULL, + e->time, + NULL, + 0, + 0, + dnd_launcher_icon->start_in_terminal, + dnd_launcher_icon->startup_notification); free(cmd); // Reply OK.
M src/execplugin/execplugin.csrc/execplugin/execplugin.c

@@ -577,7 +577,7 @@ setenvd("EXECP_X", x);

setenvd("EXECP_Y", y); setenvd("EXECP_W", execp->area.width); setenvd("EXECP_H", execp->area.height); - pid_t pid = tint_exec(command, NULL, NULL, time, obj, x, y); + pid_t pid = tint_exec(command, NULL, NULL, time, obj, x, y, FALSE, TRUE); unsetenv("EXECP_X"); unsetenv("EXECP_Y"); unsetenv("EXECP_W");
M src/launcher/apps-common.csrc/launcher/apps-common.c

@@ -113,6 +113,8 @@ gboolean read_desktop_file_full_path(const char *path, DesktopEntry *entry)

{ entry->name = entry->generic_name = entry->icon = entry->exec = entry->cwd = NULL; entry->hidden_from_menus = FALSE; + entry->start_in_terminal = FALSE; + entry->startup_notification = TRUE; FILE *fp = fopen(path, "rt"); if (fp == NULL) {

@@ -192,6 +194,10 @@ } else if (!entry->icon && strcmp(key, "Icon") == 0) {

entry->icon = strdup(value); } else if (strcmp(key, "NoDisplay") == 0) { entry->hidden_from_menus = strcasecmp(value, "true") == 0; + } else if (strcmp(key, "Terminal") == 0) { + entry->start_in_terminal = strcasecmp(value, "true") == 0; + } else if (strcmp(key, "StartupNotify") == 0) { + entry->startup_notification = strcasecmp(value, "true") == 0; } } }
M src/launcher/apps-common.hsrc/launcher/apps-common.h

@@ -17,6 +17,8 @@ char *icon;

char *path; char *cwd; gboolean hidden_from_menus; + gboolean start_in_terminal; + gboolean startup_notification; } DesktopEntry; // Parses a line of the form "key = value". Modifies the line.
M src/launcher/launcher.csrc/launcher/launcher.c

@@ -435,7 +435,7 @@ launcher_reload_icon((Launcher *)icon->area.parent, icon);

launcher_reload_hidden_icons((Launcher *)icon->area.parent); if (evt->type == ButtonPress || evt->type == ButtonRelease) - tint_exec(icon->cmd, icon->cwd, icon->icon_tooltip, evt->xbutton.time, &icon->area, x, y); + tint_exec(icon->cmd, icon->cwd, icon->icon_tooltip, evt->xbutton.time, &icon->area, x, y, icon->start_in_terminal, icon->startup_notification); } // Populates the list_icons list from the list_apps list

@@ -490,6 +490,8 @@ if (entry.cwd)

launcherIcon->cwd = strdup(entry.cwd); else launcherIcon->cwd = NULL; + launcherIcon->start_in_terminal = entry.start_in_terminal; + launcherIcon->startup_notification = entry.startup_notification; if (launcherIcon->icon_name) free(launcherIcon->icon_name); launcherIcon->icon_name = entry.icon ? strdup(entry.icon) : strdup(DEFAULT_ICON);
M src/launcher/launcher.hsrc/launcher/launcher.h

@@ -33,6 +33,8 @@ Imlib_Image image_hover;

Imlib_Image image_pressed; char *cmd; char *cwd; + gboolean start_in_terminal; + gboolean startup_notification; char *icon_name; char *icon_path; char *icon_tooltip;
M src/main.csrc/main.c

@@ -536,6 +536,7 @@ // Start real_transparency

emit_self_restart("compositor changed"); } } + fprintf(stderr, "tint2: ClientMessage %s\n", GetAtomName(server.display, ev->message_type)); if (systray_enabled && e->xclient.message_type == server.atom._NET_SYSTEM_TRAY_OPCODE && e->xclient.format == 32 && e->xclient.window == net_sel_win) { handle_systray_event(&e->xclient);
M src/util/common.csrc/util/common.c

@@ -40,6 +40,7 @@ #include <fcntl.h>

#include <sys/time.h> #include <errno.h> #include <dirent.h> +#include <wordexp.h> #ifdef HAVE_RSVG #include <librsvg/rsvg.h>

@@ -267,7 +268,15 @@ return setenv(name, buf, 1);

} #ifndef TINT2CONF -pid_t tint_exec(const char *command, const char *dir, const char *tooltip, Time time, Area *area, int x, int y) +pid_t tint_exec(const char *command, + const char *dir, + const char *tooltip, + Time time, + Area *area, + int x, + int y, + gboolean terminal, + gboolean startup_notification) { if (!command || strlen(command) == 0) return -1;

@@ -362,7 +371,7 @@ tooltip = command;

#if HAVE_SN SnLauncherContext *ctx = 0; - if (startup_notifications && time) { + if (startup_notifications && startup_notification && 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");

@@ -377,7 +386,7 @@ fprintf(stderr, "tint2: Could not fork\n");

} else if (pid == 0) { // Child process #if HAVE_SN - if (startup_notifications && time) { + if (startup_notifications && startup_notification && time) { sn_launcher_context_setup_child_process(ctx); } #endif // HAVE_SN

@@ -387,10 +396,25 @@ // Run the command

if (dir) chdir(dir); close_all_fds(); - execl("/bin/sh", "/bin/sh", "-c", command, NULL); - fprintf(stderr, "tint2: Failed to execlp %s\n", command); + if (terminal) { + fprintf(stderr, "tint2: executing in x-terminal-emulator: %s\n", command); + wordexp_t words; + words.we_offs = 2; + wordexp(command, &words, WRDE_DOOFFS | WRDE_SHOWERR); + words.we_wordv[0] = (char*)"x-terminal-emulator"; + words.we_wordv[1] = (char*)"-e"; + execvp("x-terminal-emulator", words.we_wordv); + } + fprintf(stderr, "tint2: could not execute command in x-terminal-emulator: %s, executting in shell\n", command); + wordexp_t words; + words.we_offs = 2; + wordexp(command, &words, WRDE_DOOFFS | WRDE_SHOWERR); + words.we_wordv[0] = (char*)"sh"; + words.we_wordv[1] = (char*)"-c"; + execvp("sh", words.we_wordv); + fprintf(stderr, "tint2: Failed to execute %s\n", command); #if HAVE_SN - if (startup_notifications && time) { + if (startup_notifications && startup_notification && time) { sn_launcher_context_unref(ctx); } #endif // HAVE_SN

@@ -398,7 +422,7 @@ _exit(1);

} else { // Parent process #if HAVE_SN - if (startup_notifications && time) { + if (startup_notifications && startup_notification && time) { g_tree_insert(server.pids, GINT_TO_POINTER(pid), ctx); } #endif // HAVE_SN

@@ -425,7 +449,7 @@ }

void tint_exec_no_sn(const char *command) { - tint_exec(command, NULL, NULL, 0, NULL, 0, 0); + tint_exec(command, NULL, NULL, 0, NULL, 0, 0, FALSE, FALSE); } #endif
M src/util/common.hsrc/util/common.h

@@ -66,7 +66,15 @@ void extract_values(const char *value, char **value1, char **value2, char **value3);

void extract_values_4(const char *value, char **value1, char **value2, char **value3, char **value4); // Executes a command in a shell. -pid_t tint_exec(const char *command, const char *dir, const char *tooltip, Time time, Area *area, int x, int y); +pid_t tint_exec(const char *command, + const char *dir, + const char *tooltip, + Time time, + Area *area, + int x, + int y, + gboolean terminal, + gboolean startup_notification); void tint_exec_no_sn(const char *command); int setenvd(const char *name, const int value);