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(.)
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(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_selection, &Events::listen_requestSetSel);
m_sWLRPresentation = wlr_presentation_create(m_sWLDisplay, m_sWLRBackend);
// TODO: XWayland
}
@ -82,6 +84,9 @@ void CCompositor::startCompositor() {
Debug::log(LOG, "Creating the InputManager!");
g_pInputManager = std::make_unique<CInputManager>();
Debug::log(LOG, "Creating the HyprRenderer!");
g_pHyprRenderer = std::make_unique<CHyprRenderer>();
//
//
@ -111,4 +116,31 @@ void CCompositor::startCompositor() {
// This blocks until we are done.
Debug::log(LOG, "Hyprland is ready, running the event loop!");
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 "input/InputManager.hpp"
#include "helpers/Monitor.hpp"
#include "Window.hpp"
#include "render/Renderer.hpp"
class CCompositor {
public:
@ -42,8 +44,15 @@ public:
const char* m_szWLDisplaySocket;
std::deque<SMonitor> m_vMonitors;
std::deque<CWindow> m_vWindows;
void startCompositor();
// ------------------------------------------------- //
SMonitor* getMonitorFromID(const int&);
SMonitor* getMonitorFromCursor();
};

View File

@ -1,7 +1,7 @@
#include "ManagerThread.hpp"
CManagerThread::CManagerThread() {
m_tMainThread = new std::thread([=]() {
m_tMainThread = new std::thread([&]() {
// Call the handle method.
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

@ -9,4 +9,6 @@
#define RIP(format, ... ) { fprintf(stderr, format "\n", ##__VA_ARGS__); exit(EXIT_FAILURE); }
#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 "../helpers/WLClasses.hpp"
#include "../input/InputManager.hpp"
#include "../render/Renderer.hpp"
void Events::listener_activate(wl_listener* listener, void* data) {
// TODO
@ -60,8 +61,8 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
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.destroy, &g_pCompositor->m_vMonitors[g_pCompositor->m_vMonitors.size() - 1].listen_monitorDestroy);
wl_signal_add(&OUTPUT->events.frame, &g_pCompositor->m_vMonitors.back().listen_monitorFrame);
wl_signal_add(&OUTPUT->events.destroy, &g_pCompositor->m_vMonitors.back().listen_monitorDestroy);
wlr_output_enable(OUTPUT, 1);
if (!wlr_output_commit(OUTPUT)) {
@ -80,7 +81,6 @@ void Events::listener_monitorFrame(wl_listener* listener, void* data) {
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
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))
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_clear(g_pCompositor->m_sWLRRenderer, bgcol);
// TODO: render clients
g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now);
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;
PMONITOR->m_dLayerSurfaces.push_back(SLayerSurface());
SLayerSurface* layerSurface = &PMONITOR->m_dLayerSurfaces[PMONITOR->m_dLayerSurfaces.size() - 1];
wlr_layer_surface_v1_state oldState;
if (!WLRLAYERSURFACE->output) {
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) {
// TODO:
@ -200,7 +228,22 @@ void Events::listener_newKeyboard(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) {

View File

@ -5,13 +5,22 @@ namespace Events {
LISTENER(activate);
LISTENER(change);
LISTENER(newOutput);
LISTENER(newLayerSurface);
LISTENER(destroyLayerSurface);
LISTENER(mapLayerSurface);
LISTENER(unmapLayerSurface);
LISTENER(commitLayerSurface);
LISTENER(newXDGSurface);
LISTENER(commitWindow);
LISTENER(mapWindow);
LISTENER(unmapWindow);
LISTENER(destroyWindow);
LISTENER(setTitleWindow);
LISTENER(fullscreenWindow);
LISTENER(mouseMove);
LISTENER(mouseMoveAbsolute);
LISTENER(mouseButton);

View File

@ -15,4 +15,11 @@ struct SLayerSurface {
wlr_box geometry;
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;