Implement mark/goto, modify testcase
This commit is contained in:
parent
780e773a6a
commit
6897e15e72
|
@ -238,6 +238,7 @@ struct Match {
|
||||||
char *application;
|
char *application;
|
||||||
char *class;
|
char *class;
|
||||||
char *instance;
|
char *instance;
|
||||||
|
char *mark;
|
||||||
xcb_window_t id;
|
xcb_window_t id;
|
||||||
Con *con_id;
|
Con *con_id;
|
||||||
enum { M_ANY = 0, M_TILING, M_FLOATING } floating;
|
enum { M_ANY = 0, M_TILING, M_FLOATING } floating;
|
||||||
|
@ -268,6 +269,9 @@ struct Con {
|
||||||
|
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
/* user-definable mark to jump to this container later */
|
||||||
|
char *mark;
|
||||||
|
|
||||||
double percent;
|
double percent;
|
||||||
|
|
||||||
struct Window *window;
|
struct Window *window;
|
||||||
|
|
|
@ -112,10 +112,12 @@ down { return TOK_DOWN; }
|
||||||
before { return TOK_BEFORE; }
|
before { return TOK_BEFORE; }
|
||||||
after { return TOK_AFTER; }
|
after { return TOK_AFTER; }
|
||||||
restore { BEGIN(WANT_WS_STRING); return TOK_RESTORE; }
|
restore { BEGIN(WANT_WS_STRING); return TOK_RESTORE; }
|
||||||
|
mark { BEGIN(WANT_WS_STRING); return TOK_MARK; }
|
||||||
|
|
||||||
class { BEGIN(WANT_QSTRING); return TOK_CLASS; }
|
class { BEGIN(WANT_QSTRING); return TOK_CLASS; }
|
||||||
id { BEGIN(WANT_QSTRING); return TOK_ID; }
|
id { BEGIN(WANT_QSTRING); return TOK_ID; }
|
||||||
con_id { BEGIN(WANT_QSTRING); return TOK_CON_ID; }
|
con_id { BEGIN(WANT_QSTRING); return TOK_CON_ID; }
|
||||||
|
con_mark { BEGIN(WANT_QSTRING); return TOK_MARK; }
|
||||||
|
|
||||||
. { return (int)yytext[0]; }
|
. { return (int)yytext[0]; }
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,7 @@ void parse_cmd(const char *new) {
|
||||||
%token TOK_AFTER "after"
|
%token TOK_AFTER "after"
|
||||||
%token TOK_BEFORE "before"
|
%token TOK_BEFORE "before"
|
||||||
%token TOK_RESTORE "restore"
|
%token TOK_RESTORE "restore"
|
||||||
|
%token TOK_MARK "mark"
|
||||||
|
|
||||||
%token TOK_CLASS "class"
|
%token TOK_CLASS "class"
|
||||||
%token TOK_ID "id"
|
%token TOK_ID "id"
|
||||||
|
@ -205,6 +206,11 @@ matchend:
|
||||||
TAILQ_INSERT_TAIL(&owindows, current, owindows);
|
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 {
|
} else {
|
||||||
if (current->con->window == NULL)
|
if (current->con->window == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
@ -245,6 +251,11 @@ criteria:
|
||||||
current_match.id = atoi($<string>3);
|
current_match.id = atoi($<string>3);
|
||||||
printf("window id as int = %d\n", current_match.id);
|
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:
|
operations:
|
||||||
|
@ -274,6 +285,7 @@ operation:
|
||||||
| split
|
| split
|
||||||
| mode
|
| mode
|
||||||
| level
|
| level
|
||||||
|
| mark
|
||||||
;
|
;
|
||||||
|
|
||||||
exec:
|
exec:
|
||||||
|
@ -498,3 +510,23 @@ layout_mode:
|
||||||
| TOK_STACKED { $<number>$ = L_STACKED; }
|
| TOK_STACKED { $<number>$ = L_STACKED; }
|
||||||
| TOK_TABBED { $<number>$ = L_TABBED; }
|
| 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(¤t_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);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
|
@ -13,6 +13,7 @@ bool match_is_empty(Match *match) {
|
||||||
* TAILQ and I don’t want to start with things like assuming that the
|
* 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… */
|
* last member of a struct really is at the end in memory… */
|
||||||
return (match->title == NULL &&
|
return (match->title == NULL &&
|
||||||
|
match->mark == NULL &&
|
||||||
match->application == NULL &&
|
match->application == NULL &&
|
||||||
match->class == NULL &&
|
match->class == NULL &&
|
||||||
match->instance == NULL &&
|
match->instance == NULL &&
|
||||||
|
@ -33,7 +34,6 @@ bool match_matches_window(Match *match, i3Window *window) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (match->id != XCB_NONE && window->id == match->id) {
|
if (match->id != XCB_NONE && window->id == match->id) {
|
||||||
LOG("match made by window id (%d)\n", window->id);
|
LOG("match made by window id (%d)\n", window->id);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -201,6 +201,7 @@ void tree_close_con() {
|
||||||
void tree_split(Con *con, orientation_t orientation) {
|
void tree_split(Con *con, orientation_t orientation) {
|
||||||
/* for a workspace, we just need to change orientation */
|
/* for a workspace, we just need to change orientation */
|
||||||
if (con->type == CT_WORKSPACE) {
|
if (con->type == CT_WORKSPACE) {
|
||||||
|
DLOG("Workspace, simply changing orientation to %d\n", orientation);
|
||||||
con->orientation = orientation;
|
con->orientation = orientation;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -210,8 +211,12 @@ void tree_split(Con *con, orientation_t orientation) {
|
||||||
* child and has the same orientation like we are trying to
|
* child and has the same orientation like we are trying to
|
||||||
* set, this operation is a no-op to not confuse the user */
|
* set, this operation is a no-op to not confuse the user */
|
||||||
if (parent->orientation == orientation &&
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DLOG("Splitting in orientation %d\n", orientation);
|
||||||
|
|
||||||
/* 2: replace it with a new Con */
|
/* 2: replace it with a new Con */
|
||||||
Con *new = con_new(NULL);
|
Con *new = con_new(NULL);
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
#!perl
|
#!perl
|
||||||
# vim:ts=4:sw=4:expandtab
|
# 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 X11::XCB qw(:all);
|
||||||
use Time::HiRes qw(sleep);
|
use Time::HiRes qw(sleep);
|
||||||
use Digest::SHA1 qw(sha1_base64);
|
use Digest::SHA1 qw(sha1_base64);
|
||||||
|
@ -15,21 +12,22 @@ BEGIN {
|
||||||
|
|
||||||
my $x = X11::XCB::Connection->new;
|
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('split h')->recv;
|
||||||
$i3->command('9')->recv;
|
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
# Create two windows and make sure focus switching works
|
# Create two windows and make sure focus switching works
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
|
||||||
my $top = i3test::open_standard_window($x);
|
my $top = i3test::open_standard_window($x);
|
||||||
sleep(0.25);
|
sleep 0.25;
|
||||||
my $mid = i3test::open_standard_window($x);
|
my $mid = i3test::open_standard_window($x);
|
||||||
sleep(0.25);
|
sleep 0.25;
|
||||||
my $bottom = i3test::open_standard_window($x);
|
my $bottom = i3test::open_standard_window($x);
|
||||||
sleep(0.25);
|
sleep 0.25;
|
||||||
|
|
||||||
diag("top id = " . $top->id);
|
diag("top id = " . $top->id);
|
||||||
diag("mid id = " . $mid->id);
|
diag("mid id = " . $mid->id);
|
||||||
|
@ -49,10 +47,7 @@ sub focus_after {
|
||||||
$focus = $x->input_focus;
|
$focus = $x->input_focus;
|
||||||
is($focus, $bottom->id, "Latest window focused");
|
is($focus, $bottom->id, "Latest window focused");
|
||||||
|
|
||||||
$focus = focus_after("ml");
|
$focus = focus_after("prev h");
|
||||||
is($focus, $bottom->id, "Right window still focused");
|
|
||||||
|
|
||||||
$focus = focus_after("h");
|
|
||||||
is($focus, $mid->id, "Middle window focused");
|
is($focus, $mid->id, "Middle window focused");
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
@ -61,14 +56,14 @@ is($focus, $mid->id, "Middle window focused");
|
||||||
|
|
||||||
my $random_mark = sha1_base64(rand());
|
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");
|
is($focus, $mid->id, "focus unchanged");
|
||||||
|
|
||||||
$i3->command("mark $random_mark")->recv;
|
$i3->command("mark $random_mark")->recv;
|
||||||
|
|
||||||
$focus = focus_after("k");
|
$focus = focus_after("prev h");
|
||||||
is($focus, $top->id, "Top window focused");
|
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");
|
is($focus, $mid->id, "goto worked");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue