summaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
authorDarksome <dev@darkso.me>2022-07-15 19:42:03 +0300
committerDarksome <dev@darkso.me>2022-07-15 19:42:03 +0300
commit5388b54442614cb0d3d445f101e7cd86bf64c125 (patch)
tree26057ff185e423e944e8b250ed7fe26654b69623 /src/render
parentcb8a6f881b11e9a269fd5f7aa64eafe2beda0b0d (diff)
parent6306d4dae3fa221a6099e109c7faef60bac4fac5 (diff)
Merge upstream
Diffstat (limited to 'src/render')
-rw-r--r--src/render/Framebuffer.cpp18
-rw-r--r--src/render/Framebuffer.hpp2
-rw-r--r--src/render/OpenGL.cpp55
-rw-r--r--src/render/OpenGL.hpp11
-rw-r--r--src/render/Renderer.cpp135
-rw-r--r--src/render/Renderer.hpp8
-rw-r--r--src/render/decorations/CHyprGroupBarDecoration.cpp16
7 files changed, 163 insertions, 82 deletions
diff --git a/src/render/Framebuffer.cpp b/src/render/Framebuffer.cpp
index 4a5baf50..90b41a4b 100644
--- a/src/render/Framebuffer.cpp
+++ b/src/render/Framebuffer.cpp
@@ -2,15 +2,14 @@
#include "OpenGL.hpp"
bool CFramebuffer::alloc(int w, int h) {
- bool firstAlloc = false;
- if (m_iFb == (uint32_t)-1)
- {
+ bool firstAlloc = false;
+
+ if (m_iFb == (uint32_t)-1) {
firstAlloc = true;
glGenFramebuffers(1, &m_iFb);
}
- if (m_cTex.m_iTexID == 0)
- {
+ if (m_cTex.m_iTexID == 0) {
firstAlloc = true;
glGenTextures(1, &m_cTex.m_iTexID);
glBindTexture(GL_TEXTURE_2D, m_cTex.m_iTexID);
@@ -20,13 +19,11 @@ bool CFramebuffer::alloc(int w, int h) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
- if (firstAlloc || m_Size != Vector2D(w, h))
- {
+ if (firstAlloc || m_Size != Vector2D(w, h)) {
glBindTexture(GL_TEXTURE_2D, m_cTex.m_iTexID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindFramebuffer(GL_FRAMEBUFFER, m_iFb);
- glBindTexture(GL_TEXTURE_2D, m_cTex.m_iTexID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_cTex.m_iTexID, 0);
@@ -37,7 +34,6 @@ bool CFramebuffer::alloc(int w, int h) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
glBindFramebuffer(GL_FRAMEBUFFER, m_iFb);
- glBindTexture(GL_TEXTURE_2D, m_pStencilTex->m_iTexID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_pStencilTex->m_iTexID, 0);
}
@@ -78,3 +74,7 @@ void CFramebuffer::release() {
m_cTex.m_iTexID = 0;
m_iFb = -1;
}
+
+CFramebuffer::~CFramebuffer() {
+ release();
+} \ No newline at end of file
diff --git a/src/render/Framebuffer.hpp b/src/render/Framebuffer.hpp
index 3d15069d..6af59ca2 100644
--- a/src/render/Framebuffer.hpp
+++ b/src/render/Framebuffer.hpp
@@ -6,6 +6,8 @@
class CFramebuffer {
public:
+ ~CFramebuffer();
+
bool alloc(int w, int h);
void bind();
void release();
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index 793901aa..d60e827e 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -311,21 +311,21 @@ void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixm
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
-void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha, int round) {
+void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha, int round, bool allowCustomUV) {
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
- renderTexture(CTexture(tex), pBox, alpha, round);
+ renderTexture(CTexture(tex), pBox, alpha, round, false, allowCustomUV);
}
-void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool allowPrimary) {
+void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool allowCustomUV) {
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
- renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, false, allowPrimary);
+ renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, false, allowCustomUV);
scissor((wlr_box*)nullptr);
}
-void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool noAA, bool allowPrimary) {
+void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool noAA, bool allowCustomUV) {
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
@@ -388,7 +388,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
- if (allowPrimary && m_RenderData.renderingPrimarySurface && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) {
+ if (allowCustomUV && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) {
const float verts[] = {
m_RenderData.primarySurfaceUVBottomRight.x, m_RenderData.primarySurfaceUVTopLeft.y, // top right
m_RenderData.primarySurfaceUVTopLeft.x, m_RenderData.primarySurfaceUVTopLeft.y, // top left
@@ -702,8 +702,6 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
begin(PMONITOR, &fakeDamage, true);
- pixman_region32_fini(&fakeDamage);
-
clear(CColor(0,0,0,0)); // JIC
timespec now;
@@ -717,7 +715,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
g_pConfigManager->setInt("decoration:blur", 0);
- g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders);
+ g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL);
g_pConfigManager->setInt("decoration:blur", BLURVAL);
@@ -742,9 +740,10 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
#else
glBindFramebuffer(GL_FRAMEBUFFER, m_iCurrentOutputFb);
#endif
-
end();
+ pixman_region32_fini(&fakeDamage);
+
wlr_output_rollback(PMONITOR->output);
}
@@ -762,8 +761,6 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
begin(PMONITOR, &fakeDamage, true);
- pixman_region32_fini(&fakeDamage);
-
const auto PFRAMEBUFFER = &m_mLayerFramebuffers[pLayer];
glViewport(0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y);
@@ -792,6 +789,8 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
end();
+ pixman_region32_fini(&fakeDamage);
+
wlr_output_rollback(PMONITOR->output);
}
@@ -915,9 +914,28 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
+void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const CAIROSURFACE) {
+ cairo_select_font_face(CAIRO, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+
+ const auto FONTSIZE = (int)(m_RenderData.pMonitor->vecPixelSize.y / 76);
+ cairo_set_font_size(CAIRO, FONTSIZE);
+
+ cairo_set_source_rgba(CAIRO, 1.f, 1.f, 1.f, 0.32f);
+
+ cairo_text_extents_t textExtents;
+ cairo_text_extents(CAIRO, g_pCompositor->m_szCurrentSplash.c_str(), &textExtents);
+
+ cairo_move_to(CAIRO, m_RenderData.pMonitor->vecPixelSize.x / 2.f - textExtents.width / 2.f, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height - 1);
+ cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str());
+
+ cairo_surface_flush(CAIROSURFACE);
+}
+
void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
RASSERT(m_RenderData.pMonitor, "Tried to createBGTex without begin()!");
+ static auto *const PNOSPLASH = &g_pConfigManager->getConfigValuePtr("misc:disable_splash_rendering")->intValue;
+
// release the last tex if exists
const auto PTEX = &m_mMonitorBGTextures[pMonitor];
PTEX->destroyTexture();
@@ -926,6 +944,9 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
Debug::log(LOG, "Allocated texture for BGTex");
+ // TODO: use relative paths to the installation
+ // or configure the paths at build time
+
// check if wallpapers exist
if (!std::filesystem::exists("/usr/share/hyprland/wall_8K.png"))
return; // the texture will be empty, oh well. We'll clear with a solid color anyways.
@@ -949,6 +970,9 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
const auto CAIRO = cairo_create(CAIROSURFACE);
+ if (!*PNOSPLASH)
+ renderSplash(CAIRO, CAIROSURFACE);
+
// copy the data to an OpenGL texture we have
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
glBindTexture(GL_TEXTURE_2D, PTEX->m_iTexID);
@@ -969,9 +993,12 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
void CHyprOpenGLImpl::clearWithTex() {
RASSERT(m_RenderData.pMonitor, "Tried to render BGtex without begin()!");
- wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
+ static auto *const PRENDERTEX = &g_pConfigManager->getConfigValuePtr("misc:disable_hyprland_logo")->intValue;
- renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
+ if (!*PRENDERTEX) {
+ wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
+ renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
+ }
}
void CHyprOpenGLImpl::destroyMonitorResources(SMonitor* pMonitor) {
diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp
index 292eba36..84cfcd39 100644
--- a/src/render/OpenGL.hpp
+++ b/src/render/OpenGL.hpp
@@ -6,6 +6,8 @@
#include <list>
#include <unordered_map>
+#include <cairo/cairo.h>
+
#include "Shaders.hpp"
#include "Shader.hpp"
#include "Texture.hpp"
@@ -45,7 +47,6 @@ struct SCurrentRenderData {
pixman_region32_t* pDamage = nullptr;
- bool renderingPrimarySurface = false;
Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
};
@@ -60,8 +61,8 @@ public:
void renderRect(wlr_box*, const CColor&, int round = 0);
void renderRectWithDamage(wlr_box*, const CColor&, pixman_region32_t* damage, int round = 0);
- void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0);
- void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool allowPrimary = false);
+ void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0, bool allowCustomUV = false);
+ void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool allowCustomUV = false);
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0);
void renderRoundedShadow(wlr_box*, int round, int range, float a = 1.0);
void renderBorder(wlr_box*, const CColor&, int round);
@@ -121,7 +122,9 @@ private:
// returns the out FB, can be either Mirror or MirrorSwap
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
- void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowPrimary = false);
+ void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowCustomUV = false);
+
+ void renderSplash(cairo_t *const, cairo_surface_t *const);
};
inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL; \ No newline at end of file
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index eaa3cd90..d2b5efa9 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -12,22 +12,30 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, RDATA->output, &outputX, &outputY);
wlr_box windowBox;
- if (RDATA->surface && surface == RDATA->surface) {
+ if (RDATA->surface && surface == RDATA->surface)
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, RDATA->w, RDATA->h};
- } else { // here we clamp to 2, these might be some tiny specks
+ else // here we clamp to 2, these might be some tiny specks
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::clamp(surface->current.width, 2, 1337420), std::clamp(surface->current.height, 2, 1337420)};
+
+ // squish all oversized
+ if (RDATA->squishOversized) {
+ if (x + windowBox.width > RDATA->w)
+ windowBox.width = RDATA->w - x;
+ if (y + windowBox.height > RDATA->h)
+ windowBox.height = RDATA->h - y;
}
+
scaleBox(&windowBox, RDATA->output->scale);
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
- g_pHyprOpenGL->m_RenderData.renderingPrimarySurface = false;
-
if (RDATA->surface && surface == RDATA->surface) {
- g_pHyprOpenGL->m_RenderData.renderingPrimarySurface = true;
- g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding);
+ if (RDATA->blur)
+ g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding);
+ else
+ g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
if (RDATA->decorate) {
auto col = g_pHyprOpenGL->m_pCurrentWindow->m_cRealBorderColor.col();
@@ -35,8 +43,18 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
g_pHyprOpenGL->renderBorder(&windowBox, col, rounding);
}
}
- else
- g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false, false);
+ else {
+ if (RDATA->surface && wlr_surface_is_xdg_surface(RDATA->surface)) {
+ wlr_box geo;
+ wlr_xdg_surface_get_geometry(wlr_xdg_surface_from_wlr_surface(RDATA->surface), &geo);
+
+ windowBox.x -= geo.x;
+ windowBox.y -= geo.y;
+ }
+
+ g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false);
+ }
+
wlr_surface_send_frame_done(surface, RDATA->when);
@@ -54,8 +72,8 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) {
return true;
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
- // if not, check if it maybe is active on a different monitor. vvv might be animation in progress
- if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
+ // if not, check if it maybe is active on a different monitor. vvv might be animation in progress
+ if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && PWORKSPACE->m_bForceRendering) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
return true;
if (pMonitor->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
@@ -93,7 +111,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
continue;
// found it!
- renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL);
+ renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL);
pWorkspaceWindow = w.get();
}
@@ -103,7 +121,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || !w->m_bCreatedOverFullscreen || !w->m_bIsMapped)
continue;
- renderWindow(w.get(), pMonitor, time, true);
+ renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
}
// and then special windows
@@ -118,7 +136,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
continue;
// render the bad boy
- renderWindow(w.get(), pMonitor, time, true);
+ renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
}
// and the overlay layers
@@ -140,7 +158,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
g_pHyprError->draw();
}
-void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate) {
+void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate, eRenderPassMode mode) {
if (pWindow->m_bHidden)
return;
@@ -160,9 +178,11 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
renderdata.h = std::clamp(pWindow->m_vRealSize.vec().y, (double)5, (double)1337420); // otherwise we'll have issues later with invalid boxes
renderdata.dontRound = pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL;
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (PWORKSPACE->m_fAlpha.fl() / 255.f);
- renderdata.alpha = pWindow->m_bIsFullscreen ? g_pConfigManager->getFloat("decoration:fullscreen_opacity") : pWindow == g_pCompositor->m_pLastWindow ? g_pConfigManager->getFloat("decoration:active_opacity") : g_pConfigManager->getFloat("decoration:inactive_opacity");
+ renderdata.alpha = pWindow->m_fActiveInactiveAlpha.fl();
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
+ renderdata.blur = true; // if it shouldn't, it will be ignored later
+ renderdata.squishOversized = pWindow->m_vRealPosition.isBeingAnimated();
// apply window special data
if (pWindow->m_sSpecialRenderData.alphaInactive == -1)
@@ -173,37 +193,40 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
g_pHyprOpenGL->m_pCurrentWindow = pWindow;
// render window decorations first, if not fullscreen full
- if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
- wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
-
- if (!pWindow->m_bIsX11) {
- // To everyone who makes apps with improperly aligned surfaces,
- // For example chromium, or GTK devs who allow shadows on windows,
- // a sincere FUCK YOU.
+ if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) {
+ if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
+ wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
- wlr_box geom;
- wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
+ if (!pWindow->m_bIsX11) {
+ wlr_box geom;
+ wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height);
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height);
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height);
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height);
- if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
- // No special UV mods needed
+ if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
+ // No special UV mods needed
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
+ }
+ } else {
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
}
- }
- wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
+ wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
+ }
- if (!pWindow->m_bIsX11) {
- renderdata.dontRound = false; // restore dontround
- renderdata.pMonitor = pMonitor;
- wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata);
+ if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_POPUP) {
+ if (!pWindow->m_bIsX11) {
+ renderdata.dontRound = false; // restore dontround
+ renderdata.pMonitor = pMonitor;
+ wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata);
+ }
}
g_pHyprOpenGL->m_pCurrentWindow = nullptr;
@@ -217,6 +240,11 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, SMonitor* pMonitor, times
SRenderData renderdata = {pMonitor->output, time, pLayer->geometry.x, pLayer->geometry.y};
renderdata.fadeAlpha = pLayer->alpha.fl();
+ renderdata.blur = pLayer->forceBlur;
+ renderdata.surface = pLayer->layerSurface->surface;
+ renderdata.decorate = false;
+ renderdata.w = pLayer->layerSurface->surface->current.width;
+ renderdata.h = pLayer->layerSurface->surface->current.height;
wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata);
}
@@ -243,7 +271,25 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
return;
}
- // Non-floating
+ // Non-floating main
+ for (auto& w : g_pCompositor->m_vWindows) {
+ if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
+ continue;
+
+ if (w->m_bIsFloating)
+ continue; // floating are in the second pass
+
+ if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
+ continue; // special are in the third pass
+
+ if (!shouldRenderWindow(w.get(), PMONITOR))
+ continue;
+
+ // render the bad boy
+ renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_MAIN);
+ }
+
+ // Non-floating popup
for (auto& w : g_pCompositor->m_vWindows) {
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
continue;
@@ -258,7 +304,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
continue;
// render the bad boy
- renderWindow(w.get(), PMONITOR, time, true);
+ renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_POPUP);
}
// floating on top
@@ -276,7 +322,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
continue;
// render the bad boy
- renderWindow(w.get(), PMONITOR, time, true);
+ renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_ALL);
}
// and then special
@@ -291,7 +337,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
continue;
// render the bad boy
- renderWindow(w.get(), PMONITOR, time, true);
+ renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_ALL);
}
// Render surfaces above windows for monitor
@@ -428,7 +474,7 @@ void CHyprRenderer::arrangeLayerArray(SMonitor* pMonitor, const std::list<SLayer
wlr_box full_area = {pMonitor->vecPosition.x, pMonitor->vecPosition.y, pMonitor->vecSize.x, pMonitor->vecSize.y};
for (auto& ls : layerSurfaces) {
- if (ls->fadingOut || ls->readyToDelete)
+ if (ls->fadingOut || ls->readyToDelete || !ls->layerSurface)
continue;
const auto PLAYER = ls->layerSurface;
@@ -551,6 +597,11 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) {
pixman_region32_init(&damageBox);
wlr_surface_get_effective_damage(pSurface, &damageBox);
+ // schedule frame events
+ if (!wl_list_empty(&pSurface->current.frame_callback_list)) {
+ g_pCompositor->scheduleFrameForMonitor(g_pCompositor->getMonitorFromVector(Vector2D(x, y)));
+ }
+
if (!pixman_region32_not_empty(&damageBox)) {
pixman_region32_fini(&damageBox);
return;
@@ -799,4 +850,4 @@ void CHyprRenderer::ensureCursorRenderingMode() {
bool CHyprRenderer::shouldRenderCursor() {
return m_bHasARenderedCursor;
-} \ No newline at end of file
+}
diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp
index ff9fd4ea..c03c7117 100644
--- a/src/render/Renderer.hpp
+++ b/src/render/Renderer.hpp
@@ -17,6 +17,12 @@ enum DAMAGETRACKINGMODES {
DAMAGE_TRACKING_FULL
};
+enum eRenderPassMode {
+ RENDER_PASS_ALL = 0,
+ RENDER_PASS_MAIN,
+ RENDER_PASS_POPUP
+};
+
class CHyprRenderer {
public:
@@ -41,7 +47,7 @@ public:
private:
void arrangeLayerArray(SMonitor*, const std::list<SLayerSurface*>&, bool, wlr_box*);
void renderWorkspaceWithFullscreenWindow(SMonitor*, CWorkspace*, timespec*);
- void renderWindow(CWindow*, SMonitor*, timespec*, bool);
+ void renderWindow(CWindow*, SMonitor*, timespec*, bool, eRenderPassMode);
void renderLayer(SLayerSurface*, SMonitor*, timespec*);
void renderDragIcon(SMonitor*, timespec*);
diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp
index abb5d90c..2d46d7a0 100644
--- a/src/render/decorations/CHyprGroupBarDecoration.cpp
+++ b/src/render/decorations/CHyprGroupBarDecoration.cpp
@@ -40,12 +40,8 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
if (g_pLayoutManager->getCurrentLayout()->getLayoutName() != "dwindle") {
// ????
- for (auto it = pWindow->m_dWindowDecorations.begin(); it != pWindow->m_dWindowDecorations.end(); it++) {
- if (it->get() == this) {
- pWindow->m_dWindowDecorations.erase(it);
- return;
- }
- }
+ m_pWindow->m_vDecosToRemove.push_back(this);
+ return;
}
// get the group info
@@ -58,12 +54,8 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
if (m_dwGroupMembers.size() == 0) {
// remove
- for (auto it = pWindow->m_dWindowDecorations.begin(); it != pWindow->m_dWindowDecorations.end(); it++) {
- if (it->get() == this) {
- pWindow->m_dWindowDecorations.erase(it);
- return;
- }
- }
+ m_pWindow->m_vDecosToRemove.push_back(this);
+ return;
}
}