From 8321d6be46ed2df7dfe7ec142716a7d1a50d2d5e Mon Sep 17 00:00:00 2001 From: dranull <150595692+dranull@users.noreply.github.com> Date: Thu, 28 Dec 2023 22:54:41 +0000 Subject: [PATCH] internal: Unify input handling on decorations (#4280) * Unify input handling on decorations * Make input methods private * Optional data --- src/Window.cpp | 18 +++++ src/Window.hpp | 1 + src/layout/DwindleLayout.cpp | 12 +-- src/layout/IHyprLayout.cpp | 12 +-- src/layout/MasterLayout.cpp | 12 +-- src/managers/KeybindManager.cpp | 13 +--- src/managers/input/InputManager.cpp | 31 ++------ src/managers/input/InputManager.hpp | 8 ++ .../decorations/CHyprGroupBarDecoration.cpp | 76 +++++++++++++------ .../decorations/CHyprGroupBarDecoration.hpp | 11 +-- .../decorations/IHyprWindowDecoration.cpp | 12 +-- .../decorations/IHyprWindowDecoration.hpp | 7 +- 12 files changed, 104 insertions(+), 109 deletions(-) diff --git a/src/Window.cpp b/src/Window.cpp index 9df8ef69..75a1dc2a 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -222,6 +222,24 @@ void CWindow::removeWindowDeco(IHyprWindowDecoration* deco) { g_pLayoutManager->getCurrentLayout()->recalculateWindow(this); } +bool CWindow::checkInputOnDecos(const eInputType type, const Vector2D& mouseCoords, std::any data) { + if (type != INPUT_TYPE_DRAG_END && hasPopupAt(mouseCoords)) + return false; + + for (auto& wd : m_dWindowDecorations) { + if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT)) + continue; + + if (!g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(mouseCoords)) + continue; + + if (wd->onInputOnDeco(type, mouseCoords, data)) + return true; + } + + return false; +} + pid_t CWindow::getPID() { pid_t PID = -1; if (!m_bIsX11) { diff --git a/src/Window.hpp b/src/Window.hpp index f9d31ac3..d5de927b 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -348,6 +348,7 @@ class CWindow { void addWindowDeco(std::unique_ptr deco); void updateWindowDecos(); void removeWindowDeco(IHyprWindowDecoration* deco); + bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {}); pid_t getPID(); IHyprWindowDecoration* getDecorationByType(eDecorationType); void removeDecorationByType(eDecorationType); diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 63c2fec2..53ddb86e 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -316,16 +316,8 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire } if (!m_vOverrideFocalPoint && g_pInputManager->m_bWasDraggingWindow) { - for (auto& wd : OPENINGON->pWindow->m_dWindowDecorations) { - if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT)) - continue; - - if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(MOUSECOORDS)) { - if (!wd->onEndWindowDragOnDeco(pWindow, MOUSECOORDS)) - return; - break; - } - } + if (OPENINGON->pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, pWindow)) + return; } // if it's a group, add the window diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 0c6d24fd..76f1e796 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -271,16 +271,8 @@ void IHyprLayout::onEndDragWindow() { CWindow* pWindow = g_pCompositor->vectorToWindowIdeal(MOUSECOORDS, DRAGGINGWINDOW); if (pWindow && pWindow->m_bIsFloating) { - for (auto& wd : pWindow->m_dWindowDecorations) { - if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT)) - continue; - - if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(MOUSECOORDS)) { - if (!wd->onEndWindowDragOnDeco(DRAGGINGWINDOW, MOUSECOORDS)) - return; - break; - } - } + if (pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, DRAGGINGWINDOW)) + return; if (pWindow->m_sGroupData.pNextWindow && DRAGGINGWINDOW->canBeGroupedInto(pWindow)) { static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue; diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index def03236..65f85691 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -102,16 +102,8 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal(); if (g_pInputManager->m_bWasDraggingWindow && OPENINGON) { - for (auto& wd : OPENINGON->pWindow->m_dWindowDecorations) { - if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT)) - continue; - - if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(MOUSECOORDS)) { - if (!wd->onEndWindowDragOnDeco(pWindow, MOUSECOORDS)) - return; - break; - } - } + if (OPENINGON->pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, pWindow)) + return; } // if it's a group, add the window diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index d58aa8d8..23478a10 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1840,17 +1840,8 @@ void CKeybindManager::mouse(std::string args) { const auto mouseCoords = g_pInputManager->getMouseCoordsInternal(); CWindow* pWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords); - if (pWindow && !pWindow->m_bIsFullscreen && !pWindow->hasPopupAt(mouseCoords)) { - for (auto& wd : pWindow->m_dWindowDecorations) { - if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT)) - continue; - - if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(mouseCoords)) { - wd->onBeginWindowDragOnDeco(mouseCoords); - break; - } - } - } + if (pWindow && !pWindow->m_bIsFullscreen) + pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_START, mouseCoords); if (!g_pInputManager->currentlyDraggedWindow) g_pInputManager->currentlyDraggedWindow = pWindow; diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 157893d5..b36b7dbf 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -606,17 +606,8 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) { const auto mouseCoords = g_pInputManager->getMouseCoordsInternal(); const auto w = g_pCompositor->vectorToWindowIdeal(mouseCoords); - if (w && !w->m_bIsFullscreen && !m_bLastFocusOnLS && !w->hasPopupAt(mouseCoords)) { - for (auto& wd : w->m_dWindowDecorations) { - if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT)) - continue; - - if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(mouseCoords)) { - wd->onMouseButtonOnDeco(mouseCoords, e); - return; - } - } - } + if (w && !w->m_bIsFullscreen && !m_bLastFocusOnLS && w->checkInputOnDecos(INPUT_TYPE_BUTTON, mouseCoords, e)) + return; // clicking on border triggers resize // TODO detect click on LS properly @@ -624,6 +615,7 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) { if (w && !w->m_bIsFullscreen) { const CBox real = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y}; const CBox grab = {real.x - BORDER_GRAB_AREA, real.y - BORDER_GRAB_AREA, real.width + 2 * BORDER_GRAB_AREA, real.height + 2 * BORDER_GRAB_AREA}; + if ((grab.containsPoint(mouseCoords) && (!real.containsPoint(mouseCoords) || w->isInCurvedCorner(mouseCoords.x, mouseCoords.y))) && !w->hasPopupAt(mouseCoords)) { g_pKeybindManager->resizeWithBorder(e); return; @@ -686,8 +678,7 @@ void CInputManager::processMouseDownKill(wlr_pointer_button_event* e) { } void CInputManager::onMouseWheel(wlr_pointer_axis_event* e) { - static auto* const PSCROLLFACTOR = &g_pConfigManager->getConfigValuePtr("input:touchpad:scroll_factor")->floatValue; - static auto* const PGROUPBARSCROLLING = &g_pConfigManager->getConfigValuePtr("group:groupbar:scrolling")->intValue; + static auto* const PSCROLLFACTOR = &g_pConfigManager->getConfigValuePtr("input:touchpad:scroll_factor")->floatValue; auto factor = (*PSCROLLFACTOR <= 0.f || e->source != WLR_AXIS_SOURCE_FINGER ? 1.f : *PSCROLLFACTOR); @@ -702,18 +693,10 @@ void CInputManager::onMouseWheel(wlr_pointer_axis_event* e) { return; const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal(); - const auto pWindow = g_pCompositor->vectorToWindowIdeal(MOUSECOORDS); + const auto PWINDOW = g_pCompositor->vectorToWindowIdeal(MOUSECOORDS); - if (*PGROUPBARSCROLLING && pWindow && !pWindow->m_bIsFullscreen && !pWindow->hasPopupAt(MOUSECOORDS) && pWindow->m_sGroupData.pNextWindow) { - const CBox box = g_pDecorationPositioner->getWindowDecorationBox(pWindow->getDecorationByType(DECORATION_GROUPBAR)); - if (box.containsPoint(MOUSECOORDS)) { - if (e->delta > 0) - pWindow->setGroupCurrent(pWindow->m_sGroupData.pNextWindow); - else - pWindow->setGroupCurrent(pWindow->getGroupPrevious()); - return; - } - } + if (PWINDOW && PWINDOW->checkInputOnDecos(INPUT_TYPE_AXIS, MOUSECOORDS, e)) + return; wlr_seat_pointer_notify_axis(g_pCompositor->m_sSeat.seat, e->time_msec, e->orientation, factor * e->delta, std::round(factor * e->delta_discrete), e->source); } diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 5fa5824e..2b948bb4 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -32,6 +32,14 @@ enum eBorderIconDirection { BORDERICON_DOWN_RIGHT, }; +enum eInputType { + INPUT_TYPE_AXIS = 0, + INPUT_TYPE_BUTTON, + INPUT_TYPE_DRAG_START, + INPUT_TYPE_DRAG_END, + INPUT_TYPE_MOTION +}; + struct STouchData { CWindow* touchFocusWindow = nullptr; SLayerSurface* touchFocusLS = nullptr; diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 3bc819bf..9c785935 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -300,10 +300,35 @@ void refreshGroupBarGradients() { renderGradientTo(m_tGradientLockedInactive, ((CGradientValueData*)PGROUPCOLINACTIVELOCKED->get())->m_vColors[0]); } -bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D& pos) { +bool CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) { + const float BARRELATIVEX = pos.x - assignedBoxGlobal().x; + const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING); + if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth) + return false; + + CWindow* pWindow = m_pWindow->getGroupWindowByIndex(WINDOWINDEX); + + // hack + g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); + if (!pWindow->m_bIsFloating) { + const bool GROUPSLOCKEDPREV = g_pKeybindManager->m_bGroupsLocked; + g_pKeybindManager->m_bGroupsLocked = true; + g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow); + g_pKeybindManager->m_bGroupsLocked = GROUPSLOCKEDPREV; + } + + g_pInputManager->currentlyDraggedWindow = pWindow; + + if (!g_pCompositor->isWindowActive(pWindow)) + g_pCompositor->focusWindow(pWindow); + + return true; +} + +bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, CWindow* pDraggedWindow) { if (!pDraggedWindow->canBeGroupedInto(m_pWindow)) - return true; + return false; const float BARRELATIVEX = pos.x - assignedBoxGlobal().x - m_fBarWidth / 2; const int WINDOWINDEX = BARRELATIVEX < 0 ? -1 : (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING); @@ -357,12 +382,12 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(CWindow* pDraggedWindow, con if (!pDraggedWindow->getDecorationByType(DECORATION_GROUPBAR)) pDraggedWindow->addWindowDeco(std::make_unique(pDraggedWindow)); - return false; + return true; } -void CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_pointer_button_event* e) { +bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_pointer_button_event* e) { if (e->state != WLR_BUTTON_PRESSED) - return; + return false; const float BARRELATIVEX = pos.x - assignedBoxGlobal().x; const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING); @@ -370,7 +395,7 @@ void CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_point if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth) { if (!g_pCompositor->isWindowActive(m_pWindow)) g_pCompositor->focusWindow(m_pWindow); - return; + return true; } CWindow* pWindow = m_pWindow->getGroupWindowByIndex(WINDOWINDEX); @@ -380,30 +405,33 @@ void CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_point if (!g_pCompositor->isWindowActive(pWindow)) g_pCompositor->focusWindow(pWindow); + + return true; } -void CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) { - const float BARRELATIVEX = pos.x - assignedBoxGlobal().x; - const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING); +bool CHyprGroupBarDecoration::onScrollOnDeco(const Vector2D& pos, wlr_pointer_axis_event* e) { + static auto* const PGROUPBARSCROLLING = &g_pConfigManager->getConfigValuePtr("group:groupbar:scrolling")->intValue; - if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth) - return; - - CWindow* pWindow = m_pWindow->getGroupWindowByIndex(WINDOWINDEX); - - // hack - g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); - if (!pWindow->m_bIsFloating) { - const bool GROUPSLOCKEDPREV = g_pKeybindManager->m_bGroupsLocked; - g_pKeybindManager->m_bGroupsLocked = true; - g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow); - g_pKeybindManager->m_bGroupsLocked = GROUPSLOCKEDPREV; + if (!*PGROUPBARSCROLLING || !m_pWindow->m_sGroupData.pNextWindow) { + return false; } - g_pInputManager->currentlyDraggedWindow = pWindow; + if (e->delta > 0) + m_pWindow->setGroupCurrent(m_pWindow->m_sGroupData.pNextWindow); + else + m_pWindow->setGroupCurrent(m_pWindow->getGroupPrevious()); - if (!g_pCompositor->isWindowActive(pWindow)) - g_pCompositor->focusWindow(pWindow); + return true; +} + +bool CHyprGroupBarDecoration::onInputOnDeco(const eInputType type, const Vector2D& mouseCoords, std::any data) { + switch (type) { + case INPUT_TYPE_AXIS: return onScrollOnDeco(mouseCoords, std::any_cast(data)); + case INPUT_TYPE_BUTTON: return onMouseButtonOnDeco(mouseCoords, std::any_cast(data)); + case INPUT_TYPE_DRAG_START: return onBeginWindowDragOnDeco(mouseCoords); + case INPUT_TYPE_DRAG_END: return onEndWindowDragOnDeco(mouseCoords, std::any_cast(data)); + default: return false; + } } eDecorationLayer CHyprGroupBarDecoration::getDecorationLayer() { diff --git a/src/render/decorations/CHyprGroupBarDecoration.hpp b/src/render/decorations/CHyprGroupBarDecoration.hpp index a0242e2f..04f5123b 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.hpp +++ b/src/render/decorations/CHyprGroupBarDecoration.hpp @@ -35,11 +35,7 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration { virtual void damageEntire(); - virtual void onBeginWindowDragOnDeco(const Vector2D&); - - virtual bool onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&); - - virtual void onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*); + virtual bool onInputOnDeco(const eInputType, const Vector2D&, std::any = {}); virtual eDecorationLayer getDecorationLayer(); @@ -63,6 +59,11 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration { CBox assignedBoxGlobal(); + bool onBeginWindowDragOnDeco(const Vector2D&); + bool onEndWindowDragOnDeco(const Vector2D&, CWindow*); + bool onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*); + bool onScrollOnDeco(const Vector2D&, wlr_pointer_axis_event*); + struct STitleTexs { // STitleTexs* overriden = nullptr; // TODO: make shit shared in-group to decrease VRAM usage. std::deque> titleTexs; diff --git a/src/render/decorations/IHyprWindowDecoration.cpp b/src/render/decorations/IHyprWindowDecoration.cpp index 24acdc47..973f2700 100644 --- a/src/render/decorations/IHyprWindowDecoration.cpp +++ b/src/render/decorations/IHyprWindowDecoration.cpp @@ -8,16 +8,8 @@ IHyprWindowDecoration::IHyprWindowDecoration(CWindow* pWindow) { IHyprWindowDecoration::~IHyprWindowDecoration() {} -void IHyprWindowDecoration::onBeginWindowDragOnDeco(const Vector2D&) { - ; -} - -bool IHyprWindowDecoration::onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&) { - return true; -} - -void IHyprWindowDecoration::onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*) { - ; +bool IHyprWindowDecoration::onInputOnDeco(const eInputType, const Vector2D&, std::any) { + return false; } eDecorationLayer IHyprWindowDecoration::getDecorationLayer() { diff --git a/src/render/decorations/IHyprWindowDecoration.hpp b/src/render/decorations/IHyprWindowDecoration.hpp index 2203304b..b457adf4 100644 --- a/src/render/decorations/IHyprWindowDecoration.hpp +++ b/src/render/decorations/IHyprWindowDecoration.hpp @@ -2,6 +2,7 @@ #include "../../defines.hpp" #include "../../helpers/Region.hpp" +#include "../../managers/input/InputManager.hpp" #include "DecorationPositioner.hpp" enum eDecorationType { @@ -46,11 +47,7 @@ class IHyprWindowDecoration { virtual void damageEntire() = 0; // should be ignored by non-absolute decos - virtual void onBeginWindowDragOnDeco(const Vector2D&); // called when the user calls the "movewindow" mouse dispatcher on the deco - - virtual bool onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&); // returns true if the window should be placed by the layout - - virtual void onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*); + virtual bool onInputOnDeco(const eInputType, const Vector2D&, std::any = {}); virtual eDecorationLayer getDecorationLayer();