#include "xcb_compat.h"
#endif
+#include "data.h"
#include "util.h"
#include "ipc.h"
#include "tree.h"
enum { M_USER = 0, M_RESTART } source;
+ char *target_ws;
+
/* Where the window looking for a match should be inserted:
*
* M_HERE = the matched container will be replaced by the window
* (layout saving)
- * M_ACTIVE = the window will be inserted next to the currently focused
- * container below the matched container
- * (assignments)
+ * M_ASSIGN_WS = the matched container will be inserted in the target_ws.
* M_BELOW = the window will be inserted as a child of the matched container
* (dockareas)
*
*/
- enum { M_HERE = 0, M_ACTIVE, M_BELOW } insert_where;
+ enum { M_HERE = 0, M_ASSIGN_WS, M_BELOW } insert_where;
TAILQ_ENTRY(Match) matches;
+ TAILQ_ENTRY(Match) assignments;
};
struct Con {
extern int xkb_current_group;
extern TAILQ_HEAD(bindings_head, Binding) *bindings;
extern TAILQ_HEAD(autostarts_head, Autostart) autostarts;
-extern TAILQ_HEAD(assignments_head, Assignment) assignments;
+extern TAILQ_HEAD(assignments_head, Match) assignments;
extern SLIST_HEAD(stack_wins_head, Stack_Window) stack_wins;
extern uint8_t root_depth;
extern bool xcursor_supported, xkb_supported;
*/
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
#include <stdio.h>
#include <string.h>
#include <stdint.h>
-#include "cfgparse.tab.h"
#include <xcb/xcb.h>
#include "data.h"
#include "log.h"
#include "util.h"
+#include "cfgparse.tab.h"
+
int yycolumn = 1;
#define YY_DECL int yylex (struct context *context)
char *string;
uint32_t *single_color;
struct Colortriple *color;
- struct Assignment *assignment;
+ Match *match;
struct Binding *binding;
}
assign:
TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow assign_target
{
-#if 0
printf("assignment of %s\n", $<string>3);
- struct Assignment *new = $<assignment>6;
- printf(" to %d\n", new->workspace);
- printf(" floating = %d\n", new->floating);
- new->windowclass_title = $<string>3;
- TAILQ_INSERT_TAIL(&assignments, new, assignments);
-#endif
+ struct Match *match = $<match>6;
+
+ char *separator = NULL;
+ if ((separator = strchr($<string>3, '/')) != NULL) {
+ *(separator++) = '\0';
+ match->title = sstrdup(separator);
+ }
+ if (*$<string>3 != '\0')
+ match->class = sstrdup($<string>3);
+ free($<string>3);
+
+ printf(" class = %s\n", match->class);
+ 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:
NUMBER
{
-#if 0
- struct Assignment *new = scalloc(sizeof(struct Assignment));
- new->workspace = $<number>1;
- new->floating = ASSIGN_FLOATING_NO;
- $<assignment>$ = new;
-#endif
+ /* TODO: named workspaces */
+ Match *match = smalloc(sizeof(Match));
+ match_init(match);
+ match->insert_where = M_ASSIGN_WS;
+ asprintf(&(match->target_ws), "%d", $<number>1);
+ $<match>$ = match;
}
| '~'
{
+ /* TODO: compatiblity */
#if 0
struct Assignment *new = scalloc(sizeof(struct Assignment));
new->floating = ASSIGN_FLOATING_ONLY;
}
| '~' NUMBER
{
+ /* TODO: compatiblity */
#if 0
struct Assignment *new = scalloc(sizeof(struct Assignment));
new->workspace = $<number>2;
DLOG("Initial geometry: (%d, %d, %d, %d)\n", geom->x, geom->y, geom->width, geom->height);
- Con *nc;
+ Con *nc = NULL;
Match *match;
- /* TODO: assignments */
- /* TODO: two matches for one container */
-
- /* See if any container swallows this new window */
- nc = con_for_window(search_at, cwindow, &match);
- if (nc == NULL) {
- if (focused->type == CT_CON && con_accepts_window(focused)) {
- LOG("using current container, focused = %p, focused->name = %s\n",
- focused, focused->name);
- nc = focused;
- } else nc = tree_open_con(NULL);
+ /* check assignments first */
+ if ((match = match_by_assignment(cwindow))) {
+ DLOG("Assignment matches (%p)\n", match);
+ if (match->insert_where == M_ASSIGN_WS) {
+ nc = con_descend_focused(workspace_get(match->target_ws, NULL));
+ DLOG("focused on ws %s: %p / %s\n", match->target_ws, nc, nc->name);
+ if (nc->type == CT_WORKSPACE)
+ nc = tree_open_con(nc);
+ else nc = tree_open_con(nc->parent);
+ }
} else {
- /* M_ACTIVE are assignments */
- if (match != NULL && match->insert_where == M_ACTIVE) {
- /* We need to go down the focus stack starting from nc */
- while (TAILQ_FIRST(&(nc->focus_head)) != TAILQ_END(&(nc->focus_head))) {
- DLOG("walking down one step...\n");
- nc = TAILQ_FIRST(&(nc->focus_head));
+ /* TODO: two matches for one container */
+
+ /* See if any container swallows this new window */
+ nc = con_for_window(search_at, cwindow, &match);
+ if (nc == NULL) {
+ if (focused->type == CT_CON && con_accepts_window(focused)) {
+ LOG("using current container, focused = %p, focused->name = %s\n",
+ focused, focused->name);
+ nc = focused;
+ } else nc = tree_open_con(NULL);
+ } else {
+ /* M_BELOW inserts the new window as a child of the one which was
+ * matched (e.g. dock areas) */
+ if (match != NULL && match->insert_where == M_BELOW) {
+ nc = tree_open_con(nc);
}
- /* We need to open a new con */
- /* TODO: make a difference between match-once containers (directly assign
- * cwindow) and match-multiple (tree_open_con first) */
- nc = tree_open_con(nc->parent);
- }
-
- /* M_BELOW inserts the new window as a child of the one which was
- * matched (e.g. dock areas) */
- else if (match != NULL && match->insert_where == M_BELOW) {
- nc = tree_open_con(nc);
}
}
* vim:ts=4:sw=4:expandtab
*
* 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)
*
* A "match" is a data structure which acts like a mask or expression to match
* certain windows or not. For example, when using commands, you can specify a
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;
+}
if (!render_fullscreen)
*inset = rect_add(*inset, con_border_style_rect(con));
+ DLOG("Starting with inset = (%d, %d) %d x %d\n", inset->x, inset->y, inset->width, inset->height);
/* Obey x11 border */
DLOG("X11 border: %d\n", con->border_width);
inset->width -= (2 * con->border_width);