Compare commits

...

10 Commits

Author SHA1 Message Date
f3c13b915a epic cursor lock fail
Signed-off-by: Slendi <slendi@socopon.com>
2025-10-01 00:13:36 +03:00
df00037296 SDf
Signed-off-by: Slendi <slendi@socopon.com>
2025-10-01 00:13:29 +03:00
670848e924 format
Signed-off-by: Slendi <slendi@socopon.com>
2025-09-30 23:29:33 +03:00
d28bb6f8ee format
Signed-off-by: Slendi <slendi@socopon.com>
2025-09-30 23:29:15 +03:00
c6365c0cc1 add surface damage
Signed-off-by: Slendi <slendi@socopon.com>
2025-09-30 22:30:39 +03:00
f9dff4265a remove cursor delta debug lgo
Signed-off-by: Slendi <slendi@socopon.com>
2025-09-30 18:22:03 +03:00
6cd7099c39 fix bug
Signed-off-by: Slendi <slendi@socopon.com>
2025-09-30 17:35:42 +03:00
3fcf769aff More 2D improvements
Signed-off-by: Slendi <slendi@socopon.com>
2025-09-30 17:32:06 +03:00
389c1f9934 yea
Signed-off-by: Slendi <slendi@socopon.com>
2025-09-30 16:49:29 +03:00
4ddd9a0ca7 tweaks
Signed-off-by: Slendi <slendi@socopon.com>
2025-09-30 16:43:32 +03:00
9 changed files with 208 additions and 52 deletions

View File

@@ -25,6 +25,7 @@ pkg_check_modules(WLROOTS REQUIRED IMPORTED_TARGET wlroots-0.20)
pkg_check_modules(XKBCOMMON REQUIRED IMPORTED_TARGET xkbcommon)
pkg_check_modules(OPENXR REQUIRED IMPORTED_TARGET openxr)
pkg_check_modules(LUA REQUIRED IMPORTED_TARGET lua)
pkg_check_modules(PIXMAN REQUIRED IMPORTED_TARGET pixman-1)
find_program(WAYLAND_SCANNER_EXECUTABLE wayland-scanner REQUIRED)
message(STATUS "Found wayland-scanner at ${WAYLAND_SCANNER_EXECUTABLE}")
@@ -67,6 +68,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
PkgConfig::WLROOTS
PkgConfig::OPENXR
PkgConfig::LUA
PkgConfig::PIXMAN
raylib
)

6
flake.lock generated
View File

@@ -97,11 +97,11 @@
]
},
"locked": {
"lastModified": 1759215258,
"narHash": "sha256-Y7aXk0Zxu+X2BbO5MLkCvClrPsKfZ2sm34N2n7tXx4I=",
"lastModified": 1759266345,
"narHash": "sha256-BJ+CTRXaFArVFgJfL19QpoR7Ebk8HU63Lz0+jQvhV3Y=",
"owner": "slendidev",
"repo": "wlroots-lunar",
"rev": "a9abd5a6e4fb4e5ac6c410e1fb1ad438d3b12001",
"rev": "1179ca07821decbff320eafd7ffb3caaadcefbf4",
"type": "github"
},
"original": {

34
launch_settings.cap Normal file
View File

@@ -0,0 +1,34 @@
{
"rdocCaptureSettings": 1,
"settings": {
"autoStart": false,
"commandLine": "",
"environment": [
{
"separator": "Platform style",
"type": "Set",
"value": "1",
"variable": "LWM_NO_XR"
}
],
"executable": "/home/lain/Documents/projs/lunarwm/build/LunarWM",
"inject": false,
"numQueuedFrames": 0,
"options": {
"allowFullscreen": true,
"allowVSync": true,
"apiValidation": false,
"captureAllCmdLists": false,
"captureCallstacks": false,
"captureCallstacksOnlyDraws": false,
"debugOutputMute": true,
"delayForDebugger": 0,
"hookIntoChildren": false,
"refAllResources": false,
"softMemoryLimit": 0,
"verifyBufferAccess": false
},
"queuedFrameCap": 0,
"workingDir": "/home/lain/Documents/projs/lunarwm"
}
}

View File

@@ -1,7 +1,7 @@
#ifndef LUNAR_WM_H
#define LUNAR_WM_H
#include "LunarWM_types.h"
#include "LunarWM_core.h"
#include "LunarWM_types.h"
#endif

View File

@@ -217,12 +217,23 @@ bool LunarWM_init(LunarWM *wm)
return false;
}
if (!LunarWM_xr_init(wm)) {
wlr_log(WLR_ERROR, "Failed to initialize OpenXR! Disabling XR...");
wm->xr.available = false;
LunarWM_xr_cleanup(wm);
} else {
wm->xr.available = true;
wm->xr.available = false;
{
char *no_xr = getenv("LWM_NO_XR");
bool xr = true;
if (no_xr != NULL && no_xr[0] != '\0')
xr = false;
if (xr) {
if (!LunarWM_xr_init(wm)) {
wlr_log(
WLR_ERROR, "Failed to initialize OpenXR! Disabling XR...");
LunarWM_xr_cleanup(wm);
} else {
wm->xr.available = true;
}
}
}
wlr_log(WLR_INFO, "OpenGL ES version: %s", glGetString(GL_VERSION));
@@ -417,7 +428,7 @@ void LunarWM_run(LunarWM *wm)
EndDrawing();
} else {
wm->renderer.camera.fovy = 90;
wm->renderer.camera.fovy = 75;
}
}
}

View File

@@ -22,8 +22,8 @@
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_subcompositor.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/util/box.h>
@@ -112,7 +112,6 @@ typedef struct {
struct wl_listener destroy;
} LunarWM_Output;
typedef struct {
uint32_t id;
@@ -198,6 +197,7 @@ typedef struct LunarWM {
struct wlr_allocator *allocator;
struct wlr_compositor *compositor;
struct wl_listener new_surface_listener;
struct wlr_subcompositor *subcompositor;
struct wlr_data_device_manager *data_device_manager;

View File

@@ -1,10 +1,13 @@
#include "LunarWM_wayland.h"
#include "LunarWM_core.h"
#include "LunarWM_render.h"
#include "common.h"
#include "raylib.h"
#include "vec.h"
#include <pixman.h>
#include <wlr/backend/wayland.h>
#include <wlr/backend/x11.h>
#include <wlr/render/color.h>
#include <wlr/render/pass.h>
@@ -20,6 +23,7 @@
#include <xkbcommon/xkbcommon-keysyms.h>
#include <xkbcommon/xkbcommon.h>
#include <raylib.h>
#include <rlgl.h>
static void handle_new_output(struct wl_listener *listener, void *data);
@@ -36,6 +40,90 @@ static inline SphericalCoord get_forward_spherical_with_nearest(
return Vector3ToSpherical(vec);
}
struct SurfaceDamageListener {
struct wl_listener client_commit;
struct wl_listener destroy;
};
static void surface_damage_client_commit(
struct wl_listener *listener, void *data)
{
(void)listener;
struct wlr_surface *surface = data;
if (!surface) {
return;
}
if (!wlr_surface_state_has_buffer(&surface->pending)) {
return;
}
if (pixman_region32_not_empty(&surface->pending.surface_damage)
|| pixman_region32_not_empty(&surface->pending.buffer_damage)) {
return;
}
int surface_width = surface->pending.width > 0 ? surface->pending.width
: surface->current.width;
int surface_height = surface->pending.height > 0 ? surface->pending.height
: surface->current.height;
int buffer_width = surface->pending.buffer_width > 0
? surface->pending.buffer_width
: surface->current.buffer_width;
int buffer_height = surface->pending.buffer_height > 0
? surface->pending.buffer_height
: surface->current.buffer_height;
if (surface_width <= 0 || surface_height <= 0 || buffer_width <= 0
|| buffer_height <= 0) {
return;
}
pixman_region32_union_rect(&surface->pending.surface_damage,
&surface->pending.surface_damage, 0, 0, surface_width, surface_height);
pixman_region32_union_rect(&surface->pending.buffer_damage,
&surface->pending.buffer_damage, 0, 0, buffer_width, buffer_height);
}
static void surface_damage_destroy(struct wl_listener *listener, void *data)
{
(void)data;
struct SurfaceDamageListener *hook
= wl_container_of(listener, hook, destroy);
wl_list_remove(&hook->client_commit.link);
wl_list_remove(&hook->destroy.link);
free(hook);
}
static void surface_damage_track(struct wlr_surface *surface)
{
if (!surface) {
return;
}
struct SurfaceDamageListener *hook = calloc(1, sizeof(*hook));
if (!hook) {
wlr_log(WLR_ERROR, "Failed to allocate surface damage listener");
return;
}
hook->client_commit.notify = surface_damage_client_commit;
wl_signal_add(&surface->events.client_commit, &hook->client_commit);
hook->destroy.notify = surface_damage_destroy;
wl_signal_add(&surface->events.destroy, &hook->destroy);
}
static void compositor_new_surface_notify(
struct wl_listener *listener, void *data)
{
(void)listener;
struct wlr_surface *surface = data;
if (!surface) {
return;
}
surface_damage_track(surface);
}
struct ExternalTexturePipeline {
bool attempted_init;
bool ready;
@@ -1215,6 +1303,7 @@ static void Pointer_motion_notify(struct wl_listener *listener, void *data)
if (p->server->cman->cfg.input.mouse.invert_y) {
dy *= -1;
}
float const R = p->server->cman->cfg.space.radius;
float const g = 0.0005f;
@@ -1574,8 +1663,6 @@ static void handle_output_frame(struct wl_listener *listener, void *data)
}
if (!wlr_output_commit_state(wlr_output, &state)) {
wlr_log(WLR_ERROR, "Failed to commit state for output %s",
wlr_output->name);
wlr_output_state_finish(&state);
wlr_output_schedule_frame(wlr_output);
return;
@@ -1599,9 +1686,10 @@ static void handle_output_frame(struct wl_listener *listener, void *data)
rlFramebufferAttach(wm->renderer.tmp_rt.id, wm->renderer.tmp_rt.depth.id,
RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0);
if (!IsTextureValid(wm->renderer.main_rt.texture)) {
wm->renderer.main_rt = LoadRenderTexture(width, height);
if (!wm->xr.available && !wm->renderer.first_frame) {
wm->renderer.camera.target = SphericalToVector3(wm->wm.pointer);
}
int const hud_size = wm->cman->cfg.displays.hud.size;
if (!IsTextureValid(wm->renderer.hud_rt.texture)) {
wm->renderer.hud_rt = LoadRenderTexture(hud_size, hud_size);
@@ -1611,6 +1699,10 @@ static void handle_output_frame(struct wl_listener *listener, void *data)
LunarWM_render_hud(wm, GetFrameTime(), 1);
}
EndTextureMode();
if (!IsTextureValid(wm->renderer.main_rt.texture)) {
wm->renderer.main_rt = LoadRenderTexture(width, height);
}
BeginTextureMode(wm->renderer.main_rt);
{
BeginMode3D(wm->renderer.camera);
@@ -1643,6 +1735,13 @@ static void handle_output_frame(struct wl_listener *listener, void *data)
}
EndTextureMode();
if (wm->renderer.first_frame) {
LunarWM_set_recenter_from_camera(wm);
wm->renderer.first_frame = false;
wm->wm.pointer = get_forward_spherical_with_nearest(
wm->renderer.camera.target, wm->cman->cfg.space.radius);
}
wlr_output_state_finish(&state);
}
@@ -1764,6 +1863,9 @@ bool LunarWM_wayland_init(LunarWM *this)
wlr_log(WLR_ERROR, "Failed to create compositor");
return false;
}
this->wayland.new_surface_listener.notify = compositor_new_surface_notify;
wl_signal_add(&this->wayland.compositor->events.new_surface,
&this->wayland.new_surface_listener);
this->wayland.subcompositor
= wlr_subcompositor_create(this->wayland.display);
@@ -1841,6 +1943,12 @@ void LunarWM_wayland_cleanup(LunarWM *this)
this->wayland.new_output_listener.notify = NULL;
}
if (this->wayland.new_surface_listener.link.prev
|| this->wayland.new_surface_listener.link.next) {
wl_list_remove(&this->wayland.new_surface_listener.link);
this->wayland.new_surface_listener.notify = NULL;
}
if (this->wayland.v_outputs) {
for (size_t i = 0; i < vector_size(this->wayland.v_outputs); ++i) {
destroy_output(this->wayland.v_outputs[i]);

View File

@@ -34,8 +34,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define vec_h
#ifdef __cpp_decltype
#include <type_traits>
#define typeof(T) std::remove_reference<std::add_lvalue_reference<decltype(T)>::type>::type
# include <type_traits>
# define typeof(T) \
std::remove_reference< \
std::add_lvalue_reference<decltype(T)>::type>::type
#endif
#ifdef __cplusplus
@@ -46,7 +48,7 @@ extern "C" {
#include <stdlib.h>
// generic type for internal use
typedef void* vector;
typedef void *vector;
// number of elements in a vector
typedef size_t vec_size_t;
// number of bytes for a type
@@ -58,60 +60,59 @@ typedef size_t vec_type_t;
// shortcut defines
// vec_addr is a vector* (aka type**)
#define vector_add_dst(vec_addr)\
((typeof(*vec_addr))(\
_vector_add_dst((vector*)vec_addr, sizeof(**vec_addr))\
))
#define vector_insert_dst(vec_addr, pos)\
((typeof(*vec_addr))(\
_vector_insert_dst((vector*)vec_addr, sizeof(**vec_addr), pos)))
# define vector_add_dst(vec_addr) \
((typeof(*vec_addr))(_vector_add_dst( \
(vector *)vec_addr, sizeof(**vec_addr))))
# define vector_insert_dst(vec_addr, pos) \
((typeof(*vec_addr))(_vector_insert_dst( \
(vector *)vec_addr, sizeof(**vec_addr), pos)))
#define vector_add(vec_addr, value)\
(*vector_add_dst(vec_addr) = value)
#define vector_insert(vec_addr, pos, value)\
(*vector_insert_dst(vec_addr, pos) = value)
# define vector_add(vec_addr, value) (*vector_add_dst(vec_addr) = value)
# define vector_insert(vec_addr, pos, value) \
(*vector_insert_dst(vec_addr, pos) = value)
#else
#define vector_add_dst(vec_addr, type)\
((type*)_vector_add_dst((vector*)vec_addr, sizeof(type)))
#define vector_insert_dst(vec_addr, type, pos)\
((type*)_vector_insert_dst((vector*)vec_addr, sizeof(type), pos))
# define vector_add_dst(vec_addr, type) \
((type *)_vector_add_dst((vector *)vec_addr, sizeof(type)))
# define vector_insert_dst(vec_addr, type, pos) \
((type *)_vector_insert_dst((vector *)vec_addr, sizeof(type), pos))
#define vector_add(vec_addr, type, value)\
(*vector_add_dst(vec_addr, type) = value)
#define vector_insert(vec_addr, type, pos, value)\
(*vector_insert_dst(vec_addr, type, pos) = value)
# define vector_add(vec_addr, type, value) \
(*vector_add_dst(vec_addr, type) = value)
# define vector_insert(vec_addr, type, pos, value) \
(*vector_insert_dst(vec_addr, type, pos) = value)
#endif
// vec is a vector (aka type*)
#define vector_erase(vec, pos, len)\
#define vector_erase(vec, pos, len) \
(_vector_erase((vector)vec, sizeof(*vec), pos, len))
#define vector_remove(vec, pos)\
(_vector_remove((vector)vec, sizeof(*vec), pos))
#define vector_remove(vec, pos) (_vector_remove((vector)vec, sizeof(*vec), pos))
#define vector_reserve(vec_addr, capacity)\
(_vector_reserve((vector*)vec_addr, sizeof(**vec_addr), capacity))
#define vector_reserve(vec_addr, capacity) \
(_vector_reserve((vector *)vec_addr, sizeof(**vec_addr), capacity))
#define vector_copy(vec)\
(_vector_copy((vector)vec, sizeof(*vec)))
#define vector_copy(vec) (_vector_copy((vector)vec, sizeof(*vec)))
vector vector_create(void);
void vector_free(vector vec);
void* _vector_add_dst(vector* vec_addr, vec_type_t type_size);
void *_vector_add_dst(vector *vec_addr, vec_type_t type_size);
void* _vector_insert_dst(vector* vec_addr, vec_type_t type_size, vec_size_t pos);
void *_vector_insert_dst(
vector *vec_addr, vec_type_t type_size, vec_size_t pos);
void _vector_erase(vector vec_addr, vec_type_t type_size, vec_size_t pos, vec_size_t len);
void _vector_erase(
vector vec_addr, vec_type_t type_size, vec_size_t pos, vec_size_t len);
void _vector_remove(vector vec_addr, vec_type_t type_size, vec_size_t pos);
void vector_pop(vector vec);
void _vector_reserve(vector* vec_addr, vec_type_t type_size, vec_size_t capacity);
void _vector_reserve(
vector *vec_addr, vec_type_t type_size, vec_size_t capacity);
vector _vector_copy(vector vec, vec_type_t type_size);

View File

@@ -3,6 +3,6 @@ set -euo pipefail
ROOT="$(git rev-parse --show-toplevel)"
find "$ROOT/src" -type f -name '*.cppm' -print0 | while IFS= read -r -d '' f; do
find "$ROOT/src" -type f -name '*.c' -o -name '*.h' -print0 | while IFS= read -r -d '' f; do
clang-format -i --style=file "$f"
done