Skip to content

Commit

Permalink
layout: add drag_into_group to control whether dragging a window into…
Browse files Browse the repository at this point in the history
… a unlocked group will merge them
  • Loading branch information
Aqa-Ib committed Oct 7, 2024
1 parent 97444ed commit 6f45fce
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 13 deletions.
6 changes: 6 additions & 0 deletions src/config/ConfigDescriptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,12 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
.type = CONFIG_OPTION_BOOL,
.data = SConfigOptionDescription::SBoolData{true},
},
SConfigOptionDescription{
.value = "group:drag_into_group",
.description = "whether dragging a window into a unlocked group will merge them. Options: 0 (disabled), 1 (enabled), 2 (only when dragging into the groupbar)",
.type = CONFIG_OPTION_INT,
.data = SConfigOptionDescription::SRangeData{1, 0, 2},
},

/*
* group:groupbar:
Expand Down
1 change: 1 addition & 0 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ CConfigManager::CConfigManager() {
m_pConfig->addConfigValue("group:focus_removed_window", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:merge_groups_on_drag", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:auto_group", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:drag_into_group", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:groupbar:enabled", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:groupbar:font_family", {STRVAL_EMPTY});
m_pConfig->addConfigValue("group:groupbar:font_size", Hyprlang::INT{8});
Expand Down
65 changes: 55 additions & 10 deletions src/layout/IHyprLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,21 +335,45 @@ void IHyprLayout::onEndDragWindow() {
g_pInputManager->currentlyDraggedWindow.reset();
g_pInputManager->m_bWasDraggingWindow = true;

if (DRAGGINGWINDOW->m_bDraggingTiled) {
DRAGGINGWINDOW->m_bIsFloating = false;
g_pInputManager->refocus();
changeWindowFloatingMode(DRAGGINGWINDOW);
DRAGGINGWINDOW->m_vLastFloatingSize = m_vDraggingWindowOriginalFloatSize;
} else if (g_pInputManager->dragMode == MBIND_MOVE) {
if (g_pInputManager->dragMode == MBIND_MOVE) {
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
PHLWINDOW pWindow = g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING | FLOATING_ONLY, DRAGGINGWINDOW);
PHLWINDOW pWindow = g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING, DRAGGINGWINDOW);

if (pWindow) {
if (pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, DRAGGINGWINDOW))
return;

if (pWindow->m_sGroupData.pNextWindow.lock() && DRAGGINGWINDOW->canBeGroupedInto(pWindow)) {
bool denied = false;
if (!pWindow->m_bIsFloating && !DRAGGINGWINDOW->m_bDraggingTiled)
denied = true;

static auto PDRAGINTOGROUP = CConfigValue<Hyprlang::INT>("group:drag_into_group");
if (pWindow->m_sGroupData.pNextWindow.lock() && DRAGGINGWINDOW->canBeGroupedInto(pWindow) && *PDRAGINTOGROUP == 1 && !denied) {
// fix grouping into a floating group
if (pWindow->m_bIsFloating) {
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, pWindow->m_vRealSize.goal()); // match the size of the window
if (DRAGGINGWINDOW->m_sGroupData.pNextWindow.lock()) {
std::vector<PHLWINDOW> members;
PHLWINDOW curr = DRAGGINGWINDOW->getGroupHead();
do {
members.push_back(curr);
curr = curr->m_sGroupData.pNextWindow.lock();
} while (curr != members[0]);

for (auto it = members.begin(); it != members.end(); ++it) {
(*it)->m_vRealSize = pWindow->m_vRealSize.goal(); // match the size of group members
g_pLayoutManager->getCurrentLayout()->matchFloatingState(*it, pWindow); // match the floating state of group members
}
}
}

if (DRAGGINGWINDOW->m_bDraggingTiled) {
changeWindowFloatingMode(DRAGGINGWINDOW);
DRAGGINGWINDOW->m_vLastFloatingSize = m_vDraggingWindowOriginalFloatSize;
DRAGGINGWINDOW->m_bDraggingTiled = false;
}

static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
(*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW);
pWindow->setGroupCurrent(DRAGGINGWINDOW);
Expand All @@ -361,6 +385,13 @@ void IHyprLayout::onEndDragWindow() {
}
}

if (DRAGGINGWINDOW->m_bDraggingTiled) {
DRAGGINGWINDOW->m_bIsFloating = false;
g_pInputManager->refocus();
changeWindowFloatingMode(DRAGGINGWINDOW);
DRAGGINGWINDOW->m_vLastFloatingSize = m_vDraggingWindowOriginalFloatSize;
}

g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
g_pCompositor->focusWindow(DRAGGINGWINDOW);

Expand Down Expand Up @@ -553,10 +584,10 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {

pWindow->m_vLastFloatingSize = PSAVEDSIZE;

// move to narnia because we don't wanna find our own node. onWindowCreated should apply the coords back.
// move to narnia because we don't wanna find our own node. onWindowCreatedTiling should apply the coords back.
pWindow->m_vPosition = Vector2D(-999999, -999999);

onWindowCreated(pWindow);
onWindowCreatedTiling(pWindow);

pWindow->m_vRealPosition.setValue(PSAVEDPOS);
pWindow->m_vRealSize.setValue(PSAVEDSIZE);
Expand Down Expand Up @@ -758,4 +789,18 @@ Vector2D IHyprLayout::predictSizeForNewWindow(PHLWINDOW pWindow) {
return sizePredicted;
}

void IHyprLayout::matchFloatingState(PHLWINDOW pTarget, PHLWINDOW pReference) {
switch (pTarget->m_bIsFloating) {
case false:
if (pReference->m_bIsFloating)
pTarget->m_bIsFloating = true;
break;

case true:
if (!pReference->m_bIsFloating)
pTarget->m_bIsFloating = false;
break;
}
}

IHyprLayout::~IHyprLayout() {}
5 changes: 5 additions & 0 deletions src/layout/IHyprLayout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ class IHyprLayout {
virtual Vector2D predictSizeForNewWindow(PHLWINDOW pWindow);
virtual Vector2D predictSizeForNewWindowFloating(PHLWINDOW pWindow);

/*
Change the target window to match the reference window floating state
*/
virtual void matchFloatingState(PHLWINDOW pTarget, PHLWINDOW pReference);

private:
int m_iMouseMoveEventCount;
Vector2D m_vBeginDragXY;
Expand Down
41 changes: 38 additions & 3 deletions src/render/decorations/CHyprGroupBarDecoration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,9 @@ 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()))
static auto PSTACKED = CConfigValue<Hyprlang::INT>("group:groupbar:stacked");
static auto PDRAGINTOGROUP = CConfigValue<Hyprlang::INT>("group:drag_into_group");
if (!pDraggedWindow->canBeGroupedInto(m_pWindow.lock()) || (*PDRAGINTOGROUP != 1 && *PDRAGINTOGROUP != 2))
return false;

const float BARRELATIVE = *PSTACKED ? pos.y - assignedBoxGlobal().y - (m_fBarHeight + BAR_PADDING_OUTER_VERT) / 2 : pos.x - assignedBoxGlobal().x - m_fBarWidth / 2;
Expand Down Expand Up @@ -442,8 +443,42 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWIND
}
members[0]->m_sGroupData.head = true;
members[0]->m_sGroupData.locked = WASLOCKED;
} else {
} else
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pDraggedWindow);

// fix grouping into a floating group
if (pWindowInsertAfter->m_bIsFloating) {
g_pXWaylandManager->setWindowSize(pDraggedWindow, pWindowInsertAfter->m_vRealSize.goal()); // match the size of the window
if (pDraggedWindow->m_sGroupData.pNextWindow.lock()) {
std::vector<PHLWINDOW> members;
PHLWINDOW curr = pDraggedWindow->getGroupHead();
do {
members.push_back(curr);
curr = curr->m_sGroupData.pNextWindow.lock();
} while (curr != members[0]);

for (auto it = members.begin(); it != members.end(); ++it) {
(*it)->m_vRealSize = pWindowInsertAfter->m_vRealSize.goal(); // match the size of group members
g_pLayoutManager->getCurrentLayout()->matchFloatingState(*it, pWindowInsertAfter); // match the floating state of group members
}
}
}

// fix grouping a floating window into a tiling group
if (!pWindowInsertAfter->m_bIsFloating && !g_pLayoutManager->getCurrentLayout()->isWindowTiled(pDraggedWindow)) {
if (pDraggedWindow->m_sGroupData.pNextWindow.lock()) {
std::vector<PHLWINDOW> members;
PHLWINDOW curr = pDraggedWindow->getGroupHead();
do {
members.push_back(curr);
curr = curr->m_sGroupData.pNextWindow.lock();
} while (curr != members[0]);

for (auto it = members.begin(); it != members.end(); ++it) {
g_pLayoutManager->getCurrentLayout()->matchFloatingState(*it, pWindowInsertAfter); // match the floating state of group members
}
} else
g_pLayoutManager->getCurrentLayout()->matchFloatingState(pDraggedWindow, pWindowInsertAfter);
}

pWindowInsertAfter->insertWindowToGroup(pDraggedWindow);
Expand Down

0 comments on commit 6f45fce

Please sign in to comment.