diff --git a/src/Window.cpp b/src/Window.cpp index 9cf59287..c7e9212f 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -381,3 +381,33 @@ void CWindow::updateDynamicRules() { applyDynamicRule(r); } } + +// check if the point is "hidden" under a rounded corner of the window +bool CWindow::isInCurvedCorner(double x, double y) { + static auto* const ROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue; + static auto* const BORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue; + + if (BORDERSIZE >= ROUNDING || ROUNDING == 0) + return false; + + // (x0, y0), (x0, y1), ... are the center point of rounding at each corner + double x0 = m_vRealPosition.vec().x + *ROUNDING; + double y0 = m_vRealPosition.vec().y + *ROUNDING; + double x1 = m_vRealPosition.vec().x + m_vRealSize.vec().x - *ROUNDING; + double y1 = m_vRealPosition.vec().y + m_vRealSize.vec().y - *ROUNDING; + + if (x < x0 && y < y0) { + return Vector2D{x0, y0}.distance(Vector2D{x, y}) > (double)*ROUNDING; + } + if (x > x1 && y < y0) { + return Vector2D{x1, y0}.distance(Vector2D{x, y}) > (double)*ROUNDING; + } + if (x < x0 && y > y1) { + return Vector2D{x0, y1}.distance(Vector2D{x, y}) > (double)*ROUNDING; + } + if (x > x1 && y > y1) { + return Vector2D{x1, y1}.distance(Vector2D{x, y}) > (double)*ROUNDING; + } + + return false; +} diff --git a/src/Window.hpp b/src/Window.hpp index 758acd4d..b3bf2c6a 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -218,6 +218,7 @@ class CWindow { bool isHidden(); void applyDynamicRule(const SWindowRule& r); void updateDynamicRules(); + bool isInCurvedCorner(double x, double y); private: // For hidden windows and stuff diff --git a/src/helpers/Vector2D.cpp b/src/helpers/Vector2D.cpp index 97a9685c..3ab3ce43 100644 --- a/src/helpers/Vector2D.cpp +++ b/src/helpers/Vector2D.cpp @@ -29,4 +29,10 @@ Vector2D Vector2D::floor() { Vector2D Vector2D::clamp(const Vector2D& min, const Vector2D& max) { return Vector2D(std::clamp(this->x, min.x, max.x == 0 ? INFINITY : max.x), std::clamp(this->y, min.y, max.y == 0 ? INFINITY : max.y)); -} \ No newline at end of file +} + +double Vector2D::distance(const Vector2D& other) { + double dx = x - other.x; + double dy = y - other.y; + return std::sqrt(dx * dx + dy * dy); +} diff --git a/src/helpers/Vector2D.hpp b/src/helpers/Vector2D.hpp index f2f47e6b..ff4ae499 100644 --- a/src/helpers/Vector2D.hpp +++ b/src/helpers/Vector2D.hpp @@ -39,7 +39,9 @@ class Vector2D { return Vector2D(this->x * a.x, this->y * a.y); } + double distance(const Vector2D& other); + Vector2D clamp(const Vector2D& min, const Vector2D& max = Vector2D()); Vector2D floor(); -}; \ No newline at end of file +}; diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index d68add70..37c55dbb 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -404,7 +404,8 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) { // check if clicked on gaps/border (borders are hard to click on, doesn't matter how thick it is) // TODO take curved corners into consideration const auto mouseCoords = g_pInputManager->getMouseCoordsInternal(); - if (wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && !wlr_box_contains_point(&real, mouseCoords.x, mouseCoords.y)) { + if (wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && + (!wlr_box_contains_point(&real, mouseCoords.x, mouseCoords.y) || w->isInCurvedCorner(mouseCoords.x, mouseCoords.y))) { g_pKeybindManager->onGapDragEvent(e); return; }