Launcher: Add support for Terminal=true
This commit is contained in:
parent
eb93af3622
commit
14c3824632
12 changed files with 105 additions and 30 deletions
|
@ -464,5 +464,5 @@ void battery_action(void *obj, int button, int x, int y, Time time)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -530,7 +530,7 @@ void button_action(void *obj, int mouse_button, int x, int y, Time time)
|
|||
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)
|
||||
|
|
|
@ -353,5 +353,5 @@ void clock_action(void *obj, int button, int x, int y, Time time)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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 @@ void dnd_init()
|
|||
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 @@ void handle_dnd_enter(XClientMessageEvent *e)
|
|||
__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 @@ void handle_dnd_enter(XClientMessageEvent *e)
|
|||
}
|
||||
|
||||
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 @@ void handle_dnd_position(XClientMessageEvent *e)
|
|||
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_position(XClientMessageEvent *e)
|
|||
|
||||
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 @@ void handle_dnd_selection_notify(XSelectionEvent *e)
|
|||
__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 @@ void handle_dnd_selection_notify(XSelectionEvent *e)
|
|||
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 @@ void handle_dnd_selection_notify(XSelectionEvent *e)
|
|||
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 @@ void handle_dnd_selection_notify(XSelectionEvent *e)
|
|||
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 @@ void handle_dnd_selection_notify(XSelectionEvent *e)
|
|||
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.
|
||||
|
|
|
@ -577,7 +577,7 @@ void execp_action(void *obj, int button, int x, int y, Time time)
|
|||
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");
|
||||
|
|
|
@ -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 @@ gboolean read_desktop_file_full_path(const char *path, DesktopEntry *entry)
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ typedef struct DesktopEntry {
|
|||
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.
|
||||
|
|
|
@ -435,7 +435,7 @@ void launcher_action(LauncherIcon *icon, XEvent *evt, int x, int y)
|
|||
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 @@ void launcher_reload_icon(Launcher *launcher, LauncherIcon *launcherIcon)
|
|||
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);
|
||||
|
|
|
@ -33,6 +33,8 @@ typedef struct LauncherIcon {
|
|||
Imlib_Image image_pressed;
|
||||
char *cmd;
|
||||
char *cwd;
|
||||
gboolean start_in_terminal;
|
||||
gboolean startup_notification;
|
||||
char *icon_name;
|
||||
char *icon_path;
|
||||
char *icon_tooltip;
|
||||
|
|
|
@ -536,6 +536,7 @@ void handle_x_event(XEvent *e)
|
|||
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);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <wordexp.h>
|
||||
|
||||
#ifdef HAVE_RSVG
|
||||
#include <librsvg/rsvg.h>
|
||||
|
@ -267,7 +268,15 @@ int setenvd(const char *name, const int value)
|
|||
}
|
||||
|
||||
#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 @@ pid_t tint_exec(const char *command, const char *dir, const char *tooltip, Time
|
|||
|
||||
#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 @@ pid_t tint_exec(const char *command, const char *dir, const char *tooltip, Time
|
|||
} 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 @@ pid_t tint_exec(const char *command, const char *dir, const char *tooltip, Time
|
|||
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 @@ pid_t tint_exec(const char *command, const char *dir, const char *tooltip, Time
|
|||
} 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 @@ pid_t tint_exec(const char *command, const char *dir, const char *tooltip, Time
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -66,7 +66,15 @@ 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.
|
||||
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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue