diff --git a/include/manage.h b/include/manage.h index 65542d91..9c87a08e 100644 --- a/include/manage.h +++ b/include/manage.h @@ -23,6 +23,16 @@ void manage_existing_windows(xcb_connection_t *conn, xcb_property_handlers_t *prophs, xcb_window_t root); +/** + * Restores the geometry of each window by reparenting it to the root window + * at the position of its frame. + * + * This is to be called *only* before exiting/restarting i3 because of evil + * side-effects which are to be expected when continuing to run i3. + * + */ +void restore_geometry(xcb_connection_t *conn); + /** * Do some sanity checks and then reparent the window. * diff --git a/src/commands.c b/src/commands.c index cdd82513..3aab9b82 100644 --- a/src/commands.c +++ b/src/commands.c @@ -32,6 +32,7 @@ #include "resize.h" #include "log.h" #include "sighandler.h" +#include "manage.h" bool focus_window_in_container(xcb_connection_t *conn, Container *container, direction_t direction) { /* If this container is empty, we’re done */ @@ -977,6 +978,7 @@ void parse_command(xcb_connection_t *conn, const char *command) { /* Is it an ? */ if (STARTS_WITH(command, "exit")) { LOG("User issued exit-command, exiting without error.\n"); + restore_geometry(global_conn); exit(EXIT_SUCCESS); } diff --git a/src/manage.c b/src/manage.c index 93ae4865..c4118641 100644 --- a/src/manage.c +++ b/src/manage.c @@ -63,6 +63,28 @@ void manage_existing_windows(xcb_connection_t *conn, xcb_property_handlers_t *pr free(cookies); } +/* + * Restores the geometry of each window by reparenting it to the root window + * at the position of its frame. + * + * This is to be called *only* before exiting/restarting i3 because of evil + * side-effects which are to be expected when continuing to run i3. + * + */ +void restore_geometry(xcb_connection_t *conn) { + Workspace *ws; + Client *client; + DLOG("Restoring geometry\n"); + + TAILQ_FOREACH(ws, workspaces, workspaces) + SLIST_FOREACH(client, &(ws->focus_stack), focus_clients) + xcb_reparent_window(conn, client->child, root, + client->rect.x, client->rect.y); + + /* Make sure our changes reach the X server, we restart/exit now */ + xcb_flush(conn); +} + /* * Do some sanity checks and then reparent the window. * diff --git a/src/util.c b/src/util.c index 2f8225c0..a25a9dcf 100644 --- a/src/util.c +++ b/src/util.c @@ -33,6 +33,7 @@ #include "client.h" #include "log.h" #include "ewmh.h" +#include "manage.h" static iconv_t conversion_descriptor = 0; struct keyvalue_table_head by_parent = TAILQ_HEAD_INITIALIZER(by_parent); @@ -504,6 +505,8 @@ static char **append_argument(char **original, char *argument) { * */ void i3_restart() { + restore_geometry(global_conn); + LOG("restarting \"%s\"...\n", start_argv[0]); /* make sure -a is in the argument list or append it */ start_argv = append_argument(start_argv, "-a");