diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 5e18233da..a77cf7574 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -128,6 +128,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_BOOL, .data = SConfigOptionDescription::SBoolData{false}, }, + SConfigOptionDescription{ + .value = "general:snap:respect_gaps", + .description = "if true, snapping will respect gaps between windows", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{false}, + }, /* * decoration: diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index a79afb357..acbc02626 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -456,6 +456,7 @@ CConfigManager::CConfigManager() { registerConfigVar("general:snap:window_gap", Hyprlang::INT{10}); registerConfigVar("general:snap:monitor_gap", Hyprlang::INT{10}); registerConfigVar("general:snap:border_overlap", Hyprlang::INT{0}); + registerConfigVar("general:snap:respect_gaps", Hyprlang::INT{0}); registerConfigVar("general:col.active_border", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0xffffffff"}); registerConfigVar("general:col.inactive_border", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0xff444444"}); registerConfigVar("general:col.nogroup_border", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0xffffaaff"}); diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 93b09c87d..1fe3a936f 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -417,6 +417,7 @@ static void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRA static auto SNAPWINDOWGAP = CConfigValue("general:snap:window_gap"); static auto SNAPMONITORGAP = CConfigValue("general:snap:monitor_gap"); static auto SNAPBORDEROVERLAP = CConfigValue("general:snap:border_overlap"); + static auto SNAPRESPECTGAPS = CConfigValue("general:snap:respect_gaps"); const SnapFn SNAP = (MODE == MBIND_MOVE) ? snapMove : snapResize; int snaps = 0; @@ -444,9 +445,15 @@ static void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRA const int OTHERBORDERSIZE = other->getRealBorderSize(); const double BORDERSIZE = OVERLAP ? std::max(DRAGGINGBORDERSIZE, OTHERBORDERSIZE) : (DRAGGINGBORDERSIZE + OTHERBORDERSIZE); - const CBox SURF = other->getWindowMainSurfaceBox(); - const SRange SURFBX = {SURF.x - BORDERSIZE, SURF.x + SURF.w + BORDERSIZE}; - const SRange SURFBY = {SURF.y - BORDERSIZE, SURF.y + SURF.h + BORDERSIZE}; + const CBox SURF = other->getWindowMainSurfaceBox(); + double gapOffset = 0; + if (*SNAPRESPECTGAPS) { + static auto PGAPSINDATA = CConfigValue("general:gaps_in"); + auto* PGAPSINPTR = (CCssGapData*)(PGAPSINDATA.ptr())->getData(); + gapOffset = std::max({PGAPSINPTR->m_left, PGAPSINPTR->m_right, PGAPSINPTR->m_top, PGAPSINPTR->m_bottom}); + } + const SRange SURFBX = {SURF.x - BORDERSIZE - gapOffset, SURF.x + SURF.w + BORDERSIZE + gapOffset}; + const SRange SURFBY = {SURF.y - BORDERSIZE - gapOffset, SURF.y + SURF.h + BORDERSIZE + gapOffset}; // only snap windows if their ranges overlap in the opposite axis if (sourceY.start <= SURFBY.end && SURFBY.start <= sourceY.end) { @@ -497,32 +504,37 @@ static void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRA const double GAPSIZE = *SNAPMONITORGAP; const double BORDERDIFF = OVERLAP ? DRAGGINGBORDERSIZE : 0; const auto MON = DRAGGINGWINDOW->m_monitor.lock(); - - SRange monX = {MON->m_position.x + MON->m_reservedTopLeft.x + DRAGGINGBORDERSIZE, MON->m_position.x + MON->m_size.x - MON->m_reservedBottomRight.x - DRAGGINGBORDERSIZE}; - SRange monY = {MON->m_position.y + MON->m_reservedTopLeft.y + DRAGGINGBORDERSIZE, MON->m_position.y + MON->m_size.y - MON->m_reservedBottomRight.y - DRAGGINGBORDERSIZE}; + double gapOffset = 0; + if (*SNAPRESPECTGAPS) { + static auto PGAPSOUTDATA = CConfigValue("general:gaps_out"); + auto* PGAPSOUTPTR = (CCssGapData*)(PGAPSOUTDATA.ptr())->getData(); + gapOffset = std::max({PGAPSOUTPTR->m_left, PGAPSOUTPTR->m_right, PGAPSOUTPTR->m_top, PGAPSOUTPTR->m_bottom}); + } if (CORNER & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT) && - ((MON->m_reservedTopLeft.x > 0 && canSnap(sourceX.start, monX.start, GAPSIZE)) || - canSnap(sourceX.start, (monX.start -= MON->m_reservedTopLeft.x + BORDERDIFF), GAPSIZE))) { - SNAP(sourceX.start, sourceX.end, monX.start); + ((MON->m_reservedTopLeft.x > 0 && canSnap(sourceX.start, MON->m_position.x + MON->m_reservedTopLeft.x + DRAGGINGBORDERSIZE + gapOffset, GAPSIZE)) || + canSnap(sourceX.start, MON->m_position.x + MON->m_reservedTopLeft.x - BORDERDIFF + gapOffset, GAPSIZE))) { + SNAP(sourceX.start, sourceX.end, MON->m_position.x + MON->m_reservedTopLeft.x + DRAGGINGBORDERSIZE + gapOffset); snaps |= SNAP_LEFT; } if (CORNER & (CORNER_TOPRIGHT | CORNER_BOTTOMRIGHT) && - ((MON->m_reservedBottomRight.x > 0 && canSnap(sourceX.end, monX.end, GAPSIZE)) || - canSnap(sourceX.end, (monX.end += MON->m_reservedBottomRight.x + BORDERDIFF), GAPSIZE))) { - SNAP(sourceX.end, sourceX.start, monX.end); + ((MON->m_reservedBottomRight.x > 0 && + canSnap(sourceX.end, MON->m_position.x + MON->m_size.x - MON->m_reservedBottomRight.x - DRAGGINGBORDERSIZE - gapOffset, GAPSIZE)) || + canSnap(sourceX.end, MON->m_position.x + MON->m_size.x - MON->m_reservedBottomRight.x + BORDERDIFF - gapOffset, GAPSIZE))) { + SNAP(sourceX.end, sourceX.start, MON->m_position.x + MON->m_size.x - MON->m_reservedBottomRight.x - DRAGGINGBORDERSIZE - gapOffset); snaps |= SNAP_RIGHT; } if (CORNER & (CORNER_TOPLEFT | CORNER_TOPRIGHT) && - ((MON->m_reservedTopLeft.y > 0 && canSnap(sourceY.start, monY.start, GAPSIZE)) || - canSnap(sourceY.start, (monY.start -= MON->m_reservedTopLeft.y + BORDERDIFF), GAPSIZE))) { - SNAP(sourceY.start, sourceY.end, monY.start); + ((MON->m_reservedTopLeft.y > 0 && canSnap(sourceY.start, MON->m_position.y + MON->m_reservedTopLeft.y + DRAGGINGBORDERSIZE + gapOffset, GAPSIZE)) || + canSnap(sourceY.start, MON->m_position.y + MON->m_reservedTopLeft.y - BORDERDIFF + gapOffset, GAPSIZE))) { + SNAP(sourceY.start, sourceY.end, MON->m_position.y + MON->m_reservedTopLeft.y + DRAGGINGBORDERSIZE + gapOffset); snaps |= SNAP_UP; } if (CORNER & (CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) && - ((MON->m_reservedBottomRight.y > 0 && canSnap(sourceY.end, monY.end, GAPSIZE)) || - canSnap(sourceY.end, (monY.end += MON->m_reservedBottomRight.y + BORDERDIFF), GAPSIZE))) { - SNAP(sourceY.end, sourceY.start, monY.end); + ((MON->m_reservedBottomRight.y > 0 && + canSnap(sourceY.end, MON->m_position.y + MON->m_size.y - MON->m_reservedBottomRight.y - DRAGGINGBORDERSIZE - gapOffset, GAPSIZE)) || + canSnap(sourceY.end, MON->m_position.y + MON->m_size.y - MON->m_reservedBottomRight.y + BORDERDIFF - gapOffset, GAPSIZE))) { + SNAP(sourceY.end, sourceY.start, MON->m_position.y + MON->m_size.y - MON->m_reservedBottomRight.y - DRAGGINGBORDERSIZE - gapOffset); snaps |= SNAP_DOWN; } }