]> git.sur5r.net Git - i3/i3/blobdiff - src/randr.c
x.c: correctly free con->frame_buffer in _x_con_kill
[i3/i3] / src / randr.c
index 0c1f9704c9e87b9e6340fc6ab8666c6b119125cd..fb127ab5622f1ada69da11b552a8778735972ec9 100644 (file)
@@ -420,7 +420,10 @@ void output_init_con(Output *output) {
  * • Create the first unused workspace.
  *
  */
-void init_ws_for_output(Output *output, Con *content) {
+void init_ws_for_output(Output *output) {
+    Con *content = output_get_content(output->con);
+    Con *previous_focus = con_get_workspace(focused);
+
     /* go through all assignments and move the existing workspaces to this output */
     struct Workspace_Assignment *assignment;
     TAILQ_FOREACH(assignment, &ws_assignments, ws_assignments) {
@@ -451,6 +454,9 @@ void init_ws_for_output(Output *output, Con *content) {
         workspace_move_to_output(workspace, output);
     }
 
+    /* Temporarily set the focused container, might not be initialized yet. */
+    focused = content;
+
     /* if a workspace exists, we are done now */
     if (!TAILQ_EMPTY(&(content->nodes_head))) {
         /* ensure that one of the workspaces is actually visible (in fullscreen
@@ -459,10 +465,9 @@ void init_ws_for_output(Output *output, Con *content) {
         GREP_FIRST(visible, content, child->fullscreen_mode == CF_OUTPUT);
         if (!visible) {
             visible = TAILQ_FIRST(&(content->nodes_head));
-            focused = content;
             workspace_show(visible);
         }
-        return;
+        goto restore_focus;
     }
 
     /* otherwise, we create the first assigned ws for this output */
@@ -473,17 +478,18 @@ void init_ws_for_output(Output *output, Con *content) {
 
         LOG("Initializing first assigned workspace \"%s\" for output \"%s\"\n",
             assignment->name, assignment->output);
-        focused = content;
         workspace_show_by_name(assignment->name);
-        return;
+        goto restore_focus;
     }
 
     /* if there is still no workspace, we create the first free workspace */
     DLOG("Now adding a workspace\n");
-    Con *ws = create_workspace_on_output(output, content);
+    workspace_show(create_workspace_on_output(output, content));
 
-    /* TODO: Set focus in main.c */
-    con_focus(ws);
+restore_focus:
+    if (previous_focus) {
+        workspace_show(previous_focus);
+    }
 }
 
 /*
@@ -516,7 +522,7 @@ static void output_change_mode(xcb_connection_t *conn, Output *output) {
     }
 
     /* If default_orientation is NO_ORIENTATION, we change the orientation of
-     * the workspaces and their childs depending on output resolution. This is
+     * the workspaces and their children depending on output resolution. This is
      * only done for workspaces with maximum one child. */
     if (config.default_orientation == NO_ORIENTATION) {
         TAILQ_FOREACH(workspace, &(content->nodes_head), nodes) {
@@ -903,7 +909,7 @@ void randr_query_outputs(void) {
         if (!TAILQ_EMPTY(&(content->nodes_head)))
             continue;
         DLOG("Should add ws for output %s\n", output_primary_name(output));
-        init_ws_for_output(output, content);
+        init_ws_for_output(output);
     }
 
     /* Focus the primary screen, if possible */
@@ -942,13 +948,8 @@ void randr_disable_output(Output *output) {
 
     if (output->con != NULL) {
         /* We need to move the workspaces from the disappearing output to the first output */
-        /* 1: Get the con to focus next, if the disappearing ws is focused */
-        Con *next = NULL;
-        if (TAILQ_FIRST(&(croot->focus_head)) == output->con) {
-            DLOG("This output (%p) was focused! Getting next\n", output->con);
-            next = focused;
-            DLOG("next = %p\n", next);
-        }
+        /* 1: Get the con to focus next */
+        Con *next = focused;
 
         /* 2: iterate through workspaces and re-assign them, fixing the coordinates
          * of floating containers as we go */
@@ -959,7 +960,7 @@ void randr_disable_output(Output *output) {
             if (current != next && TAILQ_EMPTY(&(current->focus_head))) {
                 /* the workspace is empty and not focused, get rid of it */
                 DLOG("Getting rid of current = %p / %s (empty, unfocused)\n", current, current->name);
-                tree_close_internal(current, DONT_KILL_WINDOW, false, false);
+                tree_close_internal(current, DONT_KILL_WINDOW, false);
                 continue;
             }
             DLOG("Detaching current = %p / %s\n", current, current->name);
@@ -971,13 +972,12 @@ void randr_disable_output(Output *output) {
             TAILQ_FOREACH(floating_con, &(current->floating_head), floating_windows) {
                 floating_fix_coordinates(floating_con, &(output->con->rect), &(first->con->rect));
             }
-            DLOG("Done, next\n");
         }
-        DLOG("re-attached all workspaces\n");
 
+        /* Restore focus after con_detach / con_attach. next can be NULL, see #3523. */
         if (next) {
             DLOG("now focusing next = %p\n", next);
-            con_activate(next);
+            con_focus(next);
             workspace_show(con_get_workspace(next));
         }
 
@@ -1005,7 +1005,7 @@ void randr_disable_output(Output *output) {
         Con *con = output->con;
         /* clear the pointer before calling tree_close_internal in which the memory is freed */
         output->con = NULL;
-        tree_close_internal(con, DONT_KILL_WINDOW, true, false);
+        tree_close_internal(con, DONT_KILL_WINDOW, true);
         DLOG("Done. Should be fine now\n");
     }
 
@@ -1016,7 +1016,7 @@ void randr_disable_output(Output *output) {
 static void fallback_to_root_output(void) {
     root_output->active = true;
     output_init_con(root_output);
-    init_ws_for_output(root_output, output_get_content(root_output->con));
+    init_ws_for_output(root_output);
 }
 
 /*