handle constraint cursor hints better

This commit is contained in:
vaxerski 2022-12-10 14:43:46 +00:00
parent bf78dcecf0
commit 62f4503f07
4 changed files with 41 additions and 9 deletions

View file

@ -110,6 +110,11 @@ void Events::listener_newConstraint(wl_listener* listener, void* data) {
if (g_pCompositor->m_pLastFocus == PCONSTRAINT->surface) { if (g_pCompositor->m_pLastFocus == PCONSTRAINT->surface) {
g_pInputManager->constrainMouse(CONSTRAINT->pMouse, PCONSTRAINT); g_pInputManager->constrainMouse(CONSTRAINT->pMouse, PCONSTRAINT);
if (!CONSTRAINT->hintSet) {
const auto PWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse);
CONSTRAINT->positionHint = g_pInputManager->getMouseCoordsInternal() - PWINDOW->m_vRealPosition.goalv();
}
} }
} }
@ -124,14 +129,14 @@ void Events::listener_destroyConstraint(void* owner, void* data) {
if (PWINDOW) { if (PWINDOW) {
if (PWINDOW->m_bIsX11) { if (PWINDOW->m_bIsX11) {
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr,
PCONSTRAINT->constraint->current.cursor_hint.x + PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y + PCONSTRAINT->constraint->current.cursor_hint.y); PCONSTRAINT->positionHint.x + PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y + PCONSTRAINT->positionHint.y);
wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->constraint->current.cursor_hint.x, PCONSTRAINT->constraint->current.cursor_hint.y); wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->positionHint.x, PCONSTRAINT->positionHint.y);
} else { } else {
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr,
PCONSTRAINT->constraint->current.cursor_hint.x + PWINDOW->m_vRealPosition.vec().x, PCONSTRAINT->constraint->current.cursor_hint.y + PWINDOW->m_vRealPosition.vec().y); PCONSTRAINT->positionHint.x + PWINDOW->m_vRealPosition.vec().x, PCONSTRAINT->positionHint.y + PWINDOW->m_vRealPosition.vec().y);
wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->constraint->current.cursor_hint.x, PCONSTRAINT->constraint->current.cursor_hint.y); wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->positionHint.x, PCONSTRAINT->positionHint.y);
} }
} }

View file

@ -146,6 +146,9 @@ struct SConstraint {
SMouse* pMouse = nullptr; SMouse* pMouse = nullptr;
wlr_pointer_constraint_v1* constraint = nullptr; wlr_pointer_constraint_v1* constraint = nullptr;
bool hintSet = false;
Vector2D positionHint; // the position hint, but will be set to the current cursor pos if not set.
DYNLISTENER(setConstraintRegion); DYNLISTENER(setConstraintRegion);
DYNLISTENER(destroyConstraint); DYNLISTENER(destroyConstraint);

View file

@ -73,9 +73,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
// XWayland windows sometimes issue constraints weirdly. // XWayland windows sometimes issue constraints weirdly.
// TODO: We probably should search their parent. wlr_xwayland_surface->parent // TODO: We probably should search their parent. wlr_xwayland_surface->parent
const auto CONSTRAINTWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse); const auto CONSTRAINTWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse);
const auto PCONSTRAINT = g_pCompositor->m_sSeat.mouse->currentConstraint; const auto PCONSTRAINT = constraintFromWlr(g_pCompositor->m_sSeat.mouse->currentConstraint);
if (!CONSTRAINTWINDOW) { if (!CONSTRAINTWINDOW || !PCONSTRAINT) {
unconstrainMouse(); unconstrainMouse();
} else { } else {
// Native Wayland apps know how 2 constrain themselves. // Native Wayland apps know how 2 constrain themselves.
@ -86,7 +86,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (g_pCompositor->m_sSeat.mouse->currentConstraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED) { if (g_pCompositor->m_sSeat.mouse->currentConstraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED) {
// we just snap the cursor to where it should be. // we just snap the cursor to where it should be.
Vector2D hint = { PCONSTRAINT->current.cursor_hint.x, PCONSTRAINT->current.cursor_hint.y }; Vector2D hint = { PCONSTRAINT->positionHint.x, PCONSTRAINT->positionHint.y };
wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, CONSTRAINTPOS.x + hint.x, CONSTRAINTPOS.y + hint.y); wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, CONSTRAINTPOS.x + hint.x, CONSTRAINTPOS.y + hint.y);
@ -94,7 +94,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
// these are usually FPS games. They will use the relative motion. // these are usually FPS games. They will use the relative motion.
} else { } else {
// we restrict the cursor to the confined region // we restrict the cursor to the confined region
if (!pixman_region32_contains_point(&PCONSTRAINT->region, mouseCoords.x - CONSTRAINTPOS.x, mouseCoords.y - CONSTRAINTPOS.y, nullptr)) { if (!pixman_region32_contains_point(&PCONSTRAINT->constraint->region, mouseCoords.x - CONSTRAINTPOS.x, mouseCoords.y - CONSTRAINTPOS.y, nullptr)) {
if (g_pCompositor->m_sSeat.mouse->constraintActive) { if (g_pCompositor->m_sSeat.mouse->constraintActive) {
wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, NULL, mouseCoords.x, mouseCoords.y); wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, NULL, mouseCoords.x, mouseCoords.y);
mouseCoords = getMouseCoordsInternal(); mouseCoords = getMouseCoordsInternal();
@ -964,6 +964,12 @@ void CInputManager::constrainMouse(SMouse* pMouse, wlr_pointer_constraint_v1* co
wlr_seat_pointer_warp(constraint->seat, constraint->current.cursor_hint.x, constraint->current.cursor_hint.y); wlr_seat_pointer_warp(constraint->seat, constraint->current.cursor_hint.x, constraint->current.cursor_hint.y);
} }
} }
const auto PCONSTRAINT = constraintFromWlr(constraint);
if (PCONSTRAINT) { // should never be null but who knows
PCONSTRAINT->positionHint = Vector2D(constraint->current.cursor_hint.x, constraint->current.cursor_hint.y);
PCONSTRAINT->hintSet = true;
}
} }
} }
@ -1009,7 +1015,15 @@ void CInputManager::unconstrainMouse() {
} }
void Events::listener_commitConstraint(void* owner, void* data) { void Events::listener_commitConstraint(void* owner, void* data) {
//g_pInputManager->recheckConstraint((SMouse*)owner); const auto PMOUSE = (SMouse*)owner;
if (PMOUSE->currentConstraint->current.committed & WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT) {
const auto PCONSTRAINT = g_pInputManager->constraintFromWlr(PMOUSE->currentConstraint);
if (PCONSTRAINT) { // should never be null but who knows
PCONSTRAINT->positionHint = Vector2D(PMOUSE->currentConstraint->current.cursor_hint.x, PMOUSE->currentConstraint->current.cursor_hint.y);
PCONSTRAINT->hintSet = true;
}
}
} }
void CInputManager::updateCapabilities() { void CInputManager::updateCapabilities() {
@ -1224,3 +1238,12 @@ std::string CInputManager::getNameForNewDevice(std::string internalName) {
return proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); return proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno)));
} }
SConstraint* CInputManager::constraintFromWlr(wlr_pointer_constraint_v1* constraint) {
for (auto& c : m_lConstraints) {
if (c.constraint == constraint)
return &c;
}
return nullptr;
}

View file

@ -50,6 +50,7 @@ public:
void constrainMouse(SMouse*, wlr_pointer_constraint_v1*); void constrainMouse(SMouse*, wlr_pointer_constraint_v1*);
void recheckConstraint(SMouse*); void recheckConstraint(SMouse*);
void unconstrainMouse(); void unconstrainMouse();
SConstraint* constraintFromWlr(wlr_pointer_constraint_v1*);
std::string getActiveLayoutForKeyboard(SKeyboard*); std::string getActiveLayoutForKeyboard(SKeyboard*);
Vector2D getMouseCoordsInternal(); Vector2D getMouseCoordsInternal();