mirror of
https://github.com/hyprwm/hyprlock.git
synced 2024-11-16 23:05:58 +01:00
parent
97548ec0ad
commit
ada7ce8e56
11 changed files with 103 additions and 61 deletions
|
@ -15,8 +15,7 @@ static void handleMode(void* data, wl_output* output, uint32_t flags, int32_t wi
|
|||
const auto POUTPUT = (COutput*)data;
|
||||
|
||||
// handle portrait mode and flipped cases
|
||||
if (POUTPUT->transform == WL_OUTPUT_TRANSFORM_270 || POUTPUT->transform == WL_OUTPUT_TRANSFORM_90 || POUTPUT->transform == WL_OUTPUT_TRANSFORM_FLIPPED_270 ||
|
||||
POUTPUT->transform == WL_OUTPUT_TRANSFORM_FLIPPED_90)
|
||||
if (POUTPUT->transform % 2 == 1)
|
||||
POUTPUT->size = {height, width};
|
||||
else
|
||||
POUTPUT->size = {width, height};
|
||||
|
|
|
@ -310,6 +310,25 @@ void CHyprlock::run() {
|
|||
|
||||
g_pRenderer = std::make_unique<CRenderer>();
|
||||
|
||||
const auto CURRENTDESKTOP = getenv("XDG_CURRENT_DESKTOP");
|
||||
const auto SZCURRENTD = std::string{CURRENTDESKTOP ? CURRENTDESKTOP : ""};
|
||||
|
||||
Debug::log(LOG, "Running on {}", SZCURRENTD);
|
||||
|
||||
// Hyprland violates the protocol a bit to allow for this.
|
||||
if (SZCURRENTD != "Hyprland") {
|
||||
while (!g_pRenderer->asyncResourceGatherer->ready) {
|
||||
wl_display_flush(m_sWaylandState.display);
|
||||
if (wl_display_prepare_read(m_sWaylandState.display) == 0) {
|
||||
wl_display_read_events(m_sWaylandState.display);
|
||||
wl_display_dispatch_pending(m_sWaylandState.display);
|
||||
} else {
|
||||
wl_display_dispatch(m_sWaylandState.display);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
lockSession();
|
||||
|
||||
signal(SIGUSR1, handleUnlockSignal);
|
||||
|
@ -388,7 +407,7 @@ void CHyprlock::run() {
|
|||
|
||||
m_sLoopState.event = false;
|
||||
|
||||
if (pollfds[0].revents & POLLIN /* dbus */) {
|
||||
if (pollfds[0].revents & POLLIN /* wl */) {
|
||||
Debug::log(TRACE, "got wl event");
|
||||
wl_display_flush(m_sWaylandState.display);
|
||||
if (wl_display_prepare_read(m_sWaylandState.display) == 0) {
|
||||
|
|
17
src/main.cpp
17
src/main.cpp
|
@ -2,13 +2,13 @@
|
|||
#include "config/ConfigManager.hpp"
|
||||
#include "core/hyprlock.hpp"
|
||||
|
||||
void help(){
|
||||
std::cout << "Usage: hyprlock [options]\n\n"
|
||||
"Options:\n"
|
||||
" -v, --verbose - Enable verbose logging\n"
|
||||
" -q, --quiet - Disable logging\n"
|
||||
" --display (display) - Specify the Wayland display to connect to\n"
|
||||
" -h, --help - Show this help message\n";
|
||||
void help() {
|
||||
std::cout << "Usage: hyprlock [options]\n\n"
|
||||
"Options:\n"
|
||||
" -v, --verbose - Enable verbose logging\n"
|
||||
" -q, --quiet - Disable logging\n"
|
||||
" --display (display) - Specify the Wayland display to connect to\n"
|
||||
" -h, --help - Show this help message\n";
|
||||
}
|
||||
int main(int argc, char** argv, char** envp) {
|
||||
std::string wlDisplay;
|
||||
|
@ -25,8 +25,7 @@ int main(int argc, char** argv, char** envp) {
|
|||
else if (arg == "--display" && i + 1 < argc) {
|
||||
wlDisplay = argv[i + 1];
|
||||
i++;
|
||||
}
|
||||
else if (arg == "--help" || arg == "-h") {
|
||||
} else if (arg == "--help" || arg == "-h") {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -151,6 +151,10 @@ void CAsyncResourceGatherer::gather() {
|
|||
}
|
||||
}
|
||||
|
||||
while (std::any_of(dmas.begin(), dmas.end(), [](const auto& d) { return !d->asset.ready; })) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
ready = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = nullptr;
|
||||
static PFNEGLQUERYDMABUFMODIFIERSEXTPROC eglQueryDmaBufModifiersEXT = nullptr;
|
||||
|
||||
static void wlrOnBuffer(void* data, zwlr_screencopy_frame_v1* frame, uint32_t format, uint32_t width, uint32_t height, uint32_t stride) {
|
||||
//
|
||||
static void wlrOnBuffer(void* data, zwlr_screencopy_frame_v1* frame, uint32_t format, uint32_t width, uint32_t height, uint32_t stride) {
|
||||
const auto PDATA = (SScreencopyData*)data;
|
||||
|
||||
Debug::log(TRACE, "[sc] wlrOnBuffer for {}", (void*)PDATA);
|
||||
|
@ -85,7 +86,7 @@ static const zwlr_screencopy_frame_v1_listener wlrFrameListener = {
|
|||
.buffer_done = wlrOnBufferDone,
|
||||
};
|
||||
|
||||
CDMAFrame::CDMAFrame(COutput* output) {
|
||||
CDMAFrame::CDMAFrame(COutput* output_) : output(output_) {
|
||||
|
||||
if (!glEGLImageTargetTexture2DOES) {
|
||||
glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
|
||||
|
@ -208,19 +209,21 @@ bool CDMAFrame::onBufferReady() {
|
|||
static const int entries_per_attrib = 2;
|
||||
EGLAttrib attribs[(general_attribs + plane_attribs * 4) * entries_per_attrib + 1];
|
||||
int attr = 0;
|
||||
attribs[attr++] = EGL_WIDTH;
|
||||
attribs[attr++] = scdata.w;
|
||||
attribs[attr++] = EGL_HEIGHT;
|
||||
attribs[attr++] = scdata.h;
|
||||
attribs[attr++] = EGL_LINUX_DRM_FOURCC_EXT;
|
||||
attribs[attr++] = scdata.fmt;
|
||||
attribs[attr++] = EGL_DMA_BUF_PLANE0_FD_EXT;
|
||||
attribs[attr++] = fd[0];
|
||||
attribs[attr++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
|
||||
attribs[attr++] = offset[0];
|
||||
attribs[attr++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
|
||||
attribs[attr++] = stride[0];
|
||||
attribs[attr] = EGL_NONE;
|
||||
Vector2D size{scdata.w, scdata.h};
|
||||
|
||||
attribs[attr++] = EGL_WIDTH;
|
||||
attribs[attr++] = size.x;
|
||||
attribs[attr++] = EGL_HEIGHT;
|
||||
attribs[attr++] = size.y;
|
||||
attribs[attr++] = EGL_LINUX_DRM_FOURCC_EXT;
|
||||
attribs[attr++] = scdata.fmt;
|
||||
attribs[attr++] = EGL_DMA_BUF_PLANE0_FD_EXT;
|
||||
attribs[attr++] = fd[0];
|
||||
attribs[attr++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
|
||||
attribs[attr++] = offset[0];
|
||||
attribs[attr++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
|
||||
attribs[attr++] = stride[0];
|
||||
attribs[attr] = EGL_NONE;
|
||||
|
||||
image = eglCreateImage(g_pEGL->eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
||||
|
||||
|
@ -230,7 +233,7 @@ bool CDMAFrame::onBufferReady() {
|
|||
}
|
||||
|
||||
asset.texture.allocate();
|
||||
asset.texture.m_vSize = {scdata.w, scdata.h};
|
||||
asset.texture.m_vSize = size;
|
||||
glBindTexture(GL_TEXTURE_2D, asset.texture.m_iTexID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
@ -239,6 +242,8 @@ bool CDMAFrame::onBufferReady() {
|
|||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
Debug::log(LOG, "Got dma frame with size {}", size);
|
||||
|
||||
asset.ready = true;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -42,5 +42,7 @@ class CDMAFrame {
|
|||
zwlr_screencopy_frame_v1* frameCb = nullptr;
|
||||
SScreencopyData scdata;
|
||||
|
||||
COutput* output = nullptr;
|
||||
|
||||
EGLImage image = nullptr;
|
||||
};
|
|
@ -242,9 +242,9 @@ void CRenderer::renderRect(const CBox& box, const CColor& col, int rounding) {
|
|||
glDisableVertexAttribArray(rectShader.posAttrib);
|
||||
}
|
||||
|
||||
void CRenderer::renderTexture(const CBox& box, const CTexture& tex, float a, int rounding, bool noTransform) {
|
||||
void CRenderer::renderTexture(const CBox& box, const CTexture& tex, float a, int rounding, std::optional<wl_output_transform> tr) {
|
||||
float matrix[9];
|
||||
wlr_matrix_project_box(matrix, &box, noTransform ? WL_OUTPUT_TRANSFORM_NORMAL : WL_OUTPUT_TRANSFORM_FLIPPED_180 /* ugh coordinate spaces */, 0,
|
||||
wlr_matrix_project_box(matrix, &box, tr.value_or(WL_OUTPUT_TRANSFORM_FLIPPED_180) /* ugh coordinate spaces */, 0,
|
||||
projMatrix.data()); // TODO: write own, don't use WLR here
|
||||
|
||||
float glMatrix[9];
|
||||
|
@ -305,7 +305,7 @@ std::vector<std::unique_ptr<IWidget>>* CRenderer::getOrCreateWidgetsFor(const CS
|
|||
else if (!PATH.empty())
|
||||
resourceID = "background:" + PATH;
|
||||
|
||||
widgets[surf].emplace_back(std::make_unique<CBackground>(surf->size, resourceID, c.values));
|
||||
widgets[surf].emplace_back(std::make_unique<CBackground>(surf->size, surf->output, resourceID, c.values, PATH == "screenshot"));
|
||||
} else if (c.type == "input-field") {
|
||||
widgets[surf].emplace_back(std::make_unique<CPasswordInputField>(surf->size, c.values));
|
||||
} else if (c.type == "label") {
|
||||
|
@ -464,7 +464,7 @@ void CRenderer::blurFB(const CFramebuffer& outfb, SBlurParams params) {
|
|||
|
||||
// finish
|
||||
outfb.bind();
|
||||
renderTexture(box, currentRenderToFB->m_cTex, 1.0, 0, true);
|
||||
renderTexture(box, currentRenderToFB->m_cTex, 1.0, 0, WL_OUTPUT_TRANSFORM_NORMAL);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
}
|
|
@ -29,7 +29,7 @@ class CRenderer {
|
|||
SRenderFeedback renderLock(const CSessionLockSurface& surface);
|
||||
|
||||
void renderRect(const CBox& box, const CColor& col, int rounding = 0);
|
||||
void renderTexture(const CBox& box, const CTexture& tex, float a = 1.0, int rounding = 0, bool noTransform = false);
|
||||
void renderTexture(const CBox& box, const CTexture& tex, float a = 1.0, int rounding = 0, std::optional<wl_output_transform> tr = {});
|
||||
void blurFB(const CFramebuffer& outfb, SBlurParams params);
|
||||
|
||||
std::unique_ptr<CAsyncResourceGatherer> asyncResourceGatherer;
|
||||
|
|
|
@ -4,21 +4,21 @@
|
|||
#include <wayland-client.h>
|
||||
#include "../helpers/Box.hpp"
|
||||
|
||||
enum wl_output_transform wlr_output_transform_invert(enum wl_output_transform tr) {
|
||||
// if ((tr & WL_OUTPUT_TRANSFORM_90) && !(tr & WL_OUTPUT_TRANSFORM_FLIPPED)) {
|
||||
// tr ^= WL_OUTPUT_TRANSFORM_180;
|
||||
// }
|
||||
static enum wl_output_transform wlr_output_transform_invert(enum wl_output_transform tr) {
|
||||
if ((tr & WL_OUTPUT_TRANSFORM_90) && !(tr & WL_OUTPUT_TRANSFORM_FLIPPED)) {
|
||||
tr = (wl_output_transform)((int)tr ^ (int)WL_OUTPUT_TRANSFORM_180);
|
||||
}
|
||||
return tr;
|
||||
}
|
||||
|
||||
void wlr_matrix_identity(float mat[9]) {
|
||||
static void wlr_matrix_identity(float mat[9]) {
|
||||
const float identity[9] = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
memcpy(mat, identity, sizeof(identity));
|
||||
}
|
||||
|
||||
void wlr_matrix_multiply(float mat[9], const float a[9], const float b[9]) {
|
||||
static void wlr_matrix_multiply(float mat[9], const float a[9], const float b[9]) {
|
||||
float product[9];
|
||||
|
||||
product[0] = a[0] * b[0] + a[1] * b[3] + a[2] * b[6];
|
||||
|
@ -36,35 +36,35 @@ void wlr_matrix_multiply(float mat[9], const float a[9], const float b[9]) {
|
|||
memcpy(mat, product, sizeof(product));
|
||||
}
|
||||
|
||||
void wlr_matrix_transpose(float mat[9], const float a[9]) {
|
||||
static void wlr_matrix_transpose(float mat[9], const float a[9]) {
|
||||
float transposition[9] = {
|
||||
a[0], a[3], a[6], a[1], a[4], a[7], a[2], a[5], a[8],
|
||||
};
|
||||
memcpy(mat, transposition, sizeof(transposition));
|
||||
}
|
||||
|
||||
void wlr_matrix_translate(float mat[9], float x, float y) {
|
||||
static void wlr_matrix_translate(float mat[9], float x, float y) {
|
||||
float translate[9] = {
|
||||
1.0f, 0.0f, x, 0.0f, 1.0f, y, 0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
wlr_matrix_multiply(mat, mat, translate);
|
||||
}
|
||||
|
||||
void wlr_matrix_scale(float mat[9], float x, float y) {
|
||||
static void wlr_matrix_scale(float mat[9], float x, float y) {
|
||||
float scale[9] = {
|
||||
x, 0.0f, 0.0f, 0.0f, y, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
wlr_matrix_multiply(mat, mat, scale);
|
||||
}
|
||||
|
||||
void wlr_matrix_rotate(float mat[9], float rad) {
|
||||
static void wlr_matrix_rotate(float mat[9], float rad) {
|
||||
float rotate[9] = {
|
||||
cos(rad), -sin(rad), 0.0f, sin(rad), cos(rad), 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
wlr_matrix_multiply(mat, mat, rotate);
|
||||
}
|
||||
|
||||
const float transforms[][9] = {
|
||||
static const float transforms[][9] = {
|
||||
[WL_OUTPUT_TRANSFORM_NORMAL] =
|
||||
{
|
||||
1.0f,
|
||||
|
@ -163,11 +163,11 @@ const float transforms[][9] = {
|
|||
},
|
||||
};
|
||||
|
||||
void wlr_matrix_transform(float mat[9], enum wl_output_transform transform) {
|
||||
static void wlr_matrix_transform(float mat[9], enum wl_output_transform transform) {
|
||||
wlr_matrix_multiply(mat, mat, transforms[transform]);
|
||||
}
|
||||
|
||||
void matrix_projection(float mat[9], int width, int height, enum wl_output_transform transform) {
|
||||
static void matrix_projection(float mat[9], int width, int height, enum wl_output_transform transform) {
|
||||
std::memset(mat, 0, sizeof(*mat) * 9);
|
||||
|
||||
const float* t = transforms[transform];
|
||||
|
@ -188,7 +188,7 @@ void matrix_projection(float mat[9], int width, int height, enum wl_output_trans
|
|||
mat[8] = 1.0f;
|
||||
}
|
||||
|
||||
void wlr_matrix_project_box(float mat[9], const CBox* box, enum wl_output_transform transform, float rotation, const float projection[9]) {
|
||||
static void wlr_matrix_project_box(float mat[9], const CBox* box, enum wl_output_transform transform, float rotation, const float projection[9]) {
|
||||
int x = box->x;
|
||||
int y = box->y;
|
||||
int width = box->width;
|
||||
|
@ -214,7 +214,7 @@ void wlr_matrix_project_box(float mat[9], const CBox* box, enum wl_output_transf
|
|||
wlr_matrix_multiply(mat, projection, mat);
|
||||
}
|
||||
|
||||
void matrixProjection(float mat[9], int w, int h, wl_output_transform tr) {
|
||||
static void matrixProjection(float mat[9], int w, int h, wl_output_transform tr) {
|
||||
memset(mat, 0, sizeof(*mat) * 9);
|
||||
|
||||
const float* t = transforms[tr];
|
||||
|
@ -233,4 +233,4 @@ void matrixProjection(float mat[9], int w, int h, wl_output_transform tr) {
|
|||
|
||||
// Identity
|
||||
mat[8] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#include "Background.hpp"
|
||||
#include "../Renderer.hpp"
|
||||
#include "../mtx.hpp"
|
||||
|
||||
CBackground::CBackground(const Vector2D& viewport_, const std::string& resourceID_, const std::unordered_map<std::string, std::any>& props) :
|
||||
viewport(viewport_), resourceID(resourceID_) {
|
||||
CBackground::CBackground(const Vector2D& viewport_, COutput* output_, const std::string& resourceID_, const std::unordered_map<std::string, std::any>& props, bool ss) :
|
||||
viewport(viewport_), resourceID(resourceID_), output(output_), isScreenshot(ss) {
|
||||
|
||||
color = std::any_cast<Hyprlang::INT>(props.at("color"));
|
||||
blurPasses = std::any_cast<Hyprlang::INT>(props.at("blur_passes"));
|
||||
|
@ -30,13 +31,19 @@ bool CBackground::draw(const SRenderData& data) {
|
|||
if (!asset)
|
||||
return false;
|
||||
|
||||
if (blurPasses > 0 && !blurredFB.isAllocated()) {
|
||||
if ((blurPasses > 0 || isScreenshot) && !blurredFB.isAllocated()) {
|
||||
// make it brah
|
||||
CBox texbox = {{}, asset->texture.m_vSize};
|
||||
Vector2D size = asset->texture.m_vSize;
|
||||
|
||||
Vector2D size = asset->texture.m_vSize;
|
||||
float scaleX = viewport.x / asset->texture.m_vSize.x;
|
||||
float scaleY = viewport.y / asset->texture.m_vSize.y;
|
||||
if (output->transform % 2 == 1 && isScreenshot) {
|
||||
size.x = asset->texture.m_vSize.y;
|
||||
size.y = asset->texture.m_vSize.x;
|
||||
}
|
||||
|
||||
CBox texbox = {{}, size};
|
||||
|
||||
float scaleX = viewport.x / size.x;
|
||||
float scaleY = viewport.y / size.y;
|
||||
|
||||
texbox.w *= std::max(scaleX, scaleY);
|
||||
texbox.h *= std::max(scaleX, scaleY);
|
||||
|
@ -48,9 +55,13 @@ bool CBackground::draw(const SRenderData& data) {
|
|||
texbox.round();
|
||||
blurredFB.alloc(viewport.x, viewport.y); // TODO 10 bit
|
||||
blurredFB.bind();
|
||||
|
||||
g_pRenderer->renderTexture(texbox, asset->texture, 1.0, 0,
|
||||
true); // this could be omitted but whatever it's only once and makes code cleaner plus less blurring on large texs
|
||||
g_pRenderer->blurFB(blurredFB, CRenderer::SBlurParams{blurSize, blurPasses, noise, contrast, brightness, vibrancy, vibrancy_darkness});
|
||||
isScreenshot ?
|
||||
wlr_output_transform_invert(output->transform) :
|
||||
WL_OUTPUT_TRANSFORM_NORMAL); // this could be omitted but whatever it's only once and makes code cleaner plus less blurring on large texs
|
||||
if (blurPasses > 0)
|
||||
g_pRenderer->blurFB(blurredFB, CRenderer::SBlurParams{blurSize, blurPasses, noise, contrast, brightness, vibrancy, vibrancy_darkness});
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
|
@ -70,7 +81,7 @@ bool CBackground::draw(const SRenderData& data) {
|
|||
else
|
||||
texbox.x = -(texbox.w - viewport.x) / 2.f;
|
||||
texbox.round();
|
||||
g_pRenderer->renderTexture(texbox, *tex, data.opacity);
|
||||
g_pRenderer->renderTexture(texbox, *tex, data.opacity, 0, WL_OUTPUT_TRANSFORM_FLIPPED_180);
|
||||
|
||||
return data.opacity < 1.0;
|
||||
}
|
|
@ -9,10 +9,11 @@
|
|||
#include <any>
|
||||
|
||||
struct SPreloadedAsset;
|
||||
class COutput;
|
||||
|
||||
class CBackground : public IWidget {
|
||||
public:
|
||||
CBackground(const Vector2D& viewport, const std::string& resourceID, const std::unordered_map<std::string, std::any>& props);
|
||||
CBackground(const Vector2D& viewport, COutput* output_, const std::string& resourceID, const std::unordered_map<std::string, std::any>& props, bool ss_);
|
||||
|
||||
virtual bool draw(const SRenderData& data);
|
||||
|
||||
|
@ -30,5 +31,7 @@ class CBackground : public IWidget {
|
|||
Vector2D viewport;
|
||||
std::string resourceID;
|
||||
CColor color;
|
||||
SPreloadedAsset* asset = nullptr;
|
||||
SPreloadedAsset* asset = nullptr;
|
||||
COutput* output = nullptr;
|
||||
bool isScreenshot = false;
|
||||
};
|
Loading…
Reference in a new issue