mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-27 04:49:49 +01:00
decoration: Stacked group tabs (#5886)
* Stacked group tabs * Fix index when creating groupbar title textures * Changes for stacked dnd * formatting * Don't remove internal horizontal padding when calculating stacked bar width
This commit is contained in:
parent
de9798fcf9
commit
ca0833c9ed
3 changed files with 60 additions and 28 deletions
|
@ -359,6 +359,7 @@ CConfigManager::CConfigManager() {
|
|||
m_pConfig->addConfigValue("group:groupbar:render_titles", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("group:groupbar:scrolling", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("group:groupbar:text_color", Hyprlang::INT{0xffffffff});
|
||||
m_pConfig->addConfigValue("group:groupbar:stacked", Hyprlang::INT{0});
|
||||
|
||||
m_pConfig->addConfigValue("debug:int", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("debug:log_damage", Hyprlang::INT{0});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "CHyprGroupBarDecoration.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
#include "../../config/ConfigValue.hpp"
|
||||
#include "managers/LayoutManager.hpp"
|
||||
#include <ranges>
|
||||
#include <pango/pangocairo.h>
|
||||
|
||||
|
@ -12,6 +13,7 @@ static CTexture m_tGradientLockedInactive;
|
|||
|
||||
constexpr int BAR_INDICATOR_HEIGHT = 3;
|
||||
constexpr int BAR_PADDING_OUTER_VERT = 2;
|
||||
constexpr int BAR_PADDING_OUTER_HORZ = 2;
|
||||
constexpr int BAR_TEXT_PAD = 2;
|
||||
constexpr int BAR_HORIZONTAL_PADDING = 2;
|
||||
|
||||
|
@ -32,6 +34,7 @@ SDecorationPositioningInfo CHyprGroupBarDecoration::getPositioningInfo() {
|
|||
static auto PRENDERTITLES = CConfigValue<Hyprlang::INT>("group:groupbar:render_titles");
|
||||
static auto PGRADIENTS = CConfigValue<Hyprlang::INT>("group:groupbar:gradients");
|
||||
static auto PPRIORITY = CConfigValue<Hyprlang::INT>("group:groupbar:priority");
|
||||
static auto PSTACKED = CConfigValue<Hyprlang::INT>("group:groupbar:stacked");
|
||||
|
||||
SDecorationPositioningInfo info;
|
||||
info.policy = DECORATION_POSITION_STICKY;
|
||||
|
@ -39,16 +42,20 @@ SDecorationPositioningInfo CHyprGroupBarDecoration::getPositioningInfo() {
|
|||
info.priority = *PPRIORITY;
|
||||
info.reserved = true;
|
||||
|
||||
if (*PENABLED && m_pWindow->m_sSpecialRenderData.decorate)
|
||||
info.desiredExtents = {{0, BAR_PADDING_OUTER_VERT * 2 + BAR_INDICATOR_HEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0) + 2}, {0, 0}};
|
||||
else
|
||||
if (*PENABLED && m_pWindow->m_sSpecialRenderData.decorate) {
|
||||
if (*PSTACKED) {
|
||||
const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + BAR_INDICATOR_HEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0);
|
||||
info.desiredExtents = {{0, (ONEBARHEIGHT * m_dwGroupMembers.size()) + 2 + BAR_PADDING_OUTER_VERT}, {0, 0}};
|
||||
} else
|
||||
info.desiredExtents = {{0, BAR_PADDING_OUTER_VERT * 2 + BAR_INDICATOR_HEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0) + 2}, {0, 0}};
|
||||
} else
|
||||
info.desiredExtents = {{0, 0}, {0, 0}};
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void CHyprGroupBarDecoration::onPositioningReply(const SDecorationPositioningReply& reply) {
|
||||
m_bAssignedBox = reply.assignedGeometry;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(m_pWindow.lock());
|
||||
}
|
||||
|
||||
eDecorationType CHyprGroupBarDecoration::getDecorationType() {
|
||||
|
@ -96,24 +103,31 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) {
|
|||
static auto PTITLEFONTSIZE = CConfigValue<Hyprlang::INT>("group:groupbar:font_size");
|
||||
static auto PHEIGHT = CConfigValue<Hyprlang::INT>("group:groupbar:height");
|
||||
static auto PGRADIENTS = CConfigValue<Hyprlang::INT>("group:groupbar:gradients");
|
||||
static auto PSTACKED = CConfigValue<Hyprlang::INT>("group:groupbar:stacked");
|
||||
|
||||
if (!*PENABLED || !m_pWindow->m_sSpecialRenderData.decorate)
|
||||
return;
|
||||
|
||||
const auto ASSIGNEDBOX = assignedBoxGlobal();
|
||||
|
||||
m_fBarWidth = (ASSIGNEDBOX.w - BAR_HORIZONTAL_PADDING * (barsToDraw - 1)) / barsToDraw;
|
||||
const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + BAR_INDICATOR_HEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0);
|
||||
m_fBarWidth = *PSTACKED ? ASSIGNEDBOX.w : (ASSIGNEDBOX.w - BAR_HORIZONTAL_PADDING * (barsToDraw - 1)) / barsToDraw;
|
||||
m_fBarHeight = *PSTACKED ? ((ASSIGNEDBOX.h - 2 - BAR_PADDING_OUTER_VERT) - BAR_PADDING_OUTER_VERT * (barsToDraw)) / barsToDraw : ASSIGNEDBOX.h - BAR_PADDING_OUTER_VERT;
|
||||
|
||||
const auto DESIREDHEIGHT = BAR_PADDING_OUTER_VERT * 2 + BAR_INDICATOR_HEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0) + 2;
|
||||
if (DESIREDHEIGHT != ASSIGNEDBOX.h)
|
||||
const auto DESIREDHEIGHT = *PSTACKED ? (ONEBARHEIGHT * m_dwGroupMembers.size()) + 2 + BAR_PADDING_OUTER_VERT : BAR_PADDING_OUTER_VERT * 2 + ONEBARHEIGHT;
|
||||
if (DESIREDHEIGHT != ASSIGNEDBOX.h) {
|
||||
g_pDecorationPositioner->repositionDeco(this);
|
||||
}
|
||||
|
||||
int xoff = 0;
|
||||
int yoff = 0;
|
||||
|
||||
for (int i = 0; i < barsToDraw; ++i) {
|
||||
CBox rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x,
|
||||
ASSIGNEDBOX.y + ASSIGNEDBOX.h - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, m_fBarWidth,
|
||||
BAR_INDICATOR_HEIGHT};
|
||||
const auto WINDOWINDEX = *PSTACKED ? m_dwGroupMembers.size() - i - 1 : i;
|
||||
|
||||
CBox rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x,
|
||||
ASSIGNEDBOX.y + ASSIGNEDBOX.h - yoff - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, m_fBarWidth,
|
||||
BAR_INDICATOR_HEIGHT};
|
||||
|
||||
if (rect.width <= 0 || rect.height <= 0)
|
||||
break;
|
||||
|
@ -133,38 +147,43 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) {
|
|||
const auto* const PCOLACTIVE = GROUPLOCKED ? GROUPCOLACTIVELOCKED : GROUPCOLACTIVE;
|
||||
const auto* const PCOLINACTIVE = GROUPLOCKED ? GROUPCOLINACTIVELOCKED : GROUPCOLINACTIVE;
|
||||
|
||||
CColor color = m_dwGroupMembers[i].lock() == g_pCompositor->m_pLastWindow.lock() ? PCOLACTIVE->m_vColors[0] : PCOLINACTIVE->m_vColors[0];
|
||||
CColor color = m_dwGroupMembers[WINDOWINDEX].lock() == g_pCompositor->m_pLastWindow.lock() ? PCOLACTIVE->m_vColors[0] : PCOLINACTIVE->m_vColors[0];
|
||||
color.a *= a;
|
||||
g_pHyprOpenGL->renderRect(&rect, color);
|
||||
|
||||
rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x,
|
||||
ASSIGNEDBOX.y - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y + BAR_PADDING_OUTER_VERT, m_fBarWidth,
|
||||
ASSIGNEDBOX.h - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT * 2};
|
||||
ASSIGNEDBOX.y + ASSIGNEDBOX.h - yoff - ONEBARHEIGHT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, m_fBarWidth,
|
||||
(*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0)};
|
||||
rect.scale(pMonitor->scale);
|
||||
|
||||
if (*PGRADIENTS) {
|
||||
const auto& GRADIENTTEX = (m_dwGroupMembers[i].lock() == g_pCompositor->m_pLastWindow.lock() ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) :
|
||||
(GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive));
|
||||
const auto& GRADIENTTEX =
|
||||
(m_dwGroupMembers[WINDOWINDEX].lock() == g_pCompositor->m_pLastWindow.lock() ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) :
|
||||
(GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive));
|
||||
if (GRADIENTTEX.m_iTexID != 0)
|
||||
g_pHyprOpenGL->renderTexture(GRADIENTTEX, &rect, 1.0);
|
||||
}
|
||||
|
||||
if (*PRENDERTITLES) {
|
||||
CTitleTex* pTitleTex = textureFromTitle(m_dwGroupMembers[i]->m_szTitle);
|
||||
CTitleTex* pTitleTex = textureFromTitle(m_dwGroupMembers[WINDOWINDEX]->m_szTitle);
|
||||
|
||||
if (!pTitleTex)
|
||||
pTitleTex = m_sTitleTexs.titleTexs
|
||||
.emplace_back(std::make_unique<CTitleTex>(
|
||||
m_dwGroupMembers[i].lock(), Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * pMonitor->scale}, pMonitor->scale))
|
||||
.get();
|
||||
pTitleTex =
|
||||
m_sTitleTexs.titleTexs
|
||||
.emplace_back(std::make_unique<CTitleTex>(m_dwGroupMembers[WINDOWINDEX].lock(),
|
||||
Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * pMonitor->scale}, pMonitor->scale))
|
||||
.get();
|
||||
|
||||
rect.y += (ASSIGNEDBOX.h / 2.0 - (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) / 2.0) * pMonitor->scale;
|
||||
rect.y += (*PHEIGHT / 2.0 - (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) / 2.0) * pMonitor->scale;
|
||||
rect.height = (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * pMonitor->scale;
|
||||
|
||||
g_pHyprOpenGL->renderTexture(pTitleTex->tex, &rect, 1.f);
|
||||
}
|
||||
|
||||
xoff += BAR_HORIZONTAL_PADDING + m_fBarWidth;
|
||||
if (*PSTACKED)
|
||||
yoff += ONEBARHEIGHT;
|
||||
else
|
||||
xoff += BAR_HORIZONTAL_PADDING + m_fBarWidth;
|
||||
}
|
||||
|
||||
if (*PRENDERTITLES)
|
||||
|
@ -335,13 +354,18 @@ void refreshGroupBarGradients() {
|
|||
}
|
||||
|
||||
bool CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
|
||||
static auto PSTACKED = CConfigValue<Hyprlang::INT>("group:groupbar:stacked");
|
||||
if (m_pWindow.lock() == m_pWindow->m_sGroupData.pNextWindow.lock())
|
||||
return false;
|
||||
|
||||
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x;
|
||||
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
||||
const float BARRELATIVEY = pos.y - assignedBoxGlobal().y;
|
||||
const int WINDOWINDEX = *PSTACKED ? (BARRELATIVEY / (m_fBarHeight + BAR_PADDING_OUTER_VERT)) : (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
||||
|
||||
if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth)
|
||||
if (!*PSTACKED && (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth))
|
||||
return false;
|
||||
|
||||
if (*PSTACKED && (BARRELATIVEY - (m_fBarHeight + BAR_PADDING_OUTER_VERT) * WINDOWINDEX < BAR_PADDING_OUTER_VERT))
|
||||
return false;
|
||||
|
||||
PHLWINDOW pWindow = m_pWindow->getGroupWindowByIndex(WINDOWINDEX);
|
||||
|
@ -364,11 +388,13 @@ bool CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
|
|||
}
|
||||
|
||||
bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWINDOW pDraggedWindow) {
|
||||
static auto PSTACKED = CConfigValue<Hyprlang::INT>("group:groupbar:stacked");
|
||||
if (!pDraggedWindow->canBeGroupedInto(m_pWindow.lock()))
|
||||
return false;
|
||||
|
||||
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x - m_fBarWidth / 2;
|
||||
const int WINDOWINDEX = BARRELATIVEX < 0 ? -1 : (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
||||
const float BARRELATIVE = *PSTACKED ? pos.y - assignedBoxGlobal().y - (m_fBarHeight + BAR_PADDING_OUTER_VERT) / 2 : pos.x - assignedBoxGlobal().x - m_fBarWidth / 2;
|
||||
const float BARSIZE = *PSTACKED ? m_fBarHeight + BAR_PADDING_OUTER_VERT : m_fBarWidth + BAR_HORIZONTAL_PADDING;
|
||||
const int WINDOWINDEX = BARRELATIVE < 0 ? -1 : BARRELATIVE / BARSIZE;
|
||||
|
||||
PHLWINDOW pWindowInsertAfter = m_pWindow->getGroupWindowByIndex(WINDOWINDEX);
|
||||
PHLWINDOW pWindowInsertEnd = pWindowInsertAfter->m_sGroupData.pNextWindow.lock();
|
||||
|
@ -423,11 +449,13 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWIND
|
|||
}
|
||||
|
||||
bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, const IPointer::SButtonEvent& e) {
|
||||
static auto PSTACKED = CConfigValue<Hyprlang::INT>("group:groupbar:stacked");
|
||||
if (m_pWindow->m_bIsFullscreen && m_pWindow->m_pWorkspace->m_efFullscreenMode == FULLSCREEN_FULL)
|
||||
return true;
|
||||
|
||||
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x;
|
||||
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
||||
const float BARRELATIVEY = pos.y - assignedBoxGlobal().y;
|
||||
const int WINDOWINDEX = *PSTACKED ? (BARRELATIVEY / (m_fBarHeight + BAR_PADDING_OUTER_VERT)) : (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
||||
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
||||
|
||||
// close window on middle click
|
||||
|
@ -446,7 +474,9 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, const IPo
|
|||
return true;
|
||||
|
||||
// click on padding
|
||||
if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth) {
|
||||
const auto TABPAD = !*PSTACKED && (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth);
|
||||
const auto STACKPAD = *PSTACKED && (BARRELATIVEY - (m_fBarHeight + BAR_PADDING_OUTER_VERT) * WINDOWINDEX < BAR_PADDING_OUTER_VERT);
|
||||
if (TABPAD || STACKPAD) {
|
||||
if (!g_pCompositor->isWindowActive(m_pWindow.lock()))
|
||||
g_pCompositor->focusWindow(m_pWindow.lock());
|
||||
return true;
|
||||
|
|
|
@ -54,6 +54,7 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration {
|
|||
std::deque<PHLWINDOWREF> m_dwGroupMembers;
|
||||
|
||||
float m_fBarWidth;
|
||||
float m_fBarHeight;
|
||||
|
||||
CTitleTex* textureFromTitle(const std::string&);
|
||||
void invalidateTextures();
|
||||
|
|
Loading…
Reference in a new issue