commit 2fd6f353433d9c6bbee37159bc94e837ead9dae8
parent 7e52bfde60eeae43e37c66066d1fab8516912bac
Author: deurzen <m.deurzen@tum.de>
Date: Sat, 21 May 2022 21:31:34 +0200
adds tree node handling
Diffstat:
13 files changed, 467 insertions(+), 216 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -35,6 +35,7 @@ add_compile_options(
-O0
# debug options
-g
+ # -DTRACING_DISABLED
# -finstrument-functions -finstrument-functions-exclude-file-list=/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/include/g++-v11,/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/include/g++-v11/backward,/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/include/g++-v11/x86_64-pc-linux-gnu,/usr/local/include -ldl -Wl,--export-dynamic
)
diff --git a/include/kranewl/input/keyboard.hh b/include/kranewl/input/keyboard.hh
@@ -9,7 +9,8 @@ extern "C" {
#include <unordered_set>
typedef class Server* Server_ptr;
-struct Keyboard {
+
+typedef struct Keyboard {
Server_ptr mp_server;
struct wl_list m_link;
@@ -17,7 +18,7 @@ struct Keyboard {
struct wl_listener ml_modifiers;
struct wl_listener ml_key;
-};
+}* Keyboard_ptr;
struct KeyboardInput {
uint32_t mod;
diff --git a/include/kranewl/model.hh b/include/kranewl/model.hh
@@ -25,7 +25,11 @@ public:
void register_server(Server_ptr);
void exit();
- Output_ptr create_output(Server_ptr, struct wlr_output*, struct wlr_scene_output*);
+ Keyboard_ptr create_keyboard(struct wlr_output*, struct wlr_scene_output*);
+ void register_keyboard(Keyboard_ptr);
+ void unregister_keyboard(Keyboard_ptr);
+
+ Output_ptr create_output(struct wlr_output*, struct wlr_scene_output*);
void register_output(Output_ptr);
void unregister_output(Output_ptr);
@@ -42,10 +46,12 @@ private:
bool m_running;
Cycle<Output_ptr> m_outputs;
+ Cycle<Keyboard_ptr> m_keyboards;
Cycle<Context_ptr> m_contexts;
Cycle<Workspace_ptr> m_workspaces;
Output_ptr mp_output;
+ Output_ptr mp_fallback_output;
Context_ptr mp_context;
Workspace_ptr mp_workspace;
diff --git a/include/kranewl/server.hh b/include/kranewl/server.hh
@@ -1,6 +1,7 @@
#pragma once
#include <kranewl/geometry.hh>
+#include <kranewl/tree/root.hh>
extern "C" {
#include <wlr/backend.h>
@@ -29,11 +30,9 @@ public:
private:
static void new_output(struct wl_listener*, void*);
- static void output_destroy(struct wl_listener*, void*);
static void output_layout_change(struct wl_listener*, void*);
static void output_manager_apply(struct wl_listener*, void*);
static void output_manager_test(struct wl_listener*, void*);
- static void output_frame(struct wl_listener*, void*);
static void new_xdg_surface(struct wl_listener*, void*);
static void new_layer_shell_surface(struct wl_listener*, void*);
@@ -89,17 +88,19 @@ private:
struct wl_event_loop* mp_event_loop;
struct wlr_backend* mp_backend;
+ struct wlr_backend* mp_headless_backend;
struct wlr_renderer* mp_renderer;
struct wlr_allocator* mp_allocator;
struct wlr_compositor* mp_compositor;
struct wlr_data_device_manager* mp_data_device_manager;
+ struct wlr_scene* mp_scene;
+
+ Root m_root;
#ifdef XWAYLAND
struct wlr_xwayland* mp_xwayland;
#endif
- struct wlr_output_layout* mp_output_layout;
- struct wlr_scene* mp_scene;
struct wlr_xdg_shell* mp_xdg_shell;
struct wlr_layer_shell_v1* mp_layer_shell;
struct wlr_xdg_activation_v1* mp_xdg_activation;
@@ -122,10 +123,6 @@ private:
struct wlr_idle_inhibit_manager_v1* mp_idle_inhibit_manager;
struct wlr_keyboard_shortcuts_inhibit_manager_v1* mp_keyboard_shortcuts_inhibit_manager;
- struct wl_list m_outputs;
- struct wl_list m_clients;
- struct wl_list m_keyboards;
-
struct wl_listener ml_new_output;
struct wl_listener ml_output_layout_change;
struct wl_listener ml_output_manager_apply;
@@ -153,12 +150,6 @@ private:
struct wl_listener ml_new_xwayland_surface;
#endif
- CursorMode m_cursor_mode;
- Client_ptr mp_grabbed_client;
- double m_grab_x, m_grab_y;
- struct wlr_box m_grab_geobox;
- uint32_t m_resize_edges;
-
const std::string m_socket;
}* Server_ptr;
diff --git a/include/kranewl/tree/node.hh b/include/kranewl/tree/node.hh
@@ -1,3 +1,51 @@
#pragma once
+#include <kranewl/common.hh>
+extern "C" {
+#include <wayland-server-core.h>
+}
+
+typedef class Root* Root_ptr;
+typedef class Output* Output_ptr;
+typedef class Context* Context_ptr;
+typedef class Workspace* Workspace_ptr;
+typedef class Container* Container_ptr;
+
+enum class NodeType {
+ Root,
+ Output,
+ Context,
+ Workspace,
+ Container,
+};
+
+typedef struct Node {
+protected:
+ Node(Root_ptr);
+ Node(Output_ptr);
+ Node(Context_ptr);
+ Node(Workspace_ptr);
+ Node(Container_ptr);
+ ~Node();
+
+public:
+ Uid m_uid;
+
+ NodeType m_type;
+ union {
+ Root_ptr m_root;
+ Output_ptr m_output;
+ Context_ptr m_context;
+ Workspace_ptr m_workspace;
+ Container_ptr m_container;
+ };
+
+ bool m_destroying;
+ bool m_dirty;
+
+ struct {
+ struct wl_signal destroy;
+ } m_events;
+
+}* Node_ptr;
diff --git a/include/kranewl/tree/output.hh b/include/kranewl/tree/output.hh
@@ -1,73 +1,36 @@
#pragma once
#include <kranewl/common.hh>
-#include <kranewl/geometry.hh>
#include <kranewl/context.hh>
-#include <kranewl/util.hh>
-
-#include <spdlog/spdlog.h>
+#include <kranewl/geometry.hh>
+#include <kranewl/tree/node.hh>
extern "C" {
-#include <wlr/backend.h>
+#include <wayland-server-core.h>
+#include <wlr/types/wlr_output.h>
}
typedef class Server* Server_ptr;
+typedef class Model* Model_ptr;
typedef class Context* Context_ptr;
-typedef class Output final {
-public:
- Output(
- Server_ptr server,
- struct wlr_output* wlr_output,
- struct wlr_scene_output* wlr_scene_output
- )
- : mp_context(nullptr),
- mp_server(server),
- mp_wlr_output(wlr_output),
- mp_wlr_scene_output(wlr_scene_output)
- {}
-
- void
- set_context(Context_ptr context)
- {
- if (!context)
- spdlog::error("output must contain a valid context");
-
- if (mp_context)
- mp_context->set_output(nullptr);
-
- context->set_output(this);
- mp_context = context;
- }
- Context_ptr
- context() const
- {
- return mp_context;
- }
-
- Region
- full_region() const
- {
- return m_full_region;
- }
-
- Region
- placeable_region() const
- {
- return m_placeable_region;
- }
-
- bool
- contains(Pos pos) const
- {
- return m_full_region.contains(pos);
- }
-
- bool
- contains(Region region) const
- {
- return m_full_region.contains(region);
- }
+typedef class Output final : public Node {
+public:
+ Output(Server_ptr, Model_ptr, struct wlr_output*, struct wlr_scene_output*);
+ ~Output();
+
+ static void handle_frame(struct wl_listener*, void*);
+ static void handle_destroy(struct wl_listener*, void*);
+ static void handle_present(struct wl_listener*, void*);
+ static void handle_mode(struct wl_listener*, void*);
+ static void handle_commit(struct wl_listener*, void*);
+
+ void set_context(Context_ptr context);
+ Context_ptr context() const;
+ Region full_region() const;
+ Region placeable_region() const;
+ bool contains(Pos pos) const;
+ bool contains(Region region) const;
private:
Context_ptr mp_context;
@@ -76,11 +39,23 @@ private:
public:
Server_ptr mp_server;
+ Model_ptr mp_model;
struct wlr_output* mp_wlr_output;
- struct wlr_scene_output* mp_wlr_scene_output;
+ struct wlr_scene_output* mp_wlr_scene_output;
+
+ struct wlr_output_damage* mp_damage;
+ struct wlr_output_mode* mp_current_mode;
+ enum wl_output_subpixel m_subpixel;
struct wl_listener ml_frame;
struct wl_listener ml_destroy;
+ struct wl_listener ml_present;
+ struct wl_listener ml_mode;
+ struct wl_listener ml_commit;
+
+ struct {
+ struct wl_signal disable;
+ } m_events;
}* Output_ptr;
diff --git a/include/kranewl/tree/root.hh b/include/kranewl/tree/root.hh
@@ -1,3 +1,43 @@
#pragma once
+#include <kranewl/common.hh>
+#include <kranewl/cycle.hh>
+#include <kranewl/geometry.hh>
+#include <kranewl/tree/node.hh>
+extern "C" {
+#include <wayland-server-core.h>
+#include <wlr/backend.h>
+}
+
+typedef class Server* Server_ptr;
+typedef class Model* Model_ptr;
+
+typedef class Root final : public Node {
+public:
+ Root(Server_ptr, Model_ptr, struct wlr_output_layout*, Output_ptr);
+ ~Root();
+
+ static void handle_output_layout_change(struct wl_listener*, void*);
+
+public:
+ Server_ptr mp_server;
+ Model_ptr mp_model;
+
+ struct wlr_output_layout* mp_output_layout;
+
+ struct wl_listener ml_output_layout_change;
+
+ struct {
+ struct wl_signal new_node;
+ } m_events;
+
+ Region m_region;
+
+ Cycle<Output_ptr> m_outputs;
+ Cycle<Container_ptr> m_scratchpad;
+
+ Output_ptr mp_fallback_output;
+ Container_ptr mp_fullscreen_global;
+
+}* Root_ptr;
diff --git a/include/version.hh b/include/version.hh
@@ -1 +1 @@
-#define VERSION "master/2754909+"
-\ No newline at end of file
+#define VERSION "master/7e52bfd+"
+\ No newline at end of file
diff --git a/src/kranewl/model.cc b/src/kranewl/model.cc
@@ -23,9 +23,11 @@ Model::Model(
: m_config{config},
m_running{true},
m_outputs{{}, true},
+ m_keyboards{{}, false},
m_contexts{{}, true},
m_workspaces{{}, true},
mp_output{nullptr},
+ mp_fallback_output{nullptr},
mp_context{nullptr},
mp_workspace{nullptr},
mp_prev_output{nullptr},
@@ -95,7 +97,6 @@ Model::register_server(Server_ptr server)
Output_ptr
Model::create_output(
- Server_ptr server,
struct wlr_output* wlr_output,
struct wlr_scene_output* wlr_scene_output
)
@@ -104,6 +105,7 @@ Model::create_output(
Output_ptr output = new Output(
mp_server,
+ this,
wlr_output,
wlr_scene_output
);
diff --git a/src/kranewl/server.cc b/src/kranewl/server.cc
@@ -20,11 +20,16 @@
#define static
extern "C" {
#include <wlr/backend.h>
+#include <wlr/backend/headless.h>
+#include <wlr/backend/multi.h>
#include <wlr/render/allocator.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_cursor.h>
+#include <wlr/types/wlr_data_control_v1.h>
#include <wlr/types/wlr_data_device.h>
+#include <wlr/types/wlr_export_dmabuf_v1.h>
+#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/types/wlr_input_device.h>
@@ -41,8 +46,8 @@ extern "C" {
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_primary_selection_v1.h>
#include <wlr/types/wlr_relative_pointer_v1.h>
-#include <wlr/types/wlr_relative_pointer_v1.h>
#include <wlr/types/wlr_scene.h>
+#include <wlr/types/wlr_screencopy_v1.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_server_decoration.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h>
@@ -76,15 +81,57 @@ Server::Server(Model_ptr model)
mp_display(wl_display_create()),
mp_event_loop(wl_display_get_event_loop(mp_display)),
mp_backend(wlr_backend_autocreate(mp_display)),
+ mp_headless_backend(wlr_headless_backend_create(mp_display)),
mp_renderer([](struct wl_display* display, struct wlr_backend* backend) {
- struct wlr_renderer* renderer = wlr_renderer_autocreate(backend);
- wlr_renderer_init_wl_display(renderer, display);
+ struct wlr_renderer* renderer = wlr_renderer_autocreate(backend);
+ wlr_renderer_init_wl_display(renderer, display);
- return renderer;
+ return renderer;
}(mp_display, mp_backend)),
mp_allocator(wlr_allocator_autocreate(mp_backend, mp_renderer)),
+ mp_compositor(wlr_compositor_create(mp_display, mp_renderer)),
+ mp_data_device_manager(wlr_data_device_manager_create(mp_display)),
+ mp_scene(wlr_scene_create()),
+ m_root([this](struct wl_display* display) {
+ struct wlr_output_layout* wlr_output_layout = wlr_output_layout_create();
+ wlr_xdg_output_manager_v1_create(display, wlr_output_layout);
+
+ struct wlr_output* wlr_output =
+ wlr_headless_add_output(mp_headless_backend, 800, 600);
+
+ wlr_output_set_name(wlr_output, "FALLBACK");
+
+ return Root(
+ this,
+ mp_model,
+ wlr_output_layout,
+ mp_model->create_output(
+ wlr_output,
+ wlr_scene_output_create(mp_scene, wlr_output)
+ )
+ );
+ }(mp_display)),
+ mp_layer_shell(wlr_layer_shell_v1_create(mp_display)),
+ mp_xdg_shell(wlr_xdg_shell_create(mp_display)),
+ mp_cursor(wlr_cursor_create()),
+ mp_cursor_manager(wlr_xcursor_manager_create(NULL, 24)),
+ mp_seat(wlr_seat_create(mp_display, "seat0")),
+ mp_presentation(wlr_presentation_create(mp_display, mp_backend)),
+ mp_idle(wlr_idle_create(mp_display)),
+ mp_idle_inhibit_manager(wlr_idle_inhibit_v1_create(mp_display)),
+ mp_server_decoration_manager(wlr_server_decoration_manager_create(mp_display)),
+ mp_xdg_decoration_manager(wlr_xdg_decoration_manager_v1_create(mp_display)),
+ mp_output_manager(wlr_output_manager_v1_create(mp_display)),
+ mp_input_inhibit_manager(wlr_input_inhibit_manager_create(mp_display)),
+ mp_keyboard_shortcuts_inhibit_manager(wlr_keyboard_shortcuts_inhibit_v1_create(mp_display)),
+ mp_pointer_constraints(wlr_pointer_constraints_v1_create(mp_display)),
+ mp_relative_pointer_manager(wlr_relative_pointer_manager_v1_create(mp_display)),
+ mp_virtual_pointer_manager(wlr_virtual_pointer_manager_v1_create(mp_display)),
+ mp_virtual_keyboard_manager(wlr_virtual_keyboard_manager_v1_create(mp_display)),
+#ifdef XWAYLAND
+ mp_xwayland(wlr_xwayland_create(mp_display, mp_compositor, 1)),
+#endif
ml_new_output({ .notify = Server::new_output }),
- ml_output_layout_change({ .notify = Server::output_layout_change }),
ml_output_manager_apply({ .notify = Server::output_manager_apply }),
ml_output_manager_test({ .notify = Server::output_manager_test }),
ml_new_xdg_surface({ .notify = Server::new_xdg_surface }),
@@ -113,112 +160,72 @@ Server::Server(Model_ptr model)
{
TRACE();
- mp_compositor = wlr_compositor_create(mp_display, mp_renderer);
- mp_data_device_manager = wlr_data_device_manager_create(mp_display);
-
- mp_output_layout = wlr_output_layout_create();
-
- wl_list_init(&m_outputs);
- wl_signal_add(&mp_backend->events.new_output, &ml_new_output);
-
- mp_scene = wlr_scene_create();
- wlr_scene_attach_output_layout(mp_scene, mp_output_layout);
-
- wl_list_init(&m_clients);
-
- mp_layer_shell = wlr_layer_shell_v1_create(mp_display);
- wl_signal_add(&mp_layer_shell->events.new_surface, &ml_new_layer_shell_surface);
-
- mp_xdg_shell = wlr_xdg_shell_create(mp_display);
- wl_signal_add(&mp_xdg_shell->events.new_surface, &ml_new_xdg_surface);
-
- mp_cursor = wlr_cursor_create();
- wlr_cursor_attach_output_layout(mp_cursor, mp_output_layout);
-
- mp_cursor_manager = wlr_xcursor_manager_create(NULL, 24);
- wlr_xcursor_manager_load(mp_cursor_manager, 1);
-
- mp_seat = wlr_seat_create(mp_display, "seat0");
- mp_presentation = wlr_presentation_create(mp_display, mp_backend);
- mp_idle = wlr_idle_create(mp_display);
-
- mp_idle_inhibit_manager = wlr_idle_inhibit_v1_create(mp_display);
- wl_signal_add(&mp_idle_inhibit_manager->events.new_inhibitor, &ml_idle_inhibitor_create);
-
- { // set up cursor handling
- wl_signal_add(&mp_cursor->events.motion, &ml_cursor_motion);
- wl_signal_add(&mp_cursor->events.motion_absolute, &ml_cursor_motion_absolute);
- wl_signal_add(&mp_cursor->events.button, &ml_cursor_button);
- wl_signal_add(&mp_cursor->events.axis, &ml_cursor_axis);
- wl_signal_add(&mp_cursor->events.frame, &ml_cursor_frame);
+ if (m_socket.empty()) {
+ wlr_backend_destroy(mp_backend);
+ wlr_backend_destroy(mp_headless_backend);
+ wl_display_destroy(mp_display);
+ std::exit(1);
+ spdlog::critical("Could not set up server socket");
+ return;
}
- { // set up keyboard handling
- wl_list_init(&m_keyboards);
- wl_signal_add(&mp_backend->events.new_input, &ml_new_input);
- wl_signal_add(&mp_seat->events.request_set_cursor, &ml_request_set_cursor);
- wl_signal_add(&mp_seat->events.request_set_selection, &ml_request_set_selection);
- wl_signal_add(&mp_seat->events.request_set_primary_selection, &ml_request_set_primary_selection);
- }
+ wlr_multi_backend_add(mp_backend, mp_headless_backend);
- mp_server_decoration_manager = wlr_server_decoration_manager_create(mp_display);
- mp_xdg_decoration_manager = wlr_xdg_decoration_manager_v1_create(mp_display);
+ wlr_export_dmabuf_manager_v1_create(mp_display);
+ wlr_screencopy_manager_v1_create(mp_display);
+ wlr_data_control_manager_v1_create(mp_display);
+ wlr_gamma_control_manager_v1_create(mp_display);
+ wlr_primary_selection_v1_device_manager_create(mp_display);
+ wlr_scene_attach_output_layout(mp_scene, m_root.mp_output_layout);
+ wlr_cursor_attach_output_layout(mp_cursor, m_root.mp_output_layout);
+ wlr_xcursor_manager_load(mp_cursor_manager, 1);
+ wlr_scene_set_presentation(mp_scene, wlr_presentation_create(mp_display, mp_backend));
wlr_server_decoration_manager_set_default_mode(
mp_server_decoration_manager,
WLR_SERVER_DECORATION_MANAGER_MODE_SERVER
);
- wlr_xdg_output_manager_v1_create(mp_display, mp_output_layout);
- wl_signal_add(&mp_output_layout->events.change, &ml_output_layout_change);
-
- mp_output_manager = wlr_output_manager_v1_create(mp_display);
+ wl_signal_add(&mp_backend->events.new_output, &ml_new_output);
+ wl_signal_add(&mp_layer_shell->events.new_surface, &ml_new_layer_shell_surface);
+ wl_signal_add(&mp_xdg_shell->events.new_surface, &ml_new_xdg_surface);
+ wl_signal_add(&mp_idle_inhibit_manager->events.new_inhibitor, &ml_idle_inhibitor_create);
+ wl_signal_add(&mp_cursor->events.motion, &ml_cursor_motion);
+ wl_signal_add(&mp_cursor->events.motion_absolute, &ml_cursor_motion_absolute);
+ wl_signal_add(&mp_cursor->events.button, &ml_cursor_button);
+ wl_signal_add(&mp_cursor->events.axis, &ml_cursor_axis);
+ wl_signal_add(&mp_cursor->events.frame, &ml_cursor_frame);
+ wl_signal_add(&mp_backend->events.new_input, &ml_new_input);
+ wl_signal_add(&mp_seat->events.request_set_cursor, &ml_request_set_cursor);
+ wl_signal_add(&mp_seat->events.request_set_selection, &ml_request_set_selection);
+ wl_signal_add(&mp_seat->events.request_set_primary_selection, &ml_request_set_primary_selection);
wl_signal_add(&mp_output_manager->events.apply, &ml_output_manager_apply);
wl_signal_add(&mp_output_manager->events.test, &ml_output_manager_test);
-
- wlr_scene_set_presentation(mp_scene, wlr_presentation_create(mp_display, mp_backend));
-
-#ifdef XWAYLAND
- mp_xwayland = wlr_xwayland_create(mp_display, mp_compositor, 1);
-
- if (mp_xwayland) {
- wl_signal_add(&mp_xwayland->events.ready, &ml_xwayland_ready);
- wl_signal_add(&mp_xwayland->events.new_surface, &ml_new_xwayland_surface);
-
- setenv("DISPLAY", mp_xwayland->display_name, 1);
- } else
- spdlog::error("Failed to initiate XWayland");
- spdlog::warn("Continuing without XWayland functionality");
-#endif
-
- mp_input_inhibit_manager = wlr_input_inhibit_manager_create(mp_display);
wl_signal_add(&mp_input_inhibit_manager->events.activate, &ml_inhibit_activate);
wl_signal_add(&mp_input_inhibit_manager->events.deactivate, &ml_inhibit_deactivate);
- mp_keyboard_shortcuts_inhibit_manager = wlr_keyboard_shortcuts_inhibit_v1_create(mp_display);
// TODO: mp_keyboard_shortcuts_inhibit_manager signals
-
- mp_pointer_constraints = wlr_pointer_constraints_v1_create(mp_display);
// TODO: mp_pointer_constraints signals
-
- mp_relative_pointer_manager = wlr_relative_pointer_manager_v1_create(mp_display);
// TODO: mp_relative_pointer_manager signals
-
- mp_virtual_pointer_manager = wlr_virtual_pointer_manager_v1_create(mp_display);
// TODO: mp_virtual_pointer_manager signals
-
- mp_virtual_keyboard_manager = wlr_virtual_keyboard_manager_v1_create(mp_display);
// TODO: mp_virtual_keyboard_manager signals
- if (m_socket.empty()) {
- wlr_backend_destroy(mp_backend);
- std::exit(1);
- return;
+#ifdef XWAYLAND
+ if (mp_xwayland) {
+ wl_signal_add(&mp_xwayland->events.ready, &ml_xwayland_ready);
+ wl_signal_add(&mp_xwayland->events.new_surface, &ml_new_xwayland_surface);
+ setenv("DISPLAY", mp_xwayland->display_name, 1);
+ } else {
+ spdlog::error("Failed to initiate XWayland");
+ spdlog::warn("Continuing without XWayland functionality");
}
+#endif
if (!wlr_backend_start(mp_backend)) {
wlr_backend_destroy(mp_backend);
+ wlr_backend_destroy(mp_headless_backend);
wl_display_destroy(mp_display);
+ spdlog::critical("Could not start backend");
std::exit(1);
return;
}
@@ -226,9 +233,6 @@ Server::Server(Model_ptr model)
setenv("WAYLAND_DISPLAY", m_socket.c_str(), true);
setenv("XDG_CURRENT_DESKTOP", "kranewl", true);
- setenv("QT_QPA_PLATFORM", "wayland", true);
- setenv("MOZ_ENABLE_WAYLAND", "1", true);
-
spdlog::info("Server initiated on WAYLAND_DISPLAY=" + m_socket);
}
@@ -254,9 +258,16 @@ Server::new_output(struct wl_listener* listener, void* data)
TRACE();
Server_ptr server = wl_container_of(listener, server, ml_new_output);
-
struct wlr_output* wlr_output = reinterpret_cast<struct wlr_output*>(data);
- wlr_output_init_render(wlr_output, server->mp_allocator, server->mp_renderer);
+
+ if (wlr_output == server->m_root.mp_fallback_output->mp_wlr_output)
+ return;
+
+ if (!wlr_output_init_render(wlr_output, server->mp_allocator, server->mp_renderer)) {
+ spdlog::error("Could not initialize rendering to output");
+ spdlog::warn("Ignoring output " + std::string(wlr_output->name));
+ return;
+ }
if (!wl_list_empty(&wlr_output->modes)) {
wlr_output_set_mode(wlr_output, wlr_output_preferred_mode(wlr_output));
@@ -268,42 +279,12 @@ Server::new_output(struct wl_listener* listener, void* data)
}
Output_ptr output = server->mp_model->create_output(
- server,
wlr_output,
wlr_scene_output_create(server->mp_scene, wlr_output)
);
wlr_output->data = output;
- output->ml_frame.notify = Server::output_frame;
- output->ml_destroy.notify = Server::output_destroy;
- wl_signal_add(&wlr_output->events.frame, &output->ml_frame);
- wl_signal_add(&wlr_output->events.destroy, &output->ml_destroy);
-
- wlr_output_layout_add_auto(server->mp_output_layout, wlr_output);
-}
-
-void
-Server::output_destroy(struct wl_listener* listener, void* data)
-{
- TRACE();
-
- struct wlr_output* wlr_output = reinterpret_cast<struct wlr_output*>(data);
- Output_ptr output = reinterpret_cast<Output_ptr>(wlr_output->data);
- Server_ptr server = output->mp_server;
-
- wl_list_remove(&output->ml_destroy.link);
- wl_list_remove(&output->ml_frame.link);
-
- wlr_scene_output_destroy(output->mp_wlr_scene_output);
- wlr_output_layout_remove(server->mp_output_layout, output->mp_wlr_output);
-
- server->mp_model->unregister_output(output);
-}
-
-void
-Server::output_layout_change(struct wl_listener* listener, void* data)
-{
- // TODO
+ wlr_output_layout_add_auto(server->m_root.mp_output_layout, wlr_output);
}
void
@@ -319,20 +300,6 @@ Server::output_manager_test(struct wl_listener* listener, void* data)
}
void
-Server::output_frame(struct wl_listener* listener, void* data)
-{
- TRACE();
-
- Output_ptr output = wl_container_of(listener, output, ml_frame);
-
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
-
- wlr_scene_output_commit(output->mp_wlr_scene_output);
- wlr_scene_output_send_frame_done(output->mp_wlr_scene_output, &now);
-}
-
-void
Server::new_xdg_surface(struct wl_listener* listener, void* data)
{
/* Server_ptr server = wl_container_of(listener, server, ml_new_xdg_surface); */
diff --git a/src/kranewl/tree/node.cc b/src/kranewl/tree/node.cc
@@ -1,3 +1,49 @@
#include <kranewl/tree/node.hh>
+Node::Node(Root_ptr root)
+ : m_uid(reinterpret_cast<Uid>(root)),
+ m_type(NodeType::Root),
+ m_root(root),
+ m_destroying(false),
+ m_dirty(false),
+ m_events{ .destroy = {} }
+{}
+Node::Node(Output_ptr output)
+ : m_uid(reinterpret_cast<Uid>(output)),
+ m_type(NodeType::Output),
+ m_output(output),
+ m_destroying(false),
+ m_dirty(false),
+ m_events{ .destroy = {} }
+{}
+
+Node::Node(Context_ptr context)
+ : m_uid(reinterpret_cast<Uid>(context)),
+ m_type(NodeType::Context),
+ m_context(context),
+ m_destroying(false),
+ m_dirty(false),
+ m_events{ .destroy = {} }
+{}
+
+Node::Node(Workspace_ptr workspace)
+ : m_uid(reinterpret_cast<Uid>(workspace)),
+ m_type(NodeType::Workspace),
+ m_workspace(workspace),
+ m_destroying(false),
+ m_dirty(false),
+ m_events{ .destroy = {} }
+{}
+
+Node::Node(Container_ptr container)
+ : m_uid(reinterpret_cast<Uid>(container)),
+ m_type(NodeType::Container),
+ m_container(container),
+ m_destroying(false),
+ m_dirty(false),
+ m_events{ .destroy = {} }
+{}
+
+Node::~Node()
+{}
diff --git a/src/kranewl/tree/output.cc b/src/kranewl/tree/output.cc
@@ -1,3 +1,140 @@
+#include <trace.hh>
+
#include <kranewl/tree/output.hh>
+#include <kranewl/server.hh>
+
+extern "C" {
+#include <wlr/types/wlr_output_damage.h>
+}
+
+Output::Output(
+ Server_ptr server,
+ Model_ptr model,
+ struct wlr_output* wlr_output,
+ struct wlr_scene_output* wlr_scene_output
+)
+ : Node(this),
+ mp_context(nullptr),
+ mp_server(server),
+ mp_model(model),
+ mp_wlr_output(wlr_output),
+ mp_wlr_scene_output(wlr_scene_output),
+ m_subpixel(wlr_output->subpixel)
+{
+ TRACE();
+
+ ml_frame.notify = Output::handle_frame;
+ ml_destroy.notify = Output::handle_destroy;
+ ml_present.notify = Output::handle_present;
+ ml_mode.notify = Output::handle_mode;
+ ml_commit.notify = Output::handle_commit;
+
+ wl_signal_add(&mp_wlr_output->events.frame, &ml_frame);
+ wl_signal_add(&mp_wlr_output->events.destroy, &ml_destroy);
+ wl_signal_add(&mp_wlr_output->events.present, &ml_present);
+ wl_signal_add(&mp_wlr_output->events.mode, &ml_mode);
+ wl_signal_add(&mp_wlr_output->events.commit, &ml_commit);
+
+ wl_signal_init(&m_events.disable);
+}
+
+Output::~Output()
+{}
+
+void
+Output::handle_frame(struct wl_listener* listener, void*)
+{
+ TRACE();
+
+ /* Output_ptr output = wl_container_of(listener, output, ml_frame); */
+
+ /* struct timespec now; */
+ /* clock_gettime(CLOCK_MONOTONIC, &now); */
+
+ /* wlr_scene_output_commit(output->mp_wlr_scene_output); */
+ /* wlr_scene_output_send_frame_done(output->mp_wlr_scene_output, &now); */
+}
+
+void
+Output::handle_destroy(struct wl_listener*, void*)
+{
+ TRACE();
+
+ /* struct wlr_output* wlr_output = reinterpret_cast<struct wlr_output*>(data); */
+ /* Output_ptr output = reinterpret_cast<Output_ptr>(wlr_output->data); */
+ /* Server_ptr server = output->mp_server; */
+
+ /* wl_list_remove(&output->ml_destroy.link); */
+ /* wl_list_remove(&output->ml_frame.link); */
+
+ /* wlr_scene_output_destroy(output->mp_wlr_scene_output); */
+ /* wlr_output_layout_remove(server->mp_output_layout, output->mp_wlr_output); */
+
+ /* server->mp_model->unregister_output(output); */
+}
+
+void
+Output::handle_present(struct wl_listener*, void*)
+{
+ TRACE();
+
+}
+
+void
+Output::handle_mode(struct wl_listener*, void*)
+{
+ TRACE();
+
+}
+
+void
+Output::handle_commit(struct wl_listener*, void*)
+{
+ TRACE();
+
+}
+
+void
+Output::set_context(Context_ptr context)
+{
+ TRACE();
+
+ if (!context)
+ spdlog::error("output must contain a valid context");
+
+ if (mp_context)
+ mp_context->set_output(nullptr);
+
+ context->set_output(this);
+ mp_context = context;
+}
+
+Context_ptr
+Output::context() const
+{
+ return mp_context;
+}
+
+Region
+Output::full_region() const
+{
+ return m_full_region;
+}
+
+Region
+Output::placeable_region() const
+{
+ return m_placeable_region;
+}
+bool
+Output::contains(Pos pos) const
+{
+ return m_full_region.contains(pos);
+}
+bool
+Output::contains(Region region) const
+{
+ return m_full_region.contains(region);
+}
diff --git a/src/kranewl/tree/root.cc b/src/kranewl/tree/root.cc
@@ -1,3 +1,40 @@
+#include <trace.hh>
+
#include <kranewl/tree/root.hh>
+#include <kranewl/cycle.t.hh>
+
+extern "C" {
+#include <wlr/types/wlr_output_layout.h>
+}
+
+Root::Root(
+ Server_ptr server,
+ Model_ptr model,
+ struct wlr_output_layout* wlr_output_layout,
+ Output_ptr fallback_output
+)
+ : Node(this),
+ mp_server(server),
+ mp_model(model),
+ mp_output_layout(wlr_output_layout),
+ m_outputs({}, true),
+ m_scratchpad({}, true),
+ mp_fallback_output(fallback_output)
+{
+ TRACE();
+
+ ml_output_layout_change.notify = Root::handle_output_layout_change;
+ wl_signal_add(&mp_output_layout->events.change, &ml_output_layout_change);
+
+ wl_signal_init(&m_events.new_node);
+}
+
+Root::~Root()
+{}
+void
+Root::handle_output_layout_change(struct wl_listener*, void*)
+{
+ TRACE();
+}