detach works

This commit is contained in:
garbeam 2005-12-05 23:22:24 +02:00
parent d1a962ea23
commit b45e29ac20
9 changed files with 83 additions and 105 deletions

View File

@ -51,18 +51,19 @@ void destroy_area(Area * a)
free(a);
}
void sel_area(Area * a, int raise, int up, int down)
void sel_area(Area * a, int raise)
{
Page *p = a->page;
if (!p)
return;
if (down && a->frame)
sel_frame(a->frame[a->sel], raise, 0, down);
if (raise && a->frame) {
int i;
for (i = 0; a->frame[i]; i++)
if (i != a->sel)
XRaiseWindow(dpy, a->frame[i]->win);
}
p->sel = index_item((void **) p->area, a);
p->file[P_SEL_AREA]->content = a->file[A_PREFIX]->content;
if (up)
sel_page(p, raise, 0);
if (a->frame)
sel_frame(a->frame[a->sel], raise);
}
void attach_frame_to_area(Area * a, Frame * f)
@ -76,7 +77,13 @@ void attach_frame_to_area(Area * a, Frame * f)
void detach_frame_from_area(Frame * f, int ignore_sel_and_destroy)
{
Area *a = f->area;
a->frame = (Frame **) detach_item((void **) a->frame, f, sizeof(Frame *));
f->area = 0;
if (a->sel)
a->sel--;
else
a->sel = 0;
}
void draw_area(Area * a)

View File

@ -34,22 +34,16 @@ Client *alloc_client(Window w)
return c;
}
void sel_client(Client * c, int raise, int up)
void sel_client(Client * c)
{
Frame *f = 0;
/* sel client */
if (c) {
f = c->frame;
for (f->sel = 0; f->client && f->client[f->sel] != c; f->sel++);
f->file[F_SEL_CLIENT]->content = c->file[C_PREFIX]->content;
if (raise)
XRaiseWindow(dpy, c->win);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
} else
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
f = c->frame;
for (f->sel = 0; f->client && f->client[f->sel] != c; f->sel++);
f->file[F_SEL_CLIENT]->content = c->file[C_PREFIX]->content;
XRaiseWindow(dpy, c->win);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
invoke_wm_event(def[WM_EVENT_CLIENT_UPDATE]);
if (up && f)
sel_frame(f, raise, up, 0);
}
void set_client_state(Client * c, int state)
@ -342,3 +336,13 @@ void attach_client(Client * c)
a->layout->attach(a, c);
invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
}
void detach_client(Client *c) {
if (c->frame)
c->frame->area->layout->detach(c->frame->area, c);
if (c->destroyed)
destroy_client(c);
if (page)
sel_page(page[sel]);
}

View File

@ -20,7 +20,6 @@ static void handle_motionnotify(XEvent * e);
static void handle_propertynotify(XEvent * e);
static void handle_unmapnotify(XEvent * e);
static void handle_enternotify(XEvent * e);
static void update_ignore_enternotify_hack(XEvent * e);
static unsigned int ignore_enternotify_hack = 0;
@ -34,14 +33,11 @@ void init_event_hander()
handler[i] = 0;
}
handler[ButtonPress] = handle_buttonpress;
handler[CirculateNotify] = update_ignore_enternotify_hack;
handler[ConfigureRequest] = handle_configurerequest;
handler[DestroyNotify] = handle_destroynotify;
handler[EnterNotify] = handle_enternotify;
handler[Expose] = handle_expose;
handler[GravityNotify] = update_ignore_enternotify_hack;
handler[MapRequest] = handle_maprequest;
handler[MapNotify] = update_ignore_enternotify_hack;
handler[MotionNotify] = handle_motionnotify;
handler[PropertyNotify] = handle_propertynotify;
handler[UnmapNotify] = handle_unmapnotify;
@ -108,7 +104,6 @@ static void handle_configurerequest(XEvent * e)
unsigned int bw = 0, tabh = 0;
Frame *f = 0;
update_ignore_enternotify_hack(e);
/* fprintf(stderr, "%s", "configure request\n"); */
c = win_to_client(ev->window);
ev->value_mask &= ~CWSibling;
@ -184,14 +179,10 @@ static void handle_destroynotify(XEvent * e)
XDestroyWindowEvent *ev = &e->xdestroywindow;
Client *c = win_to_client(ev->window);
/* fprintf(stderr, "destroy: client 0x%x\n", (int)ev->window); */
if (!c)
return;
if (c->frame)
detach_client_from_frame(c, 0, 1);
else if (detached && (index_item((void **) detached, c) >= 0))
detached = (Client **) detach_item((void **) detached, c,
sizeof(Client *));
destroy_client(c);
if (c) {
c->destroyed = True;
detach_client(c);
}
}
static void handle_expose(XEvent * e)
@ -232,13 +223,12 @@ static void handle_motionnotify(XEvent * e)
if (f) {
Frame *old = SELFRAME(page[sel]);
if (old != f) {
sel_frame(f, 0, 0, 1);
sel_frame(f, 1);
draw_frame(old);
draw_frame(f);
} else if (f->client) {
/* multihead assumption */
XSetInputFocus(dpy, f->client[f->sel]->win,
RevertToPointerRoot, CurrentTime);
XSetInputFocus(dpy, f->client[f->sel]->win, RevertToPointerRoot, CurrentTime);
XSync(dpy, False);
}
cursor = cursor_for_motion(f, e->xmotion.x, e->xmotion.y);
@ -265,20 +255,10 @@ static void handle_unmapnotify(XEvent * e)
XUnmapEvent *ev = &e->xunmap;
Client *c;
update_ignore_enternotify_hack(e);
if (ev->event == root)
return;
if ((c = win_to_client(ev->window))) {
if (c->frame) {
detach_client_from_frame(c, 1, 0);
if (page)
draw_page(page[sel]);
destroy_client(c);
} else if (detached) {
if (index_item((void **) detached, c) == -1)
destroy_client(c);
}
}
if ((c = win_to_client(ev->window)))
detach_client(c);
}
static void handle_enternotify(XEvent * e)
@ -298,7 +278,7 @@ static void handle_enternotify(XEvent * e)
Frame *old = SELFRAME(page[sel]);
XUndefineCursor(dpy, c->frame->win);
if (old != c->frame) {
sel_frame(c->frame, 0, 0, 1);
sel_frame(c->frame, 1);
draw_frame(old);
draw_frame(c->frame);
} else {
@ -308,9 +288,3 @@ static void handle_enternotify(XEvent * e)
}
}
}
static void update_ignore_enternotify_hack(XEvent * e)
{
ignore_enternotify_hack = e->xany.serial;
XSync(dpy, False);
}

View File

@ -105,17 +105,14 @@ Frame *alloc_frame(XRectangle * r)
return f;
}
void sel_frame(Frame * f, int raise, int up, int down)
void sel_frame(Frame * f, int raise)
{
Area *a = f->area;
if (down && f->client)
sel_client(f->client[f->sel], raise, 0);
sel_client(f->client[f->sel]);
a->sel = index_item((void **) a->frame, f);
a->file[A_SEL_FRAME]->content = f->file[F_PREFIX]->content;
if (raise && a->page->sel == 0) /* only floating windows are raised */
if (raise)
XRaiseWindow(dpy, f->win);
if (up)
sel_area(a, raise, up, 0);
}
Frame *win_to_frame(Window w)
@ -328,7 +325,7 @@ void handle_frame_buttonpress(XButtonEvent * e, Frame * f)
if (!f->area->page->sel)
XRaiseWindow(dpy, f->win);
if (cindex != f->sel) {
sel_client(f->client[cindex], 1, 0);
sel_client(f->client[cindex]);
draw_frame(f);
return;
}
@ -353,39 +350,30 @@ void attach_client_to_frame(Frame * f, Client * c)
reparent_client(c, f->win, border_width(f), tab_height(f));
resize_frame(f, &f->rect, 0, 1);
show_client(c);
sel_client(c, 1, 1);
sel_client(c);
}
void detach_client_from_frame(Client * c, int unmapped, int destroyed)
void detach_client_from_frame(Client * c)
{
Frame *f = c->frame;
wmii_move_ixpfile(c->file[C_PREFIX], def[WM_DETACHED_CLIENT]);
c->frame = 0;
f->client =
(Client **) detach_item((void **) f->client, c, sizeof(Client *));
f->client = (Client **) detach_item((void **) f->client, c, sizeof(Client *));
if (f->sel)
f->sel--;
else
f->sel = 0;
if (!destroyed) {
if (!unmapped) {
if (!c->destroyed) {
if (f) {
hide_client(c);
detached =
(Client **) attach_item_begin((void **) detached, c,
sizeof(Client *));
detached = (Client **) attach_item_begin((void **) detached, c, sizeof(Client *));
}
reparent_client(c, root, border_width(f), tab_height(f));
}
if (f->client) {
sel_client(f->client[f->sel], 1, 1);
sel_client(f->client[f->sel]);
draw_frame(f);
} else {
detach_frame_from_area(f, 0);
destroy_frame(f);
if (page)
sel_page(page[sel], 0, 1);
}
invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
}
static void mouse()
@ -421,7 +409,7 @@ static void select_client(void *obj, char *cmd)
else
f->sel++;
}
sel_client(f->client[f->sel], 1, 0);
sel_client(f->client[f->sel]);
draw_frame(f);
}

View File

@ -31,7 +31,7 @@ static void init_col(Area * a);
static void deinit_col(Area * a);
static void arrange_col(Area * a);
static void attach_col(Area * a, Client * c);
static void detach_col(Area * a, Client * c, int unmapped, int destroyed);
static void detach_col(Area * a, Client * c);
static void resize_col(Frame * f, XRectangle * new, XPoint * pt);
static Layout lcol = { "col", init_col, deinit_col, arrange_col, attach_col, detach_col, resize_col };
@ -162,7 +162,7 @@ static void deinit_col(Area * a)
for (j = 0; col->frame && col->frame[j]; j++) {
Frame *f = col->frame[j];
while (f->client && f->client[0])
detach_client_from_frame(f->client[0], 0, 0);
detach_client_from_frame(f->client[0]);
detach_frame_from_area(f, 1);
destroy_frame(f);
}
@ -190,7 +190,7 @@ static void attach_col(Area * a, Client * c)
arrange_col(a);
}
static void detach_col(Area * a, Client * c, int unmapped, int destroyed)
static void detach_col(Area * a, Client * c)
{
Frame *f = c->frame;
Column *col = f->aux;
@ -200,7 +200,7 @@ static void detach_col(Area * a, Client * c, int unmapped, int destroyed)
* such case */
col->frame = (Frame **) detach_item((void **) col->frame, c->frame, sizeof(Frame *));
col->refresh = 1;
detach_client_from_frame(c, unmapped, destroyed);
detach_client_from_frame(c);
detach_frame_from_area(f, 1);
destroy_frame(f);
@ -348,8 +348,7 @@ static void _drop_move(Frame * f, XRectangle * new, XPoint * pt)
}
} else {
/* detach, attach and change order in target column */
src->frame = (Frame **) detach_item((void **) src->frame,
f, sizeof(Frame *));
src->frame = (Frame **) detach_item((void **) src->frame, f, sizeof(Frame *));
tgt->frame =
(Frame **) attach_item_end((void **) tgt->frame, f,
sizeof(Frame *));

View File

@ -16,7 +16,7 @@ static void init_float(Area * a);
static void deinit_float(Area * a);
static void arrange_float(Area * a);
static void attach_float(Area * a, Client * c);
static void detach_float(Area * a, Client * c, int unmapped, int destroyed);
static void detach_float(Area * a, Client * c);
static void resize_float(Frame * f, XRectangle * new, XPoint * pt);
static Layout lfloat = { "float", init_float, deinit_float, arrange_float, attach_float, detach_float, resize_float };
@ -55,8 +55,14 @@ static void attach_float(Area * a, Client * c)
draw_frame(f);
}
static void detach_float(Area * a, Client * c, int unmapped, int destroyed)
static void detach_float(Area * a, Client * c)
{
Frame *f = c->frame;
detach_client_from_frame(f->client[0]);
if (!f->client) {
detach_frame_from_area(f, 0);
destroy_frame(f);
}
}
static void resize_float(Frame * f, XRectangle * new, XPoint * pt)

View File

@ -55,8 +55,7 @@ void destroy_page(Page * p)
if (page) {
show_page(page[sel]);
def[WM_SEL_PAGE]->content = page[sel]->file[P_PREFIX]->content;
sel_page(page[sel], 0, 1);
invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
sel_page(page[sel]);
}
}
@ -76,7 +75,7 @@ void free_page(Page * p)
free(p);
}
void sel_page(Page * p, int raise, int down)
void sel_page(Page * p)
{
if (!page)
return;
@ -87,8 +86,7 @@ void sel_page(Page * p, int raise, int down)
def[WM_SEL_PAGE]->content = p->file[P_PREFIX]->content;
}
invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
if (down)
sel_area(p->area[p->sel], raise, 0, down);
sel_area(p->area[p->sel], !p->sel);
}
void draw_page(Page * p)
@ -166,7 +164,7 @@ static void select_frame(void *obj, char *cmd)
f = f->area->frame[i];
}
if (old != f) {
sel_frame(f, 1, 1, 1);
sel_frame(f, 1);
center_pointer(f);
draw_frame(old);
draw_frame(f);

View File

@ -254,7 +254,7 @@ static void pager(void *obj, char *cmd)
XUnmapWindow(dpy, transient);
if ((i = handle_kpress(&ev.xkey)) != -1)
if (i < count_items((void **) page))
sel_page(page[i], 0, 1);
sel_page(page[i]);
XUngrabKeyboard(dpy, CurrentTime);
return;
break;
@ -263,7 +263,7 @@ static void pager(void *obj, char *cmd)
if (ev.xbutton.button == Button1) {
Page *p = xy_to_pager_page(ev.xbutton.x, ev.xbutton.y);
if (p)
sel_page(p, 0, 1);
sel_page(p);
}
return;
break;
@ -390,7 +390,7 @@ static void _detach_client(void *obj, char *cmd)
f = SELFRAME(page[sel]);
if (!f)
return;
detach_client_from_frame(f->client[f->sel], 0, 0);
f->area->layout->detach(f->area, f->client[f->sel]);
}
static void _select_page(void *obj, char *cmd)
@ -403,7 +403,7 @@ static void _select_page(void *obj, char *cmd)
sel = index_next_item((void **) page, page[sel]);
else
sel = _strtonum(cmd, 0, count_items((void **) page));
sel_page(page[sel], 0, 1);
sel_page(page[sel]);
}
static void _destroy_page(void *obj, char *cmd)

View File

@ -122,7 +122,7 @@ struct Layout {
void (*deinit) (Area *); /* called when layout is uninitialized */
void (*arrange) (Area *); /* called when area is resized */
void (*attach) (Area *, Client *); /* called on attach */
void (*detach) (Area *, Client *, int, int); /* called on detach */
void (*detach) (Area *, Client *); /* called on detach */
void (*resize) (Frame *, XRectangle *, XPoint * pt); /* called after resize */
};
@ -151,6 +151,7 @@ struct Frame {
struct Client {
int proto;
unsigned int border;
Bool destroyed;
Window win;
Window trans;
XRectangle rect;
@ -209,7 +210,7 @@ unsigned int valid_mask, num_lock_mask;
/* area.c */
Area *alloc_area(Page *p, XRectangle * r, char *layout);
void destroy_area(Area * a);
void sel_area(Area * a, int raise, int up, int down);
void sel_area(Area * a, int raise);
void attach_frame_to_area(Area * a, Frame * f);
void detach_frame_from_area(Frame * f, int ignore_sel_and_destroy);
void draw_area(Area * a);
@ -231,11 +232,12 @@ void ungrab_client(Client * c, unsigned long mod, unsigned int button);
void hide_client(Client * c);
void show_client(Client * c);
void reparent_client(Client * c, Window w, int x, int y);
void sel_client(Client * c, int raise, int up);
void attach_client(Client * c);
void sel_client(Client *c);
void attach_client(Client *c);
void detach_client(Client *c);
/* frame.c */
void sel_frame(Frame * f, int raise, int up, int down);
void sel_frame(Frame * f, int raise);
Frame *win_to_frame(Window w);
Frame *alloc_frame(XRectangle * r);
void destroy_frame(Frame * f);
@ -243,7 +245,7 @@ void resize_frame(Frame * f, XRectangle * r, XPoint * pt, int ignore_layout);
void draw_frame(Frame * f);
void handle_frame_buttonpress(XButtonEvent * e, Frame * f);
void attach_client_to_frame(Frame * f, Client * c);
void detach_client_from_frame(Client * c, int unmapped, int destroyed);
void detach_client_from_frame(Client *c);
void draw_tab(Frame * f, char *text, int x, int y, int w, int h, int sel);
unsigned int tab_height(Frame * f);
unsigned int border_width(Frame * f);
@ -264,7 +266,7 @@ void drop_move(Frame * f, XRectangle * new, XPoint * pt);
Page *alloc_page();
void free_page(Page * p);
void destroy_page(Page * p);
void sel_page(Page * p, int raise, int down);
void sel_page(Page *p);
XRectangle *rectangles(unsigned int *num);
void hide_page(Page * p);
void show_page(Page * p);