diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 77c9c48b..def12910 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -62,7 +62,7 @@ jobs: run: | sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf pacman --noconfirm --noprogressbar -Syyu - pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers xcb-util-errors xcb-util-renderutil xcb-util-wm xorg-fonts-encodings xorg-server-common xorg-setxkbmap xorg-xkbcomp xorg-xwayland git go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd + pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers git go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd cmake - name: Checkout Hyprland uses: actions/checkout@v3 with: @@ -73,13 +73,23 @@ jobs: -Ddefault_library=static - name: Compile run: ninja -C obj-x86_64-pc-linux-gnu -# - name: Compress artifacts -# run: | -# mkdir x86_64-pc-linux-gnu -# DESTDIR=$PWD/x86_64-pc-linux-gnu meson install -C obj-x86_64-pc-linux-gnu --tags runtime -# tar -cvf x86_64-pc-linux-gnu.tar.xz x86_64-pc-linux-gnu -# - name: Upload artifacts -# uses: actions/upload-artifact@v3 -# with: -# name: Build artifacts (x86_64-pc-linux-gnu) -# path: x86_64-pc-linux-gnu.tar.xz + + noxwayland: + name: "Build Hyprland in pure Wayland (Arch)" + runs-on: ubuntu-latest + container: + image: archlinux + steps: + - name: Download dependencies + run: | + sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf + pacman --noconfirm --noprogressbar -Syyu + pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers git cmake go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd + - name: Checkout Hyprland + uses: actions/checkout@v3 + with: + submodules: true + - name: Configure + run: mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DNO_XWAYLAND:STRING=true -H./ -B./build -G Ninja + - name: Compile + run: make config && make release diff --git a/CMakeLists.txt b/CMakeLists.txt index da311fde..8aed8896 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(Hyprland set(CMAKE_MESSAGE_LOG_LEVEL "STATUS") -message(STATUS "Configuring Hyprland!") +message(STATUS "Gathering git info") # Get git info # hash and branch @@ -35,14 +35,25 @@ execute_process( # # +IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) + message(STATUS "Configuring Hyprland in Debug with CMake") + add_definitions( -DHYPRLAND_DEBUG ) +ELSE() + add_compile_options( -O3 ) + message(STATUS "Configuring Hyprland in Release with CMake") +ENDIF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) + include_directories(. PRIVATE "subprojects/wlroots/include/") include_directories(. PRIVATE "subprojects/wlroots/build/include/") add_compile_options(-std=c++23 -DWLR_USE_UNSTABLE ) add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-narrowing) + +message(STATUS "Checking deps...") + find_package(Threads REQUIRED) find_package(PkgConfig REQUIRED) -pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo pango pangocairo libdrm egl xkbcommon libinput xcb) # we do not check for wlroots, as we provide it ourselves +pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo pango pangocairo libdrm egl xkbcommon libinput) # we do not check for wlroots, as we provide it ourselves file(GLOB_RECURSE SRCFILES "src/*.cpp") @@ -56,15 +67,11 @@ ENDIF(LEGACY_RENDERER MATCHES true) IF(NO_XWAYLAND MATCHES true) message(STATUS "Using the NO_XWAYLAND flag, disabling XWayland!") add_definitions( -DNO_XWAYLAND ) -ENDIF(NO_XWAYLAND MATCHES true) - -IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) - message(STATUS "Configuring Hyprland in Debug with CMake!") - add_definitions( -DHYPRLAND_DEBUG ) ELSE() - add_compile_options( -O3 ) - message(STATUS "Configuring Hyprland in Release with CMake!") -ENDIF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) + message(STATUS "XWAYLAND Enabled (NO_XWAYLAND not defined) checking deps...") + pkg_check_modules(xcbdep REQUIRED xcb) + target_link_libraries(Hyprland xcb) +ENDIF(NO_XWAYLAND MATCHES true) target_compile_definitions(Hyprland PRIVATE "-DGIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"") target_compile_definitions(Hyprland PRIVATE "-DGIT_BRANCH=\"${GIT_BRANCH}\"") @@ -77,6 +84,8 @@ set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) include(CPack) +message(STATUS "Setting link libraries") + target_link_libraries(Hyprland PkgConfig::deps) target_link_libraries(Hyprland @@ -90,6 +99,8 @@ target_link_libraries(Hyprland ) IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) + message(STATUS "Setting debug flags") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg -no-pie -fno-builtin") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg -no-pie -fno-builtin") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg -no-pie -fno-builtin") diff --git a/src/events/Misc.cpp b/src/events/Misc.cpp index 8e02579e..1edea5ba 100644 --- a/src/events/Misc.cpp +++ b/src/events/Misc.cpp @@ -45,6 +45,7 @@ void Events::listener_requestSetSel(wl_listener* listener, void* data) { } void Events::listener_readyXWayland(wl_listener* listener, void* data) { +#ifndef NO_XWAYLAND const auto XCBCONNECTION = xcb_connect(g_pXWaylandManager->m_sWLRXWayland->display_name, NULL); const auto ERR = xcb_connection_has_error(XCBCONNECTION); if (ERR) { @@ -72,6 +73,7 @@ void Events::listener_readyXWayland(wl_listener* listener, void* data) { } xcb_disconnect(XCBCONNECTION); +#endif } void Events::listener_requestDrag(wl_listener* listener, void* data) { diff --git a/src/helpers/XWaylandStubs.hpp b/src/helpers/XWaylandStubs.hpp new file mode 100644 index 00000000..a0b2a358 --- /dev/null +++ b/src/helpers/XWaylandStubs.hpp @@ -0,0 +1,152 @@ +#pragma once + +#include + +typedef unsigned int xcb_atom_t; +struct xcb_icccm_wm_hints_t; +typedef struct { + /** User specified flags */ + uint32_t flags; + /** User-specified position */ + int32_t x, y; + /** User-specified size */ + int32_t width, height; + /** Program-specified minimum size */ + int32_t min_width, min_height; + /** Program-specified maximum size */ + int32_t max_width, max_height; + /** Program-specified resize increments */ + int32_t width_inc, height_inc; + /** Program-specified minimum aspect ratios */ + int32_t min_aspect_num, min_aspect_den; + /** Program-specified maximum aspect ratios */ + int32_t max_aspect_num, max_aspect_den; + /** Program-specified base size */ + int32_t base_width, base_height; + /** Program-specified window gravity */ + uint32_t win_gravity; +} xcb_size_hints_t; +typedef unsigned int xcb_window_t; + +typedef enum xcb_stack_mode_t { + XCB_STACK_MODE_ABOVE = 0, + XCB_STACK_MODE_BELOW = 1, + XCB_STACK_MODE_TOP_IF = 2, + XCB_STACK_MODE_BOTTOM_IF = 3, + XCB_STACK_MODE_OPPOSITE = 4 +} xcb_stack_mode_t; + +struct wlr_xwayland { + struct wlr_xwayland_server *server; + struct wlr_xwm *xwm; + struct wlr_xwayland_cursor *cursor; + + const char *display_name; + + struct wl_display *wl_display; + struct wlr_compositor *compositor; + struct wlr_seat *seat; + + void *data; +}; + +struct wlr_xwayland_surface { + xcb_window_t window_id; + struct wlr_xwm *xwm; + uint32_t surface_id; + + struct wl_list link; + struct wl_list stack_link; + struct wl_list unpaired_link; + + struct wlr_surface *surface; + int16_t x, y; + uint16_t width, height; + uint16_t saved_width, saved_height; + bool override_redirect; + bool mapped; + + char *title; + char *_class; + char *instance; + char *role; + char *startup_id; + pid_t pid; + bool has_utf8_title; + + struct wl_list children; // wlr_xwayland_surface::parent_link + struct wlr_xwayland_surface *parent; + struct wl_list parent_link; // wlr_xwayland_surface::children + + xcb_atom_t *window_type; + size_t window_type_len; + + xcb_atom_t *protocols; + size_t protocols_len; + + uint32_t decorations; + xcb_icccm_wm_hints_t *hints; + xcb_size_hints_t *size_hints; + + bool pinging; + struct wl_event_source *ping_timer; + + // _NET_WM_STATE + bool modal; + bool fullscreen; + bool maximized_vert, maximized_horz; + bool minimized; + + bool has_alpha; + + struct { + struct wl_signal destroy; + struct wl_signal request_configure; + struct wl_signal request_move; + struct wl_signal request_resize; + struct wl_signal request_minimize; + struct wl_signal request_maximize; + struct wl_signal request_fullscreen; + struct wl_signal request_activate; + + struct wl_signal map; + struct wl_signal unmap; + struct wl_signal set_title; + struct wl_signal set_class; + struct wl_signal set_role; + struct wl_signal set_parent; + struct wl_signal set_pid; + struct wl_signal set_startup_id; + struct wl_signal set_window_type; + struct wl_signal set_hints; + struct wl_signal set_decorations; + struct wl_signal set_override_redirect; + struct wl_signal set_geometry; + struct wl_signal ping_timeout; + } events; +}; + +struct wlr_xwayland_surface_configure_event { + struct wlr_xwayland_surface *surface; + int16_t x, y; + uint16_t width, height; + uint16_t mask; // xcb_config_window_t +}; + +inline void wlr_xwayland_destroy(wlr_xwayland*) { } + +inline void wlr_xwayland_surface_configure(wlr_xwayland_surface*, int, int, int, int) { } + +inline bool wlr_surface_is_xwayland_surface(void*) { return false; } + +inline void wlr_xwayland_surface_activate(wlr_xwayland_surface*, bool) { } + +inline void wlr_xwayland_surface_restack(wlr_xwayland_surface*, int, xcb_stack_mode_t) { } + +inline wlr_xwayland_surface* wlr_xwayland_surface_from_wlr_surface(void*) { return nullptr; } + +inline void wlr_xwayland_surface_close(wlr_xwayland_surface*) { } + +inline void wlr_xwayland_surface_set_fullscreen(wlr_xwayland_surface*, bool) { } + +inline void wlr_xwayland_surface_set_minimized(wlr_xwayland_surface *, bool) {} diff --git a/src/includes.hpp b/src/includes.hpp index 55e8282b..607eb539 100644 --- a/src/includes.hpp +++ b/src/includes.hpp @@ -22,7 +22,6 @@ #include #include - #if true // wlroots uses dumb-ass shit that makes it not compile on C++, let's fix that. // https://github.com/swaywm/wlroots/issues/682 @@ -80,13 +79,11 @@ extern "C" { #include #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -102,6 +99,11 @@ extern "C" { #include #include #include + +#ifndef NO_XWAYLAND +#include +#include +#endif } #undef delete @@ -122,6 +124,7 @@ extern "C" { #ifdef NO_XWAYLAND #define XWAYLAND false +#include "helpers/XWaylandStubs.hpp" #else #define XWAYLAND true #endif diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index 4a0b397d..89bb6871 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -3,23 +3,23 @@ #include "../events/Events.hpp" CHyprXWaylandManager::CHyprXWaylandManager() { - if (XWAYLAND) { - m_sWLRXWayland = wlr_xwayland_create(g_pCompositor->m_sWLDisplay, g_pCompositor->m_sWLRCompositor, 1); +#ifndef NO_XWAYLAND + m_sWLRXWayland = wlr_xwayland_create(g_pCompositor->m_sWLDisplay, g_pCompositor->m_sWLRCompositor, 1); - if (!m_sWLRXWayland) { - Debug::log(ERR, "Couldn't start up the XWaylandManager because wlr_xwayland_create returned a nullptr!"); - return; - } - - addWLSignal(&m_sWLRXWayland->events.ready, &Events::listen_readyXWayland, m_sWLRXWayland, "XWayland Manager"); - addWLSignal(&m_sWLRXWayland->events.new_surface, &Events::listen_surfaceXWayland, m_sWLRXWayland, "XWayland Manager"); - - setenv("DISPLAY", m_sWLRXWayland->display_name, 1); - - Debug::log(LOG, "CHyprXWaylandManager started on display %s", m_sWLRXWayland->display_name); - } else { - unsetenv("DISPLAY"); // unset DISPLAY so that X11 apps do not try to start on a different/invalid DISPLAY + if (!m_sWLRXWayland) { + Debug::log(ERR, "Couldn't start up the XWaylandManager because wlr_xwayland_create returned a nullptr!"); + return; } + + addWLSignal(&m_sWLRXWayland->events.ready, &Events::listen_readyXWayland, m_sWLRXWayland, "XWayland Manager"); + addWLSignal(&m_sWLRXWayland->events.new_surface, &Events::listen_surfaceXWayland, m_sWLRXWayland, "XWayland Manager"); + + setenv("DISPLAY", m_sWLRXWayland->display_name, 1); + + Debug::log(LOG, "CHyprXWaylandManager started on display %s", m_sWLRXWayland->display_name); +#else + unsetenv("DISPLAY"); // unset DISPLAY so that X11 apps do not try to start on a different/invalid DISPLAY +#endif } CHyprXWaylandManager::~CHyprXWaylandManager() {