This commit is contained in:
vaxerski 2022-03-17 20:22:29 +01:00
parent ab7d727532
commit bc937e3e71
12 changed files with 222 additions and 10 deletions

View file

@ -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)

View file

@ -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];
}

View file

@ -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();
}; };

View file

@ -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
View file

40
src/Window.hpp Normal file
View 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;
};

View file

@ -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))

View file

@ -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) {

View file

@ -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);

View file

@ -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
View 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
View 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;