mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-26 07:05:58 +01:00
Renderer
This commit is contained in:
parent
ab7d727532
commit
bc937e3e71
12 changed files with 222 additions and 10 deletions
|
@ -9,7 +9,7 @@ message(STATUS "Configuring Hyprland!")
|
||||||
|
|
||||||
include_directories(.)
|
include_directories(.)
|
||||||
add_compile_options(-std=c++20 -DWLR_USE_UNSTABLE )
|
add_compile_options(-std=c++20 -DWLR_USE_UNSTABLE )
|
||||||
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value)
|
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
|
@ -62,6 +62,8 @@ CCompositor::CCompositor() {
|
||||||
wl_signal_add(&m_sWLRSeat->events.request_set_cursor, &Events::listen_requestMouse);
|
wl_signal_add(&m_sWLRSeat->events.request_set_cursor, &Events::listen_requestMouse);
|
||||||
wl_signal_add(&m_sWLRSeat->events.request_set_selection, &Events::listen_requestSetSel);
|
wl_signal_add(&m_sWLRSeat->events.request_set_selection, &Events::listen_requestSetSel);
|
||||||
|
|
||||||
|
m_sWLRPresentation = wlr_presentation_create(m_sWLDisplay, m_sWLRBackend);
|
||||||
|
|
||||||
// TODO: XWayland
|
// TODO: XWayland
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +84,9 @@ void CCompositor::startCompositor() {
|
||||||
|
|
||||||
Debug::log(LOG, "Creating the InputManager!");
|
Debug::log(LOG, "Creating the InputManager!");
|
||||||
g_pInputManager = std::make_unique<CInputManager>();
|
g_pInputManager = std::make_unique<CInputManager>();
|
||||||
|
|
||||||
|
Debug::log(LOG, "Creating the HyprRenderer!");
|
||||||
|
g_pHyprRenderer = std::make_unique<CHyprRenderer>();
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -112,3 +117,30 @@ void CCompositor::startCompositor() {
|
||||||
Debug::log(LOG, "Hyprland is ready, running the event loop!");
|
Debug::log(LOG, "Hyprland is ready, running the event loop!");
|
||||||
wl_display_run(m_sWLDisplay);
|
wl_display_run(m_sWLDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMonitor* CCompositor::getMonitorFromID(const int& id) {
|
||||||
|
for (auto& m : m_vMonitors) {
|
||||||
|
if (m.ID == id) {
|
||||||
|
return &m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SMonitor* CCompositor::getMonitorFromCursor() {
|
||||||
|
const auto COORDS = g_pInputManager->getMouseCoordsInternal();
|
||||||
|
const auto OUTPUT = wlr_output_layout_output_at(m_sWLROutputLayout, COORDS.x, COORDS.y);
|
||||||
|
|
||||||
|
if (!OUTPUT) {
|
||||||
|
Debug::log(WARN, "getMonitorFromCursor: cursour outside monitors??");
|
||||||
|
return &m_vMonitors[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& m : m_vMonitors) {
|
||||||
|
if (m.output == OUTPUT)
|
||||||
|
return &m;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &m_vMonitors[0];
|
||||||
|
}
|
|
@ -10,6 +10,8 @@
|
||||||
#include "ManagerThread.hpp"
|
#include "ManagerThread.hpp"
|
||||||
#include "input/InputManager.hpp"
|
#include "input/InputManager.hpp"
|
||||||
#include "helpers/Monitor.hpp"
|
#include "helpers/Monitor.hpp"
|
||||||
|
#include "Window.hpp"
|
||||||
|
#include "render/Renderer.hpp"
|
||||||
|
|
||||||
class CCompositor {
|
class CCompositor {
|
||||||
public:
|
public:
|
||||||
|
@ -42,8 +44,15 @@ public:
|
||||||
const char* m_szWLDisplaySocket;
|
const char* m_szWLDisplaySocket;
|
||||||
|
|
||||||
std::deque<SMonitor> m_vMonitors;
|
std::deque<SMonitor> m_vMonitors;
|
||||||
|
std::deque<CWindow> m_vWindows;
|
||||||
|
|
||||||
void startCompositor();
|
void startCompositor();
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------- //
|
||||||
|
|
||||||
|
SMonitor* getMonitorFromID(const int&);
|
||||||
|
SMonitor* getMonitorFromCursor();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "ManagerThread.hpp"
|
#include "ManagerThread.hpp"
|
||||||
|
|
||||||
CManagerThread::CManagerThread() {
|
CManagerThread::CManagerThread() {
|
||||||
m_tMainThread = new std::thread([=]() {
|
m_tMainThread = new std::thread([&]() {
|
||||||
// Call the handle method.
|
// Call the handle method.
|
||||||
this->handle();
|
this->handle();
|
||||||
});
|
});
|
||||||
|
|
0
src/Window.cpp
Normal file
0
src/Window.cpp
Normal file
40
src/Window.hpp
Normal file
40
src/Window.hpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "defines.hpp"
|
||||||
|
#include "events/Events.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
class CWindow {
|
||||||
|
public:
|
||||||
|
|
||||||
|
DYNLISTENER(commitWindow);
|
||||||
|
DYNLISTENER(mapWindow);
|
||||||
|
DYNLISTENER(unmapWindow);
|
||||||
|
DYNLISTENER(destroyWindow);
|
||||||
|
DYNLISTENER(setTitleWindow);
|
||||||
|
DYNLISTENER(fullscreenWindow);
|
||||||
|
|
||||||
|
union {
|
||||||
|
wlr_xdg_surface* xdg;
|
||||||
|
wlr_xwayland_surface* xwayland;
|
||||||
|
} m_uSurface;
|
||||||
|
|
||||||
|
// TODO: XWayland
|
||||||
|
|
||||||
|
// this is the position and size of the "bounding box"
|
||||||
|
Vector2D m_vPosition = Vector2D(0,0);
|
||||||
|
Vector2D m_vSize = Vector2D(0,0);
|
||||||
|
|
||||||
|
// this is the position and size of the goal placement
|
||||||
|
Vector2D m_vEffectivePosition = Vector2D(0,0);
|
||||||
|
Vector2D m_vEffectiveSize = Vector2D(0,0);
|
||||||
|
|
||||||
|
// this is the real position and size used to draw the thing
|
||||||
|
Vector2D m_vRealPosition = Vector2D(0,0);
|
||||||
|
Vector2D m_vRealSize = Vector2D(0,0);
|
||||||
|
|
||||||
|
uint64_t m_iTags = 0;
|
||||||
|
bool m_bIsFloating = false;
|
||||||
|
bool m_bIsFullscreen = false;
|
||||||
|
uint64_t m_iMonitorID = -1;
|
||||||
|
};
|
|
@ -10,3 +10,5 @@
|
||||||
|
|
||||||
#define LISTENER(name) void listener_##name(wl_listener*, void*); inline wl_listener listen_##name = { .notify = listener_##name };
|
#define LISTENER(name) void listener_##name(wl_listener*, void*); inline wl_listener listen_##name = { .notify = listener_##name };
|
||||||
#define DYNLISTENER(name) wl_listener listen_##name = { .notify = Events::listener_##name };
|
#define DYNLISTENER(name) wl_listener listen_##name = { .notify = Events::listener_##name };
|
||||||
|
|
||||||
|
#define VECINRECT(vec, x1, y1, x2, y2) (vec.x >= (x1) && vec.x <= (x2) && vec.y >= (y1) && vec.y <= (y2))
|
|
@ -3,6 +3,7 @@
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../helpers/WLClasses.hpp"
|
#include "../helpers/WLClasses.hpp"
|
||||||
#include "../input/InputManager.hpp"
|
#include "../input/InputManager.hpp"
|
||||||
|
#include "../render/Renderer.hpp"
|
||||||
|
|
||||||
void Events::listener_activate(wl_listener* listener, void* data) {
|
void Events::listener_activate(wl_listener* listener, void* data) {
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -60,8 +61,8 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||||
g_pCompositor->m_vMonitors.push_back(newMonitor);
|
g_pCompositor->m_vMonitors.push_back(newMonitor);
|
||||||
//
|
//
|
||||||
|
|
||||||
wl_signal_add(&OUTPUT->events.frame, &g_pCompositor->m_vMonitors[g_pCompositor->m_vMonitors.size() - 1].listen_monitorFrame);
|
wl_signal_add(&OUTPUT->events.frame, &g_pCompositor->m_vMonitors.back().listen_monitorFrame);
|
||||||
wl_signal_add(&OUTPUT->events.destroy, &g_pCompositor->m_vMonitors[g_pCompositor->m_vMonitors.size() - 1].listen_monitorDestroy);
|
wl_signal_add(&OUTPUT->events.destroy, &g_pCompositor->m_vMonitors.back().listen_monitorDestroy);
|
||||||
|
|
||||||
wlr_output_enable(OUTPUT, 1);
|
wlr_output_enable(OUTPUT, 1);
|
||||||
if (!wlr_output_commit(OUTPUT)) {
|
if (!wlr_output_commit(OUTPUT)) {
|
||||||
|
@ -80,7 +81,6 @@ void Events::listener_monitorFrame(wl_listener* listener, void* data) {
|
||||||
timespec now;
|
timespec now;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
const float bgcol[4] = {0.1f,0.1f,0.1f,1.f};
|
const float bgcol[4] = {0.1f,0.1f,0.1f,1.f};
|
||||||
const float rectcol[4] = {0.69f,0.1f,0.69f,1.f};
|
|
||||||
|
|
||||||
if (!wlr_output_attach_render(PMONITOR->output, nullptr))
|
if (!wlr_output_attach_render(PMONITOR->output, nullptr))
|
||||||
return;
|
return;
|
||||||
|
@ -88,7 +88,7 @@ void Events::listener_monitorFrame(wl_listener* listener, void* data) {
|
||||||
wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
|
wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
|
||||||
wlr_renderer_clear(g_pCompositor->m_sWLRRenderer, bgcol);
|
wlr_renderer_clear(g_pCompositor->m_sWLRRenderer, bgcol);
|
||||||
|
|
||||||
// TODO: render clients
|
g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now);
|
||||||
|
|
||||||
wlr_output_render_software_cursors(PMONITOR->output, NULL);
|
wlr_output_render_software_cursors(PMONITOR->output, NULL);
|
||||||
|
|
||||||
|
@ -118,7 +118,6 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
|
||||||
const auto PMONITOR = (SMonitor*)WLRLAYERSURFACE->output->data;
|
const auto PMONITOR = (SMonitor*)WLRLAYERSURFACE->output->data;
|
||||||
PMONITOR->m_dLayerSurfaces.push_back(SLayerSurface());
|
PMONITOR->m_dLayerSurfaces.push_back(SLayerSurface());
|
||||||
SLayerSurface* layerSurface = &PMONITOR->m_dLayerSurfaces[PMONITOR->m_dLayerSurfaces.size() - 1];
|
SLayerSurface* layerSurface = &PMONITOR->m_dLayerSurfaces[PMONITOR->m_dLayerSurfaces.size() - 1];
|
||||||
wlr_layer_surface_v1_state oldState;
|
|
||||||
|
|
||||||
if (!WLRLAYERSURFACE->output) {
|
if (!WLRLAYERSURFACE->output) {
|
||||||
WLRLAYERSURFACE->output = g_pCompositor->m_vMonitors[0].output; // TODO: current mon
|
WLRLAYERSURFACE->output = g_pCompositor->m_vMonitors[0].output; // TODO: current mon
|
||||||
|
@ -151,6 +150,35 @@ void Events::listener_commitLayerSurface(wl_listener* listener, void* data) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Events::listener_mapWindow(wl_listener* listener, void* data) {
|
||||||
|
CWindow* PWINDOW = wl_container_of(listener, PWINDOW, listen_mapWindow);
|
||||||
|
|
||||||
|
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
||||||
|
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||||
|
|
||||||
|
// test
|
||||||
|
wlr_xdg_toplevel_set_size(PWINDOW->m_uSurface.xdg->toplevel, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::listener_unmapWindow(wl_listener* listener, void* data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::listener_commitWindow(wl_listener* listener, void* data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::listener_destroyWindow(wl_listener* listener, void* data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::listener_setTitleWindow(wl_listener* listener, void* data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::listener_fullscreenWindow(wl_listener* listener, void* data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Events::listener_mouseAxis(wl_listener* listener, void* data) {
|
void Events::listener_mouseAxis(wl_listener* listener, void* data) {
|
||||||
// TODO:
|
// TODO:
|
||||||
|
@ -200,7 +228,22 @@ void Events::listener_newKeyboard(wl_listener* listener, void* data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_newXDGSurface(wl_listener* listener, void* data) {
|
void Events::listener_newXDGSurface(wl_listener* listener, void* data) {
|
||||||
|
// A window got opened
|
||||||
|
const auto XDGSURFACE = (wlr_xdg_surface*)data;
|
||||||
|
|
||||||
|
if (XDGSURFACE->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
|
||||||
|
return; // TODO: handle?
|
||||||
|
|
||||||
|
g_pCompositor->m_vWindows.push_back(CWindow());
|
||||||
|
const auto PNEWWINDOW = &g_pCompositor->m_vWindows.back();
|
||||||
|
PNEWWINDOW->m_uSurface.xdg = XDGSURFACE;
|
||||||
|
|
||||||
|
wl_signal_add(&XDGSURFACE->surface->events.commit, &PNEWWINDOW->listen_commitWindow);
|
||||||
|
wl_signal_add(&XDGSURFACE->events.map, &PNEWWINDOW->listen_mapWindow);
|
||||||
|
wl_signal_add(&XDGSURFACE->events.unmap, &PNEWWINDOW->listen_unmapWindow);
|
||||||
|
wl_signal_add(&XDGSURFACE->events.destroy, &PNEWWINDOW->listen_destroyWindow);
|
||||||
|
wl_signal_add(&XDGSURFACE->toplevel->events.set_title, &PNEWWINDOW->listen_setTitleWindow);
|
||||||
|
wl_signal_add(&XDGSURFACE->toplevel->events.request_fullscreen, &PNEWWINDOW->listen_fullscreenWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_outputMgrApply(wl_listener* listener, void* data) {
|
void Events::listener_outputMgrApply(wl_listener* listener, void* data) {
|
||||||
|
|
|
@ -5,13 +5,22 @@ namespace Events {
|
||||||
LISTENER(activate);
|
LISTENER(activate);
|
||||||
LISTENER(change);
|
LISTENER(change);
|
||||||
LISTENER(newOutput);
|
LISTENER(newOutput);
|
||||||
|
|
||||||
LISTENER(newLayerSurface);
|
LISTENER(newLayerSurface);
|
||||||
LISTENER(destroyLayerSurface);
|
LISTENER(destroyLayerSurface);
|
||||||
LISTENER(mapLayerSurface);
|
LISTENER(mapLayerSurface);
|
||||||
LISTENER(unmapLayerSurface);
|
LISTENER(unmapLayerSurface);
|
||||||
LISTENER(commitLayerSurface);
|
LISTENER(commitLayerSurface);
|
||||||
|
|
||||||
LISTENER(newXDGSurface);
|
LISTENER(newXDGSurface);
|
||||||
|
|
||||||
|
LISTENER(commitWindow);
|
||||||
|
LISTENER(mapWindow);
|
||||||
|
LISTENER(unmapWindow);
|
||||||
|
LISTENER(destroyWindow);
|
||||||
|
LISTENER(setTitleWindow);
|
||||||
|
LISTENER(fullscreenWindow);
|
||||||
|
|
||||||
LISTENER(mouseMove);
|
LISTENER(mouseMove);
|
||||||
LISTENER(mouseMoveAbsolute);
|
LISTENER(mouseMoveAbsolute);
|
||||||
LISTENER(mouseButton);
|
LISTENER(mouseButton);
|
||||||
|
|
|
@ -16,3 +16,10 @@ struct SLayerSurface {
|
||||||
wlr_box geometry;
|
wlr_box geometry;
|
||||||
zwlr_layer_shell_v1_layer layer;
|
zwlr_layer_shell_v1_layer layer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SRenderData {
|
||||||
|
wlr_output* output;
|
||||||
|
timespec* when;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
57
src/render/Renderer.cpp
Normal file
57
src/render/Renderer.cpp
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#include "Renderer.hpp"
|
||||||
|
#include "../Compositor.hpp"
|
||||||
|
|
||||||
|
void scaleBox(wlr_box* box, float scale) {
|
||||||
|
box->width = std::round((box->x + box->width) * scale) - std::round(box->x * scale);
|
||||||
|
box->height = std::round((box->y + box->height) * scale) - std::round(box->y * scale);
|
||||||
|
box->x = std::round(box->x * scale);
|
||||||
|
box->y = std::round(box->y * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||||
|
const auto TEXTURE = wlr_surface_get_texture(surface);
|
||||||
|
const auto RDATA = (SRenderData*)data;
|
||||||
|
|
||||||
|
if (!TEXTURE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double outputX = 0, outputY = 0;
|
||||||
|
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, RDATA->output, &outputX, &outputY);
|
||||||
|
|
||||||
|
wlr_box windowBox = {outputX + RDATA->x + x, outputY + RDATA->y + y, surface->current.width, surface->current.height};
|
||||||
|
scaleBox(&windowBox, RDATA->output->scale);
|
||||||
|
|
||||||
|
const auto TRANSFORM = wlr_output_transform_invert(surface->current.transform);
|
||||||
|
float matrix[9];
|
||||||
|
wlr_matrix_project_box(matrix, &windowBox, TRANSFORM, 0, RDATA->output->transform_matrix);
|
||||||
|
|
||||||
|
wlr_render_texture_with_matrix(g_pCompositor->m_sWLRRenderer, TEXTURE, matrix, 1); // TODO: fadein/out
|
||||||
|
|
||||||
|
wlr_surface_send_frame_done(surface, RDATA->when);
|
||||||
|
|
||||||
|
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||||
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(ID);
|
||||||
|
|
||||||
|
if (!PMONITOR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
|
|
||||||
|
const wlr_box geom = { w.m_vPosition.x, w.m_vPosition.y, w.m_vSize.x, w.m_vSize.y };
|
||||||
|
|
||||||
|
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, PMONITOR->output, &geom))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// render the bad boy
|
||||||
|
|
||||||
|
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, PMONITOR->output, &w.m_vPosition.x, &w.m_vPosition.y);
|
||||||
|
|
||||||
|
SRenderData renderdata = {PMONITOR->output, time, w.m_vSize.x, w.m_vSize.y};
|
||||||
|
|
||||||
|
wlr_surface_for_each_surface(w.m_uSurface.xdg->surface, renderSurface, &renderdata);
|
||||||
|
wlr_xdg_surface_for_each_popup_surface(w.m_uSurface.xdg, renderSurface, &renderdata);
|
||||||
|
}
|
||||||
|
}
|
13
src/render/Renderer.hpp
Normal file
13
src/render/Renderer.hpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../defines.hpp"
|
||||||
|
|
||||||
|
class CHyprRenderer {
|
||||||
|
public:
|
||||||
|
|
||||||
|
void renderAllClientsForMonitor(const int&, timespec*);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::unique_ptr<CHyprRenderer> g_pHyprRenderer;
|
Loading…
Reference in a new issue