diff --git a/common/util.c b/common/util.c index 133974372..e760443ac 100644 --- a/common/util.c +++ b/common/util.c @@ -1,6 +1,10 @@ #include - +#include +#include +#include +#include "readline.h" #include "util.h" +#include "log.h" int wrap(int i, int max) { return ((i % max) + max) % max; @@ -64,3 +68,36 @@ int get_modifier_names(const char **names, uint32_t modifier_masks) { return length; } + +pid_t get_parent_pid(pid_t child) { + pid_t parent; + char file_name[100]; + char *buffer = NULL; + char *token = NULL; + const char sep[2] = " "; + FILE *stat = NULL; + + sway_log(L_DEBUG, "trying to get parent pid for child pid %d", child); + + sprintf(file_name, "/proc/%d/stat", child); + + if (!(stat = fopen(file_name, "r")) || !(buffer = read_line(stat))) { + return -1; + } + + fclose(stat); + + sway_log(L_DEBUG, "buffer string is %s", buffer); + + token = strtok(buffer, sep); + + for (int i = 0; i < 3; i++) { + token = strtok(NULL, sep); + } + + parent = strtol(token, NULL, 10); + + sway_log(L_DEBUG, "found parent pid %d for child pid %d", parent, child); + + return (parent == child) ? -1 : parent; +} diff --git a/include/util.h b/include/util.h index dc47e3430..6f21bff08 100644 --- a/include/util.h +++ b/include/util.h @@ -2,6 +2,7 @@ #define _SWAY_UTIL_H #include +#include #include #include @@ -36,4 +37,11 @@ const char *get_modifier_name_by_mask(uint32_t modifier); */ int get_modifier_names(const char **names, uint32_t modifier_masks); +/** + * Get the pid of a parent process given the pid of a child process. + * + * Returns the parent pid or NULL if the parent pid cannot be determined. + */ +pid_t get_parent_pid(pid_t pid); + #endif diff --git a/sway/handlers.c b/sway/handlers.c index 317b03a86..9efd3ffc0 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -7,7 +7,9 @@ #include #include #include +#include +#include "util.h" #include "handlers.h" #include "border.h" #include "log.h" @@ -180,6 +182,12 @@ static bool handle_view_created(wlc_handle handle) { wlc_handle parent = wlc_view_get_parent(handle); swayc_t *focused = NULL; swayc_t *newview = NULL; + swayc_t *current_ws = swayc_active_workspace(); + bool return_to_workspace = false; + + if (current_ws) { + sway_log(L_DEBUG, "current workspace is %s", current_ws->name); + } // Get parent container, to add view in if (parent) { @@ -209,16 +217,22 @@ static bool handle_view_created(wlc_handle handle) { if (pid) { sway_log(L_DEBUG, "found pid %d for client", pid); int i; - for (i = 0; i < config->pid_workspaces->length; i++) { - pw = config->pid_workspaces->items[i]; - pid_t *pw_pid = pw->pid; - sway_log(L_DEBUG, "checking pid %d against pid %d, i is %d", pid, *pw_pid, i); - if (pid == *pw_pid) { - sway_log(L_DEBUG, "found pid_workspace for pid, %d %s", pid, pw->workspace); - break; + do { + for (i = 0; i < config->pid_workspaces->length; i++) { + pw = config->pid_workspaces->items[i]; + pid_t *pw_pid = pw->pid; + sway_log(L_DEBUG, "checking pid %d against pid %d, i is %d", pid, *pw_pid, i); + if (pid == *pw_pid) { + sway_log(L_DEBUG, "found pid_workspace for pid, %d %s", pid, pw->workspace); + break; // out of for loop + } + pw = NULL; } - pw = NULL; - } + if (pw) { + break; // out of do-while loop + } + pid = get_parent_pid(pid); + } while (pid > -1 && pid != getpid()); swayc_t *ws = NULL; @@ -233,6 +247,10 @@ static bool handle_view_created(wlc_handle handle) { if (ws) { sway_log(L_DEBUG, "workspace exists, name is %s", ws->name); focused = ws; + + if (current_ws && (strcmp(current_ws->name, ws->name) != 0)) { + return_to_workspace = true; + } } list_del(config->pid_workspaces, i); @@ -240,7 +258,6 @@ static bool handle_view_created(wlc_handle handle) { } free_pid_workspace(pw); - // free(&pid); if (!focused || focused->type == C_OUTPUT) { focused = get_focused_container(&root_container); @@ -330,6 +347,12 @@ static bool handle_view_created(wlc_handle handle) { list_add(output->unmanaged, h); } wlc_view_set_mask(handle, VISIBLE); + + if (return_to_workspace && current_ws) { + sway_log(L_DEBUG, "return_to_workspace && current_ws"); + workspace_switch(current_ws); + set_focused_container(current_ws->focused); + } return true; }