aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorVaxry <[email protected]>2023-09-20 16:47:05 +0100
committerGitHub <[email protected]>2023-09-20 16:47:05 +0100
commit0dbd9970031940b50f9cce4c88989c2830d2a15f (patch)
tree0dd50dd13e19e663444b1e78d14104c40dabbf76
parent3785defaf12b9d99137b2f4c74ab82c51cf733e1 (diff)
downloadHyprland-0dbd9970031940b50f9cce4c88989c2830d2a15f.tar.gz
Hyprland-0dbd9970031940b50f9cce4c88989c2830d2a15f.zip
input: Various constraint handling fixes (#3381)
Fixes #3204
-rw-r--r--src/Compositor.cpp7
-rw-r--r--src/helpers/Monitor.hpp1
-rw-r--r--src/helpers/Region.cpp12
-rw-r--r--src/helpers/Region.hpp9
-rw-r--r--src/helpers/WLClasses.cpp77
-rw-r--r--src/helpers/WLClasses.hpp8
-rw-r--r--src/managers/input/InputManager.cpp21
7 files changed, 114 insertions, 21 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index e2b920c2..99e62a46 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -875,7 +875,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
const auto PWORKSPACE = getWorkspaceByID(pWindow->m_iWorkspaceID);
PWORKSPACE->m_pLastFocusedWindow = pWindow;
PWORKSPACE->rememberPrevWorkspace(getWorkspaceByID(m_pLastMonitor->activeWorkspace));
- const auto PMONITOR = getMonitorFromID(PWORKSPACE->m_iMonitorID);
+ const auto PMONITOR = getMonitorFromID(PWORKSPACE->m_iMonitorID);
PMONITOR->changeWorkspace(PWORKSPACE, false, true);
// changeworkspace already calls focusWindow
return;
@@ -2530,5 +2530,10 @@ void CCompositor::arrangeMonitors() {
Debug::log(LOG, "arrangeMonitors: {} xwayland [{}, {:.2f}]", m->szName, maxOffset, 0.f);
m->vecXWaylandPosition = {maxOffset, 0};
maxOffset += (*PXWLFORCESCALEZERO ? m->vecTransformedSize.x : m->vecSize.x);
+
+ if (*PXWLFORCESCALEZERO)
+ m->xwaylandScale = m->scale;
+ else
+ m->xwaylandScale = 1.f;
}
}
diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp
index 2c4d4a89..93f345ba 100644
--- a/src/helpers/Monitor.hpp
+++ b/src/helpers/Monitor.hpp
@@ -59,6 +59,7 @@ class CMonitor {
bool scheduledRecalc = false;
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
bool gammaChanged = false;
+ float xwaylandScale = 1.f;
bool dpmsStatus = true;
bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it.
diff --git a/src/helpers/Region.cpp b/src/helpers/Region.cpp
index 644bd5d4..e2db4664 100644
--- a/src/helpers/Region.cpp
+++ b/src/helpers/Region.cpp
@@ -1,5 +1,6 @@
#include "Region.hpp"
#include <wlr/util/box.h>
+#include <wlr/util/region.h>
CRegion::CRegion() {
pixman_region32_init(&m_rRegion);
@@ -81,6 +82,11 @@ CRegion& CRegion::translate(const Vector2D& vec) {
return *this;
}
+CRegion& CRegion::scale(float scale) {
+ wlr_region_scale(&m_rRegion, &m_rRegion, scale);
+ return *this;
+}
+
std::vector<pixman_box32_t> CRegion::getRects() const {
std::vector<pixman_box32_t> result;
@@ -97,15 +103,15 @@ wlr_box CRegion::getExtents() {
return {box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1};
}
-bool CRegion::containsPoint(const Vector2D& vec) {
+bool CRegion::containsPoint(const Vector2D& vec) const {
return pixman_region32_contains_point(&m_rRegion, vec.x, vec.y, nullptr);
}
-bool CRegion::empty() {
+bool CRegion::empty() const {
return !pixman_region32_not_empty(&m_rRegion);
}
-Vector2D CRegion::closestPoint(const Vector2D& vec) {
+Vector2D CRegion::closestPoint(const Vector2D& vec) const {
double bestDist = __FLT_MAX__;
Vector2D leader = vec;
diff --git a/src/helpers/Region.hpp b/src/helpers/Region.hpp
index e5a99da2..cc745f9e 100644
--- a/src/helpers/Region.hpp
+++ b/src/helpers/Region.hpp
@@ -42,15 +42,16 @@ class CRegion {
CRegion& intersect(double x, double y, double w, double h);
CRegion& translate(const Vector2D& vec);
CRegion& invert(pixman_box32_t* box);
+ CRegion& scale(float scale);
wlr_box getExtents();
- bool containsPoint(const Vector2D& vec);
- bool empty();
- Vector2D closestPoint(const Vector2D& vec);
+ bool containsPoint(const Vector2D& vec) const;
+ bool empty() const;
+ Vector2D closestPoint(const Vector2D& vec) const;
std::vector<pixman_box32_t> getRects() const;
pixman_region32_t* pixman() {
- return &m_rRegion;
+ return &m_rRegion;
}
private:
diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp
index c257b6b8..1fa807fa 100644
--- a/src/helpers/WLClasses.cpp
+++ b/src/helpers/WLClasses.cpp
@@ -1,5 +1,6 @@
#include "WLClasses.hpp"
#include "../config/ConfigManager.hpp"
+#include "../Compositor.hpp"
SLayerSurface::SLayerSurface() {
alpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), nullptr, AVARDAMAGE_ENTIRE);
@@ -37,4 +38,80 @@ void SLayerSurface::applyRules() {
} catch (...) {}
}
}
+}
+
+CRegion SConstraint::getLogicCoordsRegion() {
+ CRegion result;
+
+ if (!constraint)
+ return result;
+
+ const auto PWINDOWOWNER = g_pCompositor->getWindowFromSurface(constraint->surface);
+
+ if (!PWINDOWOWNER)
+ return result;
+
+ result.add(&constraint->region); // surface-local coords
+
+ if (!PWINDOWOWNER->m_bIsX11) {
+ result.translate(PWINDOWOWNER->m_vRealPosition.goalv());
+ return result;
+ }
+
+ const auto COORDS = PWINDOWOWNER->m_bIsMapped ? PWINDOWOWNER->m_vRealPosition.goalv() :
+ g_pXWaylandManager->xwaylandToWaylandCoords({PWINDOWOWNER->m_uSurface.xwayland->x, PWINDOWOWNER->m_uSurface.xwayland->y});
+
+ const auto PMONITOR = PWINDOWOWNER->m_bIsMapped ? g_pCompositor->getMonitorFromID(PWINDOWOWNER->m_iMonitorID) : g_pCompositor->getMonitorFromVector(COORDS);
+
+ if (!PMONITOR)
+ return CRegion{};
+
+ result.scale(PMONITOR->xwaylandScale);
+
+ result.translate(COORDS);
+
+ return result;
+}
+
+Vector2D SConstraint::getLogicConstraintPos() {
+ if (!constraint)
+ return {};
+
+ const auto PWINDOWOWNER = g_pCompositor->getWindowFromSurface(constraint->surface);
+
+ if (!PWINDOWOWNER)
+ return {};
+
+ if (!PWINDOWOWNER->m_bIsX11)
+ return PWINDOWOWNER->m_vRealPosition.goalv();
+
+ const auto COORDS = PWINDOWOWNER->m_bIsMapped ? PWINDOWOWNER->m_vRealPosition.goalv() :
+ g_pXWaylandManager->xwaylandToWaylandCoords({PWINDOWOWNER->m_uSurface.xwayland->x, PWINDOWOWNER->m_uSurface.xwayland->y});
+
+ return COORDS;
+}
+
+Vector2D SConstraint::getLogicConstraintSize() {
+ if (!constraint)
+ return {};
+
+ const auto PWINDOWOWNER = g_pCompositor->getWindowFromSurface(constraint->surface);
+
+ if (!PWINDOWOWNER)
+ return {};
+
+ if (!PWINDOWOWNER->m_bIsX11)
+ return PWINDOWOWNER->m_vRealSize.goalv();
+
+ const auto PMONITOR = PWINDOWOWNER->m_bIsMapped ?
+ g_pCompositor->getMonitorFromID(PWINDOWOWNER->m_iMonitorID) :
+ g_pCompositor->getMonitorFromVector(g_pXWaylandManager->xwaylandToWaylandCoords({PWINDOWOWNER->m_uSurface.xwayland->x, PWINDOWOWNER->m_uSurface.xwayland->y}));
+
+ if (!PMONITOR)
+ return {};
+
+ const auto SIZE = PWINDOWOWNER->m_bIsMapped ? PWINDOWOWNER->m_vRealSize.goalv() :
+ Vector2D{PWINDOWOWNER->m_uSurface.xwayland->width, PWINDOWOWNER->m_uSurface.xwayland->height} * PMONITOR->xwaylandScale;
+
+ return SIZE;
} \ No newline at end of file
diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp
index 84f6d898..d66ebdfd 100644
--- a/src/helpers/WLClasses.hpp
+++ b/src/helpers/WLClasses.hpp
@@ -174,8 +174,12 @@ struct SConstraint {
DYNLISTENER(setConstraintRegion);
DYNLISTENER(destroyConstraint);
- bool operator==(const SConstraint& b) const {
- return constraint == b.constraint;
+ CRegion getLogicCoordsRegion();
+ Vector2D getLogicConstraintPos();
+ Vector2D getLogicConstraintSize();
+
+ bool operator==(const SConstraint& b) const {
+ return constraint == b.constraint;
}
};
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp
index 468f2816..ec1534d5 100644
--- a/src/managers/input/InputManager.cpp
+++ b/src/managers/input/InputManager.cpp
@@ -144,26 +144,25 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
} else {
// Native Wayland apps know how 2 constrain themselves.
// XWayland, we just have to accept them. Might cause issues, but thats XWayland for ya.
- const auto CONSTRAINTPOS =
- CONSTRAINTWINDOW->m_bIsX11 ? Vector2D(CONSTRAINTWINDOW->m_uSurface.xwayland->x, CONSTRAINTWINDOW->m_uSurface.xwayland->y) : CONSTRAINTWINDOW->m_vRealPosition.vec();
- const auto CONSTRAINTSIZE = CONSTRAINTWINDOW->m_bIsX11 ? Vector2D(CONSTRAINTWINDOW->m_uSurface.xwayland->width, CONSTRAINTWINDOW->m_uSurface.xwayland->height) :
- CONSTRAINTWINDOW->m_vRealSize.vec();
+ const auto CONSTRAINTPOS = PCONSTRAINT->getLogicConstraintPos();
+ const auto CONSTRAINTSIZE = PCONSTRAINT->getLogicConstraintSize();
if (g_pCompositor->m_sSeat.mouse->currentConstraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED) {
// we just snap the cursor to where it should be.
- Vector2D hint = {PCONSTRAINT->positionHint.x, PCONSTRAINT->positionHint.y};
-
- if (hint != Vector2D{-1, -1})
- wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, CONSTRAINTPOS.x + hint.x, CONSTRAINTPOS.y + hint.y);
+ if (PCONSTRAINT->hintSet)
+ wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, CONSTRAINTPOS.x + PCONSTRAINT->positionHint.x,
+ CONSTRAINTPOS.y + PCONSTRAINT->positionHint.y);
return; // don't process anything else, the cursor is locked. The surface should not receive any further events.
// these are usually FPS games. They will use the relative motion.
} else {
// we restrict the cursor to the confined region
- if (!pixman_region32_contains_point(&PCONSTRAINT->constraint->region, mouseCoords.x - CONSTRAINTPOS.x, mouseCoords.y - CONSTRAINTPOS.y, nullptr)) {
+ const auto REGION = PCONSTRAINT->getLogicCoordsRegion();
+
+ if (!REGION.containsPoint(mouseCoords)) {
if (g_pCompositor->m_sSeat.mouse->constraintActive) {
- const auto CLOSEST = CRegion(&PCONSTRAINT->constraint->region).closestPoint(mouseCoords - CONSTRAINTPOS) + CONSTRAINTPOS;
+ const auto CLOSEST = REGION.closestPoint(mouseCoords);
wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, NULL, CLOSEST.x, CLOSEST.y);
mouseCoords = getMouseCoordsInternal();
}
@@ -1595,7 +1594,7 @@ void CInputManager::setCursorIconOnBorder(CWindow* w) {
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
eBorderIconDirection direction = BORDERICON_NONE;
wlr_box boxFullGrabInput = {box.x - *PEXTENDBORDERGRAB - BORDERSIZE, box.y - *PEXTENDBORDERGRAB - BORDERSIZE, box.width + 2 * (*PEXTENDBORDERGRAB + BORDERSIZE),
- box.height + 2 * (*PEXTENDBORDERGRAB + BORDERSIZE)};
+ box.height + 2 * (*PEXTENDBORDERGRAB + BORDERSIZE)};
if (!wlr_box_contains_point(&boxFullGrabInput, mouseCoords.x, mouseCoords.y) || (!m_lCurrentlyHeldButtons.empty() && !currentlyDraggedWindow)) {
direction = BORDERICON_NONE;