diff --git a/CMakeLists.txt b/CMakeLists.txt index 28620fc..2df541b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,10 @@ project(Hypr DESCRIPTION "A Modern OOP C++ Window Manager" ) +set(CMAKE_MESSAGE_LOG_LEVEL "STATUS") + +message(STATUS "Building Hypr!") + add_compile_options(-std=c++17) add_compile_options(-Wall -Wextra) find_package(Threads REQUIRED) @@ -15,6 +19,13 @@ file(GLOB_RECURSE SRCFILES "src/*.cpp") add_executable(Hypr ${SRCFILES}) +IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) + message(STATUS "Building Hypr in Debug with CMake!") +ELSE() + add_compile_options(-Ofast) + message(STATUS "Building Hypr in Release with CMake!") +ENDIF(CMAKE_BUILD_TYPE MATCHES DEBUG) + target_link_libraries(Hypr rt) set(CPACK_PROJECT_NAME ${PROJECT_NAME}) @@ -34,4 +45,10 @@ target_link_libraries(Hypr xcb-shape xcb-util ${CMAKE_THREAD_LIBS_INIT} -) \ No newline at end of file +) + +IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg -no-pie -fno-builtin") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg -no-pie -fno-builtin") + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg -no-pie -fno-builtin") +ENDIF(CMAKE_BUILD_TYPE MATCHES DEBUG OR CMAKE_BUILD_TYPE MATCHES DEBUG) \ No newline at end of file diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index b3a0264..812db85 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -461,14 +461,14 @@ void ConfigManager::tick() { } } -int ConfigManager::getInt(std::string_view v) { +int ConfigManager::getInt(std::string v) { return configValues[v].intValue; } -float ConfigManager::getFloat(std::string_view v) { +float ConfigManager::getFloat(std::string v) { return configValues[v].floatValue; } -std::string ConfigManager::getString(std::string_view v) { +std::string ConfigManager::getString(std::string v) { return configValues[v].strValue; } diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 2bd09cc..8ed21b3 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -2,6 +2,7 @@ #include #include "../utilities/Debug.hpp" +#include enum ELayouts { LAYOUT_DWINDLE = 0, @@ -15,7 +16,7 @@ struct SConfigValue { }; namespace ConfigManager { - inline std::map configValues; + inline std::unordered_map configValues; inline time_t lastModifyTime = 0; inline bool loadBar = false; @@ -32,7 +33,7 @@ namespace ConfigManager { void applyKeybindsToX(); - int getInt(std::string_view); - float getFloat(std::string_view); - std::string getString(std::string_view); + int getInt(std::string); + float getFloat(std::string); + std::string getString(std::string); }; \ No newline at end of file diff --git a/src/defines.hpp b/src/defines.hpp index 648f6e0..95a39b5 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "./helpers/Vector.hpp" #include "./utilities/Debug.hpp" @@ -41,8 +42,8 @@ private: \ type m_##prefix##var; \ public: \ - type get##var() { return this->m_##prefix##var; } \ - void set##var(type value) { this->m_##prefix##var = value; } + inline type get##var() { return m_##prefix##var; } \ + void set##var(type value) { m_##prefix##var = value; } #define EVENT(name) \ diff --git a/src/window.cpp b/src/window.cpp index ccdd7f4..f4a29ed 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,7 +1,7 @@ #include "window.hpp" #include "windowManager.hpp" -CWindow::CWindow() { this->setDock(false); this->setUnderFullscreen(false); this->setIsSleeping(true); this->setFirstAnimFrame(true); this->setIsAnimated(false); this->setDead(false); this->setMasterChildIndex(0); this->setMaster(false); this->setCanKill(false); this->setImmovable(false); this->setNoInterventions(false); this->setDirty(true); this->setFullscreen(false); this->setIsFloating(false); this->setParentNodeID(0); this->setChildNodeAID(0); this->setChildNodeBID(0); this->setName(""); } +CWindow::CWindow() { this->setLastUpdatePosition(Vector2D(0,0)); this->setLastUpdateSize(Vector2D(0,0)); this->setDock(false); this->setUnderFullscreen(false); this->setIsSleeping(true); this->setFirstAnimFrame(true); this->setIsAnimated(false); this->setDead(false); this->setMasterChildIndex(0); this->setMaster(false); this->setCanKill(false); this->setImmovable(false); this->setNoInterventions(false); this->setDirty(true); this->setFullscreen(false); this->setIsFloating(false); this->setParentNodeID(0); this->setChildNodeAID(0); this->setChildNodeBID(0); this->setName(""); } CWindow::~CWindow() { } void CWindow::generateNodeID() { diff --git a/src/window.hpp b/src/window.hpp index e87642f..d260916 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -49,6 +49,8 @@ public: EXPOSED_MEMBER(Position, Vector2D, vec); EXPOSED_MEMBER(RealSize, Vector2D, vec); EXPOSED_MEMBER(RealPosition, Vector2D, vec); + EXPOSED_MEMBER(LastUpdateSize, Vector2D, vec); + EXPOSED_MEMBER(LastUpdatePosition, Vector2D, vec); EXPOSED_MEMBER(IsFloating, bool, b); EXPOSED_MEMBER(Drawable, int64_t, i); // int64_t because it's my internal ID system too. diff --git a/src/windowManager.cpp b/src/windowManager.cpp index 6384f54..127507b 100644 --- a/src/windowManager.cpp +++ b/src/windowManager.cpp @@ -331,6 +331,7 @@ void CWindowManager::cleanupUnusedWorkspaces() { } void CWindowManager::refreshDirtyWindows() { + const auto START = std::chrono::high_resolution_clock::now(); for(auto& window : windows) { if (window.getDirty()) { window.setDirty(false); @@ -351,12 +352,18 @@ void CWindowManager::refreshDirtyWindows() { // Move it to hades Values[0] = (int)1500000; // hmu when monitors actually have that many pixels Values[1] = (int)1500000; // and we are still using xorg =) - xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, Values); + if (VECTORDELTANONZERO(window.getLastUpdatePosition(), Vector2D(Values[0], Values[1]))) { + xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, Values); + window.setLastUpdatePosition(Vector2D(Values[0], Values[1])); + } // Set the size JIC. Values[0] = (int)window.getEffectiveSize().x; Values[1] = (int)window.getEffectiveSize().y; - xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, Values); + if (VECTORDELTANONZERO(window.getLastUpdateSize(), Vector2D(Values[0], Values[1]))) { + xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, Values); + window.setLastUpdateSize(Vector2D(Values[0], Values[1])); + } continue; } @@ -370,11 +377,17 @@ void CWindowManager::refreshDirtyWindows() { Values[0] = (int)MONITOR->vecSize.x; Values[1] = (int)MONITOR->vecSize.y; - xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, Values); + if (VECTORDELTANONZERO(window.getLastUpdateSize(), Vector2D(Values[0], Values[1]))) { + xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, Values); + window.setLastUpdateSize(Vector2D(Values[0], Values[1])); + } Values[0] = (int)MONITOR->vecPosition.x; Values[1] = (int)MONITOR->vecPosition.y; - xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, Values); + if (VECTORDELTANONZERO(window.getLastUpdatePosition(), Vector2D(Values[0], Values[1]))) { + xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, Values); + window.setLastUpdatePosition(Vector2D(Values[0], Values[1])); + } // Apply rounded corners, does all the checks inside applyShapeToWindow(&window); @@ -386,7 +399,10 @@ void CWindowManager::refreshDirtyWindows() { // I have added the bordersize vec2d before in the setEffectiveSizePosUsingConfig function. Values[0] = (int)window.getRealPosition().x - ConfigManager::getInt("border_size"); Values[1] = (int)window.getRealPosition().y - ConfigManager::getInt("border_size"); - xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, Values); + if (VECTORDELTANONZERO(window.getLastUpdatePosition(), Vector2D(Values[0], Values[1]))) { + xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, Values); + window.setLastUpdatePosition(Vector2D(Values[0], Values[1])); + } Values[0] = (int)ConfigManager::getInt("border_size"); xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_BORDER_WIDTH, Values); @@ -400,7 +416,10 @@ void CWindowManager::refreshDirtyWindows() { if (!window.getIsAnimated() || ConfigManager::getInt("anim:cheap") == 0) { Values[0] = (int)window.getRealSize().x; Values[1] = (int)window.getRealSize().y; - xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, Values); + if (VECTORDELTANONZERO(window.getLastUpdateSize(), Vector2D(Values[0], Values[1]))) { + xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, Values); + window.setLastUpdateSize(Vector2D(Values[0], Values[1])); + } window.setFirstAnimFrame(true); } @@ -410,15 +429,19 @@ void CWindowManager::refreshDirtyWindows() { if (window.getRealSize().x < window.getEffectiveSize().x || window.getRealSize().y < window.getEffectiveSize().y) { Values[0] = (int)window.getEffectiveSize().x; Values[1] = (int)window.getEffectiveSize().y; - xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, Values); + if (VECTORDELTANONZERO(window.getLastUpdateSize(), Vector2D(Values[0], Values[1]))) { + xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, Values); + window.setLastUpdateSize(Vector2D(Values[0], Values[1])); + } } } applyShapeToWindow(&window); + } } - Debug::log(LOG, "Refreshed dirty windows."); + Debug::log(LOG, "Refreshed dirty windows in " + std::to_string(std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - START).count()) + "us."); } void CWindowManager::setFocusedWindow(xcb_drawable_t window) { @@ -679,24 +702,29 @@ void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) { if (!pWindow || pWindow->getIsFloating()) return; + auto START = std::chrono::high_resolution_clock::now(); + const auto MONITOR = getMonitorFromWindow(pWindow); const auto BARHEIGHT = (MONITOR->ID == ConfigManager::getInt("bar:monitor") ? (ConfigManager::getInt("bar:enabled") == 1 ? ConfigManager::getInt("bar:height") : ConfigManager::parseError == "" ? 0 : ConfigManager::getInt("bar:height")) : 0); - // set some flags. const bool DISPLAYLEFT = STICKS(pWindow->getPosition().x, MONITOR->vecPosition.x); const bool DISPLAYRIGHT = STICKS(pWindow->getPosition().x + pWindow->getSize().x, MONITOR->vecPosition.x + MONITOR->vecSize.x); const bool DISPLAYTOP = STICKS(pWindow->getPosition().y, MONITOR->vecPosition.y); const bool DISPLAYBOTTOM = STICKS(pWindow->getPosition().y + pWindow->getSize().y, MONITOR->vecPosition.y + MONITOR->vecSize.y); - pWindow->setEffectivePosition(pWindow->getPosition() + Vector2D(ConfigManager::getInt("border_size"), ConfigManager::getInt("border_size"))); - pWindow->setEffectiveSize(pWindow->getSize() - (Vector2D(ConfigManager::getInt("border_size"), ConfigManager::getInt("border_size")) * 2)); + const auto BORDERSIZE = ConfigManager::getInt("border_size"); + const auto GAPSOUT = ConfigManager::getInt("gaps_out"); + const auto GAPSIN = ConfigManager::getInt("gaps_in"); - const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? ConfigManager::getInt("gaps_out") + MONITOR->vecReservedTopLeft.x : ConfigManager::getInt("gaps_in"), - DISPLAYTOP ? ConfigManager::getInt("gaps_out") + MONITOR->vecReservedTopLeft.y + BARHEIGHT : ConfigManager::getInt("gaps_in")); + pWindow->setEffectivePosition(pWindow->getPosition() + Vector2D(BORDERSIZE, BORDERSIZE)); + pWindow->setEffectiveSize(pWindow->getSize() - (Vector2D(BORDERSIZE, BORDERSIZE) * 2)); - const auto OFFSETBOTTOMRIGHT = Vector2D( DISPLAYRIGHT ? ConfigManager::getInt("gaps_out") + MONITOR->vecReservedBottomRight.x : ConfigManager::getInt("gaps_in"), - DISPLAYBOTTOM ? ConfigManager::getInt("gaps_out") + MONITOR->vecReservedBottomRight.y : ConfigManager::getInt("gaps_in")); + const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? GAPSOUT + MONITOR->vecReservedTopLeft.x : GAPSIN, + DISPLAYTOP ? GAPSOUT + MONITOR->vecReservedTopLeft.y + BARHEIGHT : GAPSIN); + + const auto OFFSETBOTTOMRIGHT = Vector2D( DISPLAYRIGHT ? GAPSOUT + MONITOR->vecReservedBottomRight.x : GAPSIN, + DISPLAYBOTTOM ? GAPSOUT + MONITOR->vecReservedBottomRight.y : GAPSIN); // do gaps, set top left pWindow->setEffectivePosition(pWindow->getEffectivePosition() + OFFSETTOPLEFT);