From: Michael Stapelberg Date: Wed, 2 Jun 2010 21:32:05 +0000 (+0200) Subject: Implement mark/goto, modify testcase X-Git-Tag: tree-pr1~184 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6897e15e72ac222815b4a01d26179e026debd1ba;p=i3%2Fi3 Implement mark/goto, modify testcase --- diff --git a/include/data.h b/include/data.h index f74f0d52..ba70de0e 100644 --- a/include/data.h +++ b/include/data.h @@ -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; diff --git a/src/cmdparse.l b/src/cmdparse.l index 8850ff64..f085a2a4 100644 --- a/src/cmdparse.l +++ b/src/cmdparse.l @@ -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]; } diff --git a/src/cmdparse.y b/src/cmdparse.y index cae2d3c5..f694e1ff 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -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($3); printf("window id as int = %d\n", current_match.id); } + | TOK_MARK '=' STR + { + printf("criteria: mark = %s\n", $3); + current_match.mark = $3; + } ; operations: @@ -274,6 +285,7 @@ operation: | split | mode | level + | mark ; exec: @@ -498,3 +510,23 @@ layout_mode: | TOK_STACKED { $$ = L_STACKED; } | TOK_TABBED { $$ = L_TABBED; } ; + +mark: + TOK_MARK WHITESPACE STR + { + printf("marking window with str %s\n", $3); + owindow *current; + + /* check if the match is empty, not if the result is empty */ + if (match_is_empty(¤t_match)) + focused->mark = sstrdup($3); + else { + TAILQ_FOREACH(current, &owindows, owindows) { + printf("matching: %p / %s\n", current->con, current->con->name); + current->con->mark = sstrdup($3); + } + } + + free($3); + } + ; diff --git a/src/match.c b/src/match.c index 763a4e7e..603be7bf 100644 --- a/src/match.c +++ b/src/match.c @@ -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; diff --git a/src/tree.c b/src/tree.c index 048fd549..a6f3dc13 100644 --- a/src/tree.c +++ b/src/tree.c @@ -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); diff --git a/testcases/t/11-goto.t b/testcases/t/11-goto.t index ea17b406..31c5187f 100644 --- a/testcases/t/11-goto.t +++ b/testcases/t/11-goto.t @@ -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");