Skip to content

Commit

Permalink
render unfocused wr
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski committed Aug 30, 2024
1 parent ad8979e commit c5692c8
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2155,7 +2155,7 @@ std::optional<std::string> CConfigManager::handleUnbind(const std::string& comma

bool windowRuleValid(const std::string& RULE) {
static const auto rules = std::unordered_set<std::string>{
"float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile",
"float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused",
};
static const auto rulesPrefix = std::vector<std::string>{
"animation", "bordercolor", "bordersize", "center", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor",
Expand Down
5 changes: 5 additions & 0 deletions src/desktop/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,9 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
if (m_sGroupData.pNextWindow.expired())
setHidden(false);
} catch (std::exception& e) { Debug::log(ERR, "minsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
} else if (r.szRule == "renderunfocused") {
m_sWindowData.renderUnfocused = CWindowOverridableVar(true, priority);
g_pHyprRenderer->addWindowToRenderUnfocused(m_pSelf.lock());
}
}

Expand All @@ -774,6 +777,8 @@ void CWindow::updateDynamicRules() {
m_sWindowData.activeBorderColor.unset(PRIORITY_WINDOW_RULE);
m_sWindowData.inactiveBorderColor.unset(PRIORITY_WINDOW_RULE);

m_sWindowData.renderUnfocused.unset(PRIORITY_WINDOW_RULE);

m_eIdleInhibitMode = IDLEINHIBIT_NONE;

m_tags.removeDynamicTags();
Expand Down
1 change: 1 addition & 0 deletions src/desktop/Window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ struct SWindowData {
CWindowOverridableVar<bool> syncFullscreen = true;
CWindowOverridableVar<bool> tearing = false;
CWindowOverridableVar<bool> xray = false;
CWindowOverridableVar<bool> renderUnfocused = false;

CWindowOverridableVar<int> rounding;
CWindowOverridableVar<int> borderSize;
Expand Down
4 changes: 4 additions & 0 deletions src/managers/eventLoop/EventLoopTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@ float CEventLoopTimer::leftUs() {

return std::chrono::duration_cast<std::chrono::microseconds>(*expires - std::chrono::steady_clock::now()).count();
}

bool CEventLoopTimer::armed() {
return expires.has_value();
}
1 change: 1 addition & 0 deletions src/managers/eventLoop/EventLoopTimer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class CEventLoopTimer {

void cancel();
bool passed();
bool armed();

float leftUs();

Expand Down
46 changes: 46 additions & 0 deletions src/render/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,42 @@ CHyprRenderer::CHyprRenderer() {

m_pCursorTicker = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, cursorTicker, nullptr);
wl_event_source_timer_update(m_pCursorTicker, 500);

m_tRenderUnfocusedTimer = makeShared<CEventLoopTimer>(
std::nullopt,
[this](SP<CEventLoopTimer> self, void* data) {
if (m_vRenderUnfocused.empty())
return;

timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);

bool dirty = false;
for (auto& w : m_vRenderUnfocused) {
if (!w) {
dirty = true;
continue;
}

if (!w->m_pWLSurface || !w->m_pWLSurface->resource() || shouldRenderWindow(w.lock()))
continue;

w->m_pWLSurface->resource()->frame(&now);
auto FEEDBACK = makeShared<CQueuedPresentationData>(w->m_pWLSurface->resource());
FEEDBACK->attachMonitor(g_pCompositor->m_pLastMonitor.get());
FEEDBACK->discarded();
PROTO::presentation->queueData(FEEDBACK);
}

if (dirty)
std::erase_if(m_vRenderUnfocused, [](const auto& e) { return !e || !e->m_sWindowData.renderUnfocused.valueOr(false); });

if (!m_vRenderUnfocused.empty())
m_tRenderUnfocusedTimer->updateTimeout(std::chrono::milliseconds(75));
},
nullptr);

g_pEventLoopManager->addTimer(m_tRenderUnfocusedTimer);
}

CHyprRenderer::~CHyprRenderer() {
Expand Down Expand Up @@ -2800,3 +2836,13 @@ SExplicitSyncSettings CHyprRenderer::getExplicitSyncSettings() {

return settings;
}

void CHyprRenderer::addWindowToRenderUnfocused(PHLWINDOW window) {
if (std::find(m_vRenderUnfocused.begin(), m_vRenderUnfocused.end(), window) != m_vRenderUnfocused.end())
return;

m_vRenderUnfocused.emplace_back(window);

if (!m_tRenderUnfocusedTimer->armed())
m_tRenderUnfocusedTimer->updateTimeout(std::chrono::milliseconds(75));
}
3 changes: 3 additions & 0 deletions src/render/Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class CHyprRenderer {
void makeEGLCurrent();
void unsetEGL();
SExplicitSyncSettings getExplicitSyncSettings();
void addWindowToRenderUnfocused(PHLWINDOW window);

// if RENDER_MODE_NORMAL, provided damage will be written to.
// otherwise, it will be the one used.
Expand Down Expand Up @@ -143,6 +144,8 @@ class CHyprRenderer {

SP<CRenderbuffer> getOrCreateRenderbuffer(SP<Aquamarine::IBuffer> buffer, uint32_t fmt);
std::vector<SP<CRenderbuffer>> m_vRenderbuffers;
std::vector<PHLWINDOWREF> m_vRenderUnfocused;
SP<CEventLoopTimer> m_tRenderUnfocusedTimer;

friend class CHyprOpenGLImpl;
friend class CToplevelExportFrame;
Expand Down

0 comments on commit c5692c8

Please sign in to comment.