renderer: fix mouse motion in VRR (#12665)
This commit is contained in:
parent
4330b49a84
commit
cbeb6984e7
12 changed files with 63 additions and 105 deletions
|
|
@ -3103,3 +3103,7 @@ std::optional<unsigned int> CCompositor::getVTNr() {
|
||||||
|
|
||||||
return ttynum;
|
return ttynum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CCompositor::isVRRActiveOnAnyMonitor() const {
|
||||||
|
return std::ranges::any_of(m_monitors, [](const PHLMONITOR& m) { return m->m_vrrActive; });
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,7 @@ class CCompositor {
|
||||||
void onNewMonitor(SP<Aquamarine::IOutput> output);
|
void onNewMonitor(SP<Aquamarine::IOutput> output);
|
||||||
void ensurePersistentWorkspacesPresent(const std::vector<SWorkspaceRule>& rules, PHLWORKSPACE pWorkspace = nullptr);
|
void ensurePersistentWorkspacesPresent(const std::vector<SWorkspaceRule>& rules, PHLWORKSPACE pWorkspace = nullptr);
|
||||||
std::optional<unsigned int> getVTNr();
|
std::optional<unsigned int> getVTNr();
|
||||||
|
bool isVRRActiveOnAnyMonitor() const;
|
||||||
|
|
||||||
NColorManagement::PImageDescription getPreferredImageDescription();
|
NColorManagement::PImageDescription getPreferredImageDescription();
|
||||||
NColorManagement::PImageDescription getHDRImageDescription();
|
NColorManagement::PImageDescription getHDRImageDescription();
|
||||||
|
|
|
||||||
|
|
@ -3021,7 +3021,7 @@ bool CConfigManager::shouldUseSoftwareCursors(PHLMONITOR pMonitor) {
|
||||||
switch (*PNOHW) {
|
switch (*PNOHW) {
|
||||||
case 0: return false;
|
case 0: return false;
|
||||||
case 1: return true;
|
case 1: return true;
|
||||||
case 2: return g_pHyprRenderer->isNvidia() && g_pHyprRenderer->isMgpu();
|
case 2: return g_pHyprRenderer->isNvidia() && (g_pHyprRenderer->isMgpu() || g_pCompositor->isVRRActiveOnAnyMonitor());
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2595,20 +2595,7 @@ void CWindow::commitWindow() {
|
||||||
|
|
||||||
const auto PMONITOR = m_monitor.lock();
|
const auto PMONITOR = m_monitor.lock();
|
||||||
|
|
||||||
if (PMONITOR)
|
g_pHyprRenderer->damageSurface(wlSurface()->resource(), m_realPosition->goal().x, m_realPosition->goal().y, m_isX11 ? 1.0 / m_X11SurfaceScaledBy : 1.0);
|
||||||
PMONITOR->debugLastPresentation(g_pSeatManager->m_isPointerFrameCommit ? "listener_commitWindow skip" : "listener_commitWindow");
|
|
||||||
|
|
||||||
if (g_pSeatManager->m_isPointerFrameCommit) {
|
|
||||||
g_pSeatManager->m_isPointerFrameSkipped = false;
|
|
||||||
g_pSeatManager->m_isPointerFrameCommit = false;
|
|
||||||
} else
|
|
||||||
g_pHyprRenderer->damageSurface(wlSurface()->resource(), m_realPosition->goal().x, m_realPosition->goal().y, m_isX11 ? 1.0 / m_X11SurfaceScaledBy : 1.0);
|
|
||||||
|
|
||||||
if (g_pSeatManager->m_isPointerFrameSkipped) {
|
|
||||||
g_pPointerManager->sendStoredMovement();
|
|
||||||
g_pSeatManager->sendPointerFrame();
|
|
||||||
g_pSeatManager->m_isPointerFrameCommit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_isX11) {
|
if (!m_isX11) {
|
||||||
m_subsurfaceHead->recheckDamageForSubsurfaces();
|
m_subsurfaceHead->recheckDamageForSubsurfaces();
|
||||||
|
|
|
||||||
|
|
@ -1043,8 +1043,10 @@ bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
|
||||||
static auto PMINRR = CConfigValue<Hyprlang::INT>("cursor:min_refresh_rate");
|
static auto PMINRR = CConfigValue<Hyprlang::INT>("cursor:min_refresh_rate");
|
||||||
|
|
||||||
// skip scheduling extra frames for fullsreen apps with vrr
|
// skip scheduling extra frames for fullsreen apps with vrr
|
||||||
const auto FS_WINDOW = getFullscreenWindow();
|
const auto FS_WINDOW = getFullscreenWindow();
|
||||||
const bool shouldSkip = FS_WINDOW && (*PNOBREAK == 1 || (*PNOBREAK == 2 && FS_WINDOW->getContentType() == CONTENT_TYPE_GAME)) && m_output->state->state().adaptiveSync;
|
const bool shouldRenderCursor = g_pHyprRenderer->shouldRenderCursor();
|
||||||
|
const bool noBreak = FS_WINDOW && (*PNOBREAK == 1 || (*PNOBREAK == 2 && FS_WINDOW->getContentType() == CONTENT_TYPE_GAME));
|
||||||
|
const bool shouldSkip = (!shouldRenderCursor || noBreak) && m_output->state->state().adaptiveSync;
|
||||||
|
|
||||||
// keep requested minimum refresh rate
|
// keep requested minimum refresh rate
|
||||||
if (shouldSkip && *PMINRR && m_lastPresentationTimer.getMillis() > 1000.0f / *PMINRR) {
|
if (shouldSkip && *PMINRR && m_lastPresentationTimer.getMillis() > 1000.0f / *PMINRR) {
|
||||||
|
|
|
||||||
|
|
@ -737,17 +737,26 @@ Vector2D CPointerManager::closestValid(const Vector2D& pos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPointerManager::damageIfSoftware() {
|
void CPointerManager::damageIfSoftware() {
|
||||||
|
if (g_pCompositor->m_unsafeState)
|
||||||
|
return;
|
||||||
|
|
||||||
auto b = getCursorBoxGlobal().expand(4);
|
auto b = getCursorBoxGlobal().expand(4);
|
||||||
|
|
||||||
for (auto const& mw : m_monitorStates) {
|
for (auto const& mw : m_monitorStates) {
|
||||||
if (mw->monitor.expired() || !mw->monitor->m_output)
|
auto monitor = mw->monitor.lock();
|
||||||
|
if (!monitor || !monitor->m_output || monitor->isMirror())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((mw->softwareLocks > 0 || mw->hardwareFailed || g_pConfigManager->shouldUseSoftwareCursors(mw->monitor.lock())) &&
|
auto usesSoftwareCursor = (mw->softwareLocks > 0 || mw->hardwareFailed || g_pConfigManager->shouldUseSoftwareCursors(monitor));
|
||||||
b.overlaps({mw->monitor->m_position, mw->monitor->m_size})) {
|
if (!usesSoftwareCursor)
|
||||||
g_pHyprRenderer->damageBox(b, mw->monitor->shouldSkipScheduleFrameOnMouseEvent());
|
continue;
|
||||||
break;
|
|
||||||
}
|
auto shouldAddDamage = !monitor->shouldSkipScheduleFrameOnMouseEvent() && b.overlaps({monitor->m_position, monitor->m_size});
|
||||||
|
if (!shouldAddDamage)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CBox damageBox = b.copy().translate(-monitor->m_position).scale(monitor->m_scale).round();
|
||||||
|
monitor->addDamage(damageBox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -924,20 +933,6 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
|
||||||
PROTO::idle->onActivity();
|
PROTO::idle->onActivity();
|
||||||
});
|
});
|
||||||
|
|
||||||
listener->frame = pointer->m_pointerEvents.frame.listen([] {
|
|
||||||
bool shouldSkip = false;
|
|
||||||
if (!g_pSeatManager->m_mouse.expired() && g_pInputManager->isLocked()) {
|
|
||||||
auto PMONITOR = Desktop::focusState()->monitor().get();
|
|
||||||
if (PMONITOR && PMONITOR->shouldSkipScheduleFrameOnMouseEvent()) {
|
|
||||||
auto fsWindow = PMONITOR->m_activeWorkspace->getFullscreenWindow();
|
|
||||||
shouldSkip = fsWindow && fsWindow->m_isX11;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_pSeatManager->m_isPointerFrameSkipped = shouldSkip;
|
|
||||||
if (!g_pSeatManager->m_isPointerFrameSkipped)
|
|
||||||
g_pSeatManager->sendPointerFrame();
|
|
||||||
});
|
|
||||||
|
|
||||||
listener->swipeBegin = pointer->m_pointerEvents.swipeBegin.listen([](const IPointer::SSwipeBeginEvent& event) {
|
listener->swipeBegin = pointer->m_pointerEvents.swipeBegin.listen([](const IPointer::SSwipeBeginEvent& event) {
|
||||||
g_pInputManager->onSwipeBegin(event);
|
g_pInputManager->onSwipeBegin(event);
|
||||||
|
|
||||||
|
|
@ -1089,7 +1084,7 @@ void CPointerManager::detachTablet(SP<CTablet> tablet) {
|
||||||
std::erase_if(m_tabletListeners, [tablet](const auto& e) { return e->tablet.expired() || e->tablet == tablet; });
|
std::erase_if(m_tabletListeners, [tablet](const auto& e) { return e->tablet.expired() || e->tablet == tablet; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPointerManager::damageCursor(PHLMONITOR pMonitor) {
|
void CPointerManager::damageCursor(PHLMONITOR pMonitor, bool skipFrameSchedule) {
|
||||||
for (auto const& mw : m_monitorStates) {
|
for (auto const& mw : m_monitorStates) {
|
||||||
if (mw->monitor != pMonitor)
|
if (mw->monitor != pMonitor)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1099,7 +1094,7 @@ void CPointerManager::damageCursor(PHLMONITOR pMonitor) {
|
||||||
if (b.empty())
|
if (b.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_pHyprRenderer->damageBox(b);
|
g_pHyprRenderer->damageBox(b, skipFrameSchedule);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1108,22 +1103,3 @@ void CPointerManager::damageCursor(PHLMONITOR pMonitor) {
|
||||||
Vector2D CPointerManager::cursorSizeLogical() {
|
Vector2D CPointerManager::cursorSizeLogical() {
|
||||||
return m_currentCursorImage.size / m_currentCursorImage.scale;
|
return m_currentCursorImage.size / m_currentCursorImage.scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPointerManager::storeMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel) {
|
|
||||||
m_storedTime = time;
|
|
||||||
m_storedDelta += delta;
|
|
||||||
m_storedUnaccel += deltaUnaccel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPointerManager::setStoredMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel) {
|
|
||||||
m_storedTime = time;
|
|
||||||
m_storedDelta = delta;
|
|
||||||
m_storedUnaccel = deltaUnaccel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPointerManager::sendStoredMovement() {
|
|
||||||
PROTO::relativePointer->sendRelativeMotion(m_storedTime * 1000, m_storedDelta, m_storedUnaccel);
|
|
||||||
m_storedTime = 0;
|
|
||||||
m_storedDelta = Vector2D{};
|
|
||||||
m_storedUnaccel = Vector2D{};
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -55,14 +55,11 @@ class CPointerManager {
|
||||||
// this is needed e.g. during screensharing where
|
// this is needed e.g. during screensharing where
|
||||||
// the software cursors aren't locked during the cursor move, but they
|
// the software cursors aren't locked during the cursor move, but they
|
||||||
// are rendered later.
|
// are rendered later.
|
||||||
void damageCursor(PHLMONITOR pMonitor);
|
void damageCursor(PHLMONITOR pMonitor, bool skipFrameSchedule = false);
|
||||||
|
|
||||||
//
|
//
|
||||||
Vector2D position();
|
Vector2D position();
|
||||||
Vector2D cursorSizeLogical();
|
Vector2D cursorSizeLogical();
|
||||||
void storeMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel);
|
|
||||||
void setStoredMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel);
|
|
||||||
void sendStoredMovement();
|
|
||||||
|
|
||||||
void recheckEnteredOutputs();
|
void recheckEnteredOutputs();
|
||||||
|
|
||||||
|
|
@ -95,7 +92,6 @@ class CPointerManager {
|
||||||
CHyprSignalListener motionAbsolute;
|
CHyprSignalListener motionAbsolute;
|
||||||
CHyprSignalListener button;
|
CHyprSignalListener button;
|
||||||
CHyprSignalListener axis;
|
CHyprSignalListener axis;
|
||||||
CHyprSignalListener frame;
|
|
||||||
|
|
||||||
CHyprSignalListener swipeBegin;
|
CHyprSignalListener swipeBegin;
|
||||||
CHyprSignalListener swipeEnd;
|
CHyprSignalListener swipeEnd;
|
||||||
|
|
@ -154,10 +150,6 @@ class CPointerManager {
|
||||||
|
|
||||||
Vector2D m_pointerPos = {0, 0};
|
Vector2D m_pointerPos = {0, 0};
|
||||||
|
|
||||||
uint64_t m_storedTime = 0;
|
|
||||||
Vector2D m_storedDelta = {0, 0};
|
|
||||||
Vector2D m_storedUnaccel = {0, 0};
|
|
||||||
|
|
||||||
struct SMonitorPointerState {
|
struct SMonitorPointerState {
|
||||||
SMonitorPointerState(const PHLMONITOR& m) : monitor(m) {}
|
SMonitorPointerState(const PHLMONITOR& m) : monitor(m) {}
|
||||||
~SMonitorPointerState() = default;
|
~SMonitorPointerState() = default;
|
||||||
|
|
|
||||||
|
|
@ -127,9 +127,6 @@ class CSeatManager {
|
||||||
void setGrab(SP<CSeatGrab> grab); // nullptr removes
|
void setGrab(SP<CSeatGrab> grab); // nullptr removes
|
||||||
SP<CSeatGrab> m_seatGrab;
|
SP<CSeatGrab> m_seatGrab;
|
||||||
|
|
||||||
bool m_isPointerFrameSkipped = false;
|
|
||||||
bool m_isPointerFrameCommit = false;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SSeatResourceContainer {
|
struct SSeatResourceContainer {
|
||||||
SSeatResourceContainer(SP<CWLSeatResource>);
|
SSeatResourceContainer(SP<CWLSeatResource>);
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@ static void handleUpdate(CAnimatedVariable<VarType>& av, bool warp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// manually schedule a frame
|
// manually schedule a frame
|
||||||
if (PMONITOR)
|
if (PMONITOR && !PMONITOR->inFullscreenMode())
|
||||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_ANIMATION);
|
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_ANIMATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,16 +130,10 @@ void CInputManager::onMouseMoved(IPointer::SMotionEvent e) {
|
||||||
|
|
||||||
const auto DELTA = *PNOACCEL == 1 ? unaccel : delta;
|
const auto DELTA = *PNOACCEL == 1 ? unaccel : delta;
|
||||||
|
|
||||||
if (g_pSeatManager->m_isPointerFrameSkipped)
|
|
||||||
g_pPointerManager->storeMovement(e.timeMs, DELTA, unaccel);
|
|
||||||
else
|
|
||||||
g_pPointerManager->setStoredMovement(e.timeMs, DELTA, unaccel);
|
|
||||||
|
|
||||||
PROTO::relativePointer->sendRelativeMotion(sc<uint64_t>(e.timeMs) * 1000, DELTA, unaccel);
|
|
||||||
|
|
||||||
if (e.mouse)
|
if (e.mouse)
|
||||||
recheckMouseWarpOnMouseInput();
|
recheckMouseWarpOnMouseInput();
|
||||||
|
|
||||||
|
PROTO::relativePointer->sendRelativeMotion(sc<uint64_t>(e.timeMs) * 1000, delta, unaccel);
|
||||||
g_pPointerManager->move(DELTA);
|
g_pPointerManager->move(DELTA);
|
||||||
|
|
||||||
mouseMoveUnified(e.timeMs, false, e.mouse);
|
mouseMoveUnified(e.timeMs, false, e.mouse);
|
||||||
|
|
@ -151,6 +145,8 @@ void CInputManager::onMouseMoved(IPointer::SMotionEvent e) {
|
||||||
|
|
||||||
if (e.mouse)
|
if (e.mouse)
|
||||||
m_lastMousePos = getMouseCoordsInternal();
|
m_lastMousePos = getMouseCoordsInternal();
|
||||||
|
|
||||||
|
g_pSeatManager->sendPointerFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInputManager::onMouseWarp(IPointer::SMotionAbsoluteEvent e) {
|
void CInputManager::onMouseWarp(IPointer::SMotionAbsoluteEvent e) {
|
||||||
|
|
@ -676,6 +672,8 @@ void CInputManager::onMouseButton(IPointer::SButtonEvent e) {
|
||||||
m_focusHeldByButtons = false;
|
m_focusHeldByButtons = false;
|
||||||
m_refocusHeldByButtons = false;
|
m_refocusHeldByButtons = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_pSeatManager->sendPointerFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInputManager::processMouseRequest(const CSeatManager::SSetCursorEvent& event) {
|
void CInputManager::processMouseRequest(const CSeatManager::SSetCursorEvent& event) {
|
||||||
|
|
@ -954,6 +952,7 @@ void CInputManager::onMouseWheel(IPointer::SAxisEvent e, SP<IPointer> pointer) {
|
||||||
int32_t deltaDiscrete = std::abs(discrete) != 0 && std::abs(discrete) < 1 ? std::copysign(1, discrete) : std::round(discrete);
|
int32_t deltaDiscrete = std::abs(discrete) != 0 && std::abs(discrete) < 1 ? std::copysign(1, discrete) : std::round(discrete);
|
||||||
|
|
||||||
g_pSeatManager->sendPointerAxis(e.timeMs, e.axis, delta, deltaDiscrete, value120, e.source, WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL);
|
g_pSeatManager->sendPointerAxis(e.timeMs, e.axis, delta, deltaDiscrete, value120, e.source, WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL);
|
||||||
|
g_pSeatManager->sendPointerFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2D CInputManager::getMouseCoordsInternal() {
|
Vector2D CInputManager::getMouseCoordsInternal() {
|
||||||
|
|
|
||||||
|
|
@ -1914,22 +1914,33 @@ void CHyprRenderer::damageSurface(SP<CWLSurfaceResource> pSurface, double x, dou
|
||||||
if (g_pCompositor->m_unsafeState)
|
if (g_pCompositor->m_unsafeState)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto WLSURF = Desktop::View::CWLSurface::fromResource(pSurface);
|
const auto WLSURF = Desktop::View::CWLSurface::fromResource(pSurface);
|
||||||
CRegion damageBox = WLSURF ? WLSURF->computeDamage() : CRegion{};
|
|
||||||
if (!WLSURF) {
|
if (!WLSURF) {
|
||||||
Log::logger->log(Log::ERR, "BUG THIS: No CWLSurface for surface in damageSurface!!!");
|
Log::logger->log(Log::ERR, "BUG THIS: No CWLSurface for surface in damageSurface!!!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scale != 1.0)
|
// hack: schedule frame events
|
||||||
damageBox.scale(scale);
|
if (!WLSURF->resource()->m_current.callbacks.empty() && pSurface->m_hlSurface) {
|
||||||
|
const auto BOX = pSurface->m_hlSurface->getSurfaceBoxGlobal();
|
||||||
|
if (BOX && !BOX->empty()) {
|
||||||
|
for (auto const& m : g_pCompositor->m_monitors) {
|
||||||
|
if (!m->m_output)
|
||||||
|
continue;
|
||||||
|
|
||||||
// schedule frame events
|
if (BOX->overlaps(m->logicalBox()))
|
||||||
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->getMonitorFromVector(Vector2D(x, y)), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
g_pCompositor->scheduleFrameForMonitor(m, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CRegion damageBox = WLSURF->computeDamage();
|
||||||
if (damageBox.empty())
|
if (damageBox.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (scale != 1.0)
|
||||||
|
damageBox.scale(scale);
|
||||||
|
|
||||||
damageBox.translate({x, y});
|
damageBox.translate({x, y});
|
||||||
|
|
||||||
CRegion damageBoxForEach;
|
CRegion damageBoxForEach;
|
||||||
|
|
@ -2049,7 +2060,7 @@ void CHyprRenderer::renderDragIcon(PHLMONITOR pMonitor, const Time::steady_tp& t
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprRenderer::setCursorSurface(SP<Desktop::View::CWLSurface> surf, int hotspotX, int hotspotY, bool force) {
|
void CHyprRenderer::setCursorSurface(SP<Desktop::View::CWLSurface> surf, int hotspotX, int hotspotY, bool force) {
|
||||||
m_cursorHasSurface = surf;
|
m_cursorHasSurface = surf && surf->resource();
|
||||||
|
|
||||||
m_lastCursorData.name = "";
|
m_lastCursorData.name = "";
|
||||||
m_lastCursorData.surf = surf;
|
m_lastCursorData.surf = surf;
|
||||||
|
|
@ -2140,30 +2151,19 @@ void CHyprRenderer::ensureCursorRenderingMode() {
|
||||||
if (HIDE == m_cursorHidden)
|
if (HIDE == m_cursorHidden)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (HIDE) {
|
if (HIDE)
|
||||||
Log::logger->log(Log::DEBUG, "Hiding the cursor (hl-mandated)");
|
Log::logger->log(Log::DEBUG, "Hiding the cursor (hl-mandated)");
|
||||||
|
else
|
||||||
for (auto const& m : g_pCompositor->m_monitors) {
|
|
||||||
if (!g_pPointerManager->softwareLockedFor(m))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
damageMonitor(m); // TODO: maybe just damage the cursor area?
|
|
||||||
}
|
|
||||||
|
|
||||||
setCursorHidden(true);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Log::logger->log(Log::DEBUG, "Showing the cursor (hl-mandated)");
|
Log::logger->log(Log::DEBUG, "Showing the cursor (hl-mandated)");
|
||||||
|
|
||||||
for (auto const& m : g_pCompositor->m_monitors) {
|
for (auto const& m : g_pCompositor->m_monitors) {
|
||||||
if (!g_pPointerManager->softwareLockedFor(m))
|
if (!g_pPointerManager->softwareLockedFor(m))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
damageMonitor(m); // TODO: maybe just damage the cursor area?
|
g_pPointerManager->damageCursor(m, m->shouldSkipScheduleFrameOnMouseEvent());
|
||||||
}
|
|
||||||
|
|
||||||
setCursorHidden(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setCursorHidden(HIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprRenderer::setCursorHidden(bool hide) {
|
void CHyprRenderer::setCursorHidden(bool hide) {
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ void CHyprBorderDecoration::updateWindow(PHLWINDOW) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprBorderDecoration::damageEntire() {
|
void CHyprBorderDecoration::damageEntire() {
|
||||||
if (!validMapped(m_window))
|
if (!validMapped(m_window) || m_window->isFullscreen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto surfaceBox = m_window->getWindowMainSurfaceBox();
|
auto surfaceBox = m_window->getWindowMainSurfaceBox();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue