diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 52e2f6ad..18bdaaab 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -608,8 +608,8 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) { // special workspace if (PMONITOR->specialWorkspaceID) { for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { - wlr_box box = {(*w)->m_vRealPosition.vec().x - BORDER_GRAB_AREA, (*w)->m_vRealPosition.vec().y - BORDER_GRAB_AREA, (*w)->m_vRealSize.vec().x + 2 * BORDER_GRAB_AREA, - (*w)->m_vRealSize.vec().y + 2 * BORDER_GRAB_AREA}; + const auto BB = w->get()->getWindowInputBox(); + wlr_box box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA}; if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == PMONITOR->specialWorkspaceID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->isHidden() && !(*w)->m_bX11ShouldntFocus) return (*w).get(); @@ -625,8 +625,8 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) { // pinned windows on top of floating regardless for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { - wlr_box box = {(*w)->m_vRealPosition.vec().x - BORDER_GRAB_AREA, (*w)->m_vRealPosition.vec().y - BORDER_GRAB_AREA, (*w)->m_vRealSize.vec().x + 2 * BORDER_GRAB_AREA, - (*w)->m_vRealSize.vec().y + 2 * BORDER_GRAB_AREA}; + const auto BB = w->get()->getWindowInputBox(); + wlr_box box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA}; if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && !(*w)->isHidden() && !(*w)->m_bX11ShouldntFocus && (*w)->m_bPinned) { if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y)) return w->get(); @@ -640,8 +640,8 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) { // first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter. for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { - wlr_box box = {(*w)->m_vRealPosition.vec().x - BORDER_GRAB_AREA, (*w)->m_vRealPosition.vec().y - BORDER_GRAB_AREA, (*w)->m_vRealSize.vec().x + 2 * BORDER_GRAB_AREA, - (*w)->m_vRealSize.vec().y + 2 * BORDER_GRAB_AREA}; + const auto BB = w->get()->getWindowInputBox(); + wlr_box box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA}; if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->isHidden() && !(*w)->m_bPinned) { // OR windows should add focus to parent if ((*w)->m_bX11ShouldntFocus && (*w)->m_iX11Type != 2) diff --git a/src/Window.cpp b/src/Window.cpp index e06c3d3a..1c3d0338 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -88,6 +88,43 @@ wlr_box CWindow::getWindowIdealBoundingBoxIgnoreReserved() { return wlr_box{(int)POS.x, (int)POS.y, (int)SIZE.x, (int)SIZE.y}; } +wlr_box CWindow::getWindowInputBox() { + static auto* const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue; + + if (m_sAdditionalConfigData.dimAround) { + const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); + return {PMONITOR->vecPosition.x, PMONITOR->vecPosition.y, PMONITOR->vecSize.x, PMONITOR->vecSize.y}; + } + + SWindowDecorationExtents maxExtents = {{*PBORDERSIZE + 2, *PBORDERSIZE + 2}, {*PBORDERSIZE + 2, *PBORDERSIZE + 2}}; + + for (auto& wd : m_dWindowDecorations) { + + if (!wd->allowsInput()) + continue; + + const auto EXTENTS = wd->getWindowDecorationExtents(); + + if (EXTENTS.topLeft.x > maxExtents.topLeft.x) + maxExtents.topLeft.x = EXTENTS.topLeft.x; + + if (EXTENTS.topLeft.y > maxExtents.topLeft.y) + maxExtents.topLeft.y = EXTENTS.topLeft.y; + + if (EXTENTS.bottomRight.x > maxExtents.bottomRight.x) + maxExtents.bottomRight.x = EXTENTS.bottomRight.x; + + if (EXTENTS.bottomRight.y > maxExtents.bottomRight.y) + maxExtents.bottomRight.y = EXTENTS.bottomRight.y; + } + + // Add extents to the real base BB and return + wlr_box finalBox = {m_vRealPosition.vec().x - maxExtents.topLeft.x, m_vRealPosition.vec().y - maxExtents.topLeft.y, + m_vRealSize.vec().x + maxExtents.topLeft.x + maxExtents.bottomRight.x, m_vRealSize.vec().y + maxExtents.topLeft.y + maxExtents.bottomRight.y}; + + return finalBox; +} + SWindowDecorationExtents CWindow::getFullWindowReservedArea() { SWindowDecorationExtents extents; diff --git a/src/Window.hpp b/src/Window.hpp index bc81e60a..85144e27 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -288,6 +288,7 @@ class CWindow { // methods wlr_box getFullWindowBoundingBox(); + wlr_box getWindowInputBox(); wlr_box getWindowIdealBoundingBoxIgnoreReserved(); void updateWindowDecos(); pid_t getPID(); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 70b42be3..7fd186c0 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -302,6 +302,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { m_pFoundSurfaceToFocus = foundSurface; } + if (currentlyDraggedWindow && !refocus) + return; + if (pFoundWindow) { // change cursor icon if hovering over border if (*PRESIZEONBORDER && *PRESIZECURSORICON && !pFoundWindow->m_bIsFullscreen && !pFoundWindow->hasPopupAt(mouseCoords)) { @@ -374,6 +377,9 @@ void CInputManager::onMouseButton(wlr_pointer_button_event* e) { std::erase_if(m_lCurrentlyHeldButtons, [&](const auto& other) { return other == e->button; }); } + if (currentlyDraggedWindow) + return; + switch (m_ecbClickBehavior) { case CLICKMODE_DEFAULT: processMouseDownNormal(e); break; case CLICKMODE_KILL: processMouseDownKill(e); break; diff --git a/src/render/decorations/IHyprWindowDecoration.cpp b/src/render/decorations/IHyprWindowDecoration.cpp index 1c1fe734..3ad5591f 100644 --- a/src/render/decorations/IHyprWindowDecoration.cpp +++ b/src/render/decorations/IHyprWindowDecoration.cpp @@ -7,3 +7,7 @@ IHyprWindowDecoration::~IHyprWindowDecoration() {} SWindowDecorationExtents IHyprWindowDecoration::getWindowDecorationReservedArea() { return SWindowDecorationExtents{}; } + +bool IHyprWindowDecoration::allowsInput() { + return false; +} \ No newline at end of file diff --git a/src/render/decorations/IHyprWindowDecoration.hpp b/src/render/decorations/IHyprWindowDecoration.hpp index f07746ef..a30d63b3 100644 --- a/src/render/decorations/IHyprWindowDecoration.hpp +++ b/src/render/decorations/IHyprWindowDecoration.hpp @@ -33,4 +33,6 @@ interface IHyprWindowDecoration { virtual void damageEntire() = 0; virtual SWindowDecorationExtents getWindowDecorationReservedArea(); + + virtual bool allowsInput(); }; \ No newline at end of file