#include "anvil.h"
#include <sys/wait.h>
+/*
+
+ X11 Client Window State Management:
+
+ CreateNotify ->Withdrawn:
+ Create window detached from any workspace (withdrawn list).
+ Place window in withdrawn list.
+
+ MapRequest ->Normal:
+ Read the window properties
+ Reparent the window to a frame if applicable
+ Move window to current workspace tiled or floating
+ Send expose event to window
+
+ UnmapNotify ->Withdrawn/Iconified:
+ if shaded -> Iconified
+ Keep window where it is, show only titlebar
+ else if unloaded
+ Keep window where it is but unmapped
+ else
+ Remove window from workspace.
+ Place window in withdrawn list.
+
+ DestroyNotify ->Destroyed
+ Window is destroyed. Free all resources.
+
+*/
+static void xcreatenotify(XEvent* e)
+{
+ XCreateWindowEvent* ev = &(e->xcreatewindow);
+ printf("CREATE(w: 0x%lx)\n", ev->window);
+
+ /* add the new window in the withdrawn state */
+ Client_Create(ev->window);
+}
+
+static void xmaprequest(XEvent* e)
+{
+ XMapRequestEvent* ev = &(e->xmaprequest);
+ printf("MAP(w: 0x%lx)\n", ev->window);
+
+ /* window request to be shown, let's place it now */
+ Client_Show(ev->window);
+}
+
+static void xunmapnotify(XEvent* e)
+{
+ XUnmapEvent* ev = &(e->xunmap);
+ printf("UNMAP(e: 0x%lx w: 0x%lx %d)\n", ev->event, ev->window, ev->from_configure);
+
+ /* hide or shade the window */
+ Client_Hide(ev->window);
+}
+
+static void xdestroynotify(XEvent* e)
+{
+ XDestroyWindowEvent* ev = &(e->xdestroywindow);
+ printf("DESTROY(w: 0x%lx)\n", ev->window);
+
+ /* remove the client altogether */
+ Client_Destroy(ev->window);
+}
+
+
+
+
XConf X = {0};
/* Anvil State */
}
}
-static void xmaprequest(XEvent* e)
-{
- XMapRequestEvent* ev = &(e->xmaprequest);
- printf("MAP(w: 0x%lx)\n", ev->window);
- XWindowAttributes attr;
- Location loc = {0};
- if (!mons_find(ev->window, &loc))
- {
- if (XGetWindowAttributes(X.disp, ev->window, &attr) && !attr.override_redirect)
- {
- (void)client_add(ev->window, &attr);
- }
- }
-}
-
-static void xmapnotify(XEvent* e)
-{
- XMapEvent* ev = &(e->xmap);
- printf("MAP(e: 0x%lx w: 0x%lx)\n", ev->event, ev->window);
- Location loc = {0};
- if (mons_find(ev->window, &loc))// && loc.client->win == ev->window)
- {
- client_draw(loc.client);
- }
-}
-
-
-static void xunmapnotify(XEvent* e)
-{
- XUnmapEvent* ev = &(e->xunmap);
- printf("UNMAP(e: 0x%lx w: 0x%lx %d)\n", ev->event, ev->window, ev->from_configure);
- Location loc = {0};
- if (mons_find(ev->window, &loc))// && loc.client->win == ev->window)
- {
- if (ev->event == X.root && ev->window == loc.client->win)
- {
- mons_delclient(&loc);
- }
- else if ( !(loc.client->flags & F_SHADED) )
- {
- XUnmapWindow(X.disp, loc.client->frame);
- }
- }
-}
-
-static void xdestroynotify(XEvent* e)
-{
- XDestroyWindowEvent* ev = &(e->xdestroywindow);
- printf("DESTROY(w: 0x%lx)\n", ev->window);
- Location loc = {0};
- if (mons_find(ev->window, &loc))
- {
- mons_delclient(&loc);
- }
-}
static void xclientmsg(XEvent* e)
{
}
}
+static void xmapnotify(XEvent* e)
+{
+ XMapEvent* ev = &(e->xmap);
+ printf("MAP(e: 0x%lx w: 0x%lx)\n", ev->event, ev->window);
+ Location loc = {0};
+ if (mons_find(ev->window, &loc))// && loc.client->win == ev->window)
+ {
+ client_draw(loc.client);
+ }
+}
+
+
+
static void xkeypress(XEvent* e)
{
XKeyEvent* ev = &(e->xkey);
keys_init();
atoms_init();
- /* setup event handlers */
+ /* setup window life-cycle management event handlers */
+ X.eventfns[CreateNotify] = xcreatenotify;
+ X.eventfns[MapRequest] = xmaprequest;
+ X.eventfns[UnmapNotify] = xunmapnotify;
+ X.eventfns[DestroyNotify] = xdestroynotify;
+
+ /* all other events */
+ X.eventfns[MapNotify] = xmapnotify;
X.eventfns[ButtonPress] = xbtnpress;
X.eventfns[ButtonRelease] = xbtnrelease;
X.eventfns[MotionNotify] = xbtnmotion;
X.eventfns[KeyPress] = xkeypress;
X.eventfns[ConfigureRequest] = xconfigrequest;
- X.eventfns[MapRequest] = xmaprequest;
- X.eventfns[MapNotify] = xmapnotify;
- X.eventfns[UnmapNotify] = xunmapnotify;
- X.eventfns[DestroyNotify] = xdestroynotify;
X.eventfns[ClientMessage] = xclientmsg;
X.eventfns[PropertyNotify] = xpropnotify;
X.eventfns[EnterNotify] = xenternotify;
#include "anvil.h"
-void client_initall(void)
+void Client_Create(Window win)
{
- /* TODO: Find all top-level windows and register them correctly
+ (void)win;
+ XWindowAttributes attr;
+ if (XGetWindowAttributes(X.disp, win, &attr) && !attr.override_redirect)
+ {
+ /* we care about it, let's add it to withdrawn */
+ Client* c = ecalloc(1, sizeof(Client));
+ c->win = win;
+ c->x = attr.x;
+ c->y = attr.y;
+ c->w = attr.width + FRAME_WIDTH_SUM;
+ c->h = attr.height + FRAME_HEIGHT_SUM;
+ c->next = Withdrawn;
+ Withdrawn = c;
+
+ /* Reparent the window if applicable */
+ c->frame = XCreateSimpleWindow(X.disp, X.root, c->x, c->y, c->w, c->h, 1, X.clr_bdr, X.clr_bg);
+ XSelectInput(X.disp, c->frame,
+ ExposureMask | EnterWindowMask |
+ ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
+ SubstructureRedirectMask | SubstructureNotifyMask
+ );
+ XSetWindowAttributes wa;
+ wa.event_mask = EnterWindowMask | PropertyChangeMask | FocusChangeMask;
+ wa.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask;
+ XChangeWindowAttributes(X.disp, c->win, CWEventMask | CWDontPropagate, &wa);
+ XReparentWindow(X.disp, c->win, c->frame, BORDER_WIDTH, MIN_HEIGHT);
+
+// /* Map the window and draw the frame */
+// XAddToSaveSet(X.disp, c->win);
+// client_readprops(c);
+// mons_addclient(c);
+// client_show(c, 1);
+// client_draw(c);
+ }
+}
- * Find all root children with override_redirect set False
- * Add them to withdrawn list if WM_STATE = withdrawn
- * Add them as floating and unshaded if WM_STATE = Normal
- * Add them as floating ad shaded if WM_STATE = Iconic
+void Client_Destroy(Window win)
+{
+ (void)win;
+}
+
+void Client_Show(Window win)
+{
+ (void)win;
+}
+
+void Client_Hide(Window win)
+{
+ (void)win;
+ /* TODO: hiding is complicated...
+ if window == frame and client_window == unmapped
+ unmap frame
+ move to withdrawn list
+ else if shaded
*/
- unsigned int nwins;
- Window d1, d2, *wins = NULL;
- XWindowAttributes attr;
- if (XQueryTree(X.disp, X.root, &d1, &d2, &wins, &nwins))
- {
- for (unsigned int i = 0; i < nwins; i++)
- {
- if (XGetWindowAttributes(X.disp, wins[i], &attr) && (attr.override_redirect == False))
- {
- Client* c = client_add(wins[i], &attr);
- c->flags |= F_FLOATING;
- }
- }
- xfree(wins);
- }
+// if (ev->event == X.root && ev->window == loc.client->win)
+// {
+//// mons_delclient(&loc);
+// }
+// else if ( !(loc.client->flags & F_SHADED) )
+// {
+// Client_Shade(ev->window);
+//// XUnmapWindow(X.disp, loc.client->frame);
+// }
+
+
+}
+
+
+
+
+void client_initall(void)
+{
+// /* TODO: Find all top-level windows and register them correctly
+//
+// * Find all root children with override_redirect set False
+// * Add them to withdrawn list if WM_STATE = withdrawn
+// * Add them as floating and unshaded if WM_STATE = Normal
+// * Add them as floating ad shaded if WM_STATE = Iconic
+//
+// */
+//
+// unsigned int nwins;
+// Window d1, d2, *wins = NULL;
+// XWindowAttributes attr;
+// if (XQueryTree(X.disp, X.root, &d1, &d2, &wins, &nwins))
+// {
+// for (unsigned int i = 0; i < nwins; i++)
+// {
+// if (XGetWindowAttributes(X.disp, wins[i], &attr) && (attr.override_redirect == False))
+// {
+// Client* c = client_add(wins[i], &attr);
+// c->flags |= F_FLOATING;
+// }
+// }
+// xfree(wins);
+// }
}
Client* client_add(Window win, XWindowAttributes* attr)