re-implement assigning windows to workspaces
This commit is contained in:
parent
7e51f626ef
commit
3d1acd6c2f
|
@ -34,6 +34,7 @@
|
||||||
#include "xcb_compat.h"
|
#include "xcb_compat.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "data.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
|
|
@ -285,20 +285,21 @@ struct Match {
|
||||||
|
|
||||||
enum { M_USER = 0, M_RESTART } source;
|
enum { M_USER = 0, M_RESTART } source;
|
||||||
|
|
||||||
|
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
|
||||||
* (layout saving)
|
* (layout saving)
|
||||||
* M_ACTIVE = the window will be inserted next to the currently focused
|
* M_ASSIGN_WS = the matched container will be inserted in the target_ws.
|
||||||
* container below the matched container
|
|
||||||
* (assignments)
|
|
||||||
* M_BELOW = the window will be inserted as a child of the matched container
|
* M_BELOW = the window will be inserted as a child of the matched container
|
||||||
* (dockareas)
|
* (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) matches;
|
||||||
|
TAILQ_ENTRY(Match) assignments;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Con {
|
struct Con {
|
||||||
|
|
|
@ -26,7 +26,7 @@ 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, Assignment) assignments;
|
extern TAILQ_HEAD(assignments_head, Match) 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;
|
||||||
|
|
|
@ -22,4 +22,10 @@ bool match_is_empty(Match *match);
|
||||||
*/
|
*/
|
||||||
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
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "cfgparse.tab.h"
|
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
#include "data.h"
|
#include "data.h"
|
||||||
|
@ -19,6 +18,8 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#include "cfgparse.tab.h"
|
||||||
|
|
||||||
int yycolumn = 1;
|
int yycolumn = 1;
|
||||||
|
|
||||||
#define YY_DECL int yylex (struct context *context)
|
#define YY_DECL int yylex (struct context *context)
|
||||||
|
|
|
@ -192,7 +192,7 @@ void parse_file(const char *f) {
|
||||||
char *string;
|
char *string;
|
||||||
uint32_t *single_color;
|
uint32_t *single_color;
|
||||||
struct Colortriple *color;
|
struct Colortriple *color;
|
||||||
struct Assignment *assignment;
|
Match *match;
|
||||||
struct Binding *binding;
|
struct Binding *binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,30 +539,40 @@ workspace_name:
|
||||||
assign:
|
assign:
|
||||||
TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow assign_target
|
TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow assign_target
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
printf("assignment of %s\n", $<string>3);
|
printf("assignment of %s\n", $<string>3);
|
||||||
|
|
||||||
struct Assignment *new = $<assignment>6;
|
struct Match *match = $<match>6;
|
||||||
printf(" to %d\n", new->workspace);
|
|
||||||
printf(" floating = %d\n", new->floating);
|
char *separator = NULL;
|
||||||
new->windowclass_title = $<string>3;
|
if ((separator = strchr($<string>3, '/')) != NULL) {
|
||||||
TAILQ_INSERT_TAIL(&assignments, new, assignments);
|
*(separator++) = '\0';
|
||||||
#endif
|
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:
|
assign_target:
|
||||||
NUMBER
|
NUMBER
|
||||||
{
|
{
|
||||||
#if 0
|
/* TODO: named workspaces */
|
||||||
struct Assignment *new = scalloc(sizeof(struct Assignment));
|
Match *match = smalloc(sizeof(Match));
|
||||||
new->workspace = $<number>1;
|
match_init(match);
|
||||||
new->floating = ASSIGN_FLOATING_NO;
|
match->insert_where = M_ASSIGN_WS;
|
||||||
$<assignment>$ = new;
|
asprintf(&(match->target_ws), "%d", $<number>1);
|
||||||
#endif
|
$<match>$ = match;
|
||||||
}
|
}
|
||||||
| '~'
|
| '~'
|
||||||
{
|
{
|
||||||
|
/* TODO: compatiblity */
|
||||||
#if 0
|
#if 0
|
||||||
struct Assignment *new = scalloc(sizeof(struct Assignment));
|
struct Assignment *new = scalloc(sizeof(struct Assignment));
|
||||||
new->floating = ASSIGN_FLOATING_ONLY;
|
new->floating = ASSIGN_FLOATING_ONLY;
|
||||||
|
@ -571,6 +581,7 @@ assign_target:
|
||||||
}
|
}
|
||||||
| '~' NUMBER
|
| '~' NUMBER
|
||||||
{
|
{
|
||||||
|
/* TODO: compatiblity */
|
||||||
#if 0
|
#if 0
|
||||||
struct Assignment *new = scalloc(sizeof(struct Assignment));
|
struct Assignment *new = scalloc(sizeof(struct Assignment));
|
||||||
new->workspace = $<number>2;
|
new->workspace = $<number>2;
|
||||||
|
|
30
src/manage.c
30
src/manage.c
|
@ -203,10 +203,20 @@ 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);
|
DLOG("Initial geometry: (%d, %d, %d, %d)\n", geom->x, geom->y, geom->width, geom->height);
|
||||||
|
|
||||||
Con *nc;
|
Con *nc = NULL;
|
||||||
Match *match;
|
Match *match;
|
||||||
|
|
||||||
/* TODO: assignments */
|
/* 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 */
|
/* TODO: two matches for one container */
|
||||||
|
|
||||||
/* See if any container swallows this new window */
|
/* See if any container swallows this new window */
|
||||||
|
@ -218,25 +228,13 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
|
||||||
nc = focused;
|
nc = focused;
|
||||||
} else nc = tree_open_con(NULL);
|
} else nc = tree_open_con(NULL);
|
||||||
} else {
|
} 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* M_BELOW inserts the new window as a child of the one which was
|
/* M_BELOW inserts the new window as a child of the one which was
|
||||||
* matched (e.g. dock areas) */
|
* matched (e.g. dock areas) */
|
||||||
else if (match != NULL && match->insert_where == M_BELOW) {
|
if (match != NULL && match->insert_where == M_BELOW) {
|
||||||
nc = tree_open_con(nc);
|
nc = tree_open_con(nc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DLOG("new container = %p\n", nc);
|
DLOG("new container = %p\n", nc);
|
||||||
nc->window = cwindow;
|
nc->window = cwindow;
|
||||||
|
|
18
src/match.c
18
src/match.c
|
@ -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)
|
||||||
*
|
*
|
||||||
* A "match" is a data structure which acts like a mask or expression to match
|
* 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
|
* 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;
|
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)
|
if (!render_fullscreen)
|
||||||
*inset = rect_add(*inset, con_border_style_rect(con));
|
*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 */
|
/* Obey x11 border */
|
||||||
DLOG("X11 border: %d\n", con->border_width);
|
DLOG("X11 border: %d\n", con->border_width);
|
||||||
inset->width -= (2 * con->border_width);
|
inset->width -= (2 * con->border_width);
|
||||||
|
|
Loading…
Reference in New Issue