re-implement assigning windows to workspaces
This commit is contained in:
parent
7e51f626ef
commit
3d1acd6c2f
|
@ -34,6 +34,7 @@
|
|||
#include "xcb_compat.h"
|
||||
#endif
|
||||
|
||||
#include "data.h"
|
||||
#include "util.h"
|
||||
#include "ipc.h"
|
||||
#include "tree.h"
|
||||
|
|
|
@ -285,20 +285,21 @@ struct Match {
|
|||
|
||||
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 {
|
||||
|
|
|
@ -26,7 +26,7 @@ extern Display *xlibdpy, *xkbdpy;
|
|||
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;
|
||||
|
|
|
@ -22,4 +22,10 @@ bool match_is_empty(Match *match);
|
|||
*/
|
||||
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
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "cfgparse.tab.h"
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "data.h"
|
||||
|
@ -19,6 +18,8 @@
|
|||
#include "log.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "cfgparse.tab.h"
|
||||
|
||||
int yycolumn = 1;
|
||||
|
||||
#define YY_DECL int yylex (struct context *context)
|
||||
|
|
|
@ -192,7 +192,7 @@ void parse_file(const char *f) {
|
|||
char *string;
|
||||
uint32_t *single_color;
|
||||
struct Colortriple *color;
|
||||
struct Assignment *assignment;
|
||||
Match *match;
|
||||
struct Binding *binding;
|
||||
}
|
||||
|
||||
|
@ -539,30 +539,40 @@ workspace_name:
|
|||
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;
|
||||
|
@ -571,6 +581,7 @@ assign_target:
|
|||
}
|
||||
| '~' NUMBER
|
||||
{
|
||||
/* TODO: compatiblity */
|
||||
#if 0
|
||||
struct Assignment *new = scalloc(sizeof(struct Assignment));
|
||||
new->workspace = $<number>2;
|
||||
|
|
54
src/manage.c
54
src/manage.c
|
@ -203,38 +203,36 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
|
|||
|
||||
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);
|
||||
} 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));
|
||||
}
|
||||
/* 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);
|
||||
/* 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 {
|
||||
/* TODO: two matches for one container */
|
||||
|
||||
/* 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);
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
src/match.c
18
src/match.c
|
@ -2,7 +2,7 @@
|
|||
* 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
|
||||
|
@ -82,3 +82,19 @@ bool match_matches_window(Match *match, i3Window *window) {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -139,6 +139,7 @@ void render_con(Con *con, bool render_fullscreen) {
|
|||
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);
|
||||
|
|
Loading…
Reference in New Issue