]> git.mdlowis.com Git - proto/anvil.git/commitdiff
started revamping client handling from the ground up
authorMike Lowis <mike.lowis@gentex.com>
Wed, 31 Jul 2024 20:31:16 +0000 (16:31 -0400)
committerMike Lowis <mike.lowis@gentex.com>
Wed, 31 Jul 2024 20:31:16 +0000 (16:31 -0400)
anvil.c
anvil.h
client.c

diff --git a/anvil.c b/anvil.c
index 93b4ada59274d3ce6b39b160a4d39395abdd385e..435bd6556d86438d6d0bd883e8d3ff777af74539 100644 (file)
--- a/anvil.c
+++ b/anvil.c
@@ -1,6 +1,72 @@
 #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 */
@@ -117,61 +183,6 @@ static void xconfigrequest(XEvent* e)
     }
 }
 
-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)
 {
@@ -220,6 +231,19 @@ static void xexpose(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);
@@ -296,16 +320,19 @@ int main(void)
     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;
diff --git a/anvil.h b/anvil.h
index 73b5cbb2bb40814b61ecbdd5ee1d1832b7bf9f9e..147a61477a0b776e5178116686872cd42d051971 100644 (file)
--- a/anvil.h
+++ b/anvil.h
@@ -167,6 +167,11 @@ void mons_tilemove(Location* loc, int hdiff);
 void mons_activate(Window win);
 
 /* client.c */
+void Client_Create(Window win);
+void Client_Destroy(Window win);
+void Client_Show(Window win);
+void Client_Hide(Window win);
+
 void client_initall(void);
 Client* client_add(Window win, XWindowAttributes* attr);
 void client_draw(Client* c);
index a4437334c8f7d91733e7afd79826a4a814225212..aabfef77b906f63bf1ae776eb3dfb9ed8a9e0160 100644 (file)
--- a/client.c
+++ b/client.c
 #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)