mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-06-19 14:33:16 -04:00
Improve automatic session launch command recovery#
This commit is contained in:
parent
44b761dbe2
commit
818f80c068
3 changed files with 464 additions and 4 deletions
|
|
@ -836,10 +836,13 @@ int32_t centerwin(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t spawn_shell(const Arg *arg) {
|
int32_t spawn_shell(const Arg *arg) {
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
if (!arg->v)
|
if (!arg->v)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (fork() == 0) {
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
// 1. 忽略可能导致 coredump 的信号
|
// 1. 忽略可能导致 coredump 的信号
|
||||||
signal(SIGSEGV, SIG_IGN);
|
signal(SIGSEGV, SIG_IGN);
|
||||||
signal(SIGABRT, SIG_IGN);
|
signal(SIGABRT, SIG_IGN);
|
||||||
|
|
@ -859,14 +862,18 @@ int32_t spawn_shell(const Arg *arg) {
|
||||||
arg->v, strerror(errno));
|
arg->v, strerror(errno));
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
if (pid > 0)
|
||||||
|
mango_session_track_spawned_command(pid, arg->v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t spawn(const Arg *arg) {
|
int32_t spawn(const Arg *arg) {
|
||||||
|
pid_t pid;
|
||||||
if (!arg->v)
|
if (!arg->v)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (fork() == 0) {
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
// 1. 忽略可能导致 coredump 的信号
|
// 1. 忽略可能导致 coredump 的信号
|
||||||
signal(SIGSEGV, SIG_IGN);
|
signal(SIGSEGV, SIG_IGN);
|
||||||
signal(SIGABRT, SIG_IGN);
|
signal(SIGABRT, SIG_IGN);
|
||||||
|
|
@ -891,6 +898,8 @@ int32_t spawn(const Arg *arg) {
|
||||||
wordfree(&p); // 释放 wordexp 分配的内存
|
wordfree(&p); // 释放 wordexp 分配的内存
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
if (pid > 0)
|
||||||
|
mango_session_track_spawned_command(pid, arg->v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
450
src/mango.c
450
src/mango.c
|
|
@ -8,6 +8,7 @@
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <scenefx/render/fx_renderer/fx_renderer.h>
|
#include <scenefx/render/fx_renderer/fx_renderer.h>
|
||||||
#include <scenefx/types/fx/blur_data.h>
|
#include <scenefx/types/fx/blur_data.h>
|
||||||
#include <scenefx/types/fx/clipped_region.h>
|
#include <scenefx/types/fx/clipped_region.h>
|
||||||
|
|
@ -556,6 +557,13 @@ typedef struct {
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
} SessionLock;
|
} SessionLock;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct wl_list link;
|
||||||
|
pid_t pid;
|
||||||
|
time_t created_at;
|
||||||
|
char command[1024];
|
||||||
|
} SessionSpawnCommand;
|
||||||
|
|
||||||
/* function declarations */
|
/* function declarations */
|
||||||
static void applybounds(
|
static void applybounds(
|
||||||
Client *c,
|
Client *c,
|
||||||
|
|
@ -758,6 +766,16 @@ static void init_fadeout_layers(LayerSurface *l);
|
||||||
static void layer_actual_size(LayerSurface *l, int32_t *width, int32_t *height);
|
static void layer_actual_size(LayerSurface *l, int32_t *width, int32_t *height);
|
||||||
static void get_layer_target_geometry(LayerSurface *l,
|
static void get_layer_target_geometry(LayerSurface *l,
|
||||||
struct wlr_box *target_box);
|
struct wlr_box *target_box);
|
||||||
|
void mango_session_spawn_tracker_init(void);
|
||||||
|
void mango_session_spawn_tracker_shutdown(void);
|
||||||
|
void mango_session_track_spawned_command(pid_t pid, const char *command);
|
||||||
|
void mango_session_attach_spawn_command(Client *c);
|
||||||
|
void mango_session_remember_client_launch_command(Client *c,
|
||||||
|
const char *command);
|
||||||
|
static char *mango_session_recover_process_command(pid_t pid);
|
||||||
|
static void mango_session_attach_process_command(Client *c);
|
||||||
|
static char *mango_session_find_desktop_exec(const char *app_id);
|
||||||
|
static char *mango_session_normalize_launch_command(Client *c, pid_t pid);
|
||||||
static void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer,
|
static void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer,
|
||||||
int32_t sx, int32_t sy, void *data);
|
int32_t sx, int32_t sy, void *data);
|
||||||
static double find_animation_curve_at(double t, int32_t type);
|
static double find_animation_curve_at(double t, int32_t type);
|
||||||
|
|
@ -987,6 +1005,7 @@ static struct wl_listener keyboard_shortcuts_inhibit_new_inhibitor = {
|
||||||
.notify = handle_keyboard_shortcuts_inhibit_new_inhibitor};
|
.notify = handle_keyboard_shortcuts_inhibit_new_inhibitor};
|
||||||
static struct wl_listener last_cursor_surface_destroy_listener = {
|
static struct wl_listener last_cursor_surface_destroy_listener = {
|
||||||
.notify = last_cursor_surface_destroy};
|
.notify = last_cursor_surface_destroy};
|
||||||
|
static struct wl_list session_spawn_commands;
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
static void fix_xwayland_unmanaged_coordinate(Client *c);
|
static void fix_xwayland_unmanaged_coordinate(Client *c);
|
||||||
|
|
@ -1056,6 +1075,428 @@ const char *mango_session_client_monitor(Client *c) {
|
||||||
return (c && c->mon && c->mon->wlr_output) ? c->mon->wlr_output->name : "";
|
return (c && c->mon && c->mon->wlr_output) ? c->mon->wlr_output->name : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mango_session_spawn_tracker_cleanup(bool all) {
|
||||||
|
SessionSpawnCommand *entry, *tmp;
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
|
wl_list_for_each_safe(entry, tmp, &session_spawn_commands, link) {
|
||||||
|
if (!all && now - entry->created_at < 300)
|
||||||
|
continue;
|
||||||
|
wl_list_remove(&entry->link);
|
||||||
|
free(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mango_session_spawn_tracker_init(void) {
|
||||||
|
wl_list_init(&session_spawn_commands);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mango_session_spawn_tracker_shutdown(void) {
|
||||||
|
mango_session_spawn_tracker_cleanup(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mango_session_track_spawned_command(pid_t pid, const char *command) {
|
||||||
|
SessionSpawnCommand *entry;
|
||||||
|
|
||||||
|
if (pid <= 0 || !command || command[0] == '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
mango_session_spawn_tracker_cleanup(false);
|
||||||
|
|
||||||
|
entry = ecalloc(1, sizeof(*entry));
|
||||||
|
entry->pid = pid;
|
||||||
|
entry->created_at = time(NULL);
|
||||||
|
strncpy(entry->command, command, sizeof(entry->command) - 1);
|
||||||
|
entry->command[sizeof(entry->command) - 1] = '\0';
|
||||||
|
wl_list_insert(&session_spawn_commands, &entry->link);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mango_session_attach_spawn_command(Client *c) {
|
||||||
|
SessionSpawnCommand *entry, *match = NULL;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if (!c)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pid = client_get_pid(c);
|
||||||
|
if (pid <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
c->pid = pid;
|
||||||
|
mango_session_spawn_tracker_cleanup(false);
|
||||||
|
|
||||||
|
wl_list_for_each(entry, &session_spawn_commands, link) {
|
||||||
|
if (entry->pid == pid || isdescprocess(entry->pid, pid)) {
|
||||||
|
match = entry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mango_session_remember_client_launch_command(c, match->command);
|
||||||
|
wl_list_remove(&match->link);
|
||||||
|
free(match);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *mango_session_shell_quote(const char *arg) {
|
||||||
|
size_t len = 2;
|
||||||
|
const char *p;
|
||||||
|
char *out, *dst;
|
||||||
|
|
||||||
|
if (!arg)
|
||||||
|
return strdup("''");
|
||||||
|
|
||||||
|
for (p = arg; *p != '\0'; ++p) {
|
||||||
|
if (*p == '\'')
|
||||||
|
len += 4;
|
||||||
|
else
|
||||||
|
len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
out = ecalloc(len + 1, sizeof(char));
|
||||||
|
dst = out;
|
||||||
|
*dst++ = '\'';
|
||||||
|
for (p = arg; *p != '\0'; ++p) {
|
||||||
|
if (*p == '\'') {
|
||||||
|
memcpy(dst, "'\\''", 4);
|
||||||
|
dst += 4;
|
||||||
|
} else {
|
||||||
|
*dst++ = *p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*dst++ = '\'';
|
||||||
|
*dst = '\0';
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *mango_session_join_argv(char **argv, size_t argc) {
|
||||||
|
char *joined;
|
||||||
|
|
||||||
|
if (!argv || argc == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
joined = strdup("");
|
||||||
|
for (size_t i = 0; i < argc; ++i) {
|
||||||
|
char *quoted = mango_session_shell_quote(argv[i]);
|
||||||
|
char *next = i == 0 ? string_printf("%s", quoted)
|
||||||
|
: string_printf("%s %s", joined, quoted);
|
||||||
|
free(quoted);
|
||||||
|
free(joined);
|
||||||
|
joined = next;
|
||||||
|
if (!joined)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return joined;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mango_session_trim_newline(char *s) {
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return;
|
||||||
|
|
||||||
|
len = strlen(s);
|
||||||
|
while (len > 0 &&
|
||||||
|
(s[len - 1] == '\n' || s[len - 1] == '\r' || s[len - 1] == ' ' ||
|
||||||
|
s[len - 1] == '\t')) {
|
||||||
|
s[--len] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *mango_session_strip_exec_field_codes(const char *exec) {
|
||||||
|
char *copy, *token, *saveptr = NULL, *result;
|
||||||
|
|
||||||
|
if (!exec || exec[0] == '\0')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
copy = strdup(exec);
|
||||||
|
if (!copy)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
result = strdup("");
|
||||||
|
for (token = strtok_r(copy, " \t", &saveptr); token != NULL;
|
||||||
|
token = strtok_r(NULL, " \t", &saveptr)) {
|
||||||
|
char *next;
|
||||||
|
|
||||||
|
if (token[0] == '%' && token[1] != '\0')
|
||||||
|
continue;
|
||||||
|
if (strcmp(token, "%%") == 0)
|
||||||
|
token = "%";
|
||||||
|
|
||||||
|
next = result[0] == '\0' ? string_printf("%s", token)
|
||||||
|
: string_printf("%s %s", result, token);
|
||||||
|
free(result);
|
||||||
|
result = next;
|
||||||
|
if (!result) {
|
||||||
|
free(copy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(copy);
|
||||||
|
|
||||||
|
if (result[0] == '\0') {
|
||||||
|
free(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mango_session_path_exists(const char *path) {
|
||||||
|
struct stat st;
|
||||||
|
return path && stat(path, &st) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mango_session_desktop_matches(const char *desktop_path,
|
||||||
|
const char *app_id,
|
||||||
|
char **exec_out) {
|
||||||
|
FILE *f;
|
||||||
|
char line[2048];
|
||||||
|
char *exec_value = NULL;
|
||||||
|
char *startup_wm_class = NULL;
|
||||||
|
char *flatpak_id = NULL;
|
||||||
|
char *desktop_id = NULL;
|
||||||
|
bool matched = false;
|
||||||
|
const char *basename;
|
||||||
|
char *dot;
|
||||||
|
|
||||||
|
if (!desktop_path || !app_id || app_id[0] == '\0')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
f = fopen(desktop_path, "r");
|
||||||
|
if (!f)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (fgets(line, sizeof(line), f)) {
|
||||||
|
mango_session_trim_newline(line);
|
||||||
|
if (strncmp(line, "Exec=", 5) == 0) {
|
||||||
|
free(exec_value);
|
||||||
|
exec_value = strdup(line + 5);
|
||||||
|
} else if (strncmp(line, "StartupWMClass=", 15) == 0) {
|
||||||
|
free(startup_wm_class);
|
||||||
|
startup_wm_class = strdup(line + 15);
|
||||||
|
} else if (strncmp(line, "X-Flatpak=", 10) == 0) {
|
||||||
|
free(flatpak_id);
|
||||||
|
flatpak_id = strdup(line + 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
basename = strrchr(desktop_path, '/');
|
||||||
|
basename = basename ? basename + 1 : desktop_path;
|
||||||
|
desktop_id = strdup(basename);
|
||||||
|
if (desktop_id) {
|
||||||
|
dot = strrchr(desktop_id, '.');
|
||||||
|
if (dot)
|
||||||
|
*dot = '\0';
|
||||||
|
if (strcmp(desktop_id, app_id) == 0)
|
||||||
|
matched = true;
|
||||||
|
free(desktop_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matched && startup_wm_class && strcmp(startup_wm_class, app_id) == 0)
|
||||||
|
matched = true;
|
||||||
|
if (!matched && flatpak_id && strcmp(flatpak_id, app_id) == 0)
|
||||||
|
matched = true;
|
||||||
|
|
||||||
|
if (matched && exec_value && exec_out)
|
||||||
|
*exec_out = mango_session_strip_exec_field_codes(exec_value);
|
||||||
|
|
||||||
|
free(exec_value);
|
||||||
|
free(startup_wm_class);
|
||||||
|
free(flatpak_id);
|
||||||
|
return matched;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *mango_session_find_desktop_exec(const char *app_id) {
|
||||||
|
const char *dirs[] = {
|
||||||
|
"/home/kenn/.local/share/applications",
|
||||||
|
"/etc/profiles/per-user/kenn/share/applications",
|
||||||
|
"/run/current-system/sw/share/applications",
|
||||||
|
"/var/lib/flatpak/exports/share/applications",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; dirs[i] != NULL; ++i) {
|
||||||
|
DIR *dir = opendir(dirs[i]);
|
||||||
|
struct dirent *entry;
|
||||||
|
|
||||||
|
if (!dir)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
|
char *path;
|
||||||
|
char *exec_value = NULL;
|
||||||
|
bool matched;
|
||||||
|
|
||||||
|
if (!strstr(entry->d_name, ".desktop"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
path = string_printf("%s/%s", dirs[i], entry->d_name);
|
||||||
|
matched = mango_session_desktop_matches(path, app_id, &exec_value);
|
||||||
|
free(path);
|
||||||
|
if (!matched)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
return exec_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *mango_session_read_cmdline(pid_t pid, size_t *argc_out) {
|
||||||
|
FILE *f;
|
||||||
|
char path[64];
|
||||||
|
char *buf = NULL;
|
||||||
|
size_t size = 0, used = 0;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (argc_out)
|
||||||
|
*argc_out = 0;
|
||||||
|
if (pid <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
|
||||||
|
f = fopen(path, "rb");
|
||||||
|
if (!f)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while ((ch = fgetc(f)) != EOF) {
|
||||||
|
if (used + 2 > size) {
|
||||||
|
size_t next_size = size == 0 ? 256 : size * 2;
|
||||||
|
char *next = realloc(buf, next_size);
|
||||||
|
if (!next) {
|
||||||
|
free(buf);
|
||||||
|
fclose(f);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
buf = next;
|
||||||
|
size = next_size;
|
||||||
|
}
|
||||||
|
buf[used++] = (char)ch;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (!buf || used == 0) {
|
||||||
|
free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[used] = '\0';
|
||||||
|
|
||||||
|
if (argc_out) {
|
||||||
|
size_t argc = 0;
|
||||||
|
for (size_t i = 0; i < used; ++i) {
|
||||||
|
if (buf[i] == '\0')
|
||||||
|
argc++;
|
||||||
|
}
|
||||||
|
*argc_out = argc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *mango_session_recover_process_command(pid_t pid) {
|
||||||
|
char *cmdline;
|
||||||
|
char *argv[64];
|
||||||
|
size_t argc = 0, idx = 0;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
cmdline = mango_session_read_cmdline(pid, &argc);
|
||||||
|
if (!cmdline || argc == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (p = cmdline; idx < argc && idx < LENGTH(argv); ++idx) {
|
||||||
|
argv[idx] = p;
|
||||||
|
p += strlen(p) + 1;
|
||||||
|
}
|
||||||
|
argc = idx;
|
||||||
|
|
||||||
|
if (argc >= 3 &&
|
||||||
|
(strcmp(argv[0], "sh") == 0 || strcmp(argv[0], "/bin/sh") == 0 ||
|
||||||
|
strcmp(argv[0], "bash") == 0 || strcmp(argv[0], "/bin/bash") == 0) &&
|
||||||
|
strcmp(argv[1], "-c") == 0) {
|
||||||
|
char *command = strdup(argv[2]);
|
||||||
|
free(cmdline);
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc >= 1) {
|
||||||
|
char *command = mango_session_join_argv(argv, argc);
|
||||||
|
free(cmdline);
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(cmdline);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *mango_session_normalize_launch_command(Client *c, pid_t pid) {
|
||||||
|
const char *app_id;
|
||||||
|
char *desktop_exec;
|
||||||
|
char *raw_command;
|
||||||
|
|
||||||
|
app_id = c ? client_get_appid(c) : NULL;
|
||||||
|
if (app_id && app_id[0] != '\0' && strcmp(app_id, "broken") != 0) {
|
||||||
|
char *flatpak_desktop = string_printf(
|
||||||
|
"/var/lib/flatpak/exports/share/applications/%s.desktop", app_id);
|
||||||
|
char *user_flatpak_desktop = string_printf(
|
||||||
|
"%s/.local/share/flatpak/exports/share/applications/%s.desktop",
|
||||||
|
getenv("HOME") ? getenv("HOME") : "", app_id);
|
||||||
|
|
||||||
|
if ((flatpak_desktop && mango_session_path_exists(flatpak_desktop)) ||
|
||||||
|
(user_flatpak_desktop &&
|
||||||
|
mango_session_path_exists(user_flatpak_desktop))) {
|
||||||
|
free(flatpak_desktop);
|
||||||
|
free(user_flatpak_desktop);
|
||||||
|
return string_printf("flatpak run %s", app_id);
|
||||||
|
}
|
||||||
|
free(flatpak_desktop);
|
||||||
|
free(user_flatpak_desktop);
|
||||||
|
|
||||||
|
desktop_exec = mango_session_find_desktop_exec(app_id);
|
||||||
|
if (desktop_exec && desktop_exec[0] != '\0')
|
||||||
|
return desktop_exec;
|
||||||
|
free(desktop_exec);
|
||||||
|
}
|
||||||
|
|
||||||
|
raw_command = mango_session_recover_process_command(pid);
|
||||||
|
if (raw_command && raw_command[0] != '\0')
|
||||||
|
return raw_command;
|
||||||
|
|
||||||
|
free(raw_command);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mango_session_attach_process_command(Client *c) {
|
||||||
|
char *command;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if (!c || c->session_launch_command[0] != '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
pid = c->pid > 0 ? c->pid : client_get_pid(c);
|
||||||
|
if (pid <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
command = mango_session_normalize_launch_command(c, pid);
|
||||||
|
if (!command || command[0] == '\0') {
|
||||||
|
free(command);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mango_session_remember_client_launch_command(c, command);
|
||||||
|
free(command);
|
||||||
|
}
|
||||||
|
|
||||||
const char *mango_session_lookup_launch_command(const char *app_id,
|
const char *mango_session_lookup_launch_command(const char *app_id,
|
||||||
const char *title) {
|
const char *title) {
|
||||||
if (!app_id || app_id[0] == '\0')
|
if (!app_id || app_id[0] == '\0')
|
||||||
|
|
@ -1094,10 +1535,13 @@ void mango_session_remember_client_launch_command(Client *c, const char *command
|
||||||
}
|
}
|
||||||
|
|
||||||
void mango_session_spawn_command(const char *command) {
|
void mango_session_spawn_command(const char *command) {
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
if (!command || command[0] == '\0')
|
if (!command || command[0] == '\0')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fork() == 0) {
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
signal(SIGSEGV, SIG_IGN);
|
signal(SIGSEGV, SIG_IGN);
|
||||||
signal(SIGABRT, SIG_IGN);
|
signal(SIGABRT, SIG_IGN);
|
||||||
signal(SIGILL, SIG_IGN);
|
signal(SIGILL, SIG_IGN);
|
||||||
|
|
@ -1109,6 +1553,8 @@ void mango_session_spawn_command(const char *command) {
|
||||||
execlp("bash", "bash", "-c", command, (char *)NULL);
|
execlp("bash", "bash", "-c", command, (char *)NULL);
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
if (pid > 0)
|
||||||
|
mango_session_track_spawned_command(pid, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool session_client_should_save(Client *c) {
|
static bool session_client_should_save(Client *c) {
|
||||||
|
|
@ -4485,6 +4931,8 @@ mapnotify(struct wl_listener *listener, void *data) {
|
||||||
// make sure the animation is open type
|
// make sure the animation is open type
|
||||||
c->is_pending_open_animation = true;
|
c->is_pending_open_animation = true;
|
||||||
resize(c, c->geom, 0);
|
resize(c, c->geom, 0);
|
||||||
|
mango_session_attach_spawn_command(c);
|
||||||
|
mango_session_attach_process_command(c);
|
||||||
session_handle_client_mapped(c);
|
session_handle_client_mapped(c);
|
||||||
printstatus();
|
printstatus();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ extern void mango_session_remember_client_launch_command(Client *c,
|
||||||
extern void mango_session_spawn_command(const char *command);
|
extern void mango_session_spawn_command(const char *command);
|
||||||
extern void mango_session_apply_restore_entry(Client *c,
|
extern void mango_session_apply_restore_entry(Client *c,
|
||||||
const SessionRestoreEntry *entry);
|
const SessionRestoreEntry *entry);
|
||||||
|
extern void mango_session_spawn_tracker_init(void);
|
||||||
|
extern void mango_session_spawn_tracker_shutdown(void);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SessionRestoreEntry entry;
|
SessionRestoreEntry entry;
|
||||||
|
|
@ -391,11 +393,12 @@ static void session_spawn_restore_entries(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_init(void) {}
|
void session_init(void) { mango_session_spawn_tracker_init(); }
|
||||||
|
|
||||||
void session_shutdown(void) {
|
void session_shutdown(void) {
|
||||||
free_pending_entries();
|
free_pending_entries();
|
||||||
restore_started = false;
|
restore_started = false;
|
||||||
|
mango_session_spawn_tracker_shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_maybe_restore_startup(void) {
|
void session_maybe_restore_startup(void) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue