diff --git a/CMakeLists.txt b/CMakeLists.txt index 571b72c..5079fcf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,10 +19,18 @@ find_package(PkgConfig REQUIRED) pkg_check_modules(WAYLAND REQUIRED IMPORTED_TARGET GLOBAL wayland-server) pkg_check_modules(EGL REQUIRED IMPORTED_TARGET egl) pkg_check_modules(GLES2 REQUIRED IMPORTED_TARGET glesv2) -pkg_check_modules(WLROOTS REQUIRED IMPORTED_TARGET wlroots-0.19) +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) +find_program(WAYLAND_SCANNER_EXECUTABLE wayland-scanner REQUIRED) +message(STATUS "Found wayland-scanner at ${WAYLAND_SCANNER_EXECUTABLE}") +pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir) +message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}") +pkg_get_variable(WAYLAND_SCANNER_PKGDATA_DIR wayland-scanner pkgdatadir) +message( + STATUS "Found wayland-scanner pkgdatadir at ${WAYLAND_SCANNER_PKGDATA_DIR}") + include(FetchContent) FetchContent_Declare( @@ -55,3 +63,55 @@ target_link_libraries(${PROJECT_NAME} PUBLIC raylib ) +set(XDG_SHELL_XML + ${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml +) + +set(XDG_SHELL_HEADER + ${CMAKE_BINARY_DIR}/xdg-shell-protocol.h +) + +set(XDG_SHELL_C + ${CMAKE_BINARY_DIR}/xdg-shell-protocol.c +) + +add_custom_command( + OUTPUT ${XDG_SHELL_HEADER} + COMMAND ${WAYLAND_SCANNER_EXECUTABLE} server-header + ${XDG_SHELL_XML} ${XDG_SHELL_HEADER} + DEPENDS ${XDG_SHELL_XML} + COMMENT "Generating xdg-shell-protocol.h (server header)" + VERBATIM +) + +add_custom_command( + OUTPUT ${XDG_SHELL_C} + COMMAND ${WAYLAND_SCANNER_EXECUTABLE} private-code + ${XDG_SHELL_XML} ${XDG_SHELL_C} + DEPENDS ${XDG_SHELL_XML} + COMMENT "Generating xdg-shell-protocol.c" + VERBATIM +) + +add_custom_target(xdg_shell_protocol + DEPENDS ${XDG_SHELL_HEADER} ${XDG_SHELL_C} +) + +add_library(xdg_shell STATIC + ${XDG_SHELL_C} +) + +add_dependencies(xdg_shell xdg_shell_protocol) + +target_include_directories(xdg_shell PUBLIC + ${CMAKE_BINARY_DIR} +) + +add_dependencies(${PROJECT_NAME} xdg_shell_protocol) + +target_link_libraries(${PROJECT_NAME} PRIVATE xdg_shell) + +target_include_directories(${PROJECT_NAME} PRIVATE + ${CMAKE_BINARY_DIR} +) + diff --git a/flake.lock b/flake.lock index c57137d..79b8d92 100644 --- a/flake.lock +++ b/flake.lock @@ -34,10 +34,26 @@ "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1751984180, + "narHash": "sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X+xgOL0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9807714d6944a957c2e036f84b0ff8caf9930bc0", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-unstable", + "type": "indirect" + } + }, "root": { "inputs": { "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "wlroots-lunar": "wlroots-lunar" } }, "systems": { @@ -54,6 +70,24 @@ "repo": "default", "type": "github" } + }, + "wlroots-lunar": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1752101817, + "narHash": "sha256-NUSPmdoPUYQDxFHnSJX9yV+tluZVmR62P4IjPTnm8dY=", + "owner": "slendidev", + "repo": "wlroots-lunar", + "rev": "ef7aadec563747f8e1026b2c339d1132ae63f8a0", + "type": "github" + }, + "original": { + "owner": "slendidev", + "repo": "wlroots-lunar", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index ba3a4b6..9cfb168 100644 --- a/flake.nix +++ b/flake.nix @@ -4,6 +4,7 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; + wlroots-lunar.url = "github:slendidev/wlroots-lunar"; }; outputs = @@ -11,6 +12,7 @@ self, nixpkgs, flake-utils, + wlroots-lunar, }: flake-utils.lib.eachDefaultSystem ( system: @@ -47,9 +49,10 @@ xorg.xcbutilrenderutil xorg.xcbutilwm xorg.xcbutilerrors - wlroots vulkan-loader + wlroots-lunar.packages."${system}".default + # For raylib xorg.libXrandr xorg.libXinerama diff --git a/src/LunarWM.cppm b/src/LunarWM.cppm index 991d49c..b512ba7 100644 --- a/src/LunarWM.cppm +++ b/src/LunarWM.cppm @@ -24,11 +24,10 @@ extern "C" { #include #include #include +#include #include } -PFNGLDRAWBUFFERSEXTPROC glDrawBuffersEXT = NULL; - #include #include #include @@ -790,8 +789,9 @@ private: bool m_initialized {}; struct Keyboard { - struct wl_list link; struct LunarWM *server; + + struct wl_list link; struct wlr_keyboard *wlr_keyboard; struct wl_listener modifiers; @@ -799,6 +799,29 @@ private: struct wl_listener destroy; }; + struct Toplevel { + Toplevel(LunarWM *server, wlr_xdg_toplevel *xdg_toplevel) + : server(server) + , xdg_toplevel(xdg_toplevel) + { + surface = wlr_surface_from_resource(xdg_toplevel->resource); + texture = wlr_surface_get_texture(surface); + gles_texture = gles2_get_texture(texture); + rl_texture.width = texture->width; + rl_texture.height = texture->height; + } + + operator Texture2D &() { return rl_texture; } + + LunarWM *server {}; + + wlr_xdg_toplevel *xdg_toplevel {}; + wlr_surface *surface {}; + wlr_texture *texture {}; + wlr_gles2_texture *gles_texture {}; + Texture2D rl_texture {}; + }; + struct { wl_display *display {}; wl_event_loop *event_loop {}; @@ -820,7 +843,13 @@ private: wl_list keyboards; wl_listener new_input_listener {}; + wlr_xdg_shell *xdg_shell; + wl_listener new_xdg_toplevel_listener {}; + wl_listener new_xdg_popup_listener {}; + wlr_cursor *cursor {}; + + std::vector toplevels; } m_wayland; struct { @@ -1148,6 +1177,28 @@ void LunarWM::init_wayland() if (!m_wayland.seat) { throw std::runtime_error("Failed to create wlroots seat"); } + + m_wayland.xdg_shell = wlr_xdg_shell_create(m_wayland.display, 3); + + m_wayland.new_xdg_toplevel_listener.notify + = [](wl_listener *listener, void *data) { + LunarWM *server + = wl_container_of(listener, static_cast(nullptr), + m_wayland.new_xdg_toplevel_listener); + }; + wl_signal_add(&m_wayland.xdg_shell->events.new_toplevel, + &m_wayland.new_xdg_toplevel_listener); + + m_wayland.new_xdg_popup_listener.notify = [](wl_listener *listener, + void *data) { + LunarWM *server = wl_container_of(listener, + static_cast(nullptr), m_wayland.new_xdg_popup_listener); + auto toplevel = reinterpret_cast(data); + + Toplevel tl(server, toplevel); + }; + wl_signal_add(&m_wayland.xdg_shell->events.new_popup, + &m_wayland.new_xdg_popup_listener); } void LunarWM::init_xr() @@ -1302,8 +1353,6 @@ void LunarWM::init_xr() glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR); { - glDrawBuffersEXT - = (PFNGLDRAWBUFFERSEXTPROC)eglGetProcAddress("glDrawBuffersEXT"); XrGraphicsBindingEGLMNDX gbind = { .type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX, .next = nullptr, @@ -1852,21 +1901,6 @@ bool LunarWM::render_layer(RenderLayerInfo &info, float dt) return true; } -void LunarWM::render_3d(float dt) -{ - static float animT { 0.0f }; - animT += dt; - - DrawGrid(10, 1); - - Vector3 forward = Vector3Normalize( - Vector3Subtract(m_renderer.camera.target, m_renderer.camera.position)); - float distance = 5.0f + sinf(animT) * 3.0f; - Vector3 spherePos = Vector3Add( - m_renderer.camera.position, Vector3Scale(forward, distance)); - DrawSphere(spherePos, 0.5f, YELLOW); -} - LunarWM::~LunarWM() { assert(m_initialized); @@ -2011,6 +2045,21 @@ void LunarWM::run() } } +void LunarWM::render_3d(float dt) +{ + static float animT { 0.0f }; + animT += dt; + + DrawGrid(10, 1); + + Vector3 forward = Vector3Normalize( + Vector3Subtract(m_renderer.camera.target, m_renderer.camera.position)); + float distance = 5.0f + sinf(animT) * 3.0f; + Vector3 spherePos = Vector3Add( + m_renderer.camera.position, Vector3Scale(forward, distance)); + DrawSphere(spherePos, 0.5f, YELLOW); +} + void LunarWM::terminate() { wlr_log(WLR_INFO, "Stopping compositor");