Commits

Micah Nordland committed b6ecb70

focus handling now implemented

Comments (0)

Files changed (5)

include/boxTree.h

         Box *prevLeaf(Box *box);
         void setFocused(Box *box);
         Box *getRoot();
-        Window *findWindow(xcb_window_t winId);
+        Box *findWindowBox(xcb_window_t winId);
     private:
         Box *firstExtrema(Box *box);
         Box *secondExtrema(Box *box);

include/eventHandlers.h

 #include <xcb/xcb.h>
 
 #include "event.h"
+#include "window.h"
+#include "box.h"
 #include "setup.h"
 
 class EventHandler
 #include "boxTree.h"
 
+/*
+ *This implementation of a binary tree
+ *was taken from bspwm because I learn from example,
+ *and because I knew it would not only work, but
+ *that it was designed for the exact purpose I
+ *needed. I've learned somethings about binary 
+ *trees from it, and one day I hope to understand
+ *it in its entirety. The original source can be 
+ *found here:
+ *https://github.com/baskerville/bspwm/
+ *Oh, the printTree(), and destroy()
+ *methods are mine, and I tweaked the 
+ *insert() method  a bit.
+ */
+
 BoxTree::BoxTree()
 {
     root = nullptr;
 
 void BoxTree::remove(Box *box)
 {
-    if(box->isLeaf())
+    if (not box)
+        return;
+
+    Box *parent = box->parent;
+
+    if (not parent)
     {
+        root = nullptr;
+        focused = nullptr;
+        focusedLast = nullptr;
+    }
+    else
+    {
+        Box *b;
+        Box *grandpa = parent->parent;
         if (box->isFirst())
         {
-            box->parent->first = box->parent->second;
+            b = parent->second;
+            rotate(b, Clockwise);
         }
-        box->parent->second = nullptr;
+        else
+        {
+            b = parent->first;
+            rotate(b, Clockwise);
+        }
+        b->parent = grandpa;
+        if (grandpa)
+        {
+            if (parent->isFirst())
+            {
+                grandpa->first = b;
+            }
+            else
+            {
+                grandpa->second = b;
+            }
+        }
+        else
+        {
+            root = b;
+        }
+        box->parent = nullptr;
+
+        if (box == focusedLast)
+            focusedLast = nullptr;
+        else if (box == focused)
+        {
+            if ( focusedLast )
+            {
+                focused = focusedLast;
+            }
+            else
+                focused = (box->isFirst() ? firstExtrema(b) : secondExtrema(b));
+            focusedLast = nullptr;
+        }
+        
     }
-    else if (box->first and not box->second)
-    {
-        if (box->isFirst())
-        {
-            box->parent->first = box->first;
-        }
-        else 
-        {
-            box->parent->second = box->first;
-
-        }
-        box->first->parent = box->parent;
-        box->first = nullptr;
-        box->parent= nullptr;
-    }
-
-    if (box == focused)
-        focused = nullptr;
+    delete box;
+    std::cout << "removed box" << std::endl;
 }
 
 void BoxTree::destroy(Box* box)
 
 void BoxTree::setFocused(Box *box)
 {
-    if (box)
-    {    
+    if (box and box->window)
+    {   
+        if (box == focused)
+            return;
+        focusedLast = focused; 
         focused = box;
+        box->window->focus();
         std::cout << box->getName() << " is now focused" << std::endl;
     }
 
     return root;
 }
 
-Window* BoxTree::findWindow(xcb_window_t winId)
+Box* BoxTree::findWindowBox(xcb_window_t winId)
 {
     if(not root)
         return nullptr;
     for (marker=firstExtrema(root); marker != nullptr; marker = nextLeaf(marker))
     {
         if (marker->window->id == winId)
-            return marker->window;
+            return marker;
     }
     return nullptr;
 }

src/eventHandlers.cpp

 #include "eventHandlers.h"
+#include "monitor.h"
 
 EventHandler::EventHandler(Setup *setup):
     setup(setup)
 void EventHandler::handleMapRequest(EventPtr event)
 {
     auto ev = convertEvent<xcb_map_request_event_t>(event);
+    Window *window = new Window(setup, ev->window);
+    Box *box = new Box();
+    box->window = window;
+    setup->monitors[0].tagList[0].boxTree.insert(box);
     xcb_map_window(setup->conn, ev->window);
 }
 
     unsigned short i = 0;
     if (ev->value_mask & XCB_CONFIG_WINDOW_X)
     {
-                    mask |= XCB_CONFIG_WINDOW_X;
-                                values[i++] = ev->x;
+        mask |= XCB_CONFIG_WINDOW_X;
+        values[i++] = ev->x;
                                         
     }
 
 
 void EventHandler::handleUnmapNotify(EventPtr event)
 {
-
+    auto ev = convertEvent<xcb_unmap_notify_event_t>(event);
+    BoxTree &tree = setup->monitors[0].tagList[0].boxTree;
+    Box *winBox = tree.findWindowBox(ev->window);
+    if (winBox)
+    {
+        tree.remove(winBox);
+    }
 }
 
 void EventHandler::handleDestroyNotify(EventPtr event)
 {
-
+    auto ev = convertEvent<xcb_unmap_notify_event_t>(event);
+    BoxTree &tree = setup->monitors[0].tagList[0].boxTree;
+    Box *winBox = tree.findWindowBox(ev->window);
+    if (winBox)
+    {
+        tree.remove(winBox);
+    }
 }
 
 void EventHandler::handleEnterNotify(EventPtr event)
 {
-
+    auto ev = convertEvent<xcb_unmap_notify_event_t>(event);
+    BoxTree &tree = setup->monitors[0].tagList[0].boxTree;
+    Box *winBox = tree.findWindowBox(ev->event);
+    if(winBox)
+        tree.setFocused(winBox);
 }
         EventHandler handler(&setup);
         eventDispatch.setHandler("ConfigureRequest", std::bind(&EventHandler::handleConfigureRequest, &handler, std::placeholders::_1));
         eventDispatch.setHandler("MapRequest", std::bind(&EventHandler::handleMapRequest, &handler, std::placeholders::_1));
+        eventDispatch.setHandler("DestroyNotify", std::bind(&EventHandler::handleDestroyNotify, &handler, std::placeholders::_1));
+        eventDispatch.setHandler("UnmapNotify", std::bind(&EventHandler::handleUnmapNotify, &handler, std::placeholders::_1));
+        eventDispatch.setHandler("EnterNotify", std::bind(&EventHandler::handleEnterNotify, &handler, std::placeholders::_1));
         eventDispatch.eventLoop();
     }
     catch (OtherWindowManager &ex)