mirror of
https://github.com/Trensa-Organization/hy3.git
synced 2025-03-15 18:53:40 +01:00
Implement damage
This commit is contained in:
parent
8e69c390c7
commit
131a51be62
4 changed files with 91 additions and 72 deletions
|
@ -1229,6 +1229,7 @@ void Hy3Layout::replaceWindowDataWith(CWindow* from, CWindow* to) {
|
|||
}
|
||||
|
||||
std::unique_ptr<HOOK_CALLBACK_FN> renderHookPtr = std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::renderHook);
|
||||
std::unique_ptr<HOOK_CALLBACK_FN> tickHookPtr = std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::tickHook);
|
||||
|
||||
void Hy3Layout::onEnable() {
|
||||
for (auto &window : g_pCompositor->m_vWindows) {
|
||||
|
@ -1242,11 +1243,13 @@ void Hy3Layout::onEnable() {
|
|||
}
|
||||
|
||||
HyprlandAPI::registerCallbackStatic(PHANDLE, "render", renderHookPtr.get());
|
||||
HyprlandAPI::registerCallbackStatic(PHANDLE, "tick", tickHookPtr.get());
|
||||
selection_hook::enable();
|
||||
}
|
||||
|
||||
void Hy3Layout::onDisable() {
|
||||
HyprlandAPI::unregisterCallback(PHANDLE, renderHookPtr.get());
|
||||
HyprlandAPI::unregisterCallback(PHANDLE, tickHookPtr.get());
|
||||
selection_hook::disable();
|
||||
this->nodes.clear();
|
||||
}
|
||||
|
@ -1531,6 +1534,57 @@ bool Hy3Layout::shouldRenderSelected(CWindow* window) {
|
|||
}
|
||||
}
|
||||
|
||||
void Hy3Layout::renderHook(void*, std::any data) {
|
||||
static bool rendering_normally = false;
|
||||
static std::vector<Hy3TabGroup*> rendered_groups;
|
||||
|
||||
auto render_stage = std::any_cast<eRenderStage>(data);
|
||||
|
||||
switch (render_stage) {
|
||||
case RENDER_PRE_WINDOWS:
|
||||
rendering_normally = true;
|
||||
rendered_groups.clear();
|
||||
break;
|
||||
case RENDER_POST_WINDOW:
|
||||
if (!rendering_normally) break;
|
||||
|
||||
for (auto& entry: g_Hy3Layout->tab_groups) {
|
||||
if (entry.target_window == g_pHyprOpenGL->m_pCurrentWindow
|
||||
&& std::find(rendered_groups.begin(), rendered_groups.end(), &entry) == rendered_groups.end()
|
||||
) {
|
||||
entry.renderTabBar();
|
||||
rendered_groups.push_back(&entry);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case RENDER_POST_WINDOWS:
|
||||
rendering_normally = false;
|
||||
|
||||
for (auto& entry: g_Hy3Layout->tab_groups) {
|
||||
if (entry.target_window->m_iMonitorID == g_pHyprOpenGL->m_RenderData.pMonitor->ID
|
||||
&& std::find(rendered_groups.begin(), rendered_groups.end(), &entry) == rendered_groups.end()
|
||||
) {
|
||||
entry.renderTabBar();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Hy3Layout::tickHook(void*, std::any) {
|
||||
auto& tab_groups = g_Hy3Layout->tab_groups;
|
||||
auto entry = tab_groups.begin();
|
||||
while (entry != tab_groups.end()) {
|
||||
entry->damageIfRequired();
|
||||
if (entry->bar.destroy) tab_groups.erase(entry++);
|
||||
else entry = std::next(entry);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Hy3Node::debugNode() {
|
||||
std::stringstream buf;
|
||||
std::string addr = "0x" + std::to_string((size_t)this);
|
||||
|
@ -1580,55 +1634,3 @@ std::string Hy3Node::debugNode() {
|
|||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
// Recursively render tabs on all tab groups.
|
||||
void renderTabsRecursive(Hy3Node& node);
|
||||
|
||||
// Render tabs for the provided node, blindly assuming it is a tab group.
|
||||
void renderTabs(Hy3Node& node);
|
||||
|
||||
void Hy3Layout::renderHook(void*, std::any data) {
|
||||
static bool rendering_normally = false;
|
||||
static std::vector<Hy3TabGroup*> rendered_groups;
|
||||
|
||||
auto render_stage = std::any_cast<eRenderStage>(data);
|
||||
|
||||
switch (render_stage) {
|
||||
case RENDER_PRE_WINDOWS:
|
||||
rendering_normally = true;
|
||||
rendered_groups.clear();
|
||||
break;
|
||||
case RENDER_POST_WINDOW: {
|
||||
if (!rendering_normally) break;
|
||||
|
||||
auto& tab_groups = g_Hy3Layout->tab_groups;
|
||||
auto entry = tab_groups.begin();
|
||||
while (entry != tab_groups.end()) {
|
||||
if (entry->target_window == g_pHyprOpenGL->m_pCurrentWindow && std::find(rendered_groups.begin(), rendered_groups.end(), &*entry) == rendered_groups.end()) {
|
||||
entry->renderTabBar();
|
||||
rendered_groups.push_back(&*entry);
|
||||
}
|
||||
|
||||
entry = std::next(entry);
|
||||
}
|
||||
} break;
|
||||
case RENDER_POST_WINDOWS: {
|
||||
rendering_normally = false;
|
||||
|
||||
auto& tab_groups = g_Hy3Layout->tab_groups;
|
||||
auto entry = tab_groups.begin();
|
||||
while (entry != tab_groups.end()) {
|
||||
if (entry->target_window->m_iMonitorID == g_pHyprOpenGL->m_RenderData.pMonitor->ID
|
||||
&& std::find(rendered_groups.begin(), rendered_groups.end(), &*entry) == rendered_groups.end()
|
||||
) {
|
||||
entry->renderTabBar();
|
||||
if (entry->bar.destroy) tab_groups.erase(entry++);
|
||||
}
|
||||
|
||||
entry = std::next(entry);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,6 +139,7 @@ public:
|
|||
Hy3Node* getWorkspaceFocusedNode(const int&);
|
||||
|
||||
static void renderHook(void*, std::any);
|
||||
static void tickHook(void*, std::any);
|
||||
|
||||
std::list<Hy3Node> nodes;
|
||||
std::list<Hy3TabGroup> tab_groups;
|
||||
|
|
|
@ -14,7 +14,7 @@ Hy3TabBarEntry::Hy3TabBarEntry(Hy3TabBar& tab_bar, Hy3Node& node): tab_bar(tab_b
|
|||
this->offset.registerVar();
|
||||
this->width.registerVar();
|
||||
|
||||
auto update_callback = [this](void*) { this->tab_bar.needs_redraw = true; };
|
||||
auto update_callback = [this](void*) { this->tab_bar.dirty = true; };
|
||||
|
||||
this->offset.setUpdateCallback(update_callback);
|
||||
this->width.setUpdateCallback(update_callback);
|
||||
|
@ -34,14 +34,14 @@ bool Hy3TabBarEntry::operator==(const Hy3TabBarEntry& entry) const {
|
|||
void Hy3TabBarEntry::setFocused(bool focused) {
|
||||
if (this->focused != focused) {
|
||||
this->focused = focused;
|
||||
this->tab_bar.needs_redraw = true;
|
||||
this->tab_bar.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Hy3TabBarEntry::setUrgent(bool urgent) {
|
||||
if (this->urgent != urgent) {
|
||||
this->urgent = urgent;
|
||||
this->tab_bar.needs_redraw = true;
|
||||
this->tab_bar.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ Hy3TabBar::Hy3TabBar() {
|
|||
this->vertical_pos.registerVar();
|
||||
this->fade_opacity.registerVar();
|
||||
|
||||
auto update_callback = [this](void*) { this->needs_redraw = true; };
|
||||
auto update_callback = [this](void*) { this->dirty = true; };
|
||||
|
||||
this->vertical_pos.setUpdateCallback(update_callback);
|
||||
this->fade_opacity.setUpdateCallback(update_callback);
|
||||
|
@ -280,6 +280,31 @@ void Hy3TabGroup::updateWithGroup(Hy3Node& node) {
|
|||
}
|
||||
}
|
||||
|
||||
void Hy3TabGroup::damageIfRequired() {
|
||||
static const auto* enter_from_top = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:from_top")->intValue;
|
||||
|
||||
auto pos = this->pos.vec();
|
||||
auto size = this->size.vec();
|
||||
pos.y += (this->bar.vertical_pos.fl() * size.y) * (*enter_from_top ? -1 : 1);
|
||||
|
||||
if (this->last_pos != pos || this->last_size != size) {
|
||||
wlr_box damage_box = { this->last_pos.x, this->last_pos.y, this->last_size.x, this->last_size.y };
|
||||
g_pHyprRenderer->damageBox(&damage_box);
|
||||
|
||||
this->bar.damaged = true;
|
||||
this->last_pos = pos;
|
||||
this->last_size = size;
|
||||
}
|
||||
|
||||
if (this->bar.destroy || this->bar.dirty) {
|
||||
wlr_box damage_box = { pos.x, pos.y, size.x, size.y };
|
||||
g_pHyprRenderer->damageBox(&damage_box);
|
||||
|
||||
this->bar.damaged = true;
|
||||
this->bar.dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Hy3TabGroup::renderTabBar() {
|
||||
static const auto* window_rounding = &HyprlandAPI::getConfigValue(PHANDLE, "decoration:rounding")->intValue;
|
||||
static const auto* enter_from_top = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:from_top")->intValue;
|
||||
|
@ -296,25 +321,16 @@ void Hy3TabGroup::renderTabBar() {
|
|||
auto scaled_size = Vector2D(std::round(size.x * scale), std::round(size.y * scale));
|
||||
wlr_box box = { scaled_pos.x, scaled_pos.y, scaled_size.x, scaled_size.y };
|
||||
|
||||
this->bar.needs_redraw = true;
|
||||
/*if (!this->bar.needs_redraw) {
|
||||
if (!this->bar.damaged) {
|
||||
pixman_region32 damage;
|
||||
pixman_region32_init(&damage);
|
||||
pixman_region32_intersect_rect(&damage, g_pHyprOpenGL->m_RenderData.pDamage, box.x, box.y, box.width, box.height);
|
||||
this->bar.needs_redraw = pixman_region32_not_empty(&damage);
|
||||
this->bar.damaged = pixman_region32_not_empty(&damage);
|
||||
pixman_region32_fini(&damage);
|
||||
}*/
|
||||
|
||||
if (this->bar.destroy || this->last_pos != scaled_pos || this->last_size != scaled_size) {
|
||||
wlr_box damage_box = { this->last_pos.x, this->last_pos.y, this->last_size.x, this->last_size.y };
|
||||
monitor->addDamage(&damage_box);
|
||||
this->last_pos = scaled_pos;
|
||||
this->last_size = scaled_size;
|
||||
this->bar.needs_redraw = true;
|
||||
}
|
||||
|
||||
if (!this->bar.needs_redraw || this->bar.destroy) return;
|
||||
this->bar.needs_redraw = false;
|
||||
if (!this->bar.damaged || this->bar.destroy) return;
|
||||
this->bar.damaged = false;
|
||||
|
||||
this->bar.setSize(scaled_size);
|
||||
|
||||
|
@ -379,8 +395,6 @@ void Hy3TabGroup::renderTabBar() {
|
|||
glStencilMask(0xff);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xff);
|
||||
}
|
||||
|
||||
monitor->addDamage(&box);
|
||||
}
|
||||
|
||||
void findOverlappingWindows(Hy3Node& node, float height, std::vector<CWindow*>& windows) {
|
||||
|
|
|
@ -38,7 +38,8 @@ struct Hy3TabBarEntry {
|
|||
class Hy3TabBar {
|
||||
public:
|
||||
bool destroy = false;
|
||||
bool needs_redraw = true;
|
||||
bool dirty = true;
|
||||
bool damaged = true;
|
||||
CAnimatedVariable vertical_pos;
|
||||
CAnimatedVariable fade_opacity;
|
||||
|
||||
|
@ -71,6 +72,7 @@ public:
|
|||
|
||||
// update tab bar with node position and data. UB if node is not a group.
|
||||
void updateWithGroup(Hy3Node&);
|
||||
void damageIfRequired();
|
||||
// render the scaled tab bar on the current monitor.
|
||||
void renderTabBar();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue