Commits

Micah Nordland committed f01b24c

changed window layout to dwm style master on left, with slave stack on
right, _NET_WM_STATE_FULLSCREEN is now supported, dialog and splash type
windows are now ignored ie they work like you'd expect.

Comments (0)

Files changed (12)

         uint32_t closeFocusedMods;
         xcb_keysym_t closeFocusedKey;
         
-        uint32_t exemptFocusedMods;
-        xcb_keysym_t exemptFocusedKey;            
-
         uint32_t fullscreenFocusedMods;
         xcb_keysym_t fullscreenFocusedKey;
         

include/monitor.h

 #include <vector>
 
 #include <xcb/xcb.h>
+#include <xcb/xcb_ewmh.h>
 
 #include "tag.h"
 
         void prevTag();
         void layoutWindows();
         bool focusWindow(xcb_window_t window);
-
+        void addStrut(xcb_ewmh_wm_strut_partial_t strut);
+        void removeStrut(xcb_ewmh_wm_strut_partial_t strut);
+    private:
+        xcb_rectangle_t totalArea;
+        void recalculateStruts();
+        std::vector<xcb_ewmh_wm_strut_partial_t> struts;
 };
 
 #endif //MONITOR_H
 #include <cstring>
 #include <string>
 #include <tuple>
+#include <map>
 
 #include <xcb/xcb.h>
 #include <xcb/xcb_ewmh.h>
         void layoutWindows();
         Monitor& getCurrentMonitor();
         void launchApp(std::string command);
-
+        xcb_atom_t getAtom(std::string atomName);
         xcb_connection_t *conn;
         xcb_ewmh_connection_t *ewmh;
         xcb_window_t root;
         xcb_screen_t *screen;
         xcb_cursor_context_t *cursorContext;
         std::vector<Monitor> monitors;
-
         int statusBarHeight = 20;
     
     private:
         bool getXrandrMonitors();
         void getMonitors();
-
         std::vector<std::string> tags;
         std::vector<Rule> windowRules;
+        std::map<std::string, xcb_atom_t> atoms;
 };
 
 #endif //SETUP_H
         Window();
         ~Window();
         xcb_window_t id;
-        bool exempt;
-        bool fullscreen;
         bool ignore;
+        bool haveStrut;
         std::string tagName;
         std::string name;
         StringPair wmClass;
         void handleTransient();
         void handleName();
         void handleClass();
+        void handleStrut();
+        void handleProtocols();
+        void handleState();
+        void handleType();
+        bool haveProto(std::string protocol);
+        bool haveState(std::string state);
+        void addState(std::string state);
+        void removeState(std::string state);
+        bool haveType(std::string type);
         void focus();
         void close();
         void stackAbove();
         void stackBelow();
+        void updateProperty(xcb_atom_t prop);
         void map();
         void unmap();
+        xcb_ewmh_wm_strut_partial_t strut;
         xcb_rectangle_t getGeometry();
         void setGeometry(xcb_rectangle_t rect);
         explicit operator bool() const
     private:
         Setup *setup;
         xcb_rectangle_t geometry;
+        std::vector<xcb_atom_t> protocols;
+        std::vector<xcb_atom_t> states;
+        std::vector<xcb_atom_t> types; 
         void sendTakeFocus();
         void sendConfigureNotify();
+        bool atomInList(std::vector<xcb_atom_t> list, std::string atom);
 
 };
 

include/windowContainer.h

         void focusWindow(Window window);
         void killFocused();
         void layoutWindows(xcb_rectangle_t area);
-        void addStack();
 		void lowerAll();
 		void raiseAll();
-        void toggleExemptFocused();
         void toggleFullscreenFocused();
-        std::pair<int, int> getFocusedIndex();
         Window invalidWin;
 
     private:
-        StackList stackList;
-        WindowList ignore;
-        std::pair<int, int> focused;
-        std::pair<int, int> lastFocused; 
-
+        WindowList windows;
+        int focused, lastFocused;
 };
 
 
     
     //This many tags per monitor:
 
-    tags = {"web", "term", "other", "skype"};
+    tags = {"web", "term", "other", "skype", "games"};
 
 
     /////////////////////////////////////////////
     closeFocusedMods = 0;
     closeFocusedKey = XK_x;
 
-    exemptFocusedMods = 0;
-    exemptFocusedKey = XK_e;
-
     fullscreenFocusedMods = 0;
     fullscreenFocusedKey = XK_f;
 
     WindowRule web{     "*",        "luakit",   "web",     false,   false};
     WindowRule skype{   "*",        "Skype",    "skype",   false,   false};
     WindowRule tray{    "*",     "stalonetray", "skype",   false,   true};
-
+    WindowRule portal{  "Portal-OpenGL", "*",   "games",   false,   false};
     //add your rules to the list
-    rules = {angel, windward, term, web, skype, tray};
+    rules = {angel, windward, term, web, skype, tray, portal};
 }
 
 Config::~Config()
         commandCallback = [&]{
             //set the status bar text
             for (auto& monitor: setup.monitors)
-                monitor.statusBar->setMode("[Command]"); 
+                monitor.statusBar->setMode(""); 
             //ungrab the command transition keybind
             keyHandler.ungrabKey(config.commandMods, config.commandKey, Press);
 
                 monitor.tagList.at(monitor.currentTag).windowContainer.killFocused();
             });
 
-            //Exempt focused window from tiling
-            keyHandler.grabKey(config.exemptFocusedMods, config.exemptFocusedKey, Press, [&]{
-                Monitor &monitor = setup.getCurrentMonitor();
-                monitor.tagList.at(monitor.currentTag).windowContainer.toggleExemptFocused();
-                monitor.tagList.at(monitor.currentTag).windowContainer.layoutWindows(monitor.area);
-
-                    });
             //Make focused window fullscreen
             keyHandler.grabKey(config.fullscreenFocusedMods, config.fullscreenFocusedKey, Press, [&]{
                 Monitor &monitor = setup.getCurrentMonitor();
 
         interactCallback = [&]{
             for (auto& monitor: setup.monitors)
-                monitor.statusBar->setMode("[--Interact--]"); 
+                monitor.statusBar->setMode("Interact"); 
             //Ungrab all command keybinds
             keyHandler.ungrabKey(config.interactMods, config.interactKey, Press);
             keyHandler.ungrabKey(config.quitMods, config.quitKey, Press);
             keyHandler.ungrabKey(config.closeFocusedMods, config.closeFocusedKey, Press);
-            keyHandler.ungrabKey(config.exemptFocusedMods, config.exemptFocusedKey, Press);
             keyHandler.ungrabKey(config.fullscreenFocusedMods, config.fullscreenFocusedKey, Press);
             keyHandler.ungrabKey(config.tagSwitchMods, config.nextTagKey, Press);
             keyHandler.ungrabKey(config.tagSwitchMods, config.prevTagKey, Press);
 
         commandCallback();
         eventDispatch.eventLoop();
-
+        xcb_ungrab_keyboard(setup.conn, XCB_CURRENT_TIME);
     }
     catch (SetupError &ex)
     {
         auto &win = tag.windowContainer.findWindow(window);
         if (win)
         {
-            std::cerr << "trying to focus " << win.name << std::endl;
             tag.windowContainer.focusWindow(win);
             currentTag = i;
             return true;
     }
     return false;
 }
+
+void Monitor::addStrut(xcb_ewmh_wm_strut_partial_t strut)
+{
+    //add strut to struts
+    //and then call recalculateStruts()
+}
+
+void Monitor::removeStrut(xcb_ewmh_wm_strut_partial_t strut)
+{
+    //remove strut from struts
+    //and then call recalculateStruts()
+    
+}
     screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
     root = screen->root;
     ewmh = ewmhInit(conn);
-
+    xcb_atom_t supported[] = {ewmh->_NET_WM_STATE, ewmh->_NET_WM_STRUT_PARTIAL};
+    xcb_ewmh_set_supported(ewmh, 0, 2, supported);
     cursorContext = cursorContextInit(conn, screen);
     if (not ewmh or not cursorContext)
     {
             xcb_randr_crtc_t *randrCRTCs = xcb_randr_get_screen_resources_crtcs(screenResReply);
             for (int i = 0; i < screenResReply->num_crtcs; i++)
             {
+                std::cout<<"got screen"<< std::endl;
                 auto crtcInfoCookie = xcb_randr_get_crtc_info(conn, randrCRTCs[i], XCB_CURRENT_TIME);
                 auto *crtcInfoReply = xcb_randr_get_crtc_info_reply(conn, crtcInfoCookie, nullptr);
                 if(!xcb_randr_get_crtc_info_outputs_length(crtcInfoReply))
         {
             std::cerr << win.name << std::endl;
             win.tagName = std::get<2>(rule);
-            win.exempt = std::get<3>(rule);
             win.ignore = std::get<4>(rule);
         }
     }
+    if (win.haveStrut)
+    {
+        monitor.addStrut(win.strut);
+        win.ignore = true;
+    }
+    if (win.transient or win.haveType("_NET_WM_WINDOW_TYPE_MODAL")
+        or win.haveType("_NET_WM_WINDOW_TYPE_DESKTOP")
+        or win.haveType("_NET_WM_WINDOW_TYPE_SPLASH")
+        or win.haveType("_NET_WM_WINDOW_TYPE_DIALOG"))
+    {
+        win.ignore = true;
+    }
 
     for (auto& tag : monitor.tagList)
         if (tag.name == win.tagName)
 
 void Setup::removeWindow(xcb_window_t window)
 {
+    std::cout << "setup::removeWindow" << std::endl;
     for (auto& monitor: monitors)
         for (auto& tag : monitor.tagList)
         {
             auto &win = tag.windowContainer.findWindow(window);
             if (win)
             {
+                std::cout << win.name << std::endl;
                 tag.windowContainer.removeWindow(win);
+                if (win.haveStrut)
+                    monitor.removeStrut(win.strut);
+                
                 return;
             }
            
 
 void Setup::layoutWindows()
 {
+    std::cout << "setup layoutWindows" << std::endl;
     for (auto &monitor : monitors)
     {
         monitor.layoutWindows();
 	}
 }
 
+xcb_atom_t Setup::getAtom(std::string atomName)
+{
+    xcb_intern_atom_reply_t *reply;
+    try
+    {
+       return atoms.at(atomName);
+    }
+    catch (std::out_of_range keyError)
+    {        
+        if ((reply = xcb_intern_atom_reply(conn, xcb_intern_atom_unchecked(conn, 
+                false, atomName.length(), atomName.c_str()), nullptr)))
+        {
+            atoms[atomName]=reply->atom;
+            free(reply);
+            return atoms.at(atomName);
+        }
+        else
+            return XCB_NONE;
+    }
+}
+

src/statusBar.cpp

             Cairo::TextExtents nameExtents;
             context->get_text_extents(name, nameExtents);
             context->rectangle(x-1, 0, nameExtents.x_advance+2,  15 + nameExtents.height);
-            context->set_source_rgb(0.31, 0.6, 0.795);
+            context->set_source_rgb(0.31, 0.7, 0.795);
             context->fill();
             context->set_source_rgb(0, 0, 0);
             context->move_to(x, y);
 
 Window::Window(Setup *setup, xcb_window_t id):
     id(id),
-    exempt(false),
-    fullscreen(false),
     ignore(false),
+    haveStrut(false),
     setup(setup)
 {
     inputHint = false;
     handleTransient();
     handleName();
     handleClass();
-
-    uint32_t event_mask[] = {XCB_EVENT_MASK_ENTER_WINDOW};
+    handleProtocols();
+    handleState();
+    handleType();
+    uint32_t event_mask[] = {XCB_EVENT_MASK_ENTER_WINDOW, XCB_EVENT_MASK_PROPERTY_CHANGE};
     xcb_change_window_attributes(setup->conn, id, XCB_CW_EVENT_MASK, event_mask);
     xcb_flush(setup->conn);
 }
     wmClass = std::make_pair("unknown", "unknown");
 }
 
+void Window::handleStrut()
+{
+    xcb_ewmh_wm_strut_partial_t tmpStrut;
+    auto cookie = xcb_ewmh_get_wm_strut_partial(setup->ewmh, id);
+    auto success = xcb_ewmh_get_wm_strut_partial_reply(setup->ewmh, cookie, &tmpStrut, nullptr);
+    if (success)
+    {
+        strut = tmpStrut;
+    }
+}
+
+void Window::handleProtocols()
+{
+    xcb_icccm_get_wm_protocols_reply_t protoReply;
+    auto success = xcb_icccm_get_wm_protocols_reply(setup->conn, 
+                       xcb_icccm_get_wm_protocols_unchecked(setup->conn, id, setup->ewmh->WM_PROTOCOLS),
+                            &protoReply, nullptr);
+    if (success)
+    {
+        protocols.assign(protoReply.atoms, protoReply.atoms+protoReply.atoms_len);
+    }
+
+}
+
+void Window::handleState()
+{
+    xcb_ewmh_get_atoms_reply_t reply;
+    auto cookie = xcb_ewmh_get_wm_state(setup->ewmh, id);
+    if (xcb_ewmh_get_wm_state_reply(setup->ewmh, cookie, &reply, nullptr))
+    {
+        states.assign(reply.atoms, reply.atoms+reply.atoms_len);
+    } 
+}
+
+void Window::addState(std::string state)
+{
+    if (haveState(state))
+        return;
+    states.push_back(setup->getAtom(state));
+    xcb_ewmh_set_wm_state(setup->ewmh, id, states.size(), &states[0]);
+}
+
+void Window::removeState(std::string state)
+{
+    auto atom = setup->getAtom(state);
+    for (auto iter = states.begin(); iter != states.end(); iter++)
+    {
+        if (*iter == atom)
+        {
+            states.erase(iter);
+            xcb_ewmh_set_wm_state(setup->ewmh, id, states.size(), &states[0]);
+            return;
+        }
+    }
+
+}
+void Window::handleType()
+{
+    xcb_ewmh_get_atoms_reply_t reply;
+    auto cookie = xcb_ewmh_get_wm_window_type(setup->ewmh, id);
+    if (xcb_ewmh_get_wm_window_type_reply(setup->ewmh, cookie, &reply, nullptr))
+    {
+        types.assign(reply.atoms, reply.atoms+reply.atoms_len);
+    } 
+}
+
+bool Window::haveProto(std::string protocol)
+{
+    return atomInList(protocols, protocol);
+}
+
+bool Window::haveState(std::string state)
+{
+    return atomInList(states, state);
+}
+
+bool Window::haveType(std::string type)
+{
+    return atomInList(types, type);
+}
+
+bool Window::atomInList(std::vector<xcb_atom_t> list, std::string atomString)
+{
+    auto atom = setup->getAtom(atomString);
+    for(auto iter = list.begin(); iter != list.end(); iter++)
+    {
+        if (*iter == atom)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
 void Window::focus()
 {
    if (takeFocus)   
 
 void Window::close()
 {
-    xcb_atom_t WM_DELETE_WINDOW;
-    std::string wmDelString = "WM_DELETE_WINDOW";
     xcb_client_message_event_t clientMessage;
-    xcb_intern_atom_reply_t *reply;
-    
-    if ((reply = xcb_intern_atom_reply(setup->conn, 
-        xcb_intern_atom_unchecked(setup->conn, false, wmDelString.length(), wmDelString.c_str()),
-        nullptr)))
+    xcb_atom_t wmDeleteAtom = setup->getAtom("WM_DELETE_WINDOW");
+    if (haveProto("WM_DELETE_WINDOW"))
     {
-        WM_DELETE_WINDOW = reply->atom;
-        free(reply);
+        clientMessage.response_type = XCB_CLIENT_MESSAGE;
+        clientMessage.window = id;
+        clientMessage.format = 32;
+        clientMessage.type = setup->ewmh->WM_PROTOCOLS;
+        clientMessage.data.data32[0] = wmDeleteAtom;
+        clientMessage.data.data32[1] = XCB_CURRENT_TIME;
+        xcb_send_event(setup->conn, false, id, XCB_EVENT_MASK_NO_EVENT, (char *) &clientMessage);
     }
     else
-        return;
-    xcb_icccm_get_wm_protocols_reply_t protoReply;
-    xcb_icccm_get_wm_protocols_reply(setup->conn, 
-    xcb_icccm_get_wm_protocols_unchecked(setup->conn, id, setup->ewmh->WM_PROTOCOLS),
-    &protoReply, nullptr);
-    if (protoReply.atoms_len>0)
-    {
-        for (int i = 0; i < protoReply.atoms_len; i++)
-            if (protoReply.atoms[i] == WM_DELETE_WINDOW)
-            {
-                clientMessage.response_type = XCB_CLIENT_MESSAGE;
-                clientMessage.window = id;
-                clientMessage.format = 32;
-                clientMessage.type = setup->ewmh->WM_PROTOCOLS;
-                clientMessage.data.data32[0] = WM_DELETE_WINDOW;
-                clientMessage.data.data32[1] = XCB_CURRENT_TIME;
-                
-                xcb_send_event(setup->conn, false, id, XCB_EVENT_MASK_NO_EVENT, (char *) &clientMessage);
-                return;
-            }
-    }
-
-    xcb_kill_client(setup->conn, id);
+        xcb_kill_client(setup->conn, id);
 
 }
 
         or geometry.height != rect.height)
     {
         xcb_configure_window(setup->conn, id, 
-        XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_BORDER_WIDTH,
-        values);
+            XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH 
+            | XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_BORDER_WIDTH,
+            values);
         xcb_flush(setup->conn);
 
         if (geometry.width == rect.width and geometry.height == rect.height)
     return geometry;
 }
 
+void Window::updateProperty(xcb_atom_t prop)
+{
+    if (prop == setup->ewmh->WM_PROTOCOLS)
+        handleProtocols();
+    else if (prop == setup->getAtom("WM_TRANSIENT_FOR"))
+        handleTransient();
+    else if (prop == setup->getAtom("WM_HINTS"))
+        handleHints();
+    else if (prop == setup->getAtom("WM_NAME"))
+        handleName();
+    else if (prop == setup->getAtom("WM_CLASS"))
+        handleClass();
+    else if (prop == setup->ewmh->_NET_WM_STATE)
+        handleState();
+    else if (prop == setup->ewmh->_NET_WM_STRUT_PARTIAL)
+        handleStrut();
+    else if (prop == setup->ewmh->_NET_WM_WINDOW_TYPE)
+        handleType();
+
+}
+
 void Window::map()
 {
     xcb_map_window(setup->conn, id);
 void Window::unmap()
 {
     xcb_unmap_window(setup->conn, id);
+    std::cout << name << " unmapped!" << std::endl;
 }
 
 void Window::sendTakeFocus()
 {
-    xcb_atom_t WM_TAKE_FOCUS;
-    std::string wmTakeString = "WM_TAKE_FOCUS";
+    xcb_atom_t WM_TAKE_FOCUS = setup->getAtom("WM_TAKE_FOCUS");
     xcb_client_message_event_t clientMessage;
-    xcb_intern_atom_reply_t *reply;
-
-    if ((reply = xcb_intern_atom_reply(setup->conn, 
-        xcb_intern_atom_unchecked(setup->conn, false, wmTakeString.length(), wmTakeString.c_str()),
-        nullptr)))
-    {
-        WM_TAKE_FOCUS = reply->atom;
-        free(reply);
+    if (WM_TAKE_FOCUS != XCB_NONE)
+    {            
+        clientMessage.response_type = XCB_CLIENT_MESSAGE;
+        clientMessage.window = id;
+        clientMessage.format = 32;
+        clientMessage.data.data32[1] = XCB_CURRENT_TIME;
+        clientMessage.type = setup->ewmh->WM_PROTOCOLS;
+        clientMessage.data.data32[0] = WM_TAKE_FOCUS;
+        xcb_send_event(setup->conn, false, id,
+            XCB_EVENT_MASK_NO_EVENT, (char *) &clientMessage);
     }
-    else
-        return;
-
-    clientMessage.response_type = XCB_CLIENT_MESSAGE;
-    clientMessage.window = id;
-    clientMessage.format = 32;
-    clientMessage.data.data32[1] = XCB_CURRENT_TIME;
-    clientMessage.type = setup->ewmh->WM_PROTOCOLS;
-    clientMessage.data.data32[0] = WM_TAKE_FOCUS;
-        
-    xcb_send_event(setup->conn, false, id,
-                    XCB_EVENT_MASK_NO_EVENT, (char *) &clientMessage);
 }
 
 void Window::sendConfigureNotify()

src/windowContainer.cpp

 #include "windowContainer.h"
 
-WindowContainer::WindowContainer()
+WindowContainer::WindowContainer():
+    focused(0),
+    lastFocused(0)
 {
-    focused = std::make_pair(0,0);
-    lastFocused = focused;
-    WindowList stack1;
-    WindowList stack2;
-    stackList.push_back(stack1);
-    stackList.push_back(stack2);
-    std::cout << stackList.size() << std::endl;
 }
 
 WindowContainer::~WindowContainer()
 
 void WindowContainer::addWindow(Window window)
 {
-    if (window.ignore)
-    {
-        ignore.push_back(window);
-        return;
-    }
-        for (auto& stack : stackList)
-    {
-        if (stack.empty())
-        {
-            stack.push_back(window);
-            return;
-        }
-    }
-    auto& stack = stackList.at(focused.first);
-    stack.insert(stack.begin() + focused.second, window);
-
+    windows.insert(windows.begin() + focused, window);
 }
 
 bool WindowContainer::removeWindow(Window window)
 {
-    for (auto& stack : stackList)
+    for (auto iter = windows.begin(); iter != windows.end(); iter++)
     {
-        for (auto iter = stack.begin(); iter != stack.end(); iter++)
+        if (iter->id == window.id)
         {
-            if (iter->id == window.id)
-            {
-                stack.erase(iter);
-                return true;
-            }
+            windows.erase(iter);
+            return true;
         }
     }
     return false;
 
 void WindowContainer::focusWindow(Window window)
 {
+    
+    window.focus();
+    try 
+    {
+        if (windows.at(focused).id == window.id)
+            return; 
+        lastFocused = focused;
 
-    window.focus();
-    if (stackList[focused.first][focused.second].id == window.id)
-        return; 
-    lastFocused = focused;
-    WindowList stack;
-    
-    for(int i = 0; i<stackList.size(); i++)
+        for (int j = 0; j < windows.size(); j++)
+        {
+            if (windows.at(j).id == window.id)
+            {
+                focused = j;
+                return;
+            }
+        
+        }
+    }
+    catch(std::out_of_range &e)
     {
-        stack = stackList.at(i); 
-        for (int j = 0; j < stack.size(); j++)
-        {
-             if (stack.at(j).id == window.id)
-             {
-                 focused = std::make_pair(i,j);
-                 return;
-             }
-        }
+        focused = 0;
     }
 }
 
 
 Window& WindowContainer::findWindow(xcb_window_t winId)
 {
-    for (auto& stack : stackList)
+    for (auto& win : windows)
     {
-        for (auto& win : stack)
-        {
-            if (win.id == winId)
-                return win;
-        }
+
+        if (win.id == winId)
+            return win;
+
     }
     return invalidWin;
 }
 {
     try
     {
-       Window &win = stackList.at(focused.first).at(focused.second);
+       Window &win = windows.at(focused);
     
         win.close();
         focused = lastFocused;
-        lastFocused = std::make_pair(0,0);
+        lastFocused = 0;
+
     }
     catch (std::out_of_range &e)
     {
 
 void WindowContainer::layoutWindows(xcb_rectangle_t area)
 {
-    xcb_rectangle_t rect = area;
-    xcb_rectangle_t temp;
-
-    int stackNum = stackList.size();
-    for (auto& stack : stackList)
+    xcb_rectangle_t slave, *rect, master;
+    slave = master = area;
+    bool firstTime = true;
+    int winNum = 0;
+    for (auto &win:windows)
+        if (not win.ignore)
+            winNum++;
+    if (winNum > 1 )
+    { 
+        master.width = master.width/2;
+        slave.width = master.width;
+        slave.x += slave.width;
+        slave.height = slave.height/(windows.size()-1);
+    }
+    rect = &master;
+    for (auto &win : windows)
     {
-        if (stack.empty())
-        {
-            stackNum--;
-        }
-    }
-
-    if (stackNum == 0)
-        return;
-
-    
-    rect.width = rect.width/stackNum;
-    rect.y = rect.y + 1;
-    lowerAll();
-    
-    for (auto& stack : stackList)
-    {
-        if (stack.empty())
+        if (win.ignore)
         {
             continue;
         }
-        temp = rect;
-        temp.height = temp.height/stack.size();
-
-        for (auto& win : stack)
+        if (win.haveState("_NET_WM_STATE_FULLSCREEN"))
         {
-            if (win.exempt)
-            {
-                xcb_rectangle_t exemptRect = win.getGeometry();
-                exemptRect.y = rect.y;
-                exemptRect.x = rect.x;
-                win.setGeometry(exemptRect);
-
-                win.setGeometry(temp);
-                temp.y += temp.height;
-            }
-            if (win.fullscreen)
-            {
-                win.setGeometry(area);
-                win.stackAbove();
-            }
-            if (not win.fullscreen and not win.exempt)
-            {
-                win.setGeometry(temp);
-                temp.y += temp.height;
-            }
-
-        }
-        rect.x += rect.width;
-    }
-}
-
-void WindowContainer::addStack()
-{
-    stackList.push_back(WindowList());
-}
-
-void WindowContainer::raiseAll()
-{
-    for (auto &stack : stackList)
-    {
-        if (stack.empty())
-        {
-            continue;
-        }
-        for (auto &win : stack)
-        {
+            rect = &area;
             win.stackAbove();
         }
+        
+        win.setGeometry(*rect);
+
+        if (firstTime)
+        {
+            rect = &slave;
+            firstTime = false;
+        }
+        else
+        {
+            slave.y += slave.height;
+        }
+
     }
 }
 
 void WindowContainer::lowerAll()
 {
-    for (auto & stack : stackList)
+    for (auto &win : windows)
     {
-        if (stack.empty())
-        {
-            continue;
-        }
-        for (auto &win : stack)
+        if (not win.ignore)
         {
             win.stackBelow();
         }
     }
+}
+
+void WindowContainer::raiseAll()
+{    
+    for (auto &win : windows)
+    {
+        if (not win.ignore)
+        {
+            win.stackAbove();
+        }
+    }
 
 }
 
-void WindowContainer::toggleExemptFocused()
-{
-    if (stackList.at(focused.first).empty())
-        return;
-
-    Window &win = stackList.at(focused.first).at(focused.second);
-    if (not win.exempt)
-        win.exempt = true;
-    else
-        win.exempt = false;
-}
-
 void WindowContainer::toggleFullscreenFocused()
 {
-    if (stackList.at(focused.first).empty())
-        return;
-
-    Window &win = stackList.at(focused.first).at(focused.second);
-    if (not win.fullscreen)
+    try
     {
-        win.fullscreen = true;
-        win.stackAbove();
+        auto &win = windows.at(focused);
+        if (win.haveState("_NET_WM_STATE_FULLSCREEN"))
+            win.removeState("_NET_WM_STATE_FULLSCREEN");
+        else
+            win.addState("_NET_WM_STATE_FULLSCREEN");
     }
-    else
+    catch(std::out_of_range &e)
     {
-        win.fullscreen = false; 
-        win.stackBelow();
+        std::cout << "got std::out_of_range " << std::endl;
     }
 }
 
-std::pair<int, int> WindowContainer::getFocusedIndex()
-{
-    return focused;
-}
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.