diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 650be373..05875f62 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -514,7 +514,7 @@ void CCompositor::startCompositor() { throwError("The backend could not start!"); } - wlr_cursor_set_xcursor(m_sWLRCursor, m_sWLRXCursorMgr, "left_ptr"); + g_pHyprRenderer->setCursorFromName("left_ptr"); #ifdef USES_SYSTEMD if (sd_booted() > 0) diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index d006c2f2..24e7cc26 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -150,7 +150,6 @@ void Events::listener_monitorFrame(void* owner, void* data) { return; if (PMONITOR->ignoreNextFlipEvent) { - Debug::log(LOG, "Ignore next flip event for {}", PMONITOR->szName); PMONITOR->ignoreNextFlipEvent = false; return; } diff --git a/src/helpers/SubsurfaceTree.cpp b/src/helpers/SubsurfaceTree.cpp index 5b86f928..0efa4c49 100644 --- a/src/helpers/SubsurfaceTree.cpp +++ b/src/helpers/SubsurfaceTree.cpp @@ -250,8 +250,14 @@ void Events::listener_commitSubsurface(void* owner, void* data) { // tearing: if solitary, redraw it. This still might be a single surface window const auto PMONITOR = g_pCompositor->getMonitorFromID(pNode->pWindowOwner->m_iMonitorID); if (PMONITOR->solitaryClient == pNode->pWindowOwner && pNode->pWindowOwner->canBeTorn() && PMONITOR->canTear) { - PMONITOR->nextRenderTorn = true; - g_pHyprRenderer->renderMonitor(PMONITOR); + + CRegion damageBox; + wlr_surface_get_effective_damage(pNode->pSurface->wlr(), damageBox.pixman()); + + if (!damageBox.empty()) { + PMONITOR->nextRenderTorn = true; + g_pHyprRenderer->renderMonitor(PMONITOR); + } } } } diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index e790bf7f..67b2e55d 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -307,9 +307,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { if (g_pHyprRenderer->m_bHasARenderedCursor) { // TODO: maybe wrap? if (m_ecbClickBehavior == CLICKMODE_KILL) - wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, "crosshair"); + g_pHyprRenderer->setCursorFromName("crosshair"); else - wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, "left_ptr"); + g_pHyprRenderer->setCursorFromName("left_ptr"); } m_bEmptyFocusCursorSet = true; @@ -372,18 +372,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { } } - // if we're on an input deco, reset cursor. Don't on overridden - // if (!m_bCursorImageOverridden) { - // if (!VECINRECT(m_vLastCursorPosFloored, pFoundWindow->m_vRealPosition.vec().x, pFoundWindow->m_vRealPosition.vec().y, - // pFoundWindow->m_vRealPosition.vec().x + pFoundWindow->m_vRealSize.vec().x, pFoundWindow->m_vRealPosition.vec().y + pFoundWindow->m_vRealSize.vec().y)) { - // wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, "left_ptr"); - // cursorSurfaceInfo.bUsed = false; - // } else if (!cursorSurfaceInfo.bUsed) { - // cursorSurfaceInfo.bUsed = true; - // wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, cursorSurfaceInfo.pSurface, cursorSurfaceInfo.vHotspot.x, cursorSurfaceInfo.vHotspot.y); - // } - // } - if (FOLLOWMOUSE != 1 && !refocus) { if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow && ((pFoundWindow->m_bIsFloating && *PFLOATBEHAVIOR == 2) || (g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating && *PFLOATBEHAVIOR != 0))) { @@ -478,7 +466,7 @@ void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_even else g_pHyprRenderer->m_bWindowRequestedCursorHide = false; - if (!cursorImageUnlocked() || !g_pHyprRenderer->shouldRenderCursor()) + if (!cursorImageUnlocked() || !g_pHyprRenderer->m_bHasARenderedCursor) return; // cursorSurfaceInfo.pSurface = e->surface; @@ -491,19 +479,19 @@ void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_even // } if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) - wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, e->surface, e->hotspot_x, e->hotspot_y); + g_pHyprRenderer->setCursorSurface(e->surface, e->hotspot_x, e->hotspot_y); } void CInputManager::processMouseRequest(wlr_cursor_shape_manager_v1_request_set_shape_event* e) { - if (!g_pHyprRenderer->shouldRenderCursor() || !cursorImageUnlocked()) + if (!g_pHyprRenderer->m_bHasARenderedCursor || !cursorImageUnlocked()) return; if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) - wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, wlr_cursor_shape_v1_name(e->shape)); + g_pHyprRenderer->setCursorFromName(wlr_cursor_shape_v1_name(e->shape)); } bool CInputManager::cursorImageUnlocked() { - if (!g_pHyprRenderer->shouldRenderCursor()) + if (!g_pHyprRenderer->m_bHasARenderedCursor) return false; if (m_ecbClickBehavior == CLICKMODE_KILL) @@ -524,7 +512,7 @@ void CInputManager::setClickMode(eClickBehaviorMode mode) { case CLICKMODE_DEFAULT: Debug::log(LOG, "SetClickMode: DEFAULT"); m_ecbClickBehavior = CLICKMODE_DEFAULT; - wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, "left_ptr"); + g_pHyprRenderer->setCursorFromName("left_ptr"); break; case CLICKMODE_KILL: @@ -536,7 +524,7 @@ void CInputManager::setClickMode(eClickBehaviorMode mode) { refocus(); // set cursor - wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, "crosshair"); + g_pHyprRenderer->setCursorFromName("crosshair"); break; default: break; } @@ -1507,7 +1495,7 @@ void CInputManager::destroySwitch(SSwitchDevice* pDevice) { } void CInputManager::setCursorImageUntilUnset(std::string name) { - wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, name.c_str()); + g_pHyprRenderer->setCursorFromName(name.c_str()); m_bCursorImageOverridden = true; } @@ -1517,7 +1505,7 @@ void CInputManager::unsetCursorImage() { m_bCursorImageOverridden = false; if (!g_pHyprRenderer->m_bWindowRequestedCursorHide) - wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, "left_ptr"); + g_pHyprRenderer->setCursorFromName("left_ptr"); } std::string CInputManager::deviceNameToInternalString(std::string in) { @@ -1598,7 +1586,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; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 982edd4b..fefab56b 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -967,58 +967,71 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { EMIT_HOOK_EVENT("render", RENDER_BEGIN); - if (pMonitor->isMirror()) { - g_pHyprOpenGL->blend(false); - g_pHyprOpenGL->renderMirrored(); - g_pHyprOpenGL->blend(true); - EMIT_HOOK_EVENT("render", RENDER_POST_MIRROR); + bool renderCursor = true; + + if (!pMonitor->solitaryClient) { + if (pMonitor->isMirror()) { + g_pHyprOpenGL->blend(false); + g_pHyprOpenGL->renderMirrored(); + g_pHyprOpenGL->blend(true); + EMIT_HOOK_EVENT("render", RENDER_POST_MIRROR); + renderCursor = false; + } else { + g_pHyprOpenGL->blend(false); + if (!canSkipBackBufferClear(pMonitor)) { + if (*PRENDERTEX /* inverted cfg flag */) + g_pHyprOpenGL->clear(CColor(*PBACKGROUNDCOLOR)); + else + g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper" + } + g_pHyprOpenGL->blend(true); + + wlr_box renderBox = {0, 0, (int)pMonitor->vecPixelSize.x, (int)pMonitor->vecPixelSize.y}; + renderWorkspace(pMonitor, g_pCompositor->getWorkspaceByID(pMonitor->activeWorkspace), &now, renderBox); + + renderLockscreen(pMonitor, &now); + + if (pMonitor == g_pCompositor->m_pLastMonitor) { + g_pHyprNotificationOverlay->draw(pMonitor); + g_pHyprError->draw(); + } + + // for drawing the debug overlay + if (pMonitor == g_pCompositor->m_vMonitors.front().get() && *PDEBUGOVERLAY == 1) { + startRenderOverlay = std::chrono::high_resolution_clock::now(); + g_pDebugOverlay->draw(); + endRenderOverlay = std::chrono::high_resolution_clock::now(); + } + + if (*PDAMAGEBLINK && damageBlinkCleanup == 0) { + wlr_box monrect = {0, 0, pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y}; + g_pHyprOpenGL->renderRect(&monrect, CColor(1.0, 0.0, 1.0, 100.0 / 255.0), 0); + damageBlinkCleanup = 1; + } else if (*PDAMAGEBLINK) { + damageBlinkCleanup++; + if (damageBlinkCleanup > 3) + damageBlinkCleanup = 0; + } + } } else { - g_pHyprOpenGL->blend(false); - if (!canSkipBackBufferClear(pMonitor)) { - if (*PRENDERTEX /* inverted cfg flag */) - g_pHyprOpenGL->clear(CColor(*PBACKGROUNDCOLOR)); - else - g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper" - } - g_pHyprOpenGL->blend(true); + g_pHyprRenderer->renderWindow(pMonitor->solitaryClient, pMonitor, &now, false, RENDER_PASS_MAIN /* solitary = no popups */); + } - wlr_box renderBox = {0, 0, (int)pMonitor->vecPixelSize.x, (int)pMonitor->vecPixelSize.y}; - renderWorkspace(pMonitor, g_pCompositor->getWorkspaceByID(pMonitor->activeWorkspace), &now, renderBox); + renderCursor = renderCursor && shouldRenderCursor(); - renderLockscreen(pMonitor, &now); + if (renderCursor && wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y)) { + TRACY_GPU_ZONE("RenderCursor"); - if (pMonitor == g_pCompositor->m_pLastMonitor) { - g_pHyprNotificationOverlay->draw(pMonitor); - g_pHyprError->draw(); - } + bool lockSoftware = pMonitor == g_pCompositor->getMonitorFromCursor() && *PZOOMFACTOR != 1.f; - // for drawing the debug overlay - if (pMonitor == g_pCompositor->m_vMonitors.front().get() && *PDEBUGOVERLAY == 1) { - startRenderOverlay = std::chrono::high_resolution_clock::now(); - g_pDebugOverlay->draw(); - endRenderOverlay = std::chrono::high_resolution_clock::now(); - } + if (lockSoftware) { + wlr_output_lock_software_cursors(pMonitor->output, true); + wlr_output_render_software_cursors(pMonitor->output, NULL); + wlr_output_lock_software_cursors(pMonitor->output, false); + } else + wlr_output_render_software_cursors(pMonitor->output, NULL); - if (*PDAMAGEBLINK && damageBlinkCleanup == 0) { - wlr_box monrect = {0, 0, pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y}; - g_pHyprOpenGL->renderRect(&monrect, CColor(1.0, 0.0, 1.0, 100.0 / 255.0), 0); - damageBlinkCleanup = 1; - } else if (*PDAMAGEBLINK) { - damageBlinkCleanup++; - if (damageBlinkCleanup > 3) - damageBlinkCleanup = 0; - } - - if (wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y)) { - TRACY_GPU_ZONE("RenderCursor"); - if (pMonitor == g_pCompositor->getMonitorFromCursor() && *PZOOMFACTOR != 1.f) { - wlr_output_lock_software_cursors(pMonitor->output, true); - wlr_output_render_software_cursors(pMonitor->output, NULL); - wlr_output_lock_software_cursors(pMonitor->output, false); - } else - wlr_output_render_software_cursors(pMonitor->output, NULL); - wlr_renderer_end(g_pCompositor->m_sWLRRenderer); - } + wlr_renderer_end(g_pCompositor->m_sWLRRenderer); } if (pMonitor == g_pCompositor->getMonitorFromCursor()) @@ -1050,8 +1063,6 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { if (*PDAMAGEBLINK) frameDamage.add(damage); - //wlr_output_set_damage(pMonitor->output, frameDamage.pixman()); - if (!pMonitor->mirrors.empty()) g_pHyprRenderer->damageMirrorsWith(pMonitor, frameDamage); @@ -1062,6 +1073,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { pMonitor->output->pending.tearing_page_flip = shouldTear; if (!wlr_output_commit(pMonitor->output)) { + if (UNLOCK_SC) wlr_output_lock_software_cursors(pMonitor->output, false); @@ -1858,6 +1870,17 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR return true; } +void CHyprRenderer::setCursorSurface(wlr_surface* surf, int hotspotX, int hotspotY) { + m_bCursorHasSurface = surf; + + wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, surf, hotspotX, hotspotY); +} +void CHyprRenderer::setCursorFromName(const std::string& name) { + m_bCursorHasSurface = true; + + wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, name.c_str()); +} + void CHyprRenderer::ensureCursorRenderingMode() { static auto* const PCURSORTIMEOUT = &g_pConfigManager->getConfigValuePtr("general:cursor_inactive_timeout")->intValue; static auto* const PHIDEONTOUCH = &g_pConfigManager->getConfigValuePtr("misc:hide_cursor_on_touch")->intValue; @@ -1870,7 +1893,7 @@ void CHyprRenderer::ensureCursorRenderingMode() { if (HIDE && m_bHasARenderedCursor) { m_bHasARenderedCursor = false; - wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, nullptr, 0, 0); // hide + setCursorSurface(nullptr, 0, 0); // hide Debug::log(LOG, "Hiding the cursor (timeout)"); @@ -1880,7 +1903,7 @@ void CHyprRenderer::ensureCursorRenderingMode() { m_bHasARenderedCursor = true; if (!m_bWindowRequestedCursorHide) - wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sWLRXCursorMgr, "left_ptr"); + setCursorFromName("left_ptr"); Debug::log(LOG, "Showing the cursor (timeout)"); @@ -1893,7 +1916,7 @@ void CHyprRenderer::ensureCursorRenderingMode() { } bool CHyprRenderer::shouldRenderCursor() { - return m_bHasARenderedCursor; + return m_bHasARenderedCursor && m_bCursorHasSurface; } std::tuple CHyprRenderer::getRenderTimes(CMonitor* pMonitor) { @@ -1995,7 +2018,8 @@ void CHyprRenderer::recheckSolitaryForMonitor(CMonitor* pMonitor) { const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pMonitor->activeWorkspace); - if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || g_pInputManager->m_sDrag.drag || g_pCompositor->m_sSeat.exclusiveClient || pMonitor->specialWorkspaceID) + if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || g_pInputManager->m_sDrag.drag || g_pCompositor->m_sSeat.exclusiveClient || pMonitor->specialWorkspaceID || + PWORKSPACE->m_fAlpha.fl() != 1.f || PWORKSPACE->m_vRenderOffset.vec() != Vector2D{}) return; const auto PCANDIDATE = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 2b437b00..e056db5c 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -56,6 +56,8 @@ class CHyprRenderer { void setOccludedForBackLayers(CRegion& region, CWorkspace* pWorkspace); bool canSkipBackBufferClear(CMonitor* pMonitor); void recheckSolitaryForMonitor(CMonitor* pMonitor); + void setCursorSurface(wlr_surface* surf, int hotspotX, int hotspotY); + void setCursorFromName(const std::string& name); bool m_bWindowRequestedCursorHide = false; bool m_bBlockSurfaceFeedback = false; @@ -94,6 +96,7 @@ class CHyprRenderer { void renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f); bool m_bHasARenderedCursor = true; + bool m_bCursorHasSurface = false; friend class CHyprOpenGLImpl; friend class CToplevelExportProtocolManager;