mirror of
https://github.com/hyprwm/Hyprland
synced 2026-05-07 10:38:01 +02:00
desktop/windowRule: add confine_pointer window rule (#13379)
This commit is contained in:
parent
30cd345add
commit
e180c59b46
6 changed files with 54 additions and 26 deletions
|
|
@ -101,6 +101,7 @@ namespace Config::Lua::Bindings::Internal {
|
|||
{"no_screen_share", []() -> ILuaConfigValue* { return new CLuaConfigBool(false); }, WE::WINDOW_RULE_EFFECT_NO_SCREEN_SHARE},
|
||||
{"no_vrr", []() -> ILuaConfigValue* { return new CLuaConfigBool(false); }, WE::WINDOW_RULE_EFFECT_NO_VRR},
|
||||
{"stay_focused", []() -> ILuaConfigValue* { return new CLuaConfigBool(false); }, WE::WINDOW_RULE_EFFECT_STAY_FOCUSED},
|
||||
{"confine_pointer", []() -> ILuaConfigValue* { return new CLuaConfigBool(false); }, WE::WINDOW_RULE_EFFECT_CONFINE_POINTER},
|
||||
};
|
||||
|
||||
std::string argStr(lua_State* L, int idx);
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@ std::unordered_set<CWindowRuleEffectContainer::storageType> CWindowRuleApplicato
|
|||
std::pair{std::ref(m_noFollowMouse), [this] { return noFollowMouseEffect(); }}, std::pair{std::ref(m_noScreenShare), [this] { return noScreenShareEffect(); }},
|
||||
std::pair{std::ref(m_noVRR), [this] { return noVRREffect(); }}, std::pair{std::ref(m_persistentSize), [this] { return persistentSizeEffect(); }},
|
||||
std::pair{std::ref(m_stayFocused), [this] { return stayFocusedEffect(); }}, std::pair{std::ref(m_idleInhibitMode), [this] { return idleInhibitModeEffect(); }},
|
||||
std::pair{std::ref(m_borderSize), [this] { return borderSizeEffect(); }}, std::pair{std::ref(m_rounding), [this] { return roundingEffect(); }},
|
||||
std::pair{std::ref(m_roundingPower), [this] { return roundingPowerEffect(); }}, std::pair{std::ref(m_scrollMouse), [this] { return scrollMouseEffect(); }},
|
||||
std::pair{std::ref(m_scrollTouchpad), [this] { return scrollTouchpadEffect(); }},
|
||||
std::pair{std::ref(m_confinePointer), [this] { return confinePointerEffect(); }}, std::pair{std::ref(m_borderSize), [this] { return borderSizeEffect(); }},
|
||||
std::pair{std::ref(m_rounding), [this] { return roundingEffect(); }}, std::pair{std::ref(m_roundingPower), [this] { return roundingPowerEffect(); }},
|
||||
std::pair{std::ref(m_scrollMouse), [this] { return scrollMouseEffect(); }}, std::pair{std::ref(m_scrollTouchpad), [this] { return scrollTouchpadEffect(); }},
|
||||
std::pair{std::ref(m_animationStyle), [this] { return animationStyleEffect(); }}, std::pair{std::ref(m_maxSize), [this] { return maxSizeEffect(); }},
|
||||
std::pair{std::ref(m_minSize), [this] { return minSizeEffect(); }}, std::pair{std::ref(m_activeBorderColor), [this] { return activeBorderColorEffect(); }},
|
||||
std::pair{std::ref(m_inactiveBorderColor), [this] { return inactiveBorderColorEffect(); }}));
|
||||
|
|
@ -342,6 +342,11 @@ CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyDynamicRule(const
|
|||
m_stayFocused.second |= rule->getPropertiesMask();
|
||||
break;
|
||||
}
|
||||
case WINDOW_RULE_EFFECT_CONFINE_POINTER: {
|
||||
m_confinePointer.first.set(truthy(effect), Types::PRIORITY_WINDOW_RULE);
|
||||
m_confinePointer.second |= rule->getPropertiesMask();
|
||||
break;
|
||||
}
|
||||
case WINDOW_RULE_EFFECT_SCROLL_MOUSE: {
|
||||
m_scrollMouse.first.set(std::get<float>(value), Types::PRIORITY_WINDOW_RULE);
|
||||
m_scrollMouse.second |= rule->getPropertiesMask();
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ namespace Desktop::Rule {
|
|||
DEFINE_PROP(bool, noVRR, false, WINDOW_RULE_EFFECT_NO_VRR)
|
||||
DEFINE_PROP(bool, persistentSize, false, WINDOW_RULE_EFFECT_PERSISTENT_SIZE)
|
||||
DEFINE_PROP(bool, stayFocused, false, WINDOW_RULE_EFFECT_STAY_FOCUSED)
|
||||
DEFINE_PROP(bool, confinePointer, false, WINDOW_RULE_EFFECT_CONFINE_POINTER)
|
||||
|
||||
DEFINE_PROP(int, idleInhibitMode, false, WINDOW_RULE_EFFECT_IDLE_INHIBIT)
|
||||
|
||||
|
|
|
|||
|
|
@ -65,12 +65,13 @@ static const std::vector<std::string> EFFECT_STRINGS = {
|
|||
"scroll_mouse", //
|
||||
"scroll_touchpad", //
|
||||
"stay_focused", //
|
||||
"confine_pointer", //
|
||||
"__internal_last_static", //
|
||||
};
|
||||
|
||||
// This is here so that if we change the rules, we get reminded to update
|
||||
// the strings.
|
||||
static_assert(WINDOW_RULE_EFFECT_LAST_STATIC == 55);
|
||||
static_assert(WINDOW_RULE_EFFECT_LAST_STATIC == 56);
|
||||
|
||||
CWindowRuleEffectContainer::CWindowRuleEffectContainer() : IEffectContainer<eWindowRuleEffect>(std::vector<std::string>{EFFECT_STRINGS}) {
|
||||
;
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ namespace Desktop::Rule {
|
|||
WINDOW_RULE_EFFECT_SCROLL_MOUSE,
|
||||
WINDOW_RULE_EFFECT_SCROLL_TOUCHPAD,
|
||||
WINDOW_RULE_EFFECT_STAY_FOCUSED,
|
||||
WINDOW_RULE_EFFECT_CONFINE_POINTER,
|
||||
|
||||
WINDOW_RULE_EFFECT_LAST_STATIC,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -265,31 +265,50 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
|
|||
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
|
||||
|
||||
// constraints
|
||||
if (!overridePos.has_value() && !g_pSeatManager->m_mouse.expired() && isConstrained()) {
|
||||
const auto SURF = Desktop::View::CWLSurface::fromResource(Desktop::focusState()->surface());
|
||||
const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
|
||||
auto confineToRegion = [&](const CRegion& rg, SP<Desktop::View::CWLSurface> surf) {
|
||||
const auto CLOSEST = rg.closestPoint(mouseCoords);
|
||||
const auto BOX = surf->getSurfaceBoxGlobal();
|
||||
const auto WINDOW = Desktop::View::CWindow::fromView(surf->view());
|
||||
const auto CLOSESTLOCAL = (CLOSEST - (BOX.has_value() ? BOX->pos() : Vector2D{})) * (WINDOW ? WINDOW->m_X11SurfaceScaledBy : 1.0);
|
||||
|
||||
if (CONSTRAINT) {
|
||||
if (CONSTRAINT->isLocked()) {
|
||||
const auto HINT = CONSTRAINT->logicPositionHint();
|
||||
g_pCompositor->warpCursorTo(HINT, true);
|
||||
g_pCompositor->warpCursorTo(CLOSEST, true);
|
||||
g_pSeatManager->sendPointerMotion(time, CLOSESTLOCAL);
|
||||
PROTO::relativePointer->sendRelativeMotion(sc<uint64_t>(time) * 1000, {}, {});
|
||||
};
|
||||
|
||||
if (!g_pSeatManager->m_mouse.expired()) {
|
||||
const auto SURF = Desktop::View::CWLSurface::fromResource(Desktop::focusState()->surface());
|
||||
|
||||
if (isConstrained()) {
|
||||
const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
|
||||
|
||||
if (CONSTRAINT) {
|
||||
if (CONSTRAINT->isLocked()) {
|
||||
const auto HINT = CONSTRAINT->logicPositionHint();
|
||||
g_pCompositor->warpCursorTo(HINT, true);
|
||||
} else {
|
||||
confineToRegion(CONSTRAINT->logicConstraintRegion(), SURF);
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
const auto RG = CONSTRAINT->logicConstraintRegion();
|
||||
const auto CLOSEST = RG.closestPoint(mouseCoords);
|
||||
const auto BOX = SURF->getSurfaceBoxGlobal();
|
||||
const auto WINDOW = Desktop::View::CWindow::fromView(SURF->view());
|
||||
const auto CLOSESTLOCAL = (CLOSEST - (BOX.has_value() ? BOX->pos() : Vector2D{})) * (WINDOW ? WINDOW->m_X11SurfaceScaledBy : 1.0);
|
||||
|
||||
g_pCompositor->warpCursorTo(CLOSEST, true);
|
||||
g_pSeatManager->sendPointerMotion(time, CLOSESTLOCAL);
|
||||
PROTO::relativePointer->sendRelativeMotion(sc<uint64_t>(time) * 1000, {}, {});
|
||||
Log::logger->log(Log::ERR, "BUG THIS: Null SURF/CONSTRAINT in mouse refocus. Ignoring constraints. {:x} {:x}", rc<uintptr_t>(SURF.get()),
|
||||
rc<uintptr_t>(CONSTRAINT.get()));
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} else
|
||||
Log::logger->log(Log::ERR, "BUG THIS: Null SURF/CONSTRAINT in mouse refocus. Ignoring constraints. {:x} {:x}", rc<uintptr_t>(SURF.get()),
|
||||
rc<uintptr_t>(CONSTRAINT.get()));
|
||||
} else {
|
||||
const auto WINDOW = SURF ? Desktop::View::CWindow::fromView(SURF->view()) : nullptr;
|
||||
if (WINDOW) {
|
||||
if (WINDOW->m_ruleApplicator->confinePointer().valueOrDefault()) {
|
||||
const auto BOX = SURF->getSurfaceBoxGlobal();
|
||||
if (BOX.has_value()) {
|
||||
CRegion rg;
|
||||
rg.set(*BOX);
|
||||
confineToRegion(rg, SURF);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PMONITOR != Desktop::focusState()->monitor() && (*PMOUSEFOCUSMON || refocus) && m_forcedFocus.expired())
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue