Implement assignments for (named) workspaces, with '~' compatibility (floating)
This commit is contained in:
parent
272a86745e
commit
2c68c234ea
|
@ -12,4 +12,10 @@
|
||||||
*/
|
*/
|
||||||
void run_assignments(i3Window *window);
|
void run_assignments(i3Window *window);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the first matching assignment for the given window.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Assignment *assignment_for(i3Window *window, int type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* vim:ts=4:sw=4:expandtab
|
* vim:ts=4:sw=4:expandtab
|
||||||
*
|
*
|
||||||
* i3 - an improved dynamic tiling window manager
|
* i3 - an improved dynamic tiling window manager
|
||||||
* © 2009-2010 Michael Stapelberg and contributors (see also: LICENSE)
|
* © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
|
||||||
*
|
*
|
||||||
* include/data.h: This file defines all data structures used by i3
|
* include/data.h: This file defines all data structures used by i3
|
||||||
*
|
*
|
||||||
|
@ -300,8 +300,6 @@ struct Match {
|
||||||
Con *con_id;
|
Con *con_id;
|
||||||
enum { M_ANY = 0, M_TILING, M_FLOATING } floating;
|
enum { M_ANY = 0, M_TILING, M_FLOATING } floating;
|
||||||
|
|
||||||
char *target_ws;
|
|
||||||
|
|
||||||
/* Where the window looking for a match should be inserted:
|
/* Where the window looking for a match should be inserted:
|
||||||
*
|
*
|
||||||
* M_HERE = the matched container will be replaced by the window
|
* M_HERE = the matched container will be replaced by the window
|
||||||
|
@ -314,9 +312,16 @@ struct Match {
|
||||||
enum { M_HERE = 0, M_ASSIGN_WS, M_BELOW } insert_where;
|
enum { M_HERE = 0, M_ASSIGN_WS, M_BELOW } insert_where;
|
||||||
|
|
||||||
TAILQ_ENTRY(Match) matches;
|
TAILQ_ENTRY(Match) matches;
|
||||||
TAILQ_ENTRY(Match) assignments;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Assignment makes specific windows go to a specific workspace/output or
|
||||||
|
* run a command for that window. With this mechanism, the user can -- for
|
||||||
|
* example -- make specific windows floating or assign his browser to workspace
|
||||||
|
* "www". Checking if a window is assigned works by comparing the Match data
|
||||||
|
* structure with the window (see match_matches_window()).
|
||||||
|
*
|
||||||
|
*/
|
||||||
struct Assignment {
|
struct Assignment {
|
||||||
/** type of this assignment:
|
/** type of this assignment:
|
||||||
*
|
*
|
||||||
|
@ -324,8 +329,17 @@ struct Assignment {
|
||||||
* A_TO_WORKSPACE = assign the matching window to the specified workspace
|
* A_TO_WORKSPACE = assign the matching window to the specified workspace
|
||||||
* A_TO_OUTPUT = assign the matching window to the specified output
|
* A_TO_OUTPUT = assign the matching window to the specified output
|
||||||
*
|
*
|
||||||
|
* While the type is a bitmask, only one value can be set at a time. It is
|
||||||
|
* a bitmask to allow filtering for multiple types, for example in the
|
||||||
|
* assignment_for() function.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
enum { A_COMMAND = 0, A_TO_WORKSPACE = 1, A_TO_OUTPUT = 2 } type;
|
enum {
|
||||||
|
A_ANY = 0,
|
||||||
|
A_COMMAND = (1 << 0),
|
||||||
|
A_TO_WORKSPACE = (1 << 1),
|
||||||
|
A_TO_OUTPUT = (1 << 2)
|
||||||
|
} type;
|
||||||
|
|
||||||
/** the criteria to check if a window matches */
|
/** the criteria to check if a window matches */
|
||||||
Match match;
|
Match match;
|
||||||
|
@ -337,7 +351,7 @@ struct Assignment {
|
||||||
char *output;
|
char *output;
|
||||||
} dest;
|
} dest;
|
||||||
|
|
||||||
TAILQ_ENTRY(Assignment) real_assignments;
|
TAILQ_ENTRY(Assignment) assignments;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Con {
|
struct Con {
|
||||||
|
|
|
@ -26,9 +26,8 @@ extern Display *xlibdpy, *xkbdpy;
|
||||||
extern int xkb_current_group;
|
extern int xkb_current_group;
|
||||||
extern TAILQ_HEAD(bindings_head, Binding) *bindings;
|
extern TAILQ_HEAD(bindings_head, Binding) *bindings;
|
||||||
extern TAILQ_HEAD(autostarts_head, Autostart) autostarts;
|
extern TAILQ_HEAD(autostarts_head, Autostart) autostarts;
|
||||||
extern TAILQ_HEAD(assignments_head, Match) assignments;
|
|
||||||
extern TAILQ_HEAD(ws_assignments_head, Workspace_Assignment) ws_assignments;
|
extern TAILQ_HEAD(ws_assignments_head, Workspace_Assignment) ws_assignments;
|
||||||
extern TAILQ_HEAD(real_assignments_head, Assignment) real_assignments;
|
extern TAILQ_HEAD(assignments_head, Assignment) assignments;
|
||||||
extern SLIST_HEAD(stack_wins_head, Stack_Window) stack_wins;
|
extern SLIST_HEAD(stack_wins_head, Stack_Window) stack_wins;
|
||||||
extern uint8_t root_depth;
|
extern uint8_t root_depth;
|
||||||
extern bool xcursor_supported, xkb_supported;
|
extern bool xcursor_supported, xkb_supported;
|
||||||
|
|
|
@ -16,16 +16,16 @@ void match_init(Match *match);
|
||||||
*/
|
*/
|
||||||
bool match_is_empty(Match *match);
|
bool match_is_empty(Match *match);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the data of a match from src to dest.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void match_copy(Match *dest, Match *src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a match data structure matches the given window.
|
* Check if a match data structure matches the given window.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool match_matches_window(Match *match, i3Window *window);
|
bool match_matches_window(Match *match, i3Window *window);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the first match in 'assignments' that matches the given window.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Match *match_by_assignment(i3Window *window);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,7 +17,7 @@ void run_assignments(i3Window *window) {
|
||||||
|
|
||||||
/* Check if any assignments match */
|
/* Check if any assignments match */
|
||||||
Assignment *current;
|
Assignment *current;
|
||||||
TAILQ_FOREACH(current, &real_assignments, real_assignments) {
|
TAILQ_FOREACH(current, &assignments, assignments) {
|
||||||
if (!match_matches_window(&(current->match), window))
|
if (!match_matches_window(&(current->match), window))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -48,3 +48,21 @@ void run_assignments(i3Window *window) {
|
||||||
window->ran_assignments[window->nr_assignments-1] = current;
|
window->ran_assignments[window->nr_assignments-1] = current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the first matching assignment for the given window.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Assignment *assignment_for(i3Window *window, int type) {
|
||||||
|
Assignment *assignment;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(assignment, &assignments, assignments) {
|
||||||
|
if ((type != A_ANY && (assignment->type & type) == 0) ||
|
||||||
|
!match_matches_window(&(assignment->match), window))
|
||||||
|
continue;
|
||||||
|
DLOG("got a matching assignment (to %s)\n", assignment->dest.workspace);
|
||||||
|
return assignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ EOL (\r?\n)
|
||||||
%s WANT_QSTRING
|
%s WANT_QSTRING
|
||||||
%s BINDSYM_COND
|
%s BINDSYM_COND
|
||||||
%s ASSIGN_COND
|
%s ASSIGN_COND
|
||||||
|
%s ASSIGN_TARGET_COND
|
||||||
%s COLOR_COND
|
%s COLOR_COND
|
||||||
%s OUTPUT_COND
|
%s OUTPUT_COND
|
||||||
%s FOR_WINDOW_COND
|
%s FOR_WINDOW_COND
|
||||||
|
@ -87,6 +88,8 @@ EOL (\r?\n)
|
||||||
<OUTPUT_COND>[a-zA-Z0-9_-]+ { yylval.string = sstrdup(yytext); return OUTPUT; }
|
<OUTPUT_COND>[a-zA-Z0-9_-]+ { yylval.string = sstrdup(yytext); return OUTPUT; }
|
||||||
^[ \t]*#[^\n]* { return TOKCOMMENT; }
|
^[ \t]*#[^\n]* { return TOKCOMMENT; }
|
||||||
<COLOR_COND>[0-9a-fA-F]+ { yylval.string = sstrdup(yytext); return HEX; }
|
<COLOR_COND>[0-9a-fA-F]+ { yylval.string = sstrdup(yytext); return HEX; }
|
||||||
|
<ASSIGN_TARGET_COND>[ \t]*→[ \t]* { BEGIN(WANT_STRING); }
|
||||||
|
<ASSIGN_TARGET_COND>[ \t]+ { BEGIN(WANT_STRING); }
|
||||||
[0-9]+ { yylval.number = atoi(yytext); return NUMBER; }
|
[0-9]+ { yylval.number = atoi(yytext); return NUMBER; }
|
||||||
mode { return TOKMODE; }
|
mode { return TOKMODE; }
|
||||||
bind { yy_push_state(WANT_STRING); yy_push_state(EAT_WHITESPACE); yy_push_state(EAT_WHITESPACE); return TOKBINDCODE; }
|
bind { yy_push_state(WANT_STRING); yy_push_state(EAT_WHITESPACE); yy_push_state(EAT_WHITESPACE); return TOKBINDCODE; }
|
||||||
|
@ -104,7 +107,7 @@ screen {
|
||||||
}
|
}
|
||||||
terminal { WS_STRING; return TOKTERMINAL; }
|
terminal { WS_STRING; return TOKTERMINAL; }
|
||||||
font { WS_STRING; return TOKFONT; }
|
font { WS_STRING; return TOKFONT; }
|
||||||
assign { BEGIN(ASSIGN_COND); return TOKASSIGN; }
|
assign { yy_push_state(ASSIGN_TARGET_COND); yy_push_state(ASSIGN_COND); return TOKASSIGN; }
|
||||||
set[^\n]* { return TOKCOMMENT; }
|
set[^\n]* { return TOKCOMMENT; }
|
||||||
ipc-socket { WS_STRING; return TOKIPCSOCKET; }
|
ipc-socket { WS_STRING; return TOKIPCSOCKET; }
|
||||||
ipc_socket { WS_STRING; return TOKIPCSOCKET; }
|
ipc_socket { WS_STRING; return TOKIPCSOCKET; }
|
||||||
|
@ -160,7 +163,6 @@ Mode_switch { yylval.number = BIND_MODE_SWITCH; return MODIF
|
||||||
control { return TOKCONTROL; }
|
control { return TOKCONTROL; }
|
||||||
ctrl { return TOKCONTROL; }
|
ctrl { return TOKCONTROL; }
|
||||||
shift { return TOKSHIFT; }
|
shift { return TOKSHIFT; }
|
||||||
→ { return TOKARROW; }
|
|
||||||
|
|
||||||
class { yy_push_state(WANT_QSTRING); return TOK_CLASS; }
|
class { yy_push_state(WANT_QSTRING); return TOK_CLASS; }
|
||||||
id { yy_push_state(WANT_QSTRING); return TOK_ID; }
|
id { yy_push_state(WANT_QSTRING); return TOK_ID; }
|
||||||
|
@ -179,14 +181,16 @@ title { yy_push_state(WANT_QSTRING); return TOK_TITLE;
|
||||||
[ \t]+ { /* ignore whitespace */ ; }
|
[ \t]+ { /* ignore whitespace */ ; }
|
||||||
\"[^\"]+\" {
|
\"[^\"]+\" {
|
||||||
/* if ASSIGN_COND then */
|
/* if ASSIGN_COND then */
|
||||||
BEGIN(INITIAL);
|
if (yy_start_stack_ptr > 0)
|
||||||
|
yy_pop_state();
|
||||||
|
else BEGIN(INITIAL);
|
||||||
/* yylval will be the string, but without quotes */
|
/* yylval will be the string, but without quotes */
|
||||||
char *copy = sstrdup(yytext+1);
|
char *copy = sstrdup(yytext+1);
|
||||||
copy[strlen(copy)-1] = '\0';
|
copy[strlen(copy)-1] = '\0';
|
||||||
yylval.string = copy;
|
yylval.string = copy;
|
||||||
return QUOTEDSTRING;
|
return QUOTEDSTRING;
|
||||||
}
|
}
|
||||||
<ASSIGN_COND>[^ \t]+ { BEGIN(INITIAL); yylval.string = sstrdup(yytext); return STR_NG; }
|
<ASSIGN_COND>[^ \t\"]+ { BEGIN(ASSIGN_TARGET_COND); yylval.string = sstrdup(yytext); return STR_NG; }
|
||||||
<BINDSYM_COND>[a-zA-Z0-9_]+ { yylval.string = sstrdup(yytext); return WORD; }
|
<BINDSYM_COND>[a-zA-Z0-9_]+ { yylval.string = sstrdup(yytext); return WORD; }
|
||||||
[a-zA-Z]+ { yylval.string = sstrdup(yytext); return WORD; }
|
[a-zA-Z]+ { yylval.string = sstrdup(yytext); return WORD; }
|
||||||
. { return (int)yytext[0]; }
|
. { return (int)yytext[0]; }
|
||||||
|
|
|
@ -268,7 +268,6 @@ void parse_file(const char *f) {
|
||||||
%type <string> optional_workspace_name
|
%type <string> optional_workspace_name
|
||||||
%type <string> workspace_name
|
%type <string> workspace_name
|
||||||
%type <string> window_class
|
%type <string> window_class
|
||||||
%type <match> assign_target
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
@ -356,7 +355,7 @@ for_window:
|
||||||
assignment->type = A_COMMAND;
|
assignment->type = A_COMMAND;
|
||||||
assignment->match = current_match;
|
assignment->match = current_match;
|
||||||
assignment->dest.command = $3;
|
assignment->dest.command = $3;
|
||||||
TAILQ_INSERT_TAIL(&real_assignments, assignment, real_assignments);
|
TAILQ_INSERT_TAIL(&assignments, assignment, assignments);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -651,57 +650,54 @@ workspace_name:
|
||||||
;
|
;
|
||||||
|
|
||||||
assign:
|
assign:
|
||||||
TOKASSIGN window_class optional_arrow assign_target
|
TOKASSIGN window_class STR
|
||||||
{
|
{
|
||||||
printf("assignment of %s\n", $2);
|
printf("assignment of %s to *%s*\n", $2, $3);
|
||||||
|
char *workspace = $3;
|
||||||
|
char *criteria = $2;
|
||||||
|
|
||||||
struct Match *match = $4;
|
Assignment *assignment = scalloc(sizeof(Assignment));
|
||||||
|
Match *match = &(assignment->match);
|
||||||
|
match_init(match);
|
||||||
|
|
||||||
char *separator = NULL;
|
char *separator = NULL;
|
||||||
if ((separator = strchr($2, '/')) != NULL) {
|
if ((separator = strchr(criteria, '/')) != NULL) {
|
||||||
*(separator++) = '\0';
|
*(separator++) = '\0';
|
||||||
match->title = sstrdup(separator);
|
match->title = sstrdup(separator);
|
||||||
}
|
}
|
||||||
if (*$2 != '\0')
|
if (*criteria != '\0')
|
||||||
match->class = sstrdup($2);
|
match->class = sstrdup(criteria);
|
||||||
free($2);
|
free(criteria);
|
||||||
|
|
||||||
printf(" class = %s\n", match->class);
|
printf(" class = %s\n", match->class);
|
||||||
printf(" title = %s\n", match->title);
|
printf(" title = %s\n", match->title);
|
||||||
if (match->insert_where == M_ASSIGN_WS)
|
|
||||||
printf(" to ws %s\n", match->target_ws);
|
|
||||||
TAILQ_INSERT_TAIL(&assignments, match, assignments);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
assign_target:
|
/* Compatibility with older versions: If the assignment target starts
|
||||||
NUMBER
|
* with ~, we create the equivalent of:
|
||||||
{
|
*
|
||||||
/* TODO: named workspaces */
|
* for_window [class="foo"] mode floating
|
||||||
Match *match = smalloc(sizeof(Match));
|
*/
|
||||||
match_init(match);
|
if (*workspace == '~') {
|
||||||
match->insert_where = M_ASSIGN_WS;
|
workspace++;
|
||||||
asprintf(&(match->target_ws), "%d", $1);
|
if (*workspace == '\0') {
|
||||||
$$ = match;
|
/* This assignment was *only* for floating */
|
||||||
|
assignment->type = A_COMMAND;
|
||||||
|
assignment->dest.command = sstrdup("mode floating");
|
||||||
|
TAILQ_INSERT_TAIL(&assignments, assignment, assignments);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
/* Create a new assignment and continue afterwards */
|
||||||
|
Assignment *floating = scalloc(sizeof(Assignment));
|
||||||
|
match_copy(&(floating->match), match);
|
||||||
|
floating->type = A_COMMAND;
|
||||||
|
floating->dest.command = sstrdup("mode floating");
|
||||||
|
TAILQ_INSERT_TAIL(&assignments, floating, assignments);
|
||||||
}
|
}
|
||||||
| '~'
|
|
||||||
{
|
|
||||||
/* TODO: compatiblity */
|
|
||||||
#if 0
|
|
||||||
struct Assignment *new = scalloc(sizeof(struct Assignment));
|
|
||||||
new->floating = ASSIGN_FLOATING_ONLY;
|
|
||||||
$<assignment>$ = new;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
| '~' NUMBER
|
|
||||||
{
|
assignment->type = A_TO_WORKSPACE;
|
||||||
/* TODO: compatiblity */
|
assignment->dest.workspace = workspace;
|
||||||
#if 0
|
TAILQ_INSERT_TAIL(&assignments, assignment, assignments);
|
||||||
struct Assignment *new = scalloc(sizeof(struct Assignment));
|
|
||||||
new->workspace = $<number>2;
|
|
||||||
new->floating = ASSIGN_FLOATING;
|
|
||||||
$<assignment>$ = new;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -710,11 +706,6 @@ window_class:
|
||||||
| STR_NG
|
| STR_NG
|
||||||
;
|
;
|
||||||
|
|
||||||
optional_arrow:
|
|
||||||
/* NULL */
|
|
||||||
| TOKARROW
|
|
||||||
;
|
|
||||||
|
|
||||||
ipcsocket:
|
ipcsocket:
|
||||||
TOKIPCSOCKET STR
|
TOKIPCSOCKET STR
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,8 +37,6 @@ struct assignments_head assignments = TAILQ_HEAD_INITIALIZER(assignments);
|
||||||
* output) */
|
* output) */
|
||||||
struct ws_assignments_head ws_assignments = TAILQ_HEAD_INITIALIZER(ws_assignments);
|
struct ws_assignments_head ws_assignments = TAILQ_HEAD_INITIALIZER(ws_assignments);
|
||||||
|
|
||||||
struct real_assignments_head real_assignments = TAILQ_HEAD_INITIALIZER(real_assignments);
|
|
||||||
|
|
||||||
/* We hope that those are supported and set them to true */
|
/* We hope that those are supported and set them to true */
|
||||||
bool xcursor_supported = true;
|
bool xcursor_supported = true;
|
||||||
bool xkb_supported = true;
|
bool xkb_supported = true;
|
||||||
|
|
10
src/manage.c
10
src/manage.c
|
@ -205,17 +205,19 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
|
||||||
|
|
||||||
Con *nc = NULL;
|
Con *nc = NULL;
|
||||||
Match *match;
|
Match *match;
|
||||||
|
Assignment *assignment;
|
||||||
|
|
||||||
/* check assignments first */
|
/* check assignments first */
|
||||||
if ((match = match_by_assignment(cwindow))) {
|
if ((assignment = assignment_for(cwindow, A_TO_WORKSPACE | A_TO_OUTPUT))) {
|
||||||
DLOG("Assignment matches (%p)\n", match);
|
DLOG("Assignment matches (%p)\n", match);
|
||||||
if (match->insert_where == M_ASSIGN_WS) {
|
if (assignment->type == A_TO_WORKSPACE) {
|
||||||
nc = con_descend_focused(workspace_get(match->target_ws, NULL));
|
nc = con_descend_focused(workspace_get(assignment->dest.workspace, NULL));
|
||||||
DLOG("focused on ws %s: %p / %s\n", match->target_ws, nc, nc->name);
|
DLOG("focused on ws %s: %p / %s\n", assignment->dest.workspace, nc, nc->name);
|
||||||
if (nc->type == CT_WORKSPACE)
|
if (nc->type == CT_WORKSPACE)
|
||||||
nc = tree_open_con(nc);
|
nc = tree_open_con(nc);
|
||||||
else nc = tree_open_con(nc->parent);
|
else nc = tree_open_con(nc->parent);
|
||||||
}
|
}
|
||||||
|
/* TODO: handle assignments with type == A_TO_OUTPUT */
|
||||||
} else {
|
} else {
|
||||||
/* TODO: two matches for one container */
|
/* TODO: two matches for one container */
|
||||||
|
|
||||||
|
|
36
src/match.c
36
src/match.c
|
@ -45,6 +45,25 @@ bool match_is_empty(Match *match) {
|
||||||
match->floating == M_ANY);
|
match->floating == M_ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copies the data of a match from src to dest.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void match_copy(Match *dest, Match *src) {
|
||||||
|
memcpy(dest, src, sizeof(Match));
|
||||||
|
|
||||||
|
#define STRDUP(field) do { \
|
||||||
|
if (src->field != NULL) \
|
||||||
|
dest->field = sstrdup(src->field); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
STRDUP(title);
|
||||||
|
STRDUP(mark);
|
||||||
|
STRDUP(application);
|
||||||
|
STRDUP(class);
|
||||||
|
STRDUP(instance);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if a match data structure matches the given window.
|
* Check if a match data structure matches the given window.
|
||||||
*
|
*
|
||||||
|
@ -87,20 +106,3 @@ bool match_matches_window(Match *match, i3Window *window) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the first match in 'assignments' that matches the given window.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Match *match_by_assignment(i3Window *window) {
|
|
||||||
Match *match;
|
|
||||||
|
|
||||||
TAILQ_FOREACH(match, &assignments, assignments) {
|
|
||||||
if (!match_matches_window(match, window))
|
|
||||||
continue;
|
|
||||||
DLOG("got a matching assignment (to %s)\n", match->target_ws);
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue