From caa967a9b2e4adfa64bdba77eea195ad012c19f9 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Fri, 10 Dec 2021 21:55:41 +0100 Subject: [PATCH] Added border animations and better config warnings --- src/config/ConfigManager.cpp | 24 +++++++++++++--------- src/utilities/AnimationUtil.cpp | 17 ++++++++++++++++ src/utilities/Util.cpp | 18 +++++++++++++++++ src/utilities/Util.hpp | 36 +++++++++++++++++++++++++++++++++ src/window.hpp | 5 +++++ src/windowManager.cpp | 27 +++++++++++-------------- 6 files changed, 103 insertions(+), 24 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 1b08850..723f4c8 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -41,6 +41,7 @@ void ConfigManager::init() { configValues["anim:speed"].floatValue = 1; configValues["anim:enabled"].intValue = 0; configValues["anim:cheap"].intValue = 1; + configValues["anim:borders"].intValue = 1; if (!g_pWindowManager->statusBar) { isFirstLaunch = true; @@ -51,8 +52,10 @@ void ConfigManager::init() { } void configSetValueSafe(const std::string& COMMAND, const std::string& VALUE) { - if (ConfigManager::configValues.find(COMMAND) == ConfigManager::configValues.end()) + if (ConfigManager::configValues.find(COMMAND) == ConfigManager::configValues.end()) { + ConfigManager::parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field."; return; + } auto& CONFIGENTRY = ConfigManager::configValues.at(COMMAND); if (CONFIGENTRY.intValue != -1) { @@ -212,11 +215,13 @@ void parseBarLine(const std::string& line) { // And parse // check if command + const auto EQUALSPLACE = line.find_first_of('='); if (EQUALSPLACE == std::string::npos) return; + const auto COMMAND = line.substr(0, EQUALSPLACE); const auto VALUE = line.substr(EQUALSPLACE + 1); @@ -252,7 +257,7 @@ void parseLine(std::string& line) { // now, cut the comment off if (COMMENTSTART != std::string::npos) - line = line.substr(COMMENTSTART); + line = line.substr(COMMENTSTART + 1); // remove shit at the beginning while (line[0] == ' ' || line[0] == '\t') { @@ -300,8 +305,9 @@ void parseLine(std::string& line) { } else if (COMMAND == "exec") { handleRawExec(COMMAND, VALUE); return; - } else if (COMMAND == "exec-once" && ConfigManager::isFirstLaunch) { - handleRawExec(COMMAND, VALUE); + } else if (COMMAND == "exec-once") { + if (ConfigManager::isFirstLaunch) + handleRawExec(COMMAND, VALUE); return; } else if (COMMAND == "status_command") { handleStatusCommand(COMMAND, VALUE); @@ -351,14 +357,14 @@ void ConfigManager::loadConfigLoadVars() { } catch(...) { Debug::log(ERR, "Error reading line from config. Line:"); Debug::log(NONE, line); - + parseError = "Config error at line " + std::to_string(linenum) + ": Line parsing error."; - break; + //break; } - if (parseError != "") { + if (parseError != "" && parseError.find("Config error at line") != 0) { parseError = "Config error at line " + std::to_string(linenum) + ": " + parseError; - break; + //break; } ++linenum; @@ -462,4 +468,4 @@ float ConfigManager::getFloat(std::string_view v) { std::string ConfigManager::getString(std::string_view v) { return configValues[v].strValue; -} \ No newline at end of file +} diff --git a/src/utilities/AnimationUtil.cpp b/src/utilities/AnimationUtil.cpp index f0dcb1c..f069630 100644 --- a/src/utilities/AnimationUtil.cpp +++ b/src/utilities/AnimationUtil.cpp @@ -16,6 +16,23 @@ void AnimationUtil::move() { // check if window needs an animation. window.setIsAnimated(false); + // Border animations + if (window.getDrawable() > 0) { + if (window.getEffectiveBorderColor() != window.getRealBorderColor()) { + + // interp border color if enabled + if (ConfigManager::getInt("anim:borders") == 1) { + window.setRealBorderColor(parabolicColor(window.getRealBorderColor(), window.getEffectiveBorderColor(), ANIMATIONSPEED)); + } else { + window.setRealBorderColor(window.getEffectiveBorderColor()); + } + + updateRequired = true; + window.setDirty(true); + + } + } + if (ConfigManager::getInt("anim:enabled") == 0 || window.getIsFloating()) { // Disabled animations. instant warps. diff --git a/src/utilities/Util.cpp b/src/utilities/Util.cpp index 481eb4d..522cbb7 100644 --- a/src/utilities/Util.cpp +++ b/src/utilities/Util.cpp @@ -29,6 +29,24 @@ double parabolic(double from, double to, double incline) { return from + ((to - from) / incline); } +CFloatingColor parabolicColor(CFloatingColor from, uint32_t to, double incline) { + from.r = parabolic(from.r, RED(to) * 255.f, incline); + from.g = parabolic(from.g, GREEN(to) * 255.f, incline); + from.b = parabolic(from.b, BLUE(to) * 255.f, incline); + from.a = parabolic(from.a, ALPHA(to) * 255.f, incline); + + return from; +} + +CFloatingColor parabolicColor(CFloatingColor from, CFloatingColor to, double incline) { + from.r = parabolic(from.r, to.r, incline); + from.g = parabolic(from.g, to.g, incline); + from.b = parabolic(from.b, to.b, incline); + from.a = parabolic(from.a, to.a, incline); + + return from; +} + void emptyEvent(xcb_drawable_t window) { xcb_expose_event_t exposeEvent; exposeEvent.window = window; diff --git a/src/utilities/Util.hpp b/src/utilities/Util.hpp index ae50270..8181ce6 100644 --- a/src/utilities/Util.hpp +++ b/src/utilities/Util.hpp @@ -2,6 +2,39 @@ #include "../defines.hpp" #include +#include + +// For precise colors +class CFloatingColor { +public: + float r = 0; + float g = 0; + float b = 0; + float a = 255; + + uint32_t getAsUint32() { + return ((int)round(a)) * 0x1000000 + ((int)round(r)) * 0x10000 + ((int)round(g)) * 0x100 + ((int)round(b)); + } + + CFloatingColor(uint32_t c) { + r = RED(c) * 255.f; + g = GREEN(c) * 255.f; + b = BLUE(c) * 255.f; + a = ALPHA(c) * 255.f; + } + + CFloatingColor() { + ; + } + + bool operator==(CFloatingColor B) { + return r == B.r && g == B.g && b == B.b && a == B.a; + } + + bool operator!=(CFloatingColor B) { + return !(r == B.r && g == B.g && b == B.b && a == B.a); + } +}; std::string exec(const char* cmd); void clearLogs(); @@ -9,6 +42,9 @@ void emptyEvent(xcb_drawable_t window = 0); void wakeUpEvent(xcb_drawable_t window); bool xcbContainsAtom(xcb_get_property_reply_t* PROP, xcb_atom_t ATOM); +CFloatingColor parabolicColor(CFloatingColor from, uint32_t to, double incline); +CFloatingColor parabolicColor(CFloatingColor from, CFloatingColor to, double incline); + double parabolic(double from, double to, double incline); std::vector splitString(std::string, char); \ No newline at end of file diff --git a/src/window.hpp b/src/window.hpp index c970014..68ef9ce 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -2,6 +2,7 @@ #include "defines.hpp" #include "utilities/Workspace.hpp" +#include "utilities/Util.hpp" class CWindow { public: @@ -83,6 +84,10 @@ public: // Weird shenaningans EXPOSED_MEMBER(IsSleeping, bool, b); + // Animate borders + EXPOSED_MEMBER(RealBorderColor, CFloatingColor, c); + EXPOSED_MEMBER(EffectiveBorderColor, CFloatingColor, c); + private: }; \ No newline at end of file diff --git a/src/windowManager.cpp b/src/windowManager.cpp index 696959f..bbba999 100644 --- a/src/windowManager.cpp +++ b/src/windowManager.cpp @@ -366,7 +366,7 @@ void CWindowManager::refreshDirtyWindows() { Values[0] = 0; xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_BORDER_WIDTH, Values); - Values[0] = 0x555555; // GRAY :) + Values[0] = window.getRealBorderColor().getAsUint32(); xcb_change_window_attributes(DisplayConnection, window.getDrawable(), XCB_CW_BORDER_PIXEL, Values); const auto MONITOR = getMonitorFromWindow(&window); @@ -394,14 +394,10 @@ void CWindowManager::refreshDirtyWindows() { Values[0] = (int)ConfigManager::getInt("border_size"); xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_BORDER_WIDTH, Values); - // Focused special border. - if (window.getDrawable() == LastWindow) { - Values[0] = ConfigManager::getInt("col.active_border"); - xcb_change_window_attributes(DisplayConnection, window.getDrawable(), XCB_CW_BORDER_PIXEL, Values); - } else { - Values[0] = ConfigManager::getInt("col.inactive_border"); - xcb_change_window_attributes(DisplayConnection, window.getDrawable(), XCB_CW_BORDER_PIXEL, Values); - } + + // do border + Values[0] = window.getRealBorderColor().getAsUint32(); + xcb_change_window_attributes(DisplayConnection, window.getDrawable(), XCB_CW_BORDER_PIXEL, Values); // If it isn't animated or we have non-cheap animations, update the real size if (!window.getIsAnimated() || ConfigManager::getInt("anim:cheap") == 0) { @@ -430,12 +426,13 @@ void CWindowManager::refreshDirtyWindows() { void CWindowManager::setFocusedWindow(xcb_drawable_t window) { if (window && window != Screen->root) { - // Fix border from the old window that was in focus. - Values[0] = ConfigManager::getInt("col.inactive_border"); - xcb_change_window_attributes(DisplayConnection, LastWindow, XCB_CW_BORDER_PIXEL, Values); - - Values[0] = ConfigManager::getInt("col.active_border"); - xcb_change_window_attributes(DisplayConnection, window, XCB_CW_BORDER_PIXEL, Values); + // border color + if (const auto PLASTWIN = getWindowFromDrawable(LastWindow); PLASTWIN) { + PLASTWIN->setEffectiveBorderColor(CFloatingColor(ConfigManager::getInt("col.inactive_border"))); + } + if (const auto PLASTWIN = getWindowFromDrawable(window); PLASTWIN) { + PLASTWIN->setEffectiveBorderColor(CFloatingColor(ConfigManager::getInt("col.active_border"))); + } float values[1]; if (g_pWindowManager->getWindowFromDrawable(window) && g_pWindowManager->getWindowFromDrawable(window)->getIsFloating()) {