Commits

Micah Nordland committed 526b6aa

Some code clean up, xcursor support added, and exemption is now toggleable

  • Participants
  • Parent commits 8194afe

Comments (0)

Files changed (12)

 program_OBJS := $(program_C_OBJS) $(program_CXX_OBJS)
 program_INCLUDE_DIRS := include 
 program_LIBRARY_DIRS :=
-program_LIBRARIES := xcb xcb-util xcb-icccm xcb-ewmh xcb-keysyms xcb-randr
+program_LIBRARIES := xcb xcb-util xcb-icccm xcb-ewmh xcb-keysyms xcb-randr xcb-cursor
 CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir))  $(shell pkg-config --cflags cairomm-1.0) -std=c++11 -g
 LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir)) $(shell pkg-config --libs cairomm-1.0)
 LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library))

File include/ewmh.h

 #include <xcb/xcb_ewmh.h>
 
 xcb_ewmh_connection_t *ewmhInit(xcb_connection_t *conn);
+void ewmhDelete(xcb_ewmh_connection_t *ewmh);
 
 #endif //EWMH_H

File include/monitor.h

         int currentTag;
         xcb_rectangle_t area;
         StatusBar* statusBar;
+        void nextTag();
+        void prevTag();
+        void layoutWindows();
+        void focusWindow(xcb_window_t window);
 
 };
 

File include/setup.h

 #include <xcb/xcb.h>
 #include <xcb/xcb_ewmh.h>
 #include <xcb/randr.h>
+#include <xcb/xcb_cursor.h>
  
 #include "ewmh.h"
+#include "cursor.h"
 
 class Monitor;
 class StatusBar;
 class Window;
 
-struct OtherWindowManager: std::exception {
-      const char* what() const noexcept {return "couldn't grab substructure notify on the root window\n";}
+class SetupError: public std::exception
+{
+    public:
+        SetupError(const std::string m="Window Manager Error");
+        ~SetupError() noexcept;
+        const char* what();
+    private:
+        std::string msg;
 
 };
 
     public:
         Setup(std::vector<std::string> tags, std::vector<Rule> windowRules);
         ~Setup();
-        xcb_connection_t* conn;
-        xcb_ewmh_connection_t* ewmh;
-        xcb_window_t root;
-        xcb_screen_t *screen;
-        std::vector<Monitor> monitors;
-        int currentMonitor;
-
-        int statusBarHeight = 20;
-        std::vector<std::string> tags;
-        std::vector<Rule> windowRules;
-
         Window& findWindow(xcb_window_t window);
         void addWindow(xcb_window_t window);
         void addWindow(Window window);
         void removeWindow(xcb_window_t window);
         void removeWindow(Window window);
-        void focusWindow(xcb_window_t window);
         void layoutWindows();
         Monitor& getCurrentMonitor();
-        void nextTag();
-        void prevTag();
         void launchApp(std::string command);
 
+        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;
 };
 
 #endif //SETUP_H

File include/windowContainer.h

         void addStack();
 		void lowerAll();
 		void raiseAll();
-        void exemptFocused();
+        void toggleExemptFocused();
         Window invalidWin;
 
     private:

File src/config.cpp

 
     WindowRule term{    "*",   "Sakura",         "term",    false};
 
+    WindowRule web{    "*",   "luakit",         "web",    false};
+
     //add your rules to the list
-    rules = {windward, term};
+    rules = {windward, term, web};
 }
 
 Config::~Config()

File src/eventHandlers.cpp

 {
     auto ev = convertEvent<xcb_enter_notify_event_t>(event);
     std::cerr << "got EnterNotify" << std::endl;
-    setup->focusWindow(ev->event);
+    setup->getCurrentMonitor().focusWindow(ev->event);
 }
 
 void EventHandler::handleButtonPress(EventPtr event)

File src/ewmh.cpp

     xcb_ewmh_connection_t *ewmh = new xcb_ewmh_connection_t();
     if (xcb_ewmh_init_atoms_replies(ewmh, xcb_ewmh_init_atoms(conn, ewmh), nullptr))
         return ewmh;
-    
-    delete ewmh;
     return nullptr;
 }
+
+void ewmhDelete(xcb_ewmh_connection_t *ewmh)
+{
+    xcb_ewmh_connection_wipe(ewmh);
+}

File src/main.cpp

             //Exempt focused window from tiling
             keyHandler.grabKey(config.exemptFocusedMods, config.exemptFocusedKey, Press, [&]{
                 Monitor &monitor = setup.getCurrentMonitor();
-                monitor.tagList.at(monitor.currentTag).windowContainer.exemptFocused();
+                monitor.tagList.at(monitor.currentTag).windowContainer.toggleExemptFocused();
                     });
 
             //Tag keybinds
-            keyHandler.grabKey(config.tagSwitchMods, config.nextTagKey, Press, [&] {setup.nextTag();});
-            keyHandler.grabKey(config.tagSwitchMods, config.prevTagKey, Press, [&]{setup.prevTag();});
+            keyHandler.grabKey(config.tagSwitchMods, config.nextTagKey, Press, [&] {setup.getCurrentMonitor().nextTag();});
+            keyHandler.grabKey(config.tagSwitchMods, config.prevTagKey, Press, [&]{setup.getCurrentMonitor().prevTag();});
 
             //quit keybind
             keyHandler.grabKey(config.quitMods, config.quitKey, Press, [&]{eventDispatch.stop();});
         eventDispatch.eventLoop();
 
     }
-    catch (OtherWindowManager &ex)
+    catch (SetupError &ex)
     {
-        std::cout << "There is another window manager running; I can't do anything. Sorry!" << std::endl;
+        std::cerr << "Mirror has encountered an error:" << ex.what()  << std::endl;
         return 0;
     }
    return 0;

File src/monitor.cpp

     delete statusBar;
 }
 
+void Monitor::nextTag()
+{
+    xcb_rectangle_t rect = area;
+    rect.x = 0 - rect.width;
+    rect.y = 0 - rect.height;
+    tagList.at(currentTag).windowContainer.layoutWindows(rect);
+    currentTag++;
 
+    if (currentTag > tagList.size()-1)
+        currentTag = 0;
+
+    tagList.at(currentTag).windowContainer.layoutWindows(area);
+    tagList.at(currentTag).windowContainer.raiseAll();
+    statusBar->setText(tagList.at(currentTag).name);
+}
+
+void Monitor::prevTag()
+{
+    xcb_rectangle_t rect = area;
+    rect.x = 0 - rect.width;
+    rect.y = 0 - rect.height;
+    tagList.at(currentTag).windowContainer.layoutWindows(rect);
+    currentTag--;
+    if (currentTag < 0)
+    {
+        currentTag = tagList.size()-1;
+    }
+
+    tagList.at(currentTag).windowContainer.layoutWindows(area);
+    tagList.at(currentTag).windowContainer.raiseAll();
+    statusBar->setText(tagList.at(currentTag).name);
+
+}
+
+void Monitor::layoutWindows()
+{
+    tagList.at(currentTag).windowContainer.layoutWindows(area);
+    xcb_rectangle_t offscreenRect = area;
+    offscreenRect.y = 0 - area.height;
+    offscreenRect.x = 0 - area.width;
+    for (auto &tag : tagList)
+    {
+        if (tag.name == tagList.at(currentTag).name)
+        {
+            continue;
+        }
+        tag.windowContainer.layoutWindows(offscreenRect);
+    }
+}
+
+void Monitor::focusWindow(xcb_window_t window)
+{
+    int i=0;
+	for (auto& tag : tagList)
+    {
+        auto &win = tag.windowContainer.findWindow(window);
+        if (win)
+        {
+            tag.windowContainer.focusWindow(win);
+            currentTag = i;
+            return;
+        }
+		i++;
+    }
+}

File src/setup.cpp

 #include "statusBar.h"
 #include "window.h"
 
+SetupError::SetupError(const std::string m): msg(m)
+{
+}
+
+SetupError::~SetupError() noexcept
+{}
+
+const char* SetupError::what()
+{
+    return msg.c_str();
+}
+
 Setup::Setup(std::vector<std::string> tags, std::vector<Rule> windowRules):
     tags(tags),
     windowRules(windowRules)
     conn = xcb_connect(nullptr, nullptr);
     screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
     root = screen->root;
+    ewmh = ewmhInit(conn);
 
-    ewmh = ewmhInit(conn);
+    cursorContext = cursorContextInit(conn, screen);
+    if (not ewmh or not cursorContext)
+    {
+        throw SetupError("ewmh or xcb-cursor failed");
+    }
+    
+    setCursor(conn, cursorContext, root, "left_ptr");
     
     uint32_t event_mask[] = {XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
                                 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
     xcb_void_cookie_t checkCookie = xcb_change_window_attributes_checked(conn, root, XCB_CW_EVENT_MASK, event_mask);
     if (xcb_request_check(conn, checkCookie))
 	{
-        throw OtherWindowManager();                                                                                       
+        throw SetupError("Other Window Manager Running");                                                                                       
     }
     getMonitors();
     for (auto& monitor : monitors)
 
 Setup::~Setup()
 {
+    ewmhDelete(ewmh);
+    cursorContextDelete(cursorContext);
     xcb_disconnect(conn);
 }
 
     }
 }
 
-void Setup::removeWindow(Window window)
-{
-    for (auto& monitor: monitors)
-    {
-        for (auto& tag : monitor.tagList)
-        {
-            if (tag.windowContainer.removeWindow(window))
-                return;
-        }
-    }
-}
-
 void Setup::removeWindow(xcb_window_t window)
 {
     for (auto& monitor: monitors)
         }
 }
 
-void Setup::focusWindow(xcb_window_t window)
+void Setup::removeWindow(Window window)
 {
-    int i=0;
-    Monitor &monitor = getCurrentMonitor();
-	for (auto& tag : monitor.tagList)
+    for (auto& monitor: monitors)
     {
-        auto &win = tag.windowContainer.findWindow(window);
-        if (win)
+        for (auto& tag : monitor.tagList)
         {
-            tag.windowContainer.focusWindow(win);
-            monitor.currentTag = i;
-            return;
+            if (tag.windowContainer.removeWindow(window))
+                return;
         }
-		i++;
     }
 }
 
-
 void Setup::layoutWindows()
 {
-    Monitor &monitor = getCurrentMonitor();
-    monitor.tagList.at(monitor.currentTag).windowContainer.layoutWindows(monitor.area);
-    xcb_rectangle_t offscreenRect = monitor.area;
-    offscreenRect.y = 0 - monitor.area.height;
-    offscreenRect.x = 0 - monitor.area.width;
-    for (auto &tag : monitor.tagList)
+    for (auto &monitor : monitors)
     {
-        if (tag.name == monitor.tagList.at(monitor.currentTag).name)
-        {
-            continue;
-        }
-        tag.windowContainer.layoutWindows(offscreenRect);
+        monitor.layoutWindows();
     }
 }
 
+
 Monitor& Setup::getCurrentMonitor()
 {
     int x = 0;
     return monitors.at(0);
 }
 
-void Setup::nextTag()
-{
-	Monitor &monitor = getCurrentMonitor();
-    xcb_rectangle_t rect = monitor.area;
-    rect.x = 0 - rect.width;
-    rect.y = 0 - rect.height;
-    monitor.tagList.at(monitor.currentTag).windowContainer.layoutWindows(rect);
-	monitor.currentTag++;
-
-	if (monitor.currentTag > monitor.tagList.size()-1)
-		monitor.currentTag = 0;
-
-    monitor.tagList.at(monitor.currentTag).windowContainer.layoutWindows(monitor.area);
-    monitor.tagList.at(monitor.currentTag).windowContainer.raiseAll();
-    monitor.statusBar->setText(monitor.tagList.at(monitor.currentTag).name);
-}
-
-void Setup::prevTag()
-{
-	Monitor &monitor = getCurrentMonitor();
-    xcb_rectangle_t rect = monitor.area;
-    rect.x = 0 - rect.width;
-    rect.y = 0 - rect.height;
-    monitor.tagList.at(monitor.currentTag).windowContainer.layoutWindows(rect);
-	monitor.currentTag--;
-	if (monitor.currentTag < 0)
-	{
-		monitor.currentTag = monitor.tagList.size()-1;
-	}
-
-    monitor.tagList.at(monitor.currentTag).windowContainer.layoutWindows(monitor.area);
-    monitor.tagList.at(monitor.currentTag).windowContainer.raiseAll();
-    monitor.statusBar->setText(monitor.tagList.at(monitor.currentTag).name);
-
-}
 
 void Setup::launchApp(std::string command)
 {
 		std::cerr << "The first fork failed when trying to launch " << command << std::endl;
 	}
 }
+

File src/windowContainer.cpp

             return;
         }
     }
-    auto& stack = stackList[focused.first];
+    auto& stack = stackList.at(focused.first);
     stack.insert(stack.begin() + focused.second, window);
 
 }
             if (iter->id == window.id)
             {
                 stack.erase(iter);
-                std::cout << stackList.size() << std::endl;
                 return true;
             }
         }
 void WindowContainer::focusWindow(Window window)
 {
 
-    std::cout << "running focusWindow" << std::endl;
     window.focus();
     if (stackList[focused.first][focused.second].id == window.id)
         return; 
 
 }
 
-void WindowContainer::exemptFocused()
+void WindowContainer::toggleExemptFocused()
 {
     if (stackList.at(focused.first).empty())
         return;
 
     Window &win = stackList.at(focused.first).at(focused.second);
-    win.exempt = true;
+    if (not win.exempt)
+        win.exempt = true;
+    else
+        win.exempt = false;
 
 }