From 1cf479d8a6310300dc45311d256c1b780742ba79 Mon Sep 17 00:00:00 2001 From: Campbell Jones <git@serebit.com> Date: Sat, 25 Nov 2023 11:43:26 -0500 Subject: [PATCH] Revert "Revert "Migrate to wlroots main"" This reverts commit 4a7ab8a53caf815fa0b8d2433e52784609da4844. --- .github/workflows/build.yml | 4 +-- meson.build | 4 +-- src/input/cursor.cpp | 2 +- src/input/keyboard.cpp | 7 ++--- src/output.cpp | 55 +++++++++++++++++++++-------------- src/output.hpp | 2 +- src/server.cpp | 28 +++++++++--------- src/server.hpp | 3 ++ src/surface/layer.cpp | 4 +-- src/surface/popup.cpp | 4 +-- src/surface/xdg_view.cpp | 4 +-- src/surface/xwayland_view.cpp | 4 +-- subprojects/wlroots.wrap | 2 +- 13 files changed, 69 insertions(+), 54 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 787d4edf7..a56c7d053 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,7 +7,7 @@ jobs: steps: - name: Install prerequisites run: | - apk add build-base git meson wlroots-dev hwdata-dev libdisplay-info-dev libinput-dev libliftoff-dev libseat-dev libxcb-dev libxkbcommon-dev pixman-dev wayland-dev wayland-protocols xcb-util-renderutil-dev xcb-util-wm-dev xwayland-dev + apk add build-base git meson hwdata-dev libdisplay-info-dev libinput-dev libliftoff-dev libseat-dev libxcb-dev libxkbcommon-dev pixman-dev wayland-dev wayland-protocols xcb-util-renderutil-dev xcb-util-wm-dev xwayland-dev - uses: actions/checkout@v4 - name: Build magpie run: | @@ -20,7 +20,7 @@ jobs: steps: - name: Install prerequisites run: | - dnf --assumeyes install gcc-c++ meson git-core wlroots-devel pixman-devel \ + dnf --assumeyes install gcc-c++ meson git-core pixman-devel \ 'pkgconfig(hwdata)' \ 'pkgconfig(libdisplay-info)' \ 'pkgconfig(libdrm)' \ diff --git a/meson.build b/meson.build index dbc93da2e..61d1b3161 100644 --- a/meson.build +++ b/meson.build @@ -14,11 +14,11 @@ dep_m = meson.get_compiler('cpp').find_library('m', required: false) dep_wayland_protocols = dependency('wayland-protocols', version: '>= 1.31') dep_wayland_scanner = dependency('wayland-scanner') dep_wayland_server = dependency('wayland-server') -dep_wlroots = dependency('wlroots', version: ['>= 0.16.0', '< 0.17.0'], fallback: ['wlroots'], default_options: ['examples=false']) +dep_wlroots = dependency('wlroots', version: ['>= 0.17', '< 0.18.0'], fallback: ['wlroots'], default_options: ['examples=false']) dep_xcb = dependency('xcb') dep_xkbcommon = dependency('xkbcommon') -foreach feature : ['drm_backend', 'libinput_backend', 'xwayland'] +foreach feature : ['drm_backend', 'libinput_backend', 'session', 'xwayland'] var_feature = 'have_' + feature if dep_wlroots.get_variable(pkgconfig: var_feature, internal: var_feature, default_value: 'false') != 'true' error('Wlroots was not built with ' + feature + ' support. Check for missing dependencies.') diff --git a/src/input/cursor.cpp b/src/input/cursor.cpp index 4a96839bd..06160dc81 100644 --- a/src/input/cursor.cpp +++ b/src/input/cursor.cpp @@ -388,5 +388,5 @@ void Cursor::set_image(const std::string& name) { } void Cursor::reload_image() const { - wlr_xcursor_manager_set_cursor_image(cursor_mgr, current_image.c_str(), &wlr); + wlr_cursor_set_xcursor(&wlr, cursor_mgr, current_image.c_str()); } diff --git a/src/input/keyboard.cpp b/src/input/keyboard.cpp index 91e3a86fa..b4026f36f 100644 --- a/src/input/keyboard.cpp +++ b/src/input/keyboard.cpp @@ -9,6 +9,7 @@ #include "wlr-wrap-start.hpp" #include <wlr/backend/multi.h> +#include <wlr/backend/session.h> #include <wlr/types/wlr_idle_notify_v1.h> #include <wlr/types/wlr_seat.h> #include "wlr-wrap-end.hpp" @@ -50,10 +51,8 @@ static bool handle_compositor_keybinding(const Keyboard& keyboard, const uint32_ } } else if (sym >= XKB_KEY_XF86Switch_VT_1 && sym <= XKB_KEY_XF86Switch_VT_12) { if (wlr_backend_is_multi(keyboard.seat.server.backend)) { - if (wlr_session* session = wlr_backend_get_session(keyboard.seat.server.backend)) { - const uint32_t vt = sym - XKB_KEY_XF86Switch_VT_1 + 1; - wlr_session_change_vt(session, vt); - } + const unsigned vt = sym - XKB_KEY_XF86Switch_VT_1 + 1; + wlr_session_change_vt(keyboard.seat.server.session, vt); } return true; } diff --git a/src/output.cpp b/src/output.cpp index 7e0027c0d..68edf8462 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -12,17 +12,13 @@ #include <wlr/types/wlr_output_layout.h> #include <wlr-wrap-end.hpp> -static void output_enable_notify(wl_listener* listener, void* data) { - Output& output = magpie_container_of(listener, output, enable); - (void) data; - - output.scene_output = wlr_scene_get_scene_output(output.server.scene, &output.wlr); -} - -static void output_mode_notify(wl_listener* listener, void* data) { - Output& output = magpie_container_of(listener, output, mode); - (void) data; +/* This function is called every time an output is ready to display a frame, + * generally at the output's refresh rate (e.g. 60Hz). */ +static void output_request_state_notify(wl_listener* listener, void* data) { + Output& output = magpie_container_of(listener, output, request_state); + const auto* event = static_cast<wlr_output_event_request_state*>(data); + wlr_output_commit_state(&output.wlr, event->state); output.update_layout(); } @@ -32,20 +28,18 @@ static void output_frame_notify(wl_listener* listener, void* data) { Output& output = magpie_container_of(listener, output, frame); (void) data; - if (output.scene_output == nullptr) { - output.scene_output = wlr_scene_get_scene_output(output.server.scene, &output.wlr); - } + wlr_scene_output* scene_output = wlr_scene_get_scene_output(output.server.scene, &output.wlr); - if (output.scene_output == nullptr || output.is_leased || !output.wlr.enabled) { + if (scene_output == nullptr || output.is_leased || !output.wlr.enabled) { return; } /* Render the scene if needed and commit the output */ - wlr_scene_output_commit(output.scene_output); + wlr_scene_output_commit(scene_output, nullptr); timespec now = {}; timespec_get(&now, TIME_UTC); - wlr_scene_output_send_frame_done(output.scene_output, &now); + wlr_scene_output_send_frame_done(scene_output, &now); } static void output_destroy_notify(wl_listener* listener, void* data) { @@ -63,26 +57,43 @@ static void output_destroy_notify(wl_listener* listener, void* data) { Output::Output(Server& server, wlr_output& wlr) noexcept : listeners(*this), server(server), wlr(wlr) { wlr.data = this; - scene_output = wlr_scene_get_scene_output(server.scene, &wlr); + wlr_output_init_render(&wlr, server.allocator, server.renderer); - listeners.enable.notify = output_enable_notify; - wl_signal_add(&wlr.events.enable, &listeners.enable); - listeners.mode.notify = output_mode_notify; - wl_signal_add(&wlr.events.mode, &listeners.mode); + wlr_output_state state = {}; + wlr_output_state_init(&state); + wlr_output_state_set_enabled(&state, true); + + wlr_output_mode* mode = wlr_output_preferred_mode(&wlr); + if (mode != nullptr) { + wlr_output_state_set_mode(&state, mode); + } + + wlr_output_commit_state(&wlr, &state); + wlr_output_state_finish(&state); + + listeners.request_state.notify = output_request_state_notify; + wl_signal_add(&wlr.events.request_state, &listeners.request_state); listeners.frame.notify = output_frame_notify; wl_signal_add(&wlr.events.frame, &listeners.frame); listeners.destroy.notify = output_destroy_notify; wl_signal_add(&wlr.events.destroy, &listeners.destroy); + + wlr_output_layout_output* layout_output = wlr_output_layout_add_auto(server.output_layout, &wlr); + wlr_scene_output* scene_output = wlr_scene_output_create(server.scene, &wlr); + wlr_scene_output_layout_add_output(server.scene_layout, layout_output, scene_output); } Output::~Output() noexcept { - wl_list_remove(&listeners.mode.link); + wl_list_remove(&listeners.request_state.link); wl_list_remove(&listeners.frame.link); wl_list_remove(&listeners.destroy.link); } void Output::update_layout() { const wlr_scene_output* scene_output = wlr_scene_get_scene_output(server.scene, &wlr); + if (scene_output == nullptr) { + return; + } full_area.x = scene_output->x; full_area.y = scene_output->y; diff --git a/src/output.hpp b/src/output.hpp index 02f1ed062..bcd1dd52c 100644 --- a/src/output.hpp +++ b/src/output.hpp @@ -17,7 +17,7 @@ class Output { struct Listeners { std::reference_wrapper<Output> parent; wl_listener enable = {}; - wl_listener mode = {}; + wl_listener request_state = {}; wl_listener frame = {}; wl_listener destroy = {}; explicit Listeners(Output& parent) noexcept : parent(parent) {} diff --git a/src/server.cpp b/src/server.cpp index 451de2419..33e52b0e8 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -13,6 +13,7 @@ #include <utility> #include "wlr-wrap-start.hpp" +#include <wlr/backend/session.h> #include <wlr/render/wlr_renderer.h> #include <wlr/types/wlr_data_control_v1.h> #include <wlr/types/wlr_data_device.h> @@ -41,12 +42,10 @@ void Server::focus_view(View* view, wlr_surface* surface) { if (prev_surface) { wlr_surface* previous = seat->wlr->keyboard_state.focused_surface; - if (wlr_surface_is_xdg_surface(previous)) { - const wlr_xdg_surface* xdg_previous = wlr_xdg_surface_from_wlr_surface(previous); + if (const auto* xdg_previous = wlr_xdg_surface_try_from_wlr_surface(previous)) { assert(xdg_previous->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); wlr_xdg_toplevel_set_activated(xdg_previous->toplevel, false); - } else if (wlr_surface_is_xwayland_surface(previous)) { - wlr_xwayland_surface* xwayland_previous = wlr_xwayland_surface_from_wlr_surface(previous); + } else if (auto* xwayland_previous = wlr_xwayland_surface_try_from_wlr_surface(previous)) { wlr_xwayland_surface_activate(xwayland_previous, false); } } @@ -96,7 +95,7 @@ Surface* Server::surface_at(const double lx, const double ly, wlr_surface** wlr, return nullptr; } wlr_scene_buffer* scene_buffer = wlr_scene_buffer_from_node(node); - const wlr_scene_surface* scene_surface = wlr_scene_surface_from_buffer(scene_buffer); + const wlr_scene_surface* scene_surface = wlr_scene_surface_try_from_buffer(scene_buffer); if (!scene_surface) { return nullptr; } @@ -212,13 +211,13 @@ static void request_activation_notify(wl_listener* listener, void* data) { Server& server = magpie_container_of(listener, server, activation_request_activation); const auto* event = static_cast<wlr_xdg_activation_v1_request_activate_event*>(data); - if (!wlr_surface_is_xdg_surface(event->surface)) { + const auto* xdg_surface = wlr_xdg_surface_try_from_wlr_surface(event->surface); + if (xdg_surface == nullptr) { return; } - const wlr_xdg_surface* xdg_surface = wlr_xdg_surface_from_wlr_surface(event->surface); auto* view = dynamic_cast<View*>(static_cast<Surface*>(xdg_surface->surface->data)); - if (view != nullptr && xdg_surface->mapped) { + if (view != nullptr && xdg_surface->surface->mapped) { server.focus_view(view, xdg_surface->surface); } } @@ -313,7 +312,7 @@ void output_manager_apply_notify(wl_listener* listener, void* data) { wlr_output_layout_get_box(server.output_layout, &output.wlr, &box); if (box.x != head->state.x || box.y != head->state.y) { /* This overrides the automatic layout */ - wlr_output_layout_move(server.output_layout, &output.wlr, head->state.x, head->state.y); + wlr_output_layout_add(server.output_layout, &output.wlr, head->state.x, head->state.y); } } @@ -339,11 +338,14 @@ Server::Server() : listeners(*this) { display = wl_display_create(); assert(display); + session = wlr_session_create(display); + assert(session); + /* The backend is a wlroots feature which abstracts the underlying input and * output hardware. The autocreate option will choose the most suitable * backend based on the current environment, such as opening an X11 window * if an X11 server is running. */ - backend = wlr_backend_autocreate(display); + backend = wlr_backend_autocreate(display, &session); assert(backend); /* Autocreates a renderer, either Pixman, GLES2 or Vulkan for us. The user @@ -368,7 +370,7 @@ Server::Server() : listeners(*this) { * to dig your fingers in and play with their behavior if you want. Note that * the clients cannot set the selection directly without compositor approval, * see the handling of the request_set_selection event below.*/ - compositor = wlr_compositor_create(display, renderer); + compositor = wlr_compositor_create(display, 6, renderer); wlr_subcompositor_create(display); wlr_data_device_manager_create(display); @@ -411,7 +413,7 @@ Server::Server() : listeners(*this) { wlr_scene_node_raise_to_top(&scene_layers[idx]->node); } - wlr_scene_attach_output_layout(scene, output_layout); + scene_layout = wlr_scene_attach_output_layout(scene, output_layout); auto* presentation = wlr_presentation_create(display, backend); assert(presentation); @@ -421,7 +423,7 @@ Server::Server() : listeners(*this) { listeners.xdg_shell_new_xdg_surface.notify = new_xdg_surface_notify; wl_signal_add(&xdg_shell->events.new_surface, &listeners.xdg_shell_new_xdg_surface); - layer_shell = wlr_layer_shell_v1_create(display); + layer_shell = wlr_layer_shell_v1_create(display, 4); listeners.layer_shell_new_layer_surface.notify = new_layer_surface_notify; wl_signal_add(&layer_shell->events.new_surface, &listeners.layer_shell_new_layer_surface); diff --git a/src/server.hpp b/src/server.hpp index a812eafbb..93bb6c069 100644 --- a/src/server.hpp +++ b/src/server.hpp @@ -8,6 +8,7 @@ #include <set> #include "wlr-wrap-start.hpp" +#include <wlr/backend/session.h> #include <wlr/render/allocator.h> #include <wlr/types/wlr_drm_lease_v1.h> #include <wlr/types/wlr_foreign_toplevel_management_v1.h> @@ -50,6 +51,7 @@ class Server { public: wl_display* display; + wlr_session* session; wlr_backend* backend; wlr_renderer* renderer; wlr_allocator* allocator; @@ -58,6 +60,7 @@ class Server { XWayland* xwayland; wlr_scene* scene; + wlr_scene_output_layout* scene_layout; wlr_scene_tree* scene_layers[MAGPIE_SCENE_LAYER_LOCK + 1] = {}; wlr_xdg_shell* xdg_shell; diff --git a/src/surface/layer.cpp b/src/surface/layer.cpp index 0c9e6dcf4..b239e033a 100644 --- a/src/surface/layer.cpp +++ b/src/surface/layer.cpp @@ -113,9 +113,9 @@ Layer::Layer(Output& output, wlr_layer_surface_v1& surface) noexcept surface.surface->data = this; listeners.map.notify = wlr_layer_surface_v1_map_notify; - wl_signal_add(&surface.events.map, &listeners.map); + wl_signal_add(&surface.surface->events.map, &listeners.map); listeners.unmap.notify = wlr_layer_surface_v1_unmap_notify; - wl_signal_add(&surface.events.unmap, &listeners.unmap); + wl_signal_add(&surface.surface->events.unmap, &listeners.unmap); listeners.destroy.notify = wlr_layer_surface_v1_destroy_notify; wl_signal_add(&surface.events.destroy, &listeners.destroy); listeners.commit.notify = wlr_layer_surface_v1_commit_notify; diff --git a/src/surface/popup.cpp b/src/surface/popup.cpp index 4528e3c90..cac8bcb0e 100644 --- a/src/surface/popup.cpp +++ b/src/surface/popup.cpp @@ -41,9 +41,9 @@ Popup::Popup(const Surface& parent, wlr_xdg_popup& wlr) noexcept wlr.base->surface->data = this; listeners.map.notify = popup_map_notify; - wl_signal_add(&wlr.base->events.map, &listeners.map); + wl_signal_add(&wlr.base->surface->events.map, &listeners.map); listeners.unmap.notify = popup_unmap_notify; - wl_signal_add(&wlr.base->events.unmap, &listeners.unmap); + wl_signal_add(&wlr.base->surface->events.unmap, &listeners.unmap); listeners.destroy.notify = popup_destroy_notify; wl_signal_add(&wlr.base->events.destroy, &listeners.destroy); listeners.commit.notify = popup_commit_notify; diff --git a/src/surface/xdg_view.cpp b/src/surface/xdg_view.cpp index a288e1b99..26d008765 100644 --- a/src/surface/xdg_view.cpp +++ b/src/surface/xdg_view.cpp @@ -143,9 +143,9 @@ XdgView::XdgView(Server& server, wlr_xdg_toplevel& toplevel) noexcept } listeners.map.notify = xdg_toplevel_map_notify; - wl_signal_add(&toplevel.base->events.map, &listeners.map); + wl_signal_add(&toplevel.base->surface->events.map, &listeners.map); listeners.unmap.notify = xdg_toplevel_unmap_notify; - wl_signal_add(&toplevel.base->events.unmap, &listeners.unmap); + wl_signal_add(&toplevel.base->surface->events.unmap, &listeners.unmap); listeners.destroy.notify = xdg_toplevel_destroy_notify; wl_signal_add(&toplevel.base->events.destroy, &listeners.destroy); listeners.request_move.notify = xdg_toplevel_request_move_notify; diff --git a/src/surface/xwayland_view.cpp b/src/surface/xwayland_view.cpp index 098688dfb..e10ab8b1b 100644 --- a/src/surface/xwayland_view.cpp +++ b/src/surface/xwayland_view.cpp @@ -143,9 +143,9 @@ XWaylandView::XWaylandView(Server& server, wlr_xwayland_surface& surface) noexce /* Listen to the various events it can emit */ listeners.map.notify = xwayland_surface_map_notify; - wl_signal_add(&surface.events.map, &listeners.map); + wl_signal_add(&surface.surface->events.map, &listeners.map); listeners.unmap.notify = xwayland_surface_unmap_notify; - wl_signal_add(&surface.events.unmap, &listeners.unmap); + wl_signal_add(&surface.surface->events.unmap, &listeners.unmap); listeners.destroy.notify = xwayland_surface_destroy_notify; wl_signal_add(&surface.events.destroy, &listeners.destroy); listeners.request_configure.notify = xwayland_surface_request_configure_notify; diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index e7e10db8c..1aa89c067 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,4 +1,4 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 0.16.2 +revision = 0.17.0 depth = 1