diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 1a6a470e..9bb82555 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -149,7 +149,8 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for PWINDOW->m_sSpecialRenderData.shadow = false; PWINDOW->m_vRealPosition = PWINDOW->m_vPosition + PWINDOW->m_seReservedInternal.topLeft + PWINDOW->m_seReservedExternal.topLeft; - PWINDOW->m_vRealSize = PWINDOW->m_vSize - (PWINDOW->m_seReservedInternal.topLeft + PWINDOW->m_seReservedInternal.bottomRight) - (PWINDOW->m_seReservedExternal.topLeft + PWINDOW->m_seReservedExternal.bottomRight); + PWINDOW->m_vRealSize = PWINDOW->m_vSize - (PWINDOW->m_seReservedInternal.topLeft + PWINDOW->m_seReservedInternal.bottomRight) - + (PWINDOW->m_seReservedExternal.topLeft + PWINDOW->m_seReservedExternal.bottomRight); PWINDOW->updateWindowDecos(); @@ -322,16 +323,21 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire m_lDwindleNodesData.remove(*PNODE); - const wlr_box box = OPENINGON->pWindow->getDecorationByType(DECORATION_GROUPBAR)->getWindowDecorationRegion().getExtents(); - if (wlr_box_contains_point(&box, MOUSECOORDS.x, MOUSECOORDS.y)) { // TODO: Deny when not using mouse - const int SIZE = OPENINGON->pWindow->getGroupSize(); - const int INDEX = (int)((MOUSECOORDS.x - box.x) * 2 * SIZE / box.width + 1) / 2 - 1; - CWindow* pWindowInsertAfter = OPENINGON->pWindow->getGroupWindowByIndex(INDEX); - pWindowInsertAfter->insertWindowToGroup(pWindow); - if (INDEX == -1) - std::swap(pWindow->m_sGroupData.pNextWindow->m_sGroupData.head, pWindow->m_sGroupData.head); - } else { - static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("misc:group_insert_after_current")->intValue; + bool handled = true; + + for (auto& wd : OPENINGON->pWindow->m_dWindowDecorations) { + if (!wd->allowsInput()) + continue; + + if (wd->getWindowDecorationRegion().containsPoint(MOUSECOORDS)) { + wd->dragWindowToDecoration(pWindow, MOUSECOORDS); + handled = false; + break; + } + } + + if (handled) { + static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue; (*USECURRPOS ? OPENINGON->pWindow : OPENINGON->pWindow->getGroupTail())->insertWindowToGroup(pWindow); } @@ -340,6 +346,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire pWindow->updateWindowDecos(); recalculateWindow(pWindow); + g_pCompositor->focusWindow(pWindow); return; } diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index c5d4bfc6..d1795fc5 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -109,16 +109,21 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc m_lMasterNodesData.remove(*PNODE); - const wlr_box box = OPENINGON->pWindow->getDecorationByType(DECORATION_GROUPBAR)->getWindowDecorationRegion().getExtents(); - if (wlr_box_contains_point(&box, MOUSECOORDS.x, MOUSECOORDS.y)) { // TODO: Deny when not using mouse - const int SIZE = OPENINGON->pWindow->getGroupSize(); - const int INDEX = (int)((MOUSECOORDS.x - box.x) * 2 * SIZE / box.width + 1) / 2 - 1; - CWindow* pWindowInsertAfter = OPENINGON->pWindow->getGroupWindowByIndex(INDEX); - pWindowInsertAfter->insertWindowToGroup(pWindow); - if (INDEX == -1) - std::swap(pWindow->m_sGroupData.pNextWindow->m_sGroupData.head, pWindow->m_sGroupData.head); - } else { - static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("misc:group_insert_after_current")->intValue; + bool handled = true; + + for (auto& wd : OPENINGON->pWindow->m_dWindowDecorations) { + if (!wd->allowsInput()) + continue; + + if (wd->getWindowDecorationRegion().containsPoint(MOUSECOORDS)) { + wd->dragWindowToDecoration(pWindow, MOUSECOORDS); + handled = false; + break; + } + } + + if (handled) { + static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue; (*USECURRPOS ? OPENINGON->pWindow : OPENINGON->pWindow->getGroupTail())->insertWindowToGroup(pWindow); } @@ -127,6 +132,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc pWindow->updateWindowDecos(); recalculateWindow(pWindow); + g_pCompositor->focusWindow(pWindow); return; } @@ -625,7 +631,8 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { PWINDOW->m_sSpecialRenderData.shadow = false; PWINDOW->m_vRealPosition = PWINDOW->m_vPosition + PWINDOW->m_seReservedInternal.topLeft + PWINDOW->m_seReservedExternal.topLeft; - PWINDOW->m_vRealSize = PWINDOW->m_vSize - (PWINDOW->m_seReservedInternal.topLeft + PWINDOW->m_seReservedInternal.bottomRight) - (PWINDOW->m_seReservedExternal.topLeft + PWINDOW->m_seReservedExternal.bottomRight); + PWINDOW->m_vRealSize = PWINDOW->m_vSize - (PWINDOW->m_seReservedInternal.topLeft + PWINDOW->m_seReservedInternal.bottomRight) - + (PWINDOW->m_seReservedExternal.topLeft + PWINDOW->m_seReservedExternal.bottomRight); PWINDOW->updateWindowDecos(); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 436654fb..071afe4f 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1831,25 +1831,22 @@ 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) && pWindow->m_sGroupData.pNextWindow) { - const wlr_box box = pWindow->getDecorationByType(DECORATION_GROUPBAR)->getWindowDecorationRegion().getExtents(); - if (wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y)) { - const int SIZE = pWindow->getGroupSize(); - pWindow = pWindow->getGroupWindowByIndex((mouseCoords.x - box.x) * SIZE / box.width); + if (pWindow && !pWindow->m_bIsFullscreen && !pWindow->hasPopupAt(mouseCoords)) { + for (auto& wd : pWindow->m_dWindowDecorations) { + if (!wd->allowsInput()) + continue; - // 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 (wd->getWindowDecorationRegion().containsPoint(mouseCoords)) { + wd->dragFromDecoration(mouseCoords); + break; } } } - g_pInputManager->currentlyDraggedWindow = pWindow; - g_pInputManager->dragMode = MBIND_MOVE; + if (g_pInputManager->currentlyDraggedWindow == nullptr) + g_pInputManager->currentlyDraggedWindow = pWindow; + + g_pInputManager->dragMode = MBIND_MOVE; g_pLayoutManager->getCurrentLayout()->onBeginDragWindow(); } else { g_pKeybindManager->m_bIsMouseBindActive = false; diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index f79278e3..d04214f1 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -540,16 +540,16 @@ 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 && !w->hasPopupAt(mouseCoords) && w->m_sGroupData.pNextWindow) { - const wlr_box box = w->getDecorationByType(DECORATION_GROUPBAR)->getWindowDecorationRegion().getExtents(); - if (wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y)) { - if (e->state == WLR_BUTTON_PRESSED) { - const int SIZE = w->getGroupSize(); - CWindow* pWindow = w->getGroupWindowByIndex((mouseCoords.x - box.x) * SIZE / box.width); - if (w != pWindow) - w->setGroupCurrent(pWindow); + if (w && !w->m_bIsFullscreen && !w->hasPopupAt(mouseCoords)) { + for (auto& wd : w->m_dWindowDecorations) { + if (!wd->allowsInput()) + continue; + + if (wd->getWindowDecorationRegion().containsPoint(mouseCoords)) { + if (e->state == WLR_BUTTON_PRESSED) + wd->clickDecoration(mouseCoords); + return; } - return; } } diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index b2de3af4..a2a850ef 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -93,11 +93,11 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& const int ROUNDING = m_pWindow->getRealRounding(); const int BORDERSIZE = m_pWindow->getRealBorderSize(); - const float BARW = (m_vLastWindowSize.x - 2 * ROUNDING - BAR_HORIZONTAL_PADDING * (barsToDraw + (m_bInternalBar ? 1 : -1))) / barsToDraw; + m_fBarWidth = (m_vLastWindowSize.x - 2 * ROUNDING - BAR_HORIZONTAL_PADDING * (barsToDraw + 1)) / barsToDraw; - float currentOffset = m_bInternalBar ? BAR_HORIZONTAL_PADDING : 0; + float currentOffset = BAR_HORIZONTAL_PADDING; - if (BARW <= 0) + if (m_fBarWidth <= 0) return; // Bottom left of groupbar @@ -106,8 +106,8 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& std::floor(m_vLastWindowPos.y) - pMonitor->vecPosition.y + offset.y + (m_bOnTop ? (m_bInternalBar ? 0 : -BORDERSIZE) : std::floor(m_vLastWindowSize.y) + m_iBarInternalHeight + BAR_INTERNAL_PADDING + (m_bInternalBar ? 0 : BORDERSIZE))); - wlr_box barBox = {pos.x, pos.y - m_iBarHeight + (m_bOnTop ? -BAR_INTERNAL_PADDING : 0), BARW, m_iBarHeight}; - wlr_box gradBox = {pos.x, pos.y - m_iBarHeight + (m_bOnTop ? -2 * BAR_INTERNAL_PADDING : -BAR_INTERNAL_PADDING) - m_iGradientHeight, BARW, m_iGradientHeight}; + wlr_box barBox = {pos.x, pos.y - m_iBarHeight + (m_bOnTop ? -BAR_INTERNAL_PADDING : 0), m_fBarWidth, m_iBarHeight}; + wlr_box gradBox = {pos.x, pos.y - m_iBarHeight + (m_bOnTop ? -2 * BAR_INTERNAL_PADDING : -BAR_INTERNAL_PADDING) - m_iGradientHeight, m_fBarWidth, m_iGradientHeight}; wlr_box textBox = m_iGradientHeight != 0 ? gradBox : barBox; textBox.y += BAR_TEXT_PAD; textBox.height -= 2 * BAR_TEXT_PAD; @@ -192,7 +192,7 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& &gradBox, 1.0); } - currentOffset += (float)(BAR_HORIZONTAL_PADDING + BARW) * pMonitor->scale; + currentOffset += (float)(BAR_HORIZONTAL_PADDING + m_fBarWidth) * pMonitor->scale; } if (*PRENDERTITLES) @@ -372,15 +372,72 @@ void CHyprGroupBarDecoration::forceReload(CWindow* pWindow) { } CRegion CHyprGroupBarDecoration::getWindowDecorationRegion() { - const int ROUNDING = m_pWindow->getRealRounding(); const int BORDERSIZE = m_pWindow->getRealBorderSize(); - return CRegion(m_vLastWindowPos.x + ROUNDING, + return CRegion(m_vLastWindowPos.x, m_vLastWindowPos.y + (m_bOnTop ? -BAR_INTERNAL_PADDING - m_iBarInternalHeight - (m_bInternalBar ? 0 : BORDERSIZE) : m_vLastWindowSize.y + BAR_INTERNAL_PADDING + (m_bInternalBar ? 0 : BORDERSIZE)), - m_vLastWindowSize.x - 2 * ROUNDING, m_iBarInternalHeight); + m_vLastWindowSize.x, m_iBarInternalHeight); } bool CHyprGroupBarDecoration::allowsInput() { return true; } + +void CHyprGroupBarDecoration::dragWindowToDecoration(CWindow* m_pDraggedWindow, const Vector2D& pos) { + const int ROUNDING = m_pWindow->getRealRounding(); + const float BARRELATIVEX = pos.x - (m_vLastWindowPos.x + ROUNDING) - (m_fBarWidth / 2 + BAR_HORIZONTAL_PADDING); + const int WINDOWINDEX = BARRELATIVEX < 0 ? -1 : (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING); + + CWindow* pWindowInsertAfter = m_pWindow->getGroupWindowByIndex(WINDOWINDEX); + + pWindowInsertAfter->insertWindowToGroup(m_pDraggedWindow); + + if (WINDOWINDEX == -1) + std::swap(m_pDraggedWindow->m_sGroupData.head, m_pDraggedWindow->m_sGroupData.pNextWindow->m_sGroupData.head); +} + +void CHyprGroupBarDecoration::clickDecoration(const Vector2D& pos) { + const int ROUNDING = m_pWindow->getRealRounding(); + const float BARRELATIVEX = pos.x - (m_vLastWindowPos.x + ROUNDING); + const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING); + + if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX < BAR_HORIZONTAL_PADDING) { + if (!g_pCompositor->isWindowActive(m_pWindow)) + g_pCompositor->focusWindow(m_pWindow); + return; + } + + CWindow* pWindow = m_pWindow->getGroupWindowByIndex(WINDOWINDEX); + + if (pWindow != m_pWindow) + pWindow->setGroupCurrent(pWindow); + + if (!g_pCompositor->isWindowActive(pWindow)) + g_pCompositor->focusWindow(pWindow); +} + +void CHyprGroupBarDecoration::dragFromDecoration(const Vector2D& pos) { + const int ROUNDING = m_pWindow->getRealRounding(); + const float BARRELATIVEX = pos.x - (m_vLastWindowPos.x + ROUNDING); + const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING); + + if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX < BAR_HORIZONTAL_PADDING) + 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; + } + + g_pInputManager->currentlyDraggedWindow = pWindow; + + if (!g_pCompositor->isWindowActive(pWindow)) + g_pCompositor->focusWindow(pWindow); +} diff --git a/src/render/decorations/CHyprGroupBarDecoration.hpp b/src/render/decorations/CHyprGroupBarDecoration.hpp index 9ef48139..7132cf3f 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.hpp +++ b/src/render/decorations/CHyprGroupBarDecoration.hpp @@ -37,6 +37,12 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration { virtual bool allowsInput(); + virtual void dragWindowToDecoration(CWindow*, const Vector2D&); + + virtual void clickDecoration(const Vector2D&); + + virtual void dragFromDecoration(const Vector2D&); + private: SWindowDecorationExtents m_seExtents; @@ -55,6 +61,8 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration { int m_iBarHeight; int m_iGradientHeight; + float m_fBarWidth; + CTitleTex* textureFromTitle(const std::string&); void invalidateTextures(); diff --git a/src/render/decorations/IHyprWindowDecoration.cpp b/src/render/decorations/IHyprWindowDecoration.cpp index b95adbd5..6cb02a4f 100644 --- a/src/render/decorations/IHyprWindowDecoration.cpp +++ b/src/render/decorations/IHyprWindowDecoration.cpp @@ -32,6 +32,12 @@ bool IHyprWindowDecoration::allowsInput() { return false; } +void IHyprWindowDecoration::dragWindowToDecoration(CWindow*, const Vector2D&) {} + +void IHyprWindowDecoration::clickDecoration(const Vector2D&) {} + +void IHyprWindowDecoration::dragFromDecoration(const Vector2D&) {} + void addExtentsToBox(wlr_box* box, SWindowDecorationExtents* extents) { box->x -= extents->topLeft.x; box->y -= extents->topLeft.y; diff --git a/src/render/decorations/IHyprWindowDecoration.hpp b/src/render/decorations/IHyprWindowDecoration.hpp index e03f49fe..b43be6b5 100644 --- a/src/render/decorations/IHyprWindowDecoration.hpp +++ b/src/render/decorations/IHyprWindowDecoration.hpp @@ -43,6 +43,12 @@ class IHyprWindowDecoration { virtual bool allowsInput(); + virtual void dragWindowToDecoration(CWindow*, const Vector2D&); + + virtual void clickDecoration(const Vector2D&); + + virtual void dragFromDecoration(const Vector2D&); + private: CWindow* m_pWindow = nullptr; };