]> git.sur5r.net Git - i3/i3/commitdiff
Added 'con_move_to_mark' to move a container to the container holding a certain mark.
authorIngo Bürk <ingo.buerk@tngtech.com>
Wed, 15 Apr 2015 16:36:45 +0000 (18:36 +0200)
committerIngo Bürk <ingo.buerk@tngtech.com>
Sun, 19 Apr 2015 18:57:49 +0000 (20:57 +0200)
include/con.h
src/commands.c
src/con.c

index c760643dad98f4d3a00f9d57007ee8344ca91f7b..4ee3fb7d1733e8632dc99db3d5d2e2e5e75210dc 100644 (file)
@@ -210,6 +210,12 @@ void con_disable_fullscreen(Con *con);
  */
 void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates, bool dont_warp);
 
+/**
+ * Moves the given container to the given mark.
+ *
+ */
+bool con_move_to_mark(Con *con, const char *mark);
+
 /**
  * Returns the orientation of the given container (for stacked containers,
  * vertical orientation is used regardless of the actual orientation of the
index c81bafb7e2aad557a2a8ed2ebfae0881e2c8c2bd..736c40271be4f0fb6b803276763516741c780235 100644 (file)
@@ -1100,12 +1100,10 @@ void cmd_unmark(I3_CMD, char *mark) {
         }
         DLOG("removed all window marks");
     } else {
-        Con *con;
-        TAILQ_FOREACH(con, &all_cons, all_cons) {
-            if (con->mark && strcmp(con->mark, mark) == 0) {
-                FREE(con->mark);
-                con->mark_changed = true;
-            }
+        Con *con = con_by_mark(mark);
+        if (con != NULL) {
+            FREE(con->mark);
+            con->mark_changed = true;
         }
         DLOG("removed window mark %s\n", mark);
     }
index 266b4d33b222e598a3be8569eabe2c84a5c7bcbf..a53045534d14f7ec16c74dbdd48f07402e5e01c0 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -70,20 +70,10 @@ Con *con_new(Con *parent, i3Window *window) {
     return new;
 }
 
-/*
- * Attaches the given container to the given parent. This happens when moving
- * a container or when inserting a new container at a specific place in the
- * tree.
- *
- * ignore_focus is to just insert the Con at the end (useful when creating a
- * new split container *around* some containers, that is, detaching and
- * attaching them in order without wanting to mess with the focus in between).
- *
- */
-void con_attach(Con *con, Con *parent, bool ignore_focus) {
+static void _con_attach(Con *con, Con *parent, Con *previous, bool ignore_focus) {
     con->parent = parent;
     Con *loop;
-    Con *current = NULL;
+    Con *current = previous;
     struct nodes_head *nodes_head = &(parent->nodes_head);
     struct focus_head *focus_head = &(parent->focus_head);
 
@@ -170,6 +160,20 @@ add_to_focus_head:
     con_force_split_parents_redraw(con);
 }
 
+/*
+ * Attaches the given container to the given parent. This happens when moving
+ * a container or when inserting a new container at a specific place in the
+ * tree.
+ *
+ * ignore_focus is to just insert the Con at the end (useful when creating a
+ * new split container *around* some containers, that is, detaching and
+ * attaching them in order without wanting to mess with the focus in between).
+ *
+ */
+void con_attach(Con *con, Con *parent, bool ignore_focus) {
+    _con_attach(con, parent, NULL, ignore_focus);
+}
+
 /*
  * Detaches the given container from its current parent
  *
@@ -697,7 +701,9 @@ void con_disable_fullscreen(Con *con) {
     con_set_fullscreen_mode(con, CF_NONE);
 }
 
-static bool _con_move_to_con(Con *con, Con *target, bool fix_coordinates, bool dont_warp) {
+static bool _con_move_to_con(Con *con, Con *target, bool behind_focused, bool fix_coordinates, bool dont_warp) {
+    Con *orig_target = target;
+
     /* Prevent moving if this would violate the fullscreen focus restrictions. */
     Con *target_ws = con_get_workspace(target);
     if (!con_fullscreen_permits_focusing(target_ws)) {
@@ -801,7 +807,7 @@ static bool _con_move_to_con(Con *con, Con *target, bool fix_coordinates, bool d
     /* 4: re-attach the con to the parent of this focused container */
     Con *parent = con->parent;
     con_detach(con);
-    con_attach(con, target, false);
+    _con_attach(con, target, behind_focused ? NULL : orig_target, !behind_focused);
 
     /* 5: fix the percentages */
     con_fix_percent(parent);
@@ -882,6 +888,35 @@ static bool _con_move_to_con(Con *con, Con *target, bool fix_coordinates, bool d
     return true;
 }
 
+/*
+ * Moves the given container to the given mark.
+ *
+ */
+bool con_move_to_mark(Con *con, const char *mark) {
+    Con *target = con_by_mark(mark);
+    if (target == NULL) {
+        DLOG("found no container with mark \"%s\"\n", mark);
+        return false;
+    }
+
+    /* For floating target containers, we just send the window to the same workspace. */
+    if (con_is_floating(target)) {
+        DLOG("target container is floating, moving container to target's workspace.\n");
+        con_move_to_workspace(con, con_get_workspace(target), true, false);
+        return true;
+    }
+
+    /* For split containers, we use the currently focused container within it.
+     * This allows setting marks on, e.g., tabbed containers which will move
+     * con to a new tab behind the focused tab. */
+    if (con_is_split(target)) {
+        DLOG("target is a split container, descending to the currently focused child.\n");
+        target = TAILQ_FIRST(&(target->focus_head));
+    }
+
+    return _con_move_to_con(con, target, false, true, false);
+}
+
 /*
  * Moves the given container to the currently focused container on the given
  * workspace.
@@ -900,6 +935,8 @@ static bool _con_move_to_con(Con *con, Con *target, bool fix_coordinates, bool d
  *
  */
 void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates, bool dont_warp) {
+    assert(workspace->type == CT_WORKSPACE);
+
     Con *source_ws = con_get_workspace(con);
     if (workspace == source_ws) {
         DLOG("Not moving, already there\n");
@@ -907,7 +944,7 @@ void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates, bool
     }
 
     Con *target = con_descend_focused(workspace);
-    _con_move_to_con(con, target, fix_coordinates, dont_warp);
+    _con_move_to_con(con, target, true, fix_coordinates, dont_warp);
 }
 
 /*