mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-07 23:05:58 +01:00
Added HyprError for showing config errors
This commit is contained in:
parent
037bad4986
commit
7347a72ba6
8 changed files with 167 additions and 1 deletions
|
@ -121,6 +121,9 @@ void CCompositor::startCompositor() {
|
|||
// Init all the managers BEFORE we start with the wayland server so that ALL of the stuff is initialized
|
||||
// properly and we dont get any bad mem reads.
|
||||
//
|
||||
Debug::log(LOG, "Creating the CHyprError!");
|
||||
g_pHyprError = std::make_unique<CHyprError>();
|
||||
|
||||
Debug::log(LOG, "Creating the KeybindManager!");
|
||||
g_pKeybindManager = std::make_unique<CKeybindManager>();
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "Window.hpp"
|
||||
#include "render/Renderer.hpp"
|
||||
#include "render/OpenGL.hpp"
|
||||
#include "hyprerror/HyprError.hpp"
|
||||
|
||||
class CCompositor {
|
||||
public:
|
||||
|
|
|
@ -310,7 +310,7 @@ void CConfigManager::loadConfigLoadVars() {
|
|||
Debug::log(ERR, "Error reading line from config. Line:");
|
||||
Debug::log(NONE, "%s", line.c_str());
|
||||
|
||||
parseError = "Config error at line " + std::to_string(linenum) + ": Line parsing error.";
|
||||
parseError += "Config error at line " + std::to_string(linenum) + ": Line parsing error.";
|
||||
}
|
||||
|
||||
if (parseError != "" && parseError.find("Config error at line") != 0) {
|
||||
|
@ -331,6 +331,12 @@ void CConfigManager::loadConfigLoadVars() {
|
|||
|
||||
// Calculate the mod mask for main_mod
|
||||
configValues["general:main_mod_internal"].intValue = g_pKeybindManager->stringToModMask(configValues["general:main_mod"].strValue);
|
||||
|
||||
// parseError will be displayed next frame
|
||||
if (parseError != "")
|
||||
g_pHyprError->queueCreate(parseError + "\nHyprland may not work correctly.", CColor(255, 50, 50, 255));
|
||||
else
|
||||
g_pHyprError->destroy();
|
||||
}
|
||||
|
||||
void CConfigManager::tick() {
|
||||
|
|
109
src/hyprerror/HyprError.cpp
Normal file
109
src/hyprerror/HyprError.cpp
Normal file
|
@ -0,0 +1,109 @@
|
|||
#include "HyprError.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
void CHyprError::queueCreate(std::string message, const CColor& color) {
|
||||
m_szQueued = message;
|
||||
m_cQueued = color;
|
||||
}
|
||||
|
||||
void CHyprError::createQueued() {
|
||||
if (m_bIsCreated) {
|
||||
m_bQueuedDestroy = false;
|
||||
m_tTexture.destroyTexture();
|
||||
}
|
||||
|
||||
const auto PMONITOR = &g_pCompositor->m_lMonitors.front();
|
||||
|
||||
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
|
||||
|
||||
const auto CAIRO = cairo_create(CAIROSURFACE);
|
||||
|
||||
// clear the pixmap
|
||||
cairo_save(CAIRO);
|
||||
cairo_set_operator(CAIRO, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_paint(CAIRO);
|
||||
cairo_restore(CAIRO);
|
||||
|
||||
const auto LINECOUNT = 1 + std::count(m_szQueued.begin(), m_szQueued.end(), '\n');
|
||||
|
||||
cairo_set_source_rgba(CAIRO, m_cQueued.r / 255.f, m_cQueued.g / 255.f, m_cQueued.b / 255.f, m_cQueued.a / 255.f);
|
||||
cairo_rectangle(CAIRO, 0, 0, PMONITOR->vecSize.x, 10 * LINECOUNT);
|
||||
|
||||
// outline
|
||||
cairo_rectangle(CAIRO, 0, 0, 1, PMONITOR->vecSize.y); // left
|
||||
cairo_rectangle(CAIRO, PMONITOR->vecSize.x - 1, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y); // right
|
||||
cairo_rectangle(CAIRO, 0, PMONITOR->vecSize.y - 1, PMONITOR->vecSize.x, PMONITOR->vecSize.y); // bottom
|
||||
|
||||
cairo_fill(CAIRO);
|
||||
|
||||
// draw the text with a common font
|
||||
const CColor textColor = m_cQueued.r * m_cQueued.g * m_cQueued.b < 0.5f ? CColor(255, 255, 255, 255) : CColor(0, 0, 0, 255);
|
||||
|
||||
cairo_select_font_face(CAIRO, "Noto Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
||||
cairo_set_font_size(CAIRO, 8);
|
||||
cairo_set_source_rgba(CAIRO, textColor.r / 255.f, textColor.g / 255.f, textColor.b / 255.f, textColor.a / 255.f);
|
||||
|
||||
float yoffset = 8;
|
||||
while(m_szQueued != "") {
|
||||
std::string current = m_szQueued.substr(0, m_szQueued.find('\n'));
|
||||
if (const auto NEWLPOS = m_szQueued.find('\n'); NEWLPOS != std::string::npos)
|
||||
m_szQueued = m_szQueued.substr(NEWLPOS + 1);
|
||||
else
|
||||
m_szQueued = "";
|
||||
cairo_move_to(CAIRO, 0, yoffset);
|
||||
cairo_show_text(CAIRO, current.c_str());
|
||||
yoffset += 9;
|
||||
}
|
||||
|
||||
|
||||
cairo_surface_flush(CAIROSURFACE);
|
||||
|
||||
// copy the data to an OpenGL texture we have
|
||||
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
||||
m_tTexture.allocate();
|
||||
glBindTexture(GL_TEXTURE_2D, m_tTexture.m_iTexID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecSize.x, PMONITOR->vecSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
// delete cairo
|
||||
cairo_destroy(CAIRO);
|
||||
cairo_surface_destroy(CAIROSURFACE);
|
||||
|
||||
m_bIsCreated = true;
|
||||
m_szQueued = "";
|
||||
m_cQueued = CColor();
|
||||
}
|
||||
|
||||
void CHyprError::draw() {
|
||||
if (!m_bIsCreated) {
|
||||
if (m_szQueued != "")
|
||||
createQueued();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_bQueuedDestroy) {
|
||||
m_bQueuedDestroy = false;
|
||||
m_tTexture.destroyTexture();
|
||||
m_bIsCreated = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = &g_pCompositor->m_lMonitors.front();
|
||||
|
||||
if (g_pHyprOpenGL->m_RenderData.pMonitor != PMONITOR)
|
||||
return; // wrong mon
|
||||
|
||||
const auto TRANSFORM = wlr_output_transform_invert(WL_OUTPUT_TRANSFORM_NORMAL);
|
||||
float matrix[9];
|
||||
wlr_box windowBox = {0, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
|
||||
wlr_matrix_project_box(matrix, &windowBox, TRANSFORM, 0, PMONITOR->output->transform_matrix);
|
||||
|
||||
g_pHyprOpenGL->renderTexture(m_tTexture, matrix, 255.f, 0);
|
||||
}
|
||||
|
||||
void CHyprError::destroy() {
|
||||
m_bQueuedDestroy = true;
|
||||
}
|
23
src/hyprerror/HyprError.hpp
Normal file
23
src/hyprerror/HyprError.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include "../render/Texture.hpp"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
|
||||
class CHyprError {
|
||||
public:
|
||||
void queueCreate(std::string message, const CColor& color);
|
||||
void draw();
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
void createQueued();
|
||||
std::string m_szQueued = "";
|
||||
CColor m_cQueued;
|
||||
bool m_bQueuedDestroy = false;
|
||||
bool m_bIsCreated = false;
|
||||
CTexture m_tTexture;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CHyprError> g_pHyprError; // This is a full-screen error. Treat it with respect, and there can only be one at a time.
|
|
@ -79,6 +79,10 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, SWor
|
|||
}
|
||||
|
||||
renderDragIcon(pMonitor, time);
|
||||
|
||||
// if correct monitor draw hyprerror
|
||||
if (pMonitor == &g_pCompositor->m_lMonitors.front())
|
||||
g_pHyprError->draw();
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate) {
|
||||
|
@ -178,6 +182,10 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
|||
}
|
||||
|
||||
renderDragIcon(PMONITOR, time);
|
||||
|
||||
// if correct monitor draw hyprerror
|
||||
if (PMONITOR == &g_pCompositor->m_lMonitors.front())
|
||||
g_pHyprError->draw();
|
||||
}
|
||||
|
||||
void CHyprRenderer::outputMgrApplyTest(wlr_output_configuration_v1* config, bool test) {
|
||||
|
|
|
@ -19,4 +19,17 @@ CTexture::CTexture(wlr_texture* tex) {
|
|||
}
|
||||
|
||||
m_vSize = Vector2D(tex->width, tex->height);
|
||||
}
|
||||
|
||||
void CTexture::destroyTexture() {
|
||||
if (m_iTexID) {
|
||||
glDeleteTextures(1, &m_iTexID);
|
||||
m_iTexID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CTexture::allocate() {
|
||||
if (!m_iTexID) {
|
||||
glGenTextures(1, &m_iTexID);
|
||||
}
|
||||
}
|
|
@ -14,6 +14,9 @@ public:
|
|||
CTexture();
|
||||
CTexture(wlr_texture*);
|
||||
|
||||
void destroyTexture();
|
||||
void allocate();
|
||||
|
||||
TEXTURETYPE m_iType = TEXTURE_RGBA;
|
||||
GLenum m_iTarget = GL_TEXTURE_2D;
|
||||
GLuint m_iTexID = 0;
|
||||
|
|
Loading…
Reference in a new issue