mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-05 11:45:59 +01:00
config: Add a window rule to render while unfocused (#7582)
This commit is contained in:
parent
fbd6354393
commit
c5fd577181
8 changed files with 73 additions and 1 deletions
|
@ -1037,6 +1037,12 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
.data = SConfigOptionDescription::SBoolData{true},
|
||||||
},
|
},
|
||||||
|
SConfigOptionDescription{
|
||||||
|
.value = "misc:render_unfocused_fps",
|
||||||
|
.description = "the maximum limit for renderunfocused windows' fps in the background",
|
||||||
|
.type = CONFIG_OPTION_INT,
|
||||||
|
.data = SConfigOptionDescription::SRangeData{15, 1, 120},
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* binds:
|
* binds:
|
||||||
|
|
|
@ -357,6 +357,7 @@ CConfigManager::CConfigManager() {
|
||||||
m_pConfig->addConfigValue("misc:exit_window_retains_fullscreen", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("misc:exit_window_retains_fullscreen", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("misc:initial_workspace_tracking", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("misc:initial_workspace_tracking", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("misc:middle_click_paste", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("misc:middle_click_paste", Hyprlang::INT{1});
|
||||||
|
m_pConfig->addConfigValue("misc:render_unfocused_fps", Hyprlang::INT{15});
|
||||||
|
|
||||||
m_pConfig->addConfigValue("group:insert_after_current", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("group:insert_after_current", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("group:focus_removed_window", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("group:focus_removed_window", Hyprlang::INT{1});
|
||||||
|
@ -2155,7 +2156,7 @@ std::optional<std::string> CConfigManager::handleUnbind(const std::string& comma
|
||||||
|
|
||||||
bool windowRuleValid(const std::string& RULE) {
|
bool windowRuleValid(const std::string& RULE) {
|
||||||
static const auto rules = std::unordered_set<std::string>{
|
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>{
|
static const auto rulesPrefix = std::vector<std::string>{
|
||||||
"animation", "bordercolor", "bordersize", "center", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor",
|
"animation", "bordercolor", "bordersize", "center", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor",
|
||||||
|
|
|
@ -757,6 +757,9 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
|
||||||
if (m_sGroupData.pNextWindow.expired())
|
if (m_sGroupData.pNextWindow.expired())
|
||||||
setHidden(false);
|
setHidden(false);
|
||||||
} catch (std::exception& e) { Debug::log(ERR, "minsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
|
} 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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,6 +777,8 @@ void CWindow::updateDynamicRules() {
|
||||||
m_sWindowData.activeBorderColor.unset(PRIORITY_WINDOW_RULE);
|
m_sWindowData.activeBorderColor.unset(PRIORITY_WINDOW_RULE);
|
||||||
m_sWindowData.inactiveBorderColor.unset(PRIORITY_WINDOW_RULE);
|
m_sWindowData.inactiveBorderColor.unset(PRIORITY_WINDOW_RULE);
|
||||||
|
|
||||||
|
m_sWindowData.renderUnfocused.unset(PRIORITY_WINDOW_RULE);
|
||||||
|
|
||||||
m_eIdleInhibitMode = IDLEINHIBIT_NONE;
|
m_eIdleInhibitMode = IDLEINHIBIT_NONE;
|
||||||
|
|
||||||
m_tags.removeDynamicTags();
|
m_tags.removeDynamicTags();
|
||||||
|
|
|
@ -174,6 +174,7 @@ struct SWindowData {
|
||||||
CWindowOverridableVar<bool> syncFullscreen = true;
|
CWindowOverridableVar<bool> syncFullscreen = true;
|
||||||
CWindowOverridableVar<bool> tearing = false;
|
CWindowOverridableVar<bool> tearing = false;
|
||||||
CWindowOverridableVar<bool> xray = false;
|
CWindowOverridableVar<bool> xray = false;
|
||||||
|
CWindowOverridableVar<bool> renderUnfocused = false;
|
||||||
|
|
||||||
CWindowOverridableVar<int> rounding;
|
CWindowOverridableVar<int> rounding;
|
||||||
CWindowOverridableVar<int> borderSize;
|
CWindowOverridableVar<int> borderSize;
|
||||||
|
|
|
@ -49,3 +49,7 @@ float CEventLoopTimer::leftUs() {
|
||||||
|
|
||||||
return std::chrono::duration_cast<std::chrono::microseconds>(*expires - std::chrono::steady_clock::now()).count();
|
return std::chrono::duration_cast<std::chrono::microseconds>(*expires - std::chrono::steady_clock::now()).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CEventLoopTimer::armed() {
|
||||||
|
return expires.has_value();
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ class CEventLoopTimer {
|
||||||
|
|
||||||
void cancel();
|
void cancel();
|
||||||
bool passed();
|
bool passed();
|
||||||
|
bool armed();
|
||||||
|
|
||||||
float leftUs();
|
float leftUs();
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,44 @@ CHyprRenderer::CHyprRenderer() {
|
||||||
|
|
||||||
m_pCursorTicker = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, cursorTicker, nullptr);
|
m_pCursorTicker = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, cursorTicker, nullptr);
|
||||||
wl_event_source_timer_update(m_pCursorTicker, 500);
|
wl_event_source_timer_update(m_pCursorTicker, 500);
|
||||||
|
|
||||||
|
m_tRenderUnfocusedTimer = makeShared<CEventLoopTimer>(
|
||||||
|
std::nullopt,
|
||||||
|
[this](SP<CEventLoopTimer> self, void* data) {
|
||||||
|
static auto PFPS = CConfigValue<Hyprlang::INT>("misc:render_unfocused_fps");
|
||||||
|
|
||||||
|
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.lock());
|
||||||
|
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(1000 / *PFPS));
|
||||||
|
},
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
g_pEventLoopManager->addTimer(m_tRenderUnfocusedTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHyprRenderer::~CHyprRenderer() {
|
CHyprRenderer::~CHyprRenderer() {
|
||||||
|
@ -2800,3 +2838,15 @@ SExplicitSyncSettings CHyprRenderer::getExplicitSyncSettings() {
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHyprRenderer::addWindowToRenderUnfocused(PHLWINDOW window) {
|
||||||
|
static auto PFPS = CConfigValue<Hyprlang::INT>("misc:render_unfocused_fps");
|
||||||
|
|
||||||
|
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(1000 / *PFPS));
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ class CWorkspace;
|
||||||
class CWindow;
|
class CWindow;
|
||||||
class CInputPopup;
|
class CInputPopup;
|
||||||
class IHLBuffer;
|
class IHLBuffer;
|
||||||
|
class CEventLoopTimer;
|
||||||
|
|
||||||
// TODO: add fuller damage tracking for updating only parts of a window
|
// TODO: add fuller damage tracking for updating only parts of a window
|
||||||
enum DAMAGETRACKINGMODES {
|
enum DAMAGETRACKINGMODES {
|
||||||
|
@ -78,6 +79,7 @@ class CHyprRenderer {
|
||||||
void makeEGLCurrent();
|
void makeEGLCurrent();
|
||||||
void unsetEGL();
|
void unsetEGL();
|
||||||
SExplicitSyncSettings getExplicitSyncSettings();
|
SExplicitSyncSettings getExplicitSyncSettings();
|
||||||
|
void addWindowToRenderUnfocused(PHLWINDOW window);
|
||||||
|
|
||||||
// if RENDER_MODE_NORMAL, provided damage will be written to.
|
// if RENDER_MODE_NORMAL, provided damage will be written to.
|
||||||
// otherwise, it will be the one used.
|
// otherwise, it will be the one used.
|
||||||
|
@ -143,6 +145,8 @@ class CHyprRenderer {
|
||||||
|
|
||||||
SP<CRenderbuffer> getOrCreateRenderbuffer(SP<Aquamarine::IBuffer> buffer, uint32_t fmt);
|
SP<CRenderbuffer> getOrCreateRenderbuffer(SP<Aquamarine::IBuffer> buffer, uint32_t fmt);
|
||||||
std::vector<SP<CRenderbuffer>> m_vRenderbuffers;
|
std::vector<SP<CRenderbuffer>> m_vRenderbuffers;
|
||||||
|
std::vector<PHLWINDOWREF> m_vRenderUnfocused;
|
||||||
|
SP<CEventLoopTimer> m_tRenderUnfocusedTimer;
|
||||||
|
|
||||||
friend class CHyprOpenGLImpl;
|
friend class CHyprOpenGLImpl;
|
||||||
friend class CToplevelExportFrame;
|
friend class CToplevelExportFrame;
|
||||||
|
|
Loading…
Reference in a new issue