Replaced a bunch of the nasty, old focus code, and fixed focusing of the empty floating area

This commit is contained in:
Kris Maglione 2007-02-10 02:13:29 -05:00
parent 2579d60417
commit 914a2d3543
3 changed files with 199 additions and 174 deletions

283
area.c
View File

@ -7,6 +7,8 @@
#include <stdio.h>
#include <string.h>
static void place_client(Area *a, Client *c);
static int
max(int a, int b) {
if(a > b)
@ -26,7 +28,7 @@ create_area(View *v, Area *pos, unsigned int w) {
static unsigned short id = 1;
unsigned int area_num, col_num, i;
unsigned int min_width;
Area *ta, *a, **p;
Area *a, **p;
min_width = screen->rect.width/NCOL;
p = pos ? &pos->next : &v->area;
@ -62,15 +64,12 @@ create_area(View *v, Area *pos, unsigned int w) {
a->sel = nil;
a->next = *p;
*p = a;
v->sel = a;
if(i) write_event("CreateColumn %d\n", i);
if(i)
write_event("CreateColumn %d\n", i);
focus_area(a);
i = 0;
for(ta=v->area; ta != v->sel; ta=ta->next)
i++;
if(i) write_event("ColumnFocus %d\n", i);
else write_event("FocusFloating\n");
return a;
}
@ -90,18 +89,124 @@ destroy_area(Area *a) {
if(c->revert == a)
c->revert = nil;
i = 0;
for(ta=v->area; ta && ta->next != a; ta=ta->next)
i++;
i = 1;
for(ta=v->area; ta; ta=ta->next)
if(ta->next == a) break;
else i++;
if(ta) {
ta->next = a->next;
if(v->sel == a) {
v->sel = ta->floating ? ta->next : ta;
if(i) write_event("ColumnFocus %d\n", i + 1);
else write_event("FocusFloating\n");
if(ta->floating && ta->next)
ta = ta->next;
if(v->sel == a)
focus_area(ta);
}
if(i) write_event("DestroyColumn %d\n", i);
free(a);
}
void
send_to_area(Area *to, Area *from, Frame *f) {
assert(to->view == f->view);
if(to->floating != from->floating) {
XRectangle temp = f->revert;
f->revert = f->rect;
f->rect = temp;
}
f->client->revert = from;
detach_from_area(from, f);
attach_to_area(to, f, True);
}
void
attach_to_area(Area *a, Frame *f, Bool send) {
unsigned int h, n_frame;
Frame *ft;
Client *c;
View *v;
v = a->view;
c = f->client;
h = 0;
n_frame = 1;
for(ft=a->frame; ft; ft=ft->anext)
n_frame++;
c->floating = a->floating;
if(!c->floating) {
h = a->rect.height / n_frame;
if(a->frame)
scale_column(a, a->rect.height - h);
}
if(!send && !c->floating) { /* column */
unsigned int w = newcolw_of_view(v);
if(v->area->next->frame && w) {
a = new_column(v, a, w);
arrange_view(v);
}
}
free(a);
f->area = a;
if(a->sel)
insert_frame(nil, f, False);
else
insert_frame(a->sel, f, False);
if(!c->floating) /* column */
f->rect.height = h;
else /* floating */
place_client(a, c);
focus_client(f->client, False);
update_client_grab(f->client);
}
void
detach_from_area(Area *a, Frame *f) {
Frame *pr;
Client *c;
View *v;
Area *ta;
unsigned int i;
v = a->view;
c = f->client;
for(pr = a->frame; pr; pr = pr->anext)
if(pr->anext == f) break;
remove_frame(f);
if(a->sel == f)
a->sel = pr;
if(a->sel == nil)
a->sel = a->frame;
if(!a->floating) {
if(a->frame)
arrange_column(a, False);
else {
i = 0;
for(ta=v->area; ta && ta != a; ta=ta->next)
i++;
if(v->area->next->next)
destroy_area(a);
else if(!a->frame && v->area->frame)
/* focus floating area if it contains something */
focus_area(v->area);
arrange_view(v);
}
}
else if(!a->frame) {
if(c->trans) {
/* focus area of transient, if possible */
Client *cl = client_of_win(c->trans);
if(cl && cl->frame) {
a = cl->sel->area;
if(a->view == v)
focus_area(a);
}
}
else if(v->area->next->frame)
focus_area(v->area->next);
}
}
static void
@ -201,122 +306,57 @@ place_client(Area *a, Client *c) {
}
void
send_to_area(Area *to, Area *from, Frame *f) {
assert(to->view == f->view);
if(to->floating != from->floating) {
XRectangle temp = f->revert;
f->revert = f->rect;
f->rect = temp;
}
f->client->revert = from;
detach_from_area(from, f);
attach_to_area(to, f, True);
focus_client(f->client, True);
}
void
attach_to_area(Area *a, Frame *f, Bool send) {
unsigned int h, n_frame;
Frame *ft;
Client *c;
focus_area(Area *a) {
Frame *f;
View *v;
Area *old_a;
int i;
v = a->view;
c = f->client;
h = 0;
f = a->sel;
old_a = v->sel;
n_frame = 1;
for(ft=a->frame; ft; ft=ft->anext)
n_frame++;
/* XXX: Replace this with an assert later */
if(a == old_a)
return;
c->floating = a->floating;
if(!c->floating) {
h = a->rect.height / n_frame;
if(a->frame)
scale_column(a, a->rect.height - h);
}
if(!send && !c->floating) { /* column */
unsigned int w = newcolw_of_view(v);
if(v->area->next->frame && w) {
a = new_column(v, a, w);
arrange_view(v);
}
}
f->area = a;
if(a->sel)
insert_frame(nil, f, False);
v->sel = a;
if(v != screen->sel)
return;
if(f)
XSetInputFocus(blz.dpy, f->client->win, RevertToPointerRoot, CurrentTime);
else
insert_frame(a->sel, f, False);
a->sel = f;
if(!c->floating) { /* column */
f->rect.height = h;
arrange_column(a, False);
}else /* floating */
place_client(a, c);
XSetInputFocus(blz.dpy, blz.root, RevertToPointerRoot, CurrentTime);
update_client_grab(f->client);
}
void
detach_from_area(Area *a, Frame *f) {
Frame *pr;
Client *c;
View *v;
Area *ta;
unsigned int i;
v = a->view;
c = f->client;
for(pr = a->frame; pr; pr = pr->anext)
if(pr->anext == f) break;
remove_frame(f);
if(a->sel == f)
a->sel = pr;
if(a->sel == nil)
a->sel = a->frame;
if(!a->floating) {
if(a->frame)
arrange_column(a, False);
else {
i = 0;
for(ta=v->area; ta && ta != a; ta=ta->next)
i++;
if(v->area->next->next)
destroy_area(a);
else if(!a->frame && v->area->frame) {
/* focus floating area if it contains something */
focus(v->area->sel->client, False);
write_event("FocusFloating\n");
}
arrange_view(v);
if(i) write_event("DestroyColumn %d\n", i);
}
if(f) {
update_frame_widget_colors(f);
draw_frame(f);
}
else if(!a->frame) {
if(c->trans) {
/* focus area of transient, if possible */
Client *cl = client_of_win(c->trans);
if(cl && cl->frame) {
a = cl->sel->area;
if(a->view == v)
focus(a->sel->client, False);
}
if(old_a) {
if(old_a->sel) {
update_frame_widget_colors(old_a->sel);
draw_frame(old_a->sel);
}
else if(v->area->next->frame)
focus(v->area->next->sel->client, False); /* focus first col as fallback */
if(a->floating != old_a->floating)
v->revert = old_a;
}
if(a != old_a) {
i = 0;
for(ta=v->area; ta && ta != v->sel; ta=ta->next)
for(a = v->area; a != v->sel; a = a->next)
i++;
if(i) write_event("ColumnFocus %d\n", i);
else write_event("FocusFloating\n");
if(i)
write_event("ColumnFocus %d\n", i);
else
write_event("FocusFloating\n");
}
}
char *
select_area(Area *a, char *arg) {
Area *new, *ta;
Area *new;
unsigned int i;
Frame *p, *f;
View *v;
@ -370,15 +410,6 @@ select_area(Area *a, char *arg) {
for(new=view->area; i && new->next; new=new->next)
i--;
}
if(new->sel)
focus_client(new->sel->client, True);
if(v->sel != new) {
i = 0;
for(ta=v->area; ta && ta != new; ta=ta->next)
i++;
if(i) write_event("ColumnFocus %d\n", i);
else write_event("FocusFloating\n");
v->sel = new;
}
focus_area(new);
return nil;
}

View File

@ -154,54 +154,60 @@ update_client_grab(Client *c) {
grab_button(c->framewin, AnyButton, AnyModifier);
}
/* convenience function */
void
focus(Client *c, Bool restack) {
View *v;
Frame *f;
if(!(f = c->sel)) return;
v = f->area->view;
arrange_column(f->area, False);
focus_client(c, restack);
focus_view(screen, v);
}
void
focus_client(Client *c, Bool restack) {
Client *old_in_area;
Client *old;
Frame *f;
Frame *f, *old_f;
View *v;
unsigned int a_i;
Area *a, *old_a;
if(!sel_screen)
return;
f = c->sel;
a = f->area;
v = f->view;
old = sel_client();
old_in_area = sel_client_of_area(f->area);
old_a = v->sel;
old_a = nil;
if(old) {
old_f = old->sel;
old_a = old_f->area;
}
if(old_a->floating != f->area->floating)
v->revert = old_a;
v->sel = f->area;
f->area->sel = f;
c->floating = f->area->floating;
if(restack)
restack_view(v);
if(!c->floating && f->area->mode == Colstack)
arrange_column(f->area, False);
XSetInputFocus(blz.dpy, c->win, RevertToPointerRoot, CurrentTime);
if(old && old != old_in_area && old != c) {
update_frame_widget_colors(old->sel);
draw_frame(old->sel);
}
if(old_in_area && old_in_area != c) {
update_frame_widget_colors(old_in_area->sel);
draw_frame(old_in_area->sel);
}
update_frame_widget_colors(c->sel);
draw_frame(c->sel);
XSync(blz.dpy, False);
if(old_a != v->sel) {
for(a = v->area, a_i = 0; a; a = a->next, a_i++)
if(a == v->sel) break;
if(a_i)
write_event("ColumnFocus %d\n", a_i);
else
write_event("FocusFloating\n");
a->sel = f;
if(!a->floating && (a->mode == Colstack))
arrange_column(a, False);
if(v != screen->sel)
return;
if(f->area != old_a)
focus_area(f->area);
else {
XSetInputFocus(blz.dpy, f->client->win, RevertToPointerRoot, CurrentTime);
update_frame_widget_colors(f);
draw_frame(f);
if(old) {
update_frame_widget_colors(old_f);
draw_frame(old_f);
}
}
if(c != old)
write_event("ClientFocus 0x%x\n", c->win);
if(restack)
restack_view(v);
}
void
@ -653,19 +659,6 @@ send_client(Frame *f, char *arg) {
return nil;
}
/* convenience function */
void
focus(Client *c, Bool restack) {
View *v;
Frame *f;
if(!(f = c->sel)) return;
v = f->area->view;
arrange_column(f->area, False);
focus_client(c, restack);
focus_view(screen, v);
}
void
update_client_views(Client *c, char **tags) {
int cmp;

1
wmii.h
View File

@ -251,6 +251,7 @@ extern char *message_root(char *message);
extern Area *create_area(View *v, Area *pos, unsigned int w);
extern void destroy_area(Area *a);
extern Area *area_of_id(View *t, unsigned short id);
extern void focus_area(Area *a);
extern char *select_area(Area *a, char *arg);
extern void send_to_area(Area *to, Area *from, Frame *f);
extern void attach_to_area(Area *a, Frame *f, Bool send);