diff --git a/src/client.c b/src/client.c index 7dca3e9..2af5b7c 100644 --- a/src/client.c +++ b/src/client.c @@ -290,19 +290,19 @@ ishide(Client *c) } /** Kill a client - * \param cmd uicb_t type unused + * \param c Client pointer */ void -uicb_client_kill(uicb_t cmd) +client_kill(Client *c) { - XEvent ev; + XEvent ev; Atom *atom = NULL; int proto; Bool canbedel = 0; - CHECK(sel); + CHECK(c); - if(XGetWMProtocols(dpy, sel->win, &atom, &proto) && atom) + if(XGetWMProtocols(dpy, c->win, &atom, &proto) && atom) { while(proto--) if(atom[proto] == wm_atom[WMDelete]) @@ -311,7 +311,7 @@ uicb_client_kill(uicb_t cmd) if(canbedel) { ev.type = ClientMessage; - ev.xclient.window = sel->win; + ev.xclient.window = c->win; ev.xclient.message_type = wm_atom[WMProtocols]; ev.xclient.format = 32; ev.xclient.data.l[0] = wm_atom[WMDelete]; @@ -319,13 +319,26 @@ uicb_client_kill(uicb_t cmd) ev.xclient.data.l[2] = 0; ev.xclient.data.l[3] = 0; ev.xclient.data.l[4] = 0; - XSendEvent(dpy, sel->win, False, NoEventMask, &ev); + XSendEvent(dpy, c->win, False, NoEventMask, &ev); } else - XDestroyWindow(dpy, sel->win); + XKillClient(dpy, c->win); } else - XDestroyWindow(dpy, sel->win); + XKillClient(dpy, c->win); + + return; +} + +/** Kill the selected client + * \param cmd uicb_t type unused +*/ +void +uicb_client_kill(uicb_t cmd) +{ + CHECK(sel); + + client_kill(sel); return; } @@ -345,6 +358,7 @@ client_map(Client *c) bar_map(c->titlebar); bar_map_subwin(c->titlebar); } + c->unmapped = False; return; } @@ -583,6 +597,7 @@ client_unmanage(Client *c) { XGrabServer(dpy); XSetErrorHandler(errorhandlerdummy); + XReparentWindow(dpy, c->win, root, c->geo.x, c->geo.y); if(sel == c) client_focus(NULL); @@ -590,9 +605,9 @@ client_unmanage(Client *c) client_detach(c); XUngrabButton(dpy, AnyButton, AnyModifier, c->win); setwinstate(c->win, WithdrawnState); + frame_delete(c); XSync(dpy, False); XUngrabServer(dpy); - frame_delete(c); arrange(); XFree(c->title); efree(c); @@ -615,6 +630,7 @@ client_unmap(Client *c) } XUnmapWindow(dpy, c->frame); XUnmapSubwindows(dpy, c->frame); + c->unmapped = True; return; } diff --git a/src/event.c b/src/event.c index 9dac66e..18af8a0 100644 --- a/src/event.c +++ b/src/event.c @@ -297,11 +297,18 @@ void maprequest(XMapRequestEvent *ev) { XWindowAttributes at; + Client *c; CHECK(XGetWindowAttributes(dpy, ev->window, &at)); CHECK(!at.override_redirect); - if(!client_gb_win(ev->window)) + if(!(c = client_gb_win(ev->window))) client_manage(ev->window, &at); + else + /* Re-map the clients that was unmapped + * with the unmap event + */ + if(c->unmapped) + client_map(c); return; @@ -340,6 +347,22 @@ propertynotify(XPropertyEvent *ev) return; } +/** UnmapNotify handle event + * \param ev XUnmapEvent pointer + */ +void +unmapnotify(XUnmapEvent *ev) +{ + Client *c; + + if((c = client_gb_win(ev->window)) + && ev->send_event) + client_unmap(c); + + return; +} + + /** Event handle function: execute every function * handle by event * \param ev Event @@ -361,6 +384,7 @@ getevent(XEvent ev) case MapRequest: maprequest(&ev.xmaprequest); break; case MappingNotify: mappingnotify(&ev.xmapping); break; case PropertyNotify: propertynotify(&ev.xproperty); break; + case UnmapNotify: unmapnotify(&ev.xunmap); break; } diff --git a/src/frame.c b/src/frame.c index 261c5cb..ed93d37 100644 --- a/src/frame.c +++ b/src/frame.c @@ -64,7 +64,8 @@ frame_create(Client *c) c->frame_geo.y, c->frame_geo.width, c->frame_geo.height, 0, - CWOverrideRedirect|CWBackPixmap|CWEventMask, c->colors.frame, &at); + CWOverrideRedirect|CWBackPixmap|CWEventMask, + c->colors.frame, &at); /* Create titlebar window */ if(TBARH) diff --git a/src/structs.h b/src/structs.h index 43c9721..839b60b 100644 --- a/src/structs.h +++ b/src/structs.h @@ -103,7 +103,7 @@ struct Client } colors; /* Client Layout Information */ Bool max, tile, free, hide; - Bool hint, lmax, havetbar; + Bool hint, lmax, unmapped; /* Struct in chains */ Client *next; Client *prev; diff --git a/src/wmfs.c b/src/wmfs.c index 00579c9..41e9cca 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -36,6 +36,7 @@ int errorhandler(Display *d, XErrorEvent *event) { char mess[256]; + Client *c; /* Check if there are another WM running */ if(BadAccess == event->error_code @@ -45,8 +46,10 @@ errorhandler(Display *d, XErrorEvent *event) exit(EXIT_FAILURE); } - /* Ignore focus change error */ - if(event->request_code == 42) + /* Ignore focus change error for unmapped client */ + if((c = client_gb_win(event->resourceid)) + && c->unmapped + && event->request_code == 42) return 0; XGetErrorText(d, event->error_code, mess, 128); @@ -56,7 +59,6 @@ errorhandler(Display *d, XErrorEvent *event) event->minor_code, event->resourceid); - return 1; } @@ -80,6 +82,11 @@ quit(void) for(c = clients; c; c = c->next) { XReparentWindow(dpy, c->win, root, c->frame_geo.x, c->frame_geo.y); + if(c->hide) + client_unhide(c); + if(c->unmapped) + client_map(c); + client_unmanage(c); } diff --git a/src/wmfs.h b/src/wmfs.h index 9bcd32e..7634f97 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -119,6 +119,7 @@ Client* client_gb_resize(Window w); /* }}} */ void client_get_name(Client *c); void client_hide(Client *c); +void client_kill(Client *c); Bool ishide(Client *c); void client_map(Client *c); void client_manage(Window w, XWindowAttributes *wa);