Skip to content

Commit

Permalink
Insert receptacle to replace stickies
Browse files Browse the repository at this point in the history
Removing a sticky window from the desktop tree causes the entire layout
to go out the window, which makes sticky essentially useless for tiled
windows. Instead I suggest we insert a receptacle bound to the node when
moving a sticky window around. When moving that sticky window back
we reinsert it into that receptacle. This way we get to keep the layout
we set up, while still moving all the sticky windows around.

When removing the windows (or just the sticky flag) we now have to
remember to remove the placeholders from all desktops on that monitor.
There's probably many more cases where we have to remove the
placeholders. I'd like feedback on that.
  • Loading branch information
Jesper Jensen committed Nov 29, 2019
1 parent df7c6cc commit b141b36
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/query.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ void query_node(node_t *n, FILE *rsp)
fprintf(rsp, "\"constraints\":");
query_constraints(n->constraints, rsp);
fprintf(rsp,",");
fprintf(rsp, "\"placeholderFor\":");
query_node(n->placeholder_for, rsp);
fprintf(rsp,",");
fprintf(rsp, "\"firstChild\":");
query_node(n->first_child, rsp);
fprintf(rsp,",");
Expand Down
57 changes: 56 additions & 1 deletion src/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,13 +495,62 @@ bool activate_node(monitor_t *m, desktop_t *d, node_t *n)
return true;
}

node_t* find_placeholder(desktop_t *d, node_t *dn, node_t *n)
{
if(dn == NULL) {
return NULL;
} else if (dn->placeholder_for == n) {
return dn;
} else {
node_t *first_child = dn->first_child;
node_t *second_child = dn->second_child;

node_t *found = find_placeholder(d, first_child, n);
if(found != NULL)
return found;

found = find_placeholder(d, second_child, n);
if(found != NULL)
return found;

}

return NULL;
}

void remove_placeholders(monitor_t *m, node_t *n) {
if(n == NULL)
return;

for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
node_t* p = find_placeholder(d, d->root, n);
if(p != NULL) {
remove_node(m, d, p);
arrange(m, d);
}
}
}

void transfer_sticky_nodes(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd, node_t *n)
{
if(ms != md) {
remove_placeholders(ms, n);
}

if (n == NULL) {
return;
} else if (n->sticky) {
node_t *r = make_node(XCB_NONE);
r->placeholder_for = n;
insert_node(ms, ds, r, n);

sticky_still = false;
transfer_node(ms, ds, n, md, dd, dd->focus, false);

node_t *dest = find_placeholder(ds, dd->root, n);
if(dest == NULL)
dest = dd->focus;

transfer_node(ms, ds, n, md, dd, dest, false);
sticky_still = true;
} else {
/* we need references to the children because n might be freed after
Expand Down Expand Up @@ -1321,6 +1370,8 @@ void remove_node(monitor_t *m, desktop_t *d, node_t *n)
return;
}

remove_placeholders(m, n);

unlink_node(m, d, n);
history_remove(d, n, true);
remove_stack_node(n);
Expand Down Expand Up @@ -2001,6 +2052,10 @@ void set_sticky(monitor_t *m, desktop_t *d, node_t *n, bool value)
return;
}

if(!value) {
remove_placeholders(m, n);
}

if (d != m->desk) {
transfer_node(m, d, n, m, m->desk, m->desk->focus, false);
}
Expand Down
1 change: 1 addition & 0 deletions src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ struct node_t {
bool private;
bool locked;
bool marked;
node_t *placeholder_for;
node_t *first_child;
node_t *second_child;
node_t *parent;
Expand Down

0 comments on commit b141b36

Please sign in to comment.