Compare commits

...

4 Commits

Author SHA1 Message Date
Agent00Ming 59e600e1b5
Merge ce90673621 into 9c5dd59d4b 2024-06-29 07:48:06 +07:00
Vaxry 9c5dd59d4b input: fix capabilities enum types passed
hyprland down to the seat protocol impl expects IHID capabilities, not WL_ ones

ref #6702 #6196
2024-06-29 00:23:02 +02:00
Vaxry d16c6aa1db pointer-constraint: set lifetime correctly
ref #6679
2024-06-29 00:18:24 +02:00
Agent_00Ming ce90673621 Customizable directional window resize logic 2024-06-24 19:14:41 -04:00
10 changed files with 367 additions and 75 deletions

View File

@ -701,7 +701,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
if (properties & ALLOW_FLOATING) {
for (auto& w : m_vWindows | std::views::reverse) {
const auto BB = w->getWindowBoxUnified(properties);
CBox box = BB.copy().expand(w->m_iX11Type == 2 ? BORDER_GRAB_AREA : 0);
CBox box = BB.copy().expand(w->m_iX11Type != 2 ? BORDER_GRAB_AREA : 0);
if (w->m_bIsFloating && w->m_bIsMapped && !w->isHidden() && !w->m_bX11ShouldntFocus && w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && w != pIgnoreWindow) {
if (box.containsPoint(g_pPointerManager->position()))
return w;
@ -730,7 +730,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
BB.x + BB.width <= PWINDOWMONITOR->vecPosition.x + PWINDOWMONITOR->vecSize.x && BB.y + BB.height <= PWINDOWMONITOR->vecPosition.y + PWINDOWMONITOR->vecSize.y)
continue;
CBox box = BB.copy().expand(w->m_iX11Type == 2 ? BORDER_GRAB_AREA : 0);
CBox box = BB.copy().expand(w->m_iX11Type != 2 ? BORDER_GRAB_AREA : 0);
if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_pWorkspace) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus &&
w != pIgnoreWindow && (!aboveFullscreen || w->m_bCreatedOverFullscreen)) {
// OR windows should add focus to parent

View File

@ -324,6 +324,8 @@ CConfigManager::CConfigManager() {
m_pConfig->addConfigValue("general:layout", {"dwindle"});
m_pConfig->addConfigValue("general:allow_tearing", Hyprlang::INT{0});
m_pConfig->addConfigValue("general:resize_corner", Hyprlang::INT{0});
m_pConfig->addConfigValue("general:edge_depth", {0.0f});
m_pConfig->addConfigValue("general:resize_mouse_bind_pattern", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:disable_hyprland_logo", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:disable_splash_rendering", Hyprlang::INT{0});

View File

@ -2,6 +2,7 @@
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
#include "../Compositor.hpp"
#include "../config/ConfigValue.hpp"
#include "debug/Log.hpp"
void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverride, bool verticalOverride) {
if (children[0]) {
@ -624,29 +625,60 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
if (!m_PseudoDragFlags.started) {
m_PseudoDragFlags.started = true;
const auto pseudoSize = PWINDOW->m_vRealSize.goal();
const auto mouseOffset = g_pInputManager->getMouseCoordsInternal() - (PNODE->box.pos() + ((PNODE->box.size() / 2) - (pseudoSize / 2)));
// I know this appears like 4 times...
static auto b = CConfigValue<Hyprlang::INT>("general:border_size");
static auto r = CConfigValue<Hyprlang::INT>("general:resize_on_border");
static auto e = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area");
const CBox h = {-(*b + *e * (*r != 0)), -(*b + *e * (*r != 0)), 2 * (*b + *e * (*r != 0)) + 1, 2 * (*b + *e * (*r != 0)) + 1}; // why weird vs IHyprlayout:432 ?
const CBox p = {PWINDOW->m_vRealPosition.goal() + h.pos(), PWINDOW->m_vRealSize.goal() + h.size()};
if (mouseOffset.x > 0 && mouseOffset.x < pseudoSize.x && mouseOffset.y > 0 && mouseOffset.y < pseudoSize.y) {
m_PseudoDragFlags.pseudo = true;
m_PseudoDragFlags.xExtent = mouseOffset.x > pseudoSize.x / 2;
m_PseudoDragFlags.yExtent = mouseOffset.y > pseudoSize.y / 2;
if (p.containsPoint(g_pInputManager->getMouseCoordsInternal())) {
m_PseudoDragFlags.pseudo = true;
PWINDOW->m_vPseudoSize = pseudoSize;
} else {
switch (corner) {
case CORNER_TOPLEFT:
m_PseudoDragFlags.xExtent = -1;
m_PseudoDragFlags.yExtent = -1;
break;
case CORNER_TOPRIGHT:
m_PseudoDragFlags.xExtent = 1;
m_PseudoDragFlags.yExtent = -1;
break;
case CORNER_BOTTOMRIGHT:
m_PseudoDragFlags.xExtent = 1;
m_PseudoDragFlags.yExtent = 1;
break;
case CORNER_BOTTOMLEFT:
m_PseudoDragFlags.xExtent = -1;
m_PseudoDragFlags.yExtent = 1;
break;
case EDGE_TOP:
m_PseudoDragFlags.xExtent = 0;
m_PseudoDragFlags.yExtent = -1;
break;
case EDGE_RIGHT:
m_PseudoDragFlags.xExtent = 1;
m_PseudoDragFlags.yExtent = 0;
break;
case EDGE_BOTTOM:
m_PseudoDragFlags.xExtent = 0;
m_PseudoDragFlags.yExtent = 1;
break;
case EDGE_LEFT:
m_PseudoDragFlags.xExtent = -1;
m_PseudoDragFlags.yExtent = 0;
break;
default: break; // idk future problem
}
PWINDOW->m_vPseudoSize = pWindow->m_vRealSize.goal();
} else
m_PseudoDragFlags.pseudo = false;
}
}
if (m_PseudoDragFlags.pseudo) {
if (m_PseudoDragFlags.xExtent)
PWINDOW->m_vPseudoSize.x += pixResize.x * 2;
else
PWINDOW->m_vPseudoSize.x -= pixResize.x * 2;
if (m_PseudoDragFlags.yExtent)
PWINDOW->m_vPseudoSize.y += pixResize.y * 2;
else
PWINDOW->m_vPseudoSize.y -= pixResize.y * 2;
PWINDOW->m_vPseudoSize.x += 2 * pixResize.x * m_PseudoDragFlags.xExtent;
PWINDOW->m_vPseudoSize.y += 2 * pixResize.y * m_PseudoDragFlags.yExtent;
CBox wbox = PNODE->box;
wbox.round();
@ -675,10 +707,10 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
SDwindleNodeData* PHOUTER = nullptr;
SDwindleNodeData* PHINNER = nullptr;
const auto LEFT = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT || DISPLAYRIGHT;
const auto TOP = corner == CORNER_TOPLEFT || corner == CORNER_TOPRIGHT || DISPLAYBOTTOM;
const auto RIGHT = corner == CORNER_TOPRIGHT || corner == CORNER_BOTTOMRIGHT || DISPLAYLEFT;
const auto BOTTOM = corner == CORNER_BOTTOMLEFT || corner == CORNER_BOTTOMRIGHT || DISPLAYTOP;
const auto LEFT = corner == EDGE_LEFT || corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT /*|| DISPLAYRIGHT*/;
const auto TOP = corner == EDGE_TOP || corner == CORNER_TOPLEFT || corner == CORNER_TOPRIGHT /*|| DISPLAYBOTTOM*/;
const auto RIGHT = corner == EDGE_RIGHT || corner == CORNER_TOPRIGHT || corner == CORNER_BOTTOMRIGHT /*|| DISPLAYLEFT*/;
const auto BOTTOM = corner == EDGE_BOTTOM || corner == CORNER_BOTTOMLEFT || corner == CORNER_BOTTOMRIGHT /*|| DISPLAYTOP*/;
const auto NONE = corner == CORNER_NONE;
for (auto PCURRENT = PNODE; PCURRENT && PCURRENT->pParent; PCURRENT = PCURRENT->pParent) {

View File

@ -71,8 +71,8 @@ class CHyprDwindleLayout : public IHyprLayout {
struct {
bool started = false;
bool pseudo = false;
bool xExtent = false;
bool yExtent = false;
int xExtent = 0;
int yExtent = 0;
} m_PseudoDragFlags;
std::optional<Vector2D> m_vOverrideFocalPoint; // for onWindowCreatedTiling.

View File

@ -7,6 +7,15 @@
#include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XSurface.hpp"
#include "debug/Log.hpp"
#include "managers/input/InputManager.hpp"
#include <algorithm>
#include <bitset>
#include <cstdint>
#include <hyprlang.hpp>
#include <hyprutils/math/Box.hpp>
#include <hyprutils/math/Vector2D.hpp>
#include <string>
void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) {
if (pWindow->m_bIsFloating) {
@ -176,6 +185,159 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
pWindow->m_vPendingReportedSize = pWindow->m_vRealSize.goal();
pWindow->m_vReportedSize = pWindow->m_vPendingReportedSize;
}
// additional hitbox area to be added to floating windows
static auto b = CConfigValue<Hyprlang::INT>("general:border_size");
static auto r = CConfigValue<Hyprlang::INT>("general:resize_on_border");
static auto e = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area");
const CBox h = {-(*b + *e * (*r != 0)), -(*b + *e * (*r != 0)), 2 * (*b + *e * (*r != 0)), 2 * (*b + *e * (*r != 0))};
pWindow->m_vPosition = pWindow->m_vRealPosition.goal() + h.pos();
pWindow->m_vSize = pWindow->m_vRealSize.goal() + h.size();
}
int IHyprLayout::getWindowRegion(Vector2D cursor, CBox window, CBox edge, bool raw) {
// explode if point isn't in rectangle
if (!window.containsPoint(cursor))
return 255;
// middle rectangle of the window with the edges cut off
const CBox middle = {window.x + edge.x, window.y + edge.y, window.w - (edge.x + edge.w), window.h - (edge.y + edge.h)};
std::string b1 = std::to_string(window.x - middle.x);
std::string b2 = std::to_string(window.y - middle.y);
std::string b3 = std::to_string(window.w - middle.w);
std::string b4 = std::to_string(window.h - middle.h);
// Debug::log(WARN, "DIFF: {} {} -- {} {}", b1, b2, b3, b4);
std::string s1 = std::to_string(window.x);
std::string s2 = std::to_string(window.y);
std::string s3 = std::to_string(window.w);
std::string s4 = std::to_string(window.h);
std::string s5 = std::to_string(middle.x);
std::string s6 = std::to_string(middle.y);
std::string s7 = std::to_string(middle.w);
std::string s8 = std::to_string(middle.h);
std::string s9 = std::to_string(cursor.x);
std::string s0 = std::to_string(cursor.y);
// Debug::log(WARN, "Window: {} {} -- {} {}", s1,s2,s3,s4);
// Debug::log(WARN, "Edge: {} {} -- {} {}", edge.x, edge.y, edge.w, edge.h);
// Debug::log(WARN, "Middle: {} {} -- {} {}", s5,s6,s7,s8);
// Debug::log(WARN, "Mouse: {} {}", s9,s0);
// Bit meanings from left to right:
// 10000000 is in bottom half
// 01000000 is in right half
// 00110000 is in left/right edge (exclusive)
// 00001100 is in top/bottom edge (exclusive)
// 00000010 is in bottom left half ([\] diagonal split)
// 00000001 is in bottom right half ([/] diagonal split)
uint8_t BITTALLY = 0;
// cardinals
if (cursor.x > window.x + window.w / 2.0)
BITTALLY |= 1 << 7;
if (cursor.y > window.y + window.h / 2.0)
BITTALLY |= 1 << 6;
if (edge != 0) {
// left edge
if (cursor.x < middle.x)
BITTALLY |= 1 << 5;
// right edge
if (cursor.x > middle.x + middle.w)
BITTALLY |= 1 << 4;
// top edge
if (cursor.y < middle.y)
BITTALLY |= 1 << 3;
// bottom edge
if (cursor.y > middle.y + middle.h)
BITTALLY |= 1 << 2;
}
// look at bits 2 through 5 for edges to check the diagonal(s) where necessary
// divide by zero :trollface:
switch (BITTALLY & 0b00111100) {
case 0b00101000: // top left corner -> check [\] diagonal
if ((cursor.y - middle.y) / (cursor.x - middle.x) < (edge.y / edge.x))
BITTALLY |= 1 << 1;
break;
case 0b00001000: // top edge only -> none
break;
case 0b00011000: // top right corner -> check diagonal
if ((cursor.y - middle.y) / (cursor.x - (middle.x + middle.w)) > (-edge.y / edge.w))
BITTALLY |= 1 << 0;
break;
case 0b00010000: // right edge only == [/] diagonal
BITTALLY |= 1 << 0;
break;
case 0b00010100: // bottom right corner -> [/] diagonal + check [\] diagonal
if ((cursor.y - (middle.y + middle.h)) / (cursor.x - (middle.x + middle.w)) > (edge.h / edge.w))
BITTALLY |= 0b00000011;
else
BITTALLY |= 0b00000001;
break;
case 0b00000100: // bottom edge only == [/] + [\] diagonals
BITTALLY |= 0b00000011;
break;
case 0b00100100: // bottom left corner -> [\] diagonal + check [/] diagonal
if ((cursor.y - (middle.y + middle.h)) / (cursor.x - middle.x) < (edge.h / -edge.x))
BITTALLY |= 0b00000011;
else
BITTALLY |= 0b00000010;
break;
case 0b00100000: // left edge only == [\] diagonal
BITTALLY |= 1 << 1;
break;
default: // catch-all for central rectangle and edge == 0
if ((cursor.y - middle.y) / (cursor.x - middle.x) > middle.h / middle.w)
BITTALLY |= 1 << 1;
if ((cursor.y - (middle.y + middle.h)) / (cursor.x - middle.x) > -1 * middle.h / middle.w)
BITTALLY |= 1 << 0;
break;
}
std::bitset<8> funny = BITTALLY;
Debug::log(WARN, "{}", funny.to_string());
if (!raw)
switch (BITTALLY) {
// ordered clockwise starting and ending at top left quadrant
// center 8 'tiles' (no edges)
case 0b00000000: return 0;
case 0b10000000: return 1;
case 0b10000001: return 2;
case 0b11000001: return 3;
case 0b11000011: return 4;
case 0b01000011: return 5;
case 0b01000010: return 6;
case 0b00000010: return 7;
// edge 8 'tiles' (1 edge)
case 0b00001000: return 8;
case 0b10001000: return 9;
case 0b10010001: return 10;
case 0b11010001: return 11;
case 0b11000111: return 12;
case 0b01000111: return 13;
case 0b01100010: return 14;
case 0b00100010: return 15;
// corner 8 'tiles' (2 edges)
case 0b00101000: return 16;
case 0b10011000: return 17;
case 0b10011001: return 18;
case 0b11010101: return 19;
case 0b11010111: return 20;
case 0b01100111: return 21;
case 0b01100110: return 22;
case 0b00101010: return 23;
// oopsie
default: Debug::log(WARN, "No window region matching table."); return 0;
}
return BITTALLY;
}
void IHyprLayout::onBeginDragWindow() {
@ -222,10 +384,26 @@ void IHyprLayout::onBeginDragWindow() {
m_vBeginDragXY = g_pInputManager->getMouseCoordsInternal();
m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition.goal();
m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.goal();
m_vBeginDragFullPosXY = DRAGGINGWINDOW->m_vPosition;
m_vBeginDragFullSizeXY = DRAGGINGWINDOW->m_vSize;
m_vLastDragXY = m_vBeginDragXY;
// get the grab corner
static auto RESIZECORNER = CConfigValue<Hyprlang::INT>("general:resize_corner");
std::string s1 = std::to_string(m_vBeginDragPositionXY.x);
std::string s2 = std::to_string(m_vBeginDragPositionXY.y);
std::string s3 = std::to_string(m_vBeginDragSizeXY.x);
std::string s4 = std::to_string(m_vBeginDragSizeXY.y);
std::string s5 = std::to_string(m_vBeginDragFullPosXY.x);
std::string s6 = std::to_string(m_vBeginDragFullPosXY.y);
std::string s7 = std::to_string(m_vBeginDragFullSizeXY.x);
std::string s8 = std::to_string(m_vBeginDragFullSizeXY.y);
Debug::log(WARN, "Real: {}, {} -- {}, {}", s1, s2, s3, s4);
Debug::log(WARN, "Full: {}, {} -- {}, {}", s5, s6, s7, s8);
static auto RESIZECORNER = CConfigValue<Hyprlang::INT>("general:resize_corner");
static auto EDGEDEPTH = CConfigValue<Hyprlang::FLOAT>("general:edge_depth");
static auto RESIZEPATTERN = CConfigValue<Hyprlang::INT>("general:resize_mouse_bind_pattern");
if (*RESIZECORNER != 0 && *RESIZECORNER <= 4 && DRAGGINGWINDOW->m_bIsFloating) {
switch (*RESIZECORNER) {
case 1:
@ -245,22 +423,72 @@ void IHyprLayout::onBeginDragWindow() {
g_pInputManager->setCursorImageUntilUnset("sw-resize");
break;
}
} else if (m_vBeginDragXY.x < m_vBeginDragPositionXY.x + m_vBeginDragSizeXY.x / 2.0) {
if (m_vBeginDragXY.y < m_vBeginDragPositionXY.y + m_vBeginDragSizeXY.y / 2.0) {
m_eGrabbedCorner = CORNER_TOPLEFT;
g_pInputManager->setCursorImageUntilUnset("nw-resize");
} else {
m_eGrabbedCorner = CORNER_BOTTOMLEFT;
g_pInputManager->setCursorImageUntilUnset("sw-resize");
}
} else {
if (m_vBeginDragXY.y < m_vBeginDragPositionXY.y + m_vBeginDragSizeXY.y / 2.0) {
m_eGrabbedCorner = CORNER_TOPRIGHT;
g_pInputManager->setCursorImageUntilUnset("ne-resize");
} else {
m_eGrabbedCorner = CORNER_BOTTOMRIGHT;
g_pInputManager->setCursorImageUntilUnset("se-resize");
CBox window = {m_vBeginDragFullPosXY, m_vBeginDragFullSizeXY};
CBox edge;
if (DRAGGINGWINDOW->m_bIsPseudotiled) {
static auto b = CConfigValue<Hyprlang::INT>("general:border_size");
static auto r = CConfigValue<Hyprlang::INT>("general:resize_on_border");
static auto e = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area");
const CBox h = {-(*b + *e * (*r != 0)), -(*b + *e * (*r != 0)), 2 * (*b + *e * (*r != 0)), 2 * (*b + *e * (*r != 0))};
const CBox p = {m_vBeginDragPositionXY + h.pos(), m_vBeginDragSizeXY + h.size()};
if (p.containsPoint(m_vBeginDragXY))
window = p;
}
if (*EDGEDEPTH <= 0)
edge = 0;
else if (*EDGEDEPTH < 1)
edge = window.h > window.w ? window.w / 2 * *EDGEDEPTH : window.h / 2 * *EDGEDEPTH;
else
edge = std::clamp((int)*EDGEDEPTH, 1, window.h > window.w ? (int)window.w / 2 : (int)window.h / 2);
// get grabbed corner/edge
const uint8_t region = getWindowRegion(m_vBeginDragXY, window, edge);
const std::string direction[] = {"move", "nw-resize", "ne-resize", "se-resize", "sw-resize", "n-resize", "e-resize", "s-resize", "w-resize"};
// clang-format off
// pattern definitions
// a pattern can contain values 0 through 8 to match the valid values of eRectCorner
// for ease of reading, the patterns are broken up into groups of 8 values (center, edge, corner)
std::vector<int> pattern = {1, 2, 2, 3, 3, 4, 4, 1,
1, 2, 2, 3, 3, 4, 4, 1,
1, 2, 2, 3, 3, 4, 4, 1};
switch ((int)*RESIZEPATTERN) {
case 1: // window pattern: edges & corners = cardinal, center = diagonal
pattern = {1, 2, 2, 3, 3, 4, 4, 1,
5, 5, 6, 6, 7, 7, 8, 8,
5, 5, 6, 6, 7, 7, 8, 8};
break;
case 2: // chess pattern: edges = cardinal, corners & center = diagonal
pattern = {1, 2, 2, 3, 3, 4, 4, 1,
5, 5, 6, 6, 7, 7, 8, 8,
1, 2, 2, 3, 3, 4, 4, 1};
break;
case 3: // cross pattern: center & edges = cardinal, corners = diagonal
pattern = {5, 5, 6, 6, 7, 7, 8, 8,
5, 5, 6, 6, 7, 7, 8, 8,
1, 2, 2, 3, 3, 4, 4, 1};
break;
case 4: // cardinal only
pattern = {5, 5, 6, 6, 7, 7, 8, 8,
5, 5, 6, 6, 7, 7, 8, 8,
5, 5, 6, 6, 7, 7, 8, 8};
break;
case 420: // having a trip
for (std::size_t i = 0; i != pattern.size(); ++i)
pattern[i] = std::rand() % 8;
break;
default: break;
}
// clang-format on
// we translate the value into the desired direction through table lookup
m_eGrabbedCorner = static_cast<eRectCorner>(pattern[region]);
g_pInputManager->setCursorImageUntilUnset(direction[pattern[region]]);
}
if (g_pInputManager->dragMode != MBIND_RESIZE && g_pInputManager->dragMode != MBIND_RESIZE_FORCE_RATIO && g_pInputManager->dragMode != MBIND_RESIZE_BLOCK_RATIO)
@ -381,6 +609,8 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
DRAGGINGWINDOW->m_vRealPosition = wb.pos();
else
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos());
// update window pos alongside realpos
DRAGGINGWINDOW->m_vPosition = m_vBeginDragFullPosXY + DELTA;
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goal());
} else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) {
@ -392,14 +622,17 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
Vector2D newSize = m_vBeginDragSizeXY;
Vector2D newPos = m_vBeginDragPositionXY;
if (m_eGrabbedCorner == CORNER_BOTTOMRIGHT)
newSize = newSize + DELTA;
else if (m_eGrabbedCorner == CORNER_TOPLEFT)
newSize = newSize - DELTA;
else if (m_eGrabbedCorner == CORNER_TOPRIGHT)
newSize = newSize + Vector2D(DELTA.x, -DELTA.y);
else if (m_eGrabbedCorner == CORNER_BOTTOMLEFT)
newSize = newSize + Vector2D(-DELTA.x, DELTA.y);
switch (m_eGrabbedCorner) {
case CORNER_NONE: break;
case CORNER_TOPLEFT: newSize = newSize - DELTA; break;
case CORNER_TOPRIGHT: newSize = newSize + Vector2D(DELTA.x, -DELTA.y); break;
case CORNER_BOTTOMRIGHT: newSize = newSize + DELTA; break;
case CORNER_BOTTOMLEFT: newSize = newSize + Vector2D(-DELTA.x, DELTA.y); break;
case EDGE_TOP: newSize = newSize + Vector2D(0.0, -DELTA.y); break;
case EDGE_RIGHT: newSize = newSize + Vector2D(DELTA.x, 0.0); break;
case EDGE_BOTTOM: newSize = newSize + Vector2D(0.0, DELTA.y); break;
case EDGE_LEFT: newSize = newSize + Vector2D(-DELTA.x, 0.0); break;
}
if ((m_vBeginDragSizeXY.x >= 1 && m_vBeginDragSizeXY.y >= 1) &&
(g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO ||
@ -425,15 +658,18 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
newSize = newSize.clamp(MINSIZE, MAXSIZE);
if (m_eGrabbedCorner == CORNER_TOPLEFT)
newPos = newPos - newSize + m_vBeginDragSizeXY;
else if (m_eGrabbedCorner == CORNER_TOPRIGHT)
newPos = newPos + Vector2D(0.0, (m_vBeginDragSizeXY - newSize).y);
else if (m_eGrabbedCorner == CORNER_BOTTOMLEFT)
newPos = newPos + Vector2D((m_vBeginDragSizeXY - newSize).x, 0.0);
switch (m_eGrabbedCorner) {
case CORNER_TOPLEFT: newPos = newPos - newSize + m_vBeginDragSizeXY; break;
case CORNER_TOPRIGHT: newPos = newPos + Vector2D(0.0, (m_vBeginDragSizeXY - newSize).y); break;
case CORNER_BOTTOMLEFT: newPos = newPos + Vector2D((m_vBeginDragSizeXY - newSize).x, 0.0); break;
case EDGE_TOP: newPos = newPos + Vector2D(0.0, (m_vBeginDragSizeXY - newSize).y); break;
case EDGE_LEFT: newPos = newPos + Vector2D((m_vBeginDragSizeXY - newSize).x, 0.0); break;
default: break;
}
CBox wb = {newPos, newSize};
wb.round();
CBox transform = {wb.pos() - m_vBeginDragPositionXY, wb.size() - m_vBeginDragSizeXY};
if (*PANIMATE) {
DRAGGINGWINDOW->m_vRealSize = wb.size();
@ -443,6 +679,12 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos());
}
// update window size and pos alongisde realsize and realpos
// not always correct if the user messes with the config values
// but it's corrected on float/unfloat so whatever :P
DRAGGINGWINDOW->m_vSize = m_vBeginDragFullSizeXY + transform.size();
DRAGGINGWINDOW->m_vPosition = m_vBeginDragFullPosXY + transform.pos();
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goal());
} else {
resizeActiveWindow(TICKDELTA, m_eGrabbedCorner, DRAGGINGWINDOW);
@ -522,7 +764,13 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
g_pCompositor->changeWindowZOrder(pWindow, true);
CBox wb = {pWindow->m_vRealPosition.goal() + (pWindow->m_vRealSize.goal() - pWindow->m_vLastFloatingSize) / 2.f, pWindow->m_vLastFloatingSize};
// additional hitbox area to be added to floating windows
static auto b = CConfigValue<Hyprlang::INT>("general:border_size");
static auto r = CConfigValue<Hyprlang::INT>("general:resize_on_border");
static auto e = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area");
const CBox h = {-(*b + *e * (*r != 0)), -(*b + *e * (*r != 0)), 2 * (*b + *e * (*r != 0)), 2 * (*b + *e * (*r != 0))};
CBox wb = {pWindow->m_vRealPosition.goal() + (pWindow->m_vRealSize.goal() - pWindow->m_vLastFloatingSize) / 2.f, pWindow->m_vLastFloatingSize};
wb.round();
if (!(pWindow->m_bIsFloating && pWindow->m_bIsPseudotiled) && DELTALESSTHAN(pWindow->m_vRealSize.value().x, pWindow->m_vLastFloatingSize.x, 10) &&
@ -533,8 +781,8 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
pWindow->m_vRealPosition = wb.pos();
pWindow->m_vRealSize = wb.size();
pWindow->m_vSize = wb.pos();
pWindow->m_vPosition = wb.size();
pWindow->m_vPosition = wb.pos() + h.pos();
pWindow->m_vSize = wb.size() + h.size();
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
@ -563,6 +811,7 @@ void IHyprLayout::moveActiveWindow(const Vector2D& delta, PHLWINDOW pWindow) {
PWINDOW->setAnimationsToMove();
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + delta;
PWINDOW->m_vPosition = PWINDOW->m_vPosition + delta;
g_pHyprRenderer->damageWindow(PWINDOW);
}

View File

@ -1,7 +1,10 @@
#pragma once
#include "../defines.hpp"
#include "hyprutils/math/Box.hpp"
#include "hyprutils/math/Vector2D.hpp"
#include <any>
#include <cstdint>
class CWindow;
class CGradientValueData;
@ -22,7 +25,11 @@ enum eRectCorner {
CORNER_TOPLEFT,
CORNER_TOPRIGHT,
CORNER_BOTTOMRIGHT,
CORNER_BOTTOMLEFT
CORNER_BOTTOMLEFT,
EDGE_TOP,
EDGE_RIGHT,
EDGE_BOTTOM,
EDGE_LEFT
};
enum eDirection {
@ -75,6 +82,13 @@ class IHyprLayout {
Called when a window is requested to be floated
*/
virtual void changeWindowFloatingMode(PHLWINDOW);
/*
Called when cursor position on a window is requested. Returns a value between from 0 to 23
depending on the parameters given or the raw uint8_t to be interpreted by its bit composition.
*/
virtual int getWindowRegion(Vector2D cursor, CBox window, CBox edge = 0, bool raw = false);
/*
Called when a window is clicked on, beginning a drag
this might be a resize, move, whatever the layout defines it
@ -201,6 +215,8 @@ class IHyprLayout {
Vector2D m_vLastDragXY;
Vector2D m_vBeginDragPositionXY;
Vector2D m_vBeginDragSizeXY;
Vector2D m_vBeginDragFullPosXY;
Vector2D m_vBeginDragFullSizeXY;
Vector2D m_vDraggingWindowOriginalFloatSize;
eRectCorner m_eGrabbedCorner = CORNER_TOPLEFT;

View File

@ -763,8 +763,8 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
const bool DISPLAYTOP = STICKS(PWINDOW->m_vPosition.y, PMONITOR->vecPosition.y + PMONITOR->vecReservedTopLeft.y);
const bool DISPLAYLEFT = STICKS(PWINDOW->m_vPosition.x, PMONITOR->vecPosition.x + PMONITOR->vecReservedTopLeft.x);
const bool LEFT = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT;
const bool TOP = corner == CORNER_TOPLEFT || corner == CORNER_TOPRIGHT;
const bool LEFT = corner == EDGE_LEFT || corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT;
const bool TOP = corner == EDGE_TOP || corner == CORNER_TOPLEFT || corner == CORNER_TOPRIGHT;
const bool NONE = corner == CORNER_NONE;
const auto MASTERS = getMastersOnWorkspace(PNODE->workspaceID);

View File

@ -1473,14 +1473,7 @@ void CInputManager::updateCapabilities() {
if (h.expired())
continue;
auto cap = h->getCapabilities();
if (cap & HID_INPUT_CAPABILITY_KEYBOARD)
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
if (cap & HID_INPUT_CAPABILITY_POINTER)
caps |= WL_SEAT_CAPABILITY_POINTER;
if (cap & HID_INPUT_CAPABILITY_TOUCH)
caps |= WL_SEAT_CAPABILITY_TOUCH;
caps |= h->getCapabilities();
}
g_pSeatManager->updateCapabilities(caps);

View File

@ -7,8 +7,8 @@
#define LOGM PROTO::constraints->protoLog
CPointerConstraint::CPointerConstraint(SP<CZwpLockedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime) :
resourceL(resource_), locked(true) {
CPointerConstraint::CPointerConstraint(SP<CZwpLockedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime_) :
resourceL(resource_), locked(true), lifetime(lifetime_) {
if (!resource_->resource())
return;
@ -46,8 +46,8 @@ CPointerConstraint::CPointerConstraint(SP<CZwpLockedPointerV1> resource_, SP<CWL
sharedConstructions();
}
CPointerConstraint::CPointerConstraint(SP<CZwpConfinedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime) :
resourceC(resource_), locked(false) {
CPointerConstraint::CPointerConstraint(SP<CZwpConfinedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime_) :
resourceC(resource_), locked(false), lifetime(lifetime_) {
if (!resource_->resource())
return;

View File

@ -16,8 +16,8 @@ class CWLSurfaceResource;
class CPointerConstraint {
public:
CPointerConstraint(SP<CZwpLockedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region, zwpPointerConstraintsV1Lifetime lifetime);
CPointerConstraint(SP<CZwpConfinedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region, zwpPointerConstraintsV1Lifetime lifetime);
CPointerConstraint(SP<CZwpLockedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region, zwpPointerConstraintsV1Lifetime lifetime_);
CPointerConstraint(SP<CZwpConfinedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region, zwpPointerConstraintsV1Lifetime lifetime_);
~CPointerConstraint();
bool good();