]> git.sur5r.net Git - i3/i3/commitdiff
Implement mark/goto, modify testcase
authorMichael Stapelberg <michael@stapelberg.de>
Wed, 2 Jun 2010 21:32:05 +0000 (23:32 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Wed, 2 Jun 2010 21:32:05 +0000 (23:32 +0200)
include/data.h
src/cmdparse.l
src/cmdparse.y
src/match.c
src/tree.c
testcases/t/11-goto.t

index f74f0d52d1faba271fc7d8c2b35dad3f78683997..ba70de0eabad1fc7491cc786b3a2a8ec332a97ac 100644 (file)
@@ -238,6 +238,7 @@ struct Match {
     char *application;
     char *class;
     char *instance;
+    char *mark;
     xcb_window_t id;
     Con *con_id;
     enum { M_ANY = 0, M_TILING, M_FLOATING } floating;
@@ -268,6 +269,9 @@ struct Con {
 
     char *name;
 
+    /* user-definable mark to jump to this container later */
+    char *mark;
+
     double percent;
 
     struct Window *window;
index 8850ff6419d96f75b7af69d5d8cc9d54770810e7..f085a2a4a5f401c900232fa9678ce9b074fd97a1 100644 (file)
@@ -112,10 +112,12 @@ down                            { return TOK_DOWN; }
 before                          { return TOK_BEFORE; }
 after                           { return TOK_AFTER; }
 restore                         { BEGIN(WANT_WS_STRING); return TOK_RESTORE; }
+mark                            { BEGIN(WANT_WS_STRING); return TOK_MARK; }
 
 class                           { BEGIN(WANT_QSTRING); return TOK_CLASS; }
 id                              { BEGIN(WANT_QSTRING); return TOK_ID; }
 con_id                          { BEGIN(WANT_QSTRING); return TOK_CON_ID; }
+con_mark                        { BEGIN(WANT_QSTRING); return TOK_MARK; }
 
 .                               { return (int)yytext[0]; }
 
index cae2d3c56bd1728fc100e926eeb5930f6b0836a6..f694e1ff0494cac622c4bc043fa31ccc5d5ad566 100644 (file)
@@ -124,6 +124,7 @@ void parse_cmd(const char *new) {
 %token TOK_AFTER "after"
 %token TOK_BEFORE "before"
 %token TOK_RESTORE "restore"
+%token TOK_MARK "mark"
 
 %token TOK_CLASS "class"
 %token TOK_ID "id"
@@ -205,6 +206,11 @@ matchend:
                     TAILQ_INSERT_TAIL(&owindows, current, owindows);
 
                 }
+            } else if (current_match.mark != NULL && current->con->mark != NULL &&
+                    strcasecmp(current_match.mark, current->con->mark) == 0) {
+                printf("match by mark\n");
+                    TAILQ_INSERT_TAIL(&owindows, current, owindows);
+
             } else {
                 if (current->con->window == NULL)
                     continue;
@@ -245,6 +251,11 @@ criteria:
         current_match.id = atoi($<string>3);
         printf("window id as int = %d\n", current_match.id);
     }
+    | TOK_MARK '=' STR
+    {
+        printf("criteria: mark = %s\n", $<string>3);
+        current_match.mark = $<string>3;
+    }
     ;
 
 operations:
@@ -274,6 +285,7 @@ operation:
     | split
     | mode
     | level
+    | mark
     ;
 
 exec:
@@ -498,3 +510,23 @@ layout_mode:
     | TOK_STACKED { $<number>$ = L_STACKED; }
     | TOK_TABBED  { $<number>$ = L_TABBED; }
     ;
+
+mark:
+    TOK_MARK WHITESPACE STR
+    {
+        printf("marking window with str %s\n", $<string>3);
+        owindow *current;
+
+        /* check if the match is empty, not if the result is empty */
+        if (match_is_empty(&current_match))
+            focused->mark = sstrdup($<string>3);
+        else {
+            TAILQ_FOREACH(current, &owindows, owindows) {
+                printf("matching: %p / %s\n", current->con, current->con->name);
+                current->con->mark = sstrdup($<string>3);
+            }
+        }
+
+        free($<string>3);
+    }
+    ;
index 763a4e7e94bd22aa8bf4cfb124c64591af5f1b59..603be7bf761f4f348566d4bcb52510f48779903f 100644 (file)
@@ -13,6 +13,7 @@ bool match_is_empty(Match *match) {
      * TAILQ and I don’t want to start with things like assuming that the
      * last member of a struct really is at the end in memory… */
     return (match->title == NULL &&
+            match->mark == NULL &&
             match->application == NULL &&
             match->class == NULL &&
             match->instance == NULL &&
@@ -33,7 +34,6 @@ bool match_matches_window(Match *match, i3Window *window) {
         return true;
     }
 
-
     if (match->id != XCB_NONE && window->id == match->id) {
         LOG("match made by window id (%d)\n", window->id);
         return true;
index 048fd54904a62d7ea0d173ba17425adfbdb4c6e5..a6f3dc138933a07b2e5b5219f033bfbddbace69b 100644 (file)
@@ -201,6 +201,7 @@ void tree_close_con() {
 void tree_split(Con *con, orientation_t orientation) {
     /* for a workspace, we just need to change orientation */
     if (con->type == CT_WORKSPACE) {
+        DLOG("Workspace, simply changing orientation to %d\n", orientation);
         con->orientation = orientation;
         return;
     }
@@ -210,8 +211,12 @@ void tree_split(Con *con, orientation_t orientation) {
      * child and has the same orientation like we are trying to
      * set, this operation is a no-op to not confuse the user */
     if (parent->orientation == orientation &&
-        TAILQ_NEXT(con, nodes) == TAILQ_END(&(parent->nodes_head)))
+        TAILQ_NEXT(con, nodes) == TAILQ_END(&(parent->nodes_head))) {
+        DLOG("Not splitting the same way again\n");
         return;
+    }
+
+    DLOG("Splitting in orientation %d\n", orientation);
 
     /* 2: replace it with a new Con */
     Con *new = con_new(NULL);
index ea17b4065981ea631e43948dd51dd8fed2d30902..31c5187f1ac2ffb113c8c78795683cb5f8eda801 100644 (file)
@@ -1,10 +1,7 @@
 #!perl
 # vim:ts=4:sw=4:expandtab
-# Beware that this test uses workspace 9 to perform some tests (it expects
-# the workspace to be empty).
-# TODO: skip it by default?
 
-use i3test tests => 7;
+use i3test tests => 6;
 use X11::XCB qw(:all);
 use Time::HiRes qw(sleep);
 use Digest::SHA1 qw(sha1_base64);
@@ -15,21 +12,22 @@ BEGIN {
 
 my $x = X11::XCB::Connection->new;
 
-my $i3 = i3;
+my $i3 = i3("/tmp/nestedcons");
+my $tmp = get_unused_workspace();
+$i3->command("workspace $tmp")->recv;
 
-# Switch to the nineth workspace
-$i3->command('9')->recv;
+$i3->command('split h')->recv;
 
 #####################################################################
 # Create two windows and make sure focus switching works
 #####################################################################
 
 my $top = i3test::open_standard_window($x);
-sleep(0.25);
+sleep 0.25;
 my $mid = i3test::open_standard_window($x);
-sleep(0.25);
+sleep 0.25;
 my $bottom = i3test::open_standard_window($x);
-sleep(0.25);
+sleep 0.25;
 
 diag("top id = " . $top->id);
 diag("mid id = " . $mid->id);
@@ -49,10 +47,7 @@ sub focus_after {
 $focus = $x->input_focus;
 is($focus, $bottom->id, "Latest window focused");
 
-$focus = focus_after("ml");
-is($focus, $bottom->id, "Right window still focused");
-
-$focus = focus_after("h");
+$focus = focus_after("prev h");
 is($focus, $mid->id, "Middle window focused");
 
 #####################################################################
@@ -61,14 +56,14 @@ is($focus, $mid->id, "Middle window focused");
 
 my $random_mark = sha1_base64(rand());
 
-$focus = focus_after("goto $random_mark");
+$focus = focus_after(qq|[con_mark="$random_mark"] focus|);
 is($focus, $mid->id, "focus unchanged");
 
 $i3->command("mark $random_mark")->recv;
 
-$focus = focus_after("k");
+$focus = focus_after("prev h");
 is($focus, $top->id, "Top window focused");
 
-$focus = focus_after("goto $random_mark");
+$focus = focus_after(qq|[con_mark="$random_mark"] focus|);
 is($focus, $mid->id, "goto worked");