all repos — tint2 @ d49adfdef3a91c6ad6b7de07ac151ebe882326f4

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

Launcher: Support %f and %F
o9000 mrovi9000@gmail.com
commit

d49adfdef3a91c6ad6b7de07ac151ebe882326f4

parent

498b665c8a2616df542b29a7fc3d559a777513bb

M src/drag_and_drop.csrc/drag_and_drop.c

@@ -298,23 +298,6 @@ XSendEvent(server.display, e->data.l[0], False, NoEventMask, (XEvent *)&m);

} } -GString *tint2_g_string_replace(GString *s, const char *from, const char *to) -{ - GString *result = g_string_new(""); - for (char *p = s->str; *p;) { - if (strstr(p, from) == p) { - g_string_append(result, to); - p += strlen(from); - } else { - g_string_append_c(result, *p); - p += 1; - } - } - g_string_assign(s, result->str); - g_string_free(result, TRUE); - return s; -} - void handle_dnd_selection_notify(XSelectionEvent *e) { Atom target = e->target;

@@ -326,11 +309,7 @@ "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__,

@@ -371,25 +350,49 @@ fprintf(stderr, "%c", ((char *)prop.data)[i]);

fprintf(stderr, "tint2: --------\n"); } - // TODO: support %r nd %F // https://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables GString *cmd = g_string_new(dnd_launcher_icon->cmd); const char *atom_name = GetAtomName(server.display, prop.type); - if (strcasecmp(atom_name, "STRING") == 0 || - strcasecmp(atom_name, "text/uri-list") == 0) { + if (strcasecmp(atom_name, "STRING") == 0 || strcasecmp(atom_name, "text/uri-list") == 0) { GString *url = g_string_new(""); GString *prev_url = g_string_new(""); + gboolean must_unescape = strcasecmp(atom_name, "text/uri-list") == 0; for (int i = 0; i < prop.nitems * prop.format / 8; i++) { char c = ((char *)prop.data)[i]; if (c == '\n') { + if (must_unescape) { + char *raw = g_uri_unescape_string(url->str, NULL); + if (raw) { + g_string_assign(url, raw); + } + free(raw); + } // Many programs cannot handle this prefix tint2_g_string_replace(url, "file://", ""); // Some programs put duplicates in the list, we remove them if (strcmp(url->str, prev_url->str) != 0) { - g_string_append(cmd, " \""); - g_string_append(cmd, url->str); - g_string_append(cmd, "\""); + if (strstr(cmd->str, "%F")) { + GString *piece = g_string_new(""); + g_string_append(piece, " \""); + g_string_append(piece, url->str); + g_string_append(piece, "\""); + g_string_append(piece, " %F"); + tint2_g_string_replace(cmd, "%F", piece->str); + g_string_free(piece, TRUE); + } else if (strstr(cmd->str, "%f")) { + GString *piece = g_string_new(""); + g_string_append(piece, " \""); + g_string_append(piece, url->str); + g_string_append(piece, "\""); + tint2_g_string_replace(cmd, "%f", piece->str); + g_string_free(piece, TRUE); + break; + } else { + g_string_append(cmd, " \""); + g_string_append(cmd, url->str); + g_string_append(cmd, "\""); + } } g_string_assign(prev_url, url->str); g_string_assign(url, "");

@@ -405,6 +408,8 @@ }

g_string_free(url, TRUE); g_string_free(prev_url, TRUE); } + tint2_g_string_replace(cmd, "%F", ""); + tint2_g_string_replace(cmd, "%f", ""); if (debug_dnd) fprintf(stderr, "tint2: DnD %s:%d: Running command: %s\n", __FILE__, __LINE__, cmd->str); tint_exec(cmd->str,
M src/launcher/apps-common.csrc/launcher/apps-common.c

@@ -96,6 +96,10 @@ sprintf(q, "'%s'", path);

q += strlen("''"); q += strlen(path); q--; // To balance the q++ in the for + } else if (*p == 'f' || *p == 'F') { + sprintf(q, "%c%c", '%', *p); + q += 2; + q--; // To balance the q++ in the for } else { // We don't care about other expansions q--; // Delete the last % from q
M src/launcher/launcher.csrc/launcher/launcher.c

@@ -385,7 +385,12 @@

void launcher_icon_dump_geometry(void *obj, int indent) { LauncherIcon *launcherIcon = (LauncherIcon *)obj; - fprintf(stderr, "tint2: %*sIcon: w = h = %d, name = %s\n", indent, "", launcherIcon->icon_size, launcherIcon->icon_name); + fprintf(stderr, + "tint2: %*sIcon: w = h = %d, name = %s\n", + indent, + "", + launcherIcon->icon_size, + launcherIcon->icon_name); } Imlib_Image scale_icon(Imlib_Image original, int icon_size)

@@ -434,8 +439,21 @@ {

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, icon->start_in_terminal, icon->startup_notification); + if (evt->type == ButtonPress || evt->type == ButtonRelease) { + GString *cmd = g_string_new(icon->cmd); + tint2_g_string_replace(cmd, "%f", ""); + tint2_g_string_replace(cmd, "%F", ""); + tint_exec(cmd->str, + icon->cwd, + icon->icon_tooltip, + evt->xbutton.time, + &icon->area, + x, + y, + icon->start_in_terminal, + icon->startup_notification); + g_string_free(cmd, TRUE); + } } // Populates the list_icons list from the list_apps list
M src/main.csrc/main.c

@@ -536,7 +536,6 @@ // 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

@@ -400,10 +400,11 @@ 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); + if (wordexp(command, &words, WRDE_DOOFFS | WRDE_SHOWERR) == 0) { + 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); } execlp("sh", "sh", "-c", command, NULL);

@@ -1033,3 +1034,20 @@ for (int fd = 3; fd < maxfd; fd++) {

close(fd); } } + +GString *tint2_g_string_replace(GString *s, const char *from, const char *to) +{ + GString *result = g_string_new(""); + for (char *p = s->str; *p;) { + if (strstr(p, from) == p) { + g_string_append(result, to); + p += strlen(from); + } else { + g_string_append_c(result, *p); + p += 1; + } + } + g_string_assign(s, result->str); + g_string_free(result, TRUE); + return s; +}
M src/util/common.hsrc/util/common.h

@@ -148,6 +148,8 @@

// A trivial pointer comparator. gint cmp_ptr(gconstpointer a, gconstpointer b); +GString *tint2_g_string_replace(GString *s, const char *from, const char *to); + #define free_and_null(p) \ { \ free(p); \