Skip to content

Commit

Permalink
input: Various constraint handling fixes (#3381)
Browse files Browse the repository at this point in the history
Fixes #3204
  • Loading branch information
vaxerski authored Sep 20, 2023
1 parent 3785def commit 0dbd997
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 21 deletions.
7 changes: 6 additions & 1 deletion src/Compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}
1 change: 1 addition & 0 deletions src/helpers/Monitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
12 changes: 9 additions & 3 deletions src/helpers/Region.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Region.hpp"
#include <wlr/util/box.h>
#include <wlr/util/region.h>

CRegion::CRegion() {
pixman_region32_init(&m_rRegion);
Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand Down
9 changes: 5 additions & 4 deletions src/helpers/Region.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
77 changes: 77 additions & 0 deletions src/helpers/WLClasses.cpp
Original file line number Diff line number Diff line change
@@ -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);
Expand Down Expand Up @@ -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;
}
8 changes: 6 additions & 2 deletions src/helpers/WLClasses.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
};

Expand Down
21 changes: 10 additions & 11 deletions src/managers/input/InputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 0dbd997

Please sign in to comment.