layout: add drag_into_group to control merging dragging windows (#8004)

This commit is contained in:
Aqa-Ib 2024-10-08 12:20:41 +02:00 committed by GitHub
parent 4711796d38
commit 45e82199fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 63 additions and 25 deletions

View file

@ -778,6 +778,12 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
.type = CONFIG_OPTION_BOOL, .type = CONFIG_OPTION_BOOL,
.data = SConfigOptionDescription::SBoolData{true}, .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_CHOICE,
.data = SConfigOptionDescription::SChoiceData{0, "disabled,enabled,only when dragging into the groupbar"},
},
/* /*
* group:groupbar: * group:groupbar:

View file

@ -378,6 +378,7 @@ CConfigManager::CConfigManager() {
m_pConfig->addConfigValue("group:focus_removed_window", Hyprlang::INT{1}); 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:merge_groups_on_drag", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:auto_group", 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:enabled", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:groupbar:font_family", {STRVAL_EMPTY}); m_pConfig->addConfigValue("group:groupbar:font_family", {STRVAL_EMPTY});
m_pConfig->addConfigValue("group:groupbar:font_size", Hyprlang::INT{8}); m_pConfig->addConfigValue("group:groupbar:font_size", Hyprlang::INT{8});

View file

@ -193,17 +193,7 @@ bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) {
&& pWindow->canBeGroupedInto(OPENINGON) // check if the new window can be grouped into OPENINGON && pWindow->canBeGroupedInto(OPENINGON) // check if the new window can be grouped into OPENINGON
&& !g_pXWaylandManager->shouldBeFloated(pWindow)) { // don't group XWayland windows that should be floated. && !g_pXWaylandManager->shouldBeFloated(pWindow)) { // don't group XWayland windows that should be floated.
switch (pWindow->m_bIsFloating) { pWindow->m_bIsFloating = OPENINGON->m_bIsFloating; // match the floating state
case false:
if (OPENINGON->m_bIsFloating)
pWindow->m_bIsFloating = true;
break;
case true:
if (!OPENINGON->m_bIsFloating)
pWindow->m_bIsFloating = false;
break;
}
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current"); static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
(*USECURRPOS ? OPENINGON : OPENINGON->getGroupTail())->insertWindowToGroup(pWindow); (*USECURRPOS ? OPENINGON : OPENINGON->getGroupTail())->insertWindowToGroup(pWindow);
@ -335,21 +325,47 @@ void IHyprLayout::onEndDragWindow() {
g_pInputManager->currentlyDraggedWindow.reset(); g_pInputManager->currentlyDraggedWindow.reset();
g_pInputManager->m_bWasDraggingWindow = true; g_pInputManager->m_bWasDraggingWindow = true;
if (DRAGGINGWINDOW->m_bDraggingTiled) { if (g_pInputManager->dragMode == MBIND_MOVE) {
DRAGGINGWINDOW->m_bIsFloating = false;
g_pInputManager->refocus();
changeWindowFloatingMode(DRAGGINGWINDOW);
DRAGGINGWINDOW->m_vLastFloatingSize = m_vDraggingWindowOriginalFloatSize;
} else if (g_pInputManager->dragMode == MBIND_MOVE) {
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW); g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal(); 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) {
if (pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, DRAGGINGWINDOW)) if (pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, DRAGGINGWINDOW))
return; 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) {
if (DRAGGINGWINDOW->m_bDraggingTiled) {
changeWindowFloatingMode(DRAGGINGWINDOW);
DRAGGINGWINDOW->m_vLastFloatingSize = m_vDraggingWindowOriginalFloatSize;
DRAGGINGWINDOW->m_bDraggingTiled = false;
}
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_bIsFloating = pWindow->m_bIsFloating; // match the floating state of group members
if (pWindow->m_bIsFloating)
(*it)->m_vRealSize = pWindow->m_vRealSize.goal(); // match the size of group members
}
}
DRAGGINGWINDOW->m_bIsFloating = pWindow->m_bIsFloating; // match the floating state of the window
if (pWindow->m_bIsFloating)
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, pWindow->m_vRealSize.goal()); // match the size of the window
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current"); static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
(*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW); (*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW);
pWindow->setGroupCurrent(DRAGGINGWINDOW); pWindow->setGroupCurrent(DRAGGINGWINDOW);
@ -361,6 +377,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_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
g_pCompositor->focusWindow(DRAGGINGWINDOW); g_pCompositor->focusWindow(DRAGGINGWINDOW);
@ -553,10 +576,10 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
pWindow->m_vLastFloatingSize = PSAVEDSIZE; 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); pWindow->m_vPosition = Vector2D(-999999, -999999);
onWindowCreated(pWindow); onWindowCreatedTiling(pWindow);
pWindow->m_vRealPosition.setValue(PSAVEDPOS); pWindow->m_vRealPosition.setValue(PSAVEDPOS);
pWindow->m_vRealSize.setValue(PSAVEDSIZE); pWindow->m_vRealSize.setValue(PSAVEDSIZE);

View file

@ -403,7 +403,8 @@ bool CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWINDOW pDraggedWindow) { bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWINDOW pDraggedWindow) {
static auto PSTACKED = CConfigValue<Hyprlang::INT>("group:groupbar:stacked"); static auto PSTACKED = CConfigValue<Hyprlang::INT>("group:groupbar:stacked");
if (!pDraggedWindow->canBeGroupedInto(m_pWindow.lock())) static auto PDRAGINTOGROUP = CConfigValue<Hyprlang::INT>("group:drag_into_group");
if (!pDraggedWindow->canBeGroupedInto(m_pWindow.lock()) || (*PDRAGINTOGROUP != 1 && *PDRAGINTOGROUP != 2))
return false; return false;
const float BARRELATIVE = *PSTACKED ? pos.y - assignedBoxGlobal().y - (m_fBarHeight + BAR_PADDING_OUTER_VERT) / 2 : pos.x - assignedBoxGlobal().x - m_fBarWidth / 2; const float BARRELATIVE = *PSTACKED ? pos.y - assignedBoxGlobal().y - (m_fBarHeight + BAR_PADDING_OUTER_VERT) / 2 : pos.x - assignedBoxGlobal().x - m_fBarWidth / 2;
@ -435,6 +436,9 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWIND
// restores the group // restores the group
for (auto it = members.begin(); it != members.end(); ++it) { for (auto it = members.begin(); it != members.end(); ++it) {
(*it)->m_bIsFloating = pWindowInsertAfter->m_bIsFloating; // match the floating state of group members
if (pWindowInsertAfter->m_bIsFloating)
(*it)->m_vRealSize = pWindowInsertAfter->m_vRealSize.goal(); // match the size of group members
if (std::next(it) != members.end()) if (std::next(it) != members.end())
(*it)->m_sGroupData.pNextWindow = *std::next(it); (*it)->m_sGroupData.pNextWindow = *std::next(it);
else else
@ -442,9 +446,13 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWIND
} }
members[0]->m_sGroupData.head = true; members[0]->m_sGroupData.head = true;
members[0]->m_sGroupData.locked = WASLOCKED; members[0]->m_sGroupData.locked = WASLOCKED;
} else { } else
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pDraggedWindow); g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pDraggedWindow);
}
pDraggedWindow->m_bIsFloating = pWindowInsertAfter->m_bIsFloating; // match the floating state of the window
if (pWindowInsertAfter->m_bIsFloating)
g_pXWaylandManager->setWindowSize(pDraggedWindow, pWindowInsertAfter->m_vRealSize.goal()); // match the size of the window
pWindowInsertAfter->insertWindowToGroup(pDraggedWindow); pWindowInsertAfter->insertWindowToGroup(pDraggedWindow);