]> git.sur5r.net Git - i3/i3/blobdiff - src/commands.c
Added configuration directive for 'move [container|window] [to] mark <str>'
[i3/i3] / src / commands.c
index f5f8d05c7c9a1befe8b9ea4112edc93dcdca8aed..c81bafb7e2aad557a2a8ed2ebfae0881e2c8c2bd 100644 (file)
@@ -494,27 +494,7 @@ void cmd_move_con_to_workspace_name(I3_CMD, char *name) {
 
     LOG("should move window to workspace %s\n", name);
     /* get the workspace */
-    Con *ws = NULL;
-    Con *output = NULL;
-
-    /* first look for a workspace with this name */
-    TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
-        GREP_FIRST(ws, output_get_content(output), !strcasecmp(child->name, name));
-    }
-
-    /* if the name is plain digits, we interpret this as a "workspace number"
-     * command */
-    if (!ws && name_is_digits(name)) {
-        long parsed_num = ws_name_to_number(name);
-        TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
-            GREP_FIRST(ws, output_get_content(output),
-                       child->num == parsed_num);
-        }
-    }
-
-    /* if no workspace was found, make a new one */
-    if (!ws)
-        ws = workspace_get(name, NULL);
+    Con *ws = workspace_get(name, NULL);
 
     ws = maybe_auto_back_and_forth_workspace(ws);
 
@@ -1049,30 +1029,7 @@ void cmd_workspace_name(I3_CMD, char *name) {
     DLOG("should switch to workspace %s\n", name);
     if (maybe_back_and_forth(cmd_output, name))
         return;
-
-    Con *ws = NULL;
-    Con *output = NULL;
-
-    /* first look for a workspace with this name */
-    TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
-        GREP_FIRST(ws, output_get_content(output), !strcasecmp(child->name, name));
-    }
-
-    /* if the name is only digits, we interpret this as a "workspace number"
-     * command */
-    if (!ws && name_is_digits(name)) {
-        long parsed_num = ws_name_to_number(name);
-        TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
-            GREP_FIRST(ws, output_get_content(output),
-                       child->num == parsed_num);
-        }
-    }
-
-    /* if no workspace was found, make a new one */
-    if (!ws)
-        ws = workspace_get(name, NULL);
-
-    workspace_show(ws);
+    workspace_show_by_name(name);
 
     cmd_output->needs_tree_render = true;
     // XXX: default reply for now, make this a better reply
@@ -1080,28 +1037,48 @@ void cmd_workspace_name(I3_CMD, char *name) {
 }
 
 /*
- * Implementation of 'mark <mark>'
+ * Implementation of 'mark [--toggle] <mark>'
  *
  */
-void cmd_mark(I3_CMD, char *mark) {
-    DLOG("Clearing all windows which have that mark first\n");
+void cmd_mark(I3_CMD, char *mark, char *toggle) {
+    HANDLE_EMPTY_MATCH;
 
-    Con *con;
-    TAILQ_FOREACH(con, &all_cons, all_cons) {
-        if (con->mark && strcmp(con->mark, mark) == 0)
-            FREE(con->mark);
+    owindow *current = TAILQ_FIRST(&owindows);
+    if (current == NULL) {
+        ysuccess(false);
+        return;
     }
 
-    DLOG("marking window with str %s\n", mark);
-    owindow *current;
-
-    HANDLE_EMPTY_MATCH;
+    /* Marks must be unique, i.e., no two windows must have the same mark. */
+    if (current != TAILQ_LAST(&owindows, owindows_head)) {
+        yerror("A mark must not be put onto more than one window");
+        return;
+    }
 
-    TAILQ_FOREACH(current, &owindows, owindows) {
-        DLOG("matching: %p / %s\n", current->con, current->con->name);
+    DLOG("matching: %p / %s\n", current->con, current->con->name);
+    current->con->mark_changed = true;
+    if (toggle != NULL && current->con->mark && strcmp(current->con->mark, mark) == 0) {
+        DLOG("removing window mark %s\n", mark);
+        FREE(current->con->mark);
+    } else {
+        DLOG("marking window with str %s\n", mark);
+        FREE(current->con->mark);
         current->con->mark = sstrdup(mark);
     }
 
+    DLOG("Clearing all non-matched windows with this mark\n");
+    Con *con;
+    TAILQ_FOREACH(con, &all_cons, all_cons) {
+        /* Skip matched window, we took care of it already. */
+        if (current->con == con)
+            continue;
+
+        if (con->mark && strcmp(con->mark, mark) == 0) {
+            FREE(con->mark);
+            con->mark_changed = true;
+        }
+    }
+
     cmd_output->needs_tree_render = true;
     // XXX: default reply for now, make this a better reply
     ysuccess(true);
@@ -1115,14 +1092,20 @@ void cmd_unmark(I3_CMD, char *mark) {
     if (mark == NULL) {
         Con *con;
         TAILQ_FOREACH(con, &all_cons, all_cons) {
+            if (con->mark == NULL)
+                continue;
+
             FREE(con->mark);
+            con->mark_changed = true;
         }
         DLOG("removed all window marks");
     } else {
         Con *con;
         TAILQ_FOREACH(con, &all_cons, all_cons) {
-            if (con->mark && strcmp(con->mark, mark) == 0)
+            if (con->mark && strcmp(con->mark, mark) == 0) {
                 FREE(con->mark);
+                con->mark_changed = true;
+            }
         }
         DLOG("removed window mark %s\n", mark);
     }
@@ -1186,6 +1169,14 @@ void cmd_move_con_to_output(I3_CMD, char *name) {
     ysuccess(true);
 }
 
+/*
+ * Implementation of 'move [container|window] [to] mark <str>'.
+ *
+ */
+void cmd_move_con_to_mark(I3_CMD, char *mark) {
+    ysuccess(true);
+}
+
 /*
  * Implementation of 'floating enable|disable|toggle'
  *
@@ -1789,25 +1780,18 @@ void cmd_move_window_to_center(I3_CMD, char *method) {
     }
 
     if (strcmp(method, "absolute") == 0) {
-        Rect *rect = &focused->parent->rect;
-
         DLOG("moving to absolute center\n");
-        rect->x = croot->rect.width / 2 - rect->width / 2;
-        rect->y = croot->rect.height / 2 - rect->height / 2;
+        floating_center(focused->parent, croot->rect);
 
         floating_maybe_reassign_ws(focused->parent);
         cmd_output->needs_tree_render = true;
     }
 
     if (strcmp(method, "position") == 0) {
-        Rect *wsrect = &con_get_workspace(focused)->rect;
-        Rect newrect = focused->parent->rect;
-
         DLOG("moving to center\n");
-        newrect.x = wsrect->width / 2 - newrect.width / 2;
-        newrect.y = wsrect->height / 2 - newrect.height / 2;
+        floating_center(focused->parent, con_get_workspace(focused)->rect);
 
-        floating_reposition(focused->parent, newrect);
+        cmd_output->needs_tree_render = true;
     }
 
     // XXX: default reply for now, make this a better reply
@@ -1879,6 +1863,7 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name) {
                    !strcasecmp(child->name, old_name));
     } else {
         workspace = con_get_workspace(focused);
+        old_name = workspace->name;
     }
 
     if (!workspace) {
@@ -1914,13 +1899,15 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name) {
     TAILQ_FOREACH(assignment, &ws_assignments, ws_assignments) {
         if (assignment->output == NULL)
             continue;
-        if (strcmp(assignment->name, workspace->name) != 0
-            && (!name_is_digits(assignment->name) || ws_name_to_number(assignment->name) != workspace->num)) {
-
+        if (strcmp(assignment->name, workspace->name) != 0 && (!name_is_digits(assignment->name) || ws_name_to_number(assignment->name) != workspace->num)) {
             continue;
         }
 
         workspace_move_to_output(workspace, assignment->output);
+
+        if (previously_focused)
+            workspace_show(con_get_workspace(previously_focused));
+
         break;
     }
 
@@ -1934,6 +1921,8 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name) {
     ewmh_update_desktop_names();
     ewmh_update_desktop_viewport();
     ewmh_update_current_desktop();
+
+    startup_sequence_rename_workspace(old_name, new_name);
 }
 
 /*