kranewl

A wlroots-based dynamic Wayland compositor, written in C++, configurable with Lua
git clone git://git.deurzen.net/kranewl
Log | Files | Refs | LICENSE

commit 9561b895db55cf5acb38d948564d511ebd0b6a4a
parent 79fe78836bbd78fdeb49ac4e00333d19e83f7671
Author: deurzen <m.deurzen@tum.de>
Date:   Thu, 19 May 2022 01:23:44 +0200

adds signals

Diffstat:
Ainclude/kranewl/client.hh | 184+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/kranewl/common.hh | 10++++++++++
Ainclude/kranewl/decoration.hh | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/kranewl/geometry.hh | 27++++++++++++++-------------
Minclude/kranewl/input/keyboard.hh | 6++++--
Minclude/kranewl/server.hh | 64+++++++++++++++++++++++++++++++++++++++++++++++++---------------
Minclude/kranewl/tree/output.hh | 4+++-
Ainclude/kranewl/tree/surface.hh | 13+++++++++++++
Minclude/kranewl/tree/view.hh | 14+++++++++-----
Minclude/version.hh | 4++--
Asrc/kranewl/client.cc | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/kranewl/main.cc | 1+
Msrc/kranewl/server.cc | 243++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
13 files changed, 694 insertions(+), 120 deletions(-)

diff --git a/include/kranewl/client.hh b/include/kranewl/client.hh @@ -0,0 +1,184 @@ +#pragma once + +#include <kranewl/common.hh> +#include <kranewl/decoration.hh> +#include <kranewl/geometry.hh> +#include <kranewl/tree/surface.hh> + +extern "C" { +#include <wlr/backend.h> +} + +#include <chrono> +#include <optional> +#include <string> +#include <vector> + +typedef class Partition* Partition_ptr; +typedef class Context* Context_ptr; +typedef class Workspace* Workspace_ptr; + +typedef struct Client* Client_ptr; +typedef struct Client final +{ + enum class OutsideState + { + Focused, + FocusedDisowned, + FocusedSticky, + Unfocused, + UnfocusedDisowned, + UnfocusedSticky, + Urgent + }; + + static bool + is_free(Client_ptr client) + { + return (client->floating && (!client->fullscreen || client->contained)) + || !client->managed + || client->disowned; + } + + Client( + Surface surface, + Partition_ptr partition, + Context_ptr context, + Workspace_ptr workspace, + std::optional<Pid> pid, + std::optional<Pid> ppid + ); + + ~Client(); + + Client(Client const&) = default; + Client& operator=(Client const&) = default; + + OutsideState get_outside_state() const noexcept; + + void focus() noexcept; + void unfocus() noexcept; + + void stick() noexcept; + void unstick() noexcept; + + void disown() noexcept; + void reclaim() noexcept; + + void set_urgent() noexcept; + void unset_urgent() noexcept; + + void expect_unmap() noexcept; + bool consume_unmap_if_expecting() noexcept; + + void set_tile_region(Region&) noexcept; + void set_free_region(Region&) noexcept; + + void set_tile_decoration(Decoration const&) noexcept; + void set_free_decoration(Decoration const&) noexcept; + + SurfaceType surface_type; + Surface surface; + + struct wlr_scene_node* scene; + struct wlr_scene_node* scene_surface; + struct wlr_scene_rect* border[4]; // protrusions (top, bottom, left, right) + + std::string title; + + Partition_ptr partition; + Context_ptr context; + Workspace_ptr workspace; + + Region free_region; + Region tile_region; + Region active_region; + Region previous_region; + Region inner_region; + + Decoration tile_decoration; + Decoration free_decoration; + Decoration active_decoration; + + Client_ptr parent; + std::vector<Client_ptr> children; + Client_ptr producer; + std::vector<Client_ptr> consumers; + + bool focused; + bool mapped; + bool managed; + bool urgent; + bool floating; + bool fullscreen; + bool contained; + bool invincible; + bool sticky; + bool iconifyable; + bool iconified; + bool disowned; + bool producing; + bool attaching; + + std::optional<Pid> pid; + std::optional<Pid> ppid; + + std::chrono::time_point<std::chrono::steady_clock> last_focused; + std::chrono::time_point<std::chrono::steady_clock> managed_since; + + struct wl_listener l_commit; + struct wl_listener l_map; + struct wl_listener l_unmap; + struct wl_listener l_destroy; + struct wl_listener l_set_title; + struct wl_listener l_fullscreen; +#ifdef XWAYLAND + struct wl_listener l_activate; + struct wl_listener l_configure; + struct wl_listener l_set_hints; +#else + struct wl_listener l_new_xdg_popup; +#endif + +private: + OutsideState m_outside_state; + + void set_inner_region(Region&) noexcept; + void set_active_region(Region&) noexcept; + +}* Client_ptr; + +inline bool +operator==(Client const& lhs, Client const& rhs) +{ + if (lhs.surface_type != rhs.surface_type) + return false; + + switch (lhs.surface_type) { + case SurfaceType::XDGShell: // fallthrough + case SurfaceType::LayerShell: return lhs.surface.xdg == rhs.surface.xdg; + case SurfaceType::X11Managed: // fallthrough + case SurfaceType::X11Unmanaged: return lhs.surface.xwayland == rhs.surface.xwayland; + } +} + +namespace std +{ + template <> + struct hash<Client> { + + std::size_t + operator()(Client const& client) const + { + switch (client.surface_type) { + case SurfaceType::XDGShell: // fallthrough + case SurfaceType::LayerShell: + return std::hash<wlr_xdg_surface*>{}(client.surface.xdg); + case SurfaceType::X11Managed: // fallthrough + case SurfaceType::X11Unmanaged: + return std::hash<wlr_xwayland_surface*>{}(client.surface.xwayland); + } + } + + }; +} diff --git a/include/kranewl/common.hh b/include/kranewl/common.hh @@ -0,0 +1,10 @@ +#pragma once + +typedef unsigned Pid; + +enum class Toggle +{ + On, + Off, + Reverse +}; diff --git a/include/kranewl/decoration.hh b/include/kranewl/decoration.hh @@ -0,0 +1,58 @@ +#pragma once + +#include <kranewl/geometry.hh> + +#include <optional> + +struct RGBA final { + RGBA(unsigned _hex) + : hex(_hex) + { + values[0] = static_cast<float>(hex & 0xff) / 255.f; + values[1] = static_cast<float>((hex >> 8) & 0xff) / 255.f; + values[2] = static_cast<float>((hex >> 16) & 0xff) / 255.f; + values[3] = static_cast<float>((hex >> 24) & 0xff) / 255.f; + } + + RGBA(const float _values[4]) + : hex(((static_cast<unsigned>(_values[3] * 255.f) & 0xff) << 24) + + ((static_cast<unsigned>(_values[2] * 255.f) & 0xff) << 16) + + ((static_cast<unsigned>(_values[1] * 255.f) & 0xff) << 8) + + ((static_cast<unsigned>(_values[0] * 255.f) & 0xff))) + { + values[0] = _values[0]; + values[1] = _values[1]; + values[2] = _values[2]; + values[3] = _values[3]; + } + + unsigned hex; + float values[4]; +}; + +struct ColorScheme final { + RGBA focused; + RGBA fdisowned; + RGBA fsticky; + RGBA unfocused; + RGBA udisowned; + RGBA usticky; + RGBA urgent; +}; + +struct Frame final { + Extents extents; + ColorScheme colorscheme; +}; + +struct Decoration final { + std::optional<Frame> frame; + + const Extents extents() const + { + if (frame) + return frame->extents; + + return Extents{0, 0, 0, 0}; + } +}; diff --git a/include/kranewl/geometry.hh b/include/kranewl/geometry.hh @@ -26,12 +26,12 @@ operator==(Dim const& lhs, Dim const& rhs) } inline std::ostream& -operator<<(std::ostream& os, Dim const& dim) { +operator<<(std::ostream& os, Dim const& dim) +{ return os << "(" << dim.w << "×" << dim.h << ")"; } -struct Pos final -{ +struct Pos final { int x; int y; @@ -58,7 +58,8 @@ operator==(Pos const& lhs, Pos const& rhs) } inline std::ostream& -operator<<(std::ostream& os, Pos const& pos) { +operator<<(std::ostream& os, Pos const& pos) +{ return os << "(" << pos.x << ", " << pos.y << ")"; } @@ -98,8 +99,7 @@ operator-(Pos const& pos, Dim const& dim) }; } -struct Padding final -{ +struct Padding final { int left; int right; int top; @@ -109,15 +109,15 @@ struct Padding final typedef Padding Extents; inline std::ostream& -operator<<(std::ostream& os, Padding const& padding) { +operator<<(std::ostream& os, Padding const& padding) +{ return os << "[" << padding.left << "; " << padding.top << "; " << padding.right << "; " << padding.bottom << "]"; } -struct Region final -{ +struct Region final { Pos pos; Dim dim; }; @@ -129,17 +129,18 @@ operator==(Region const& lhs, Region const& rhs) } inline std::ostream& -operator<<(std::ostream& os, Region const& region) { +operator<<(std::ostream& os, Region const& region) +{ return os << "[" << region.pos << " " << region.dim << "]"; } -struct Distance final -{ +struct Distance final { int dx; int dy; }; inline std::ostream& -operator<<(std::ostream& os, Distance const& dist) { +operator<<(std::ostream& os, Distance const& dist) +{ return os << "𝛿(" << dist.dx << ", " << dist.dy << ")"; } diff --git a/include/kranewl/input/keyboard.hh b/include/kranewl/input/keyboard.hh @@ -7,9 +7,11 @@ extern "C" { class Server; struct Keyboard { struct wl_list link; + Server* server; + struct wlr_input_device* device; - struct wl_listener modifiers; - struct wl_listener key; + struct wl_listener l_modifiers; + struct wl_listener l_key; }; diff --git a/include/kranewl/server.hh b/include/kranewl/server.hh @@ -1,5 +1,7 @@ #pragma once +#include <kranewl/geometry.hh> + extern "C" { #include <wlr/backend.h> #include <wlr/util/box.h> @@ -26,7 +28,12 @@ public: private: static void new_output(struct wl_listener*, void*); + static void output_manager_apply(struct wl_listener*, void*); + static void output_manager_test(struct wl_listener*, void*); + static void new_xdg_surface(struct wl_listener*, void*); + static void new_layer_shell_surface(struct wl_listener*, void*); + static void new_input(struct wl_listener*, void*); static void new_pointer(Server*, struct wlr_input_device*); static void new_keyboard(Server*, struct wlr_input_device*); @@ -36,16 +43,18 @@ private: static void cursor_axis(struct wl_listener*, void*); static void cursor_button(struct wl_listener*, void*); static void cursor_frame(struct wl_listener*, void*); + static void request_set_cursor(struct wl_listener*, void*); static void cursor_process_motion(Server*, uint32_t); static void cursor_process_move(Server*, uint32_t); static void cursor_process_resize(Server*, uint32_t); + static void request_start_drag(struct wl_listener*, void*); + static void start_drag(struct wl_listener*, void*); static void keyboard_handle_modifiers(struct wl_listener*, void*); static void keyboard_handle_key(struct wl_listener*, void*); static bool keyboard_handle_keybinding(Server*, xkb_keysym_t); - - static void seat_request_cursor(struct wl_listener*, void*); - static void seat_request_set_selection(struct wl_listener*, void*); + static void request_set_selection(struct wl_listener*, void*); + static void request_set_primary_selection(struct wl_listener*, void*); static void output_frame(struct wl_listener*, void*); static View* desktop_view_at(Server*, double, double, struct wlr_surface**, double*, double*); @@ -59,28 +68,51 @@ private: static void xdg_toplevel_handle_moveresize(View*, CursorMode, uint32_t); struct wl_display* m_display; + struct wlr_backend* m_backend; struct wlr_renderer* m_renderer; struct wlr_allocator* m_allocator; - struct wlr_scene* m_scene; + struct wlr_compositor* m_compositor; + struct wlr_data_device_manager* m_data_device_manager; + struct wlr_scene* m_scene; struct wlr_xdg_shell* m_xdg_shell; - struct wl_listener m_new_xdg_surface; + struct wl_listener ml_new_xdg_surface; + struct wl_listener ml_new_layer_shell_surface; struct wl_list m_views; + struct wlr_seat* m_seat; + struct wlr_presentation* m_presentation; + struct wlr_idle* m_idle; + + struct wlr_server_decoration_manager* m_server_decoration_manager; + struct wlr_xdg_decoration_manager_v1* m_xdg_decoration_manager; + + struct wlr_output_manager_v1* m_output_manager; + struct wlr_input_inhibit_manager* m_input_inhibit_manager; + struct wlr_keyboard_shortcuts_inhibit_manager_v1* m_keyboard_shortcuts_inhibit_manager; + + struct wlr_pointer_constraints_v1* m_pointer_constraints; + struct wlr_relative_pointer_manager_v1* m_relative_pointer_manager; + struct wlr_virtual_pointer_manager_v1* m_virtual_pointer_manager; + struct wlr_virtual_keyboard_manager_v1* m_virtual_keyboard_manager; + struct wlr_cursor* m_cursor; struct wlr_xcursor_manager* m_cursor_mgr; - struct wl_listener m_cursor_motion; - struct wl_listener m_cursor_motion_absolute; - struct wl_listener m_cursor_button; - struct wl_listener m_cursor_axis; - struct wl_listener m_cursor_frame; + struct wl_listener ml_cursor_motion; + struct wl_listener ml_cursor_motion_absolute; + struct wl_listener ml_cursor_button; + struct wl_listener ml_cursor_axis; + struct wl_listener ml_cursor_frame; + struct wl_listener ml_request_set_cursor; + struct wl_listener ml_request_start_drag; + struct wl_listener ml_start_drag; - struct wlr_seat* m_seat; - struct wl_listener m_new_input; - struct wl_listener m_request_cursor; - struct wl_listener m_request_set_selection; struct wl_list m_keyboards; + struct wl_listener ml_new_input; + struct wl_listener ml_request_set_selection; + struct wl_listener ml_request_set_primary_selection; + CursorMode m_cursor_mode; View* m_grabbed_view; double m_grab_x, m_grab_y; @@ -89,7 +121,9 @@ private: struct wlr_output_layout* m_output_layout; struct wl_list m_outputs; - struct wl_listener m_new_output; + struct wl_listener ml_new_output; + struct wl_listener ml_output_manager_apply; + struct wl_listener ml_output_manager_test; const std::string m_socket; diff --git a/include/kranewl/tree/output.hh b/include/kranewl/tree/output.hh @@ -7,7 +7,9 @@ extern "C" { class Server; struct Output { struct wl_list link; + Server* server; + struct wlr_output* wlr_output; - struct wl_listener frame; + struct wl_listener l_frame; }; diff --git a/include/kranewl/tree/surface.hh b/include/kranewl/tree/surface.hh @@ -0,0 +1,13 @@ +#pragma once + +enum class SurfaceType { + XDGShell, + LayerShell, + X11Managed, + X11Unmanaged +}; + +union Surface { + struct wlr_xdg_surface* xdg; + struct wlr_xwayland_surface* xwayland; +}; diff --git a/include/kranewl/tree/view.hh b/include/kranewl/tree/view.hh @@ -7,13 +7,17 @@ extern "C" { class Server; struct View { struct wl_list link; + Server* server; + struct wlr_xdg_surface* xdg_surface; struct wlr_scene_node* scene_node; - struct wl_listener map; - struct wl_listener unmap; - struct wl_listener destroy; - struct wl_listener request_move; - struct wl_listener request_resize; + + struct wl_listener l_map; + struct wl_listener l_unmap; + struct wl_listener l_destroy; + struct wl_listener l_request_move; + struct wl_listener l_request_resize; + int x, y; }; diff --git a/include/version.hh b/include/version.hh @@ -1 +1 @@ -#define VERSION "master/3e4771f+" -\ No newline at end of file +#define VERSION "master/79fe788+" +\ No newline at end of file diff --git a/src/kranewl/client.cc b/src/kranewl/client.cc @@ -0,0 +1,186 @@ +#include <kranewl/client.hh> + +Client::Client( + Surface surface, + Partition_ptr partition, + Context_ptr context, + Workspace_ptr workspace, + std::optional<Pid> pid, + std::optional<Pid> ppid +) + : surface(surface), + partition(partition), + context(context), + workspace(workspace), + free_region({}), + tile_region({}), + active_region({}), + previous_region({}), + inner_region({}), + tile_decoration({}), + free_decoration({}), + active_decoration({}), + parent(nullptr), + children({}), + producer(nullptr), + consumers({}), + focused(false), + mapped(false), + managed(true), + urgent(false), + floating(false), + fullscreen(false), + contained(false), + invincible(false), + sticky(false), + iconifyable(true), + iconified(false), + disowned(false), + producing(true), + attaching(false), + pid(pid), + ppid(ppid), + last_focused(std::chrono::steady_clock::now()), + managed_since(std::chrono::steady_clock::now()), + m_outside_state(OutsideState::Unfocused) +{} + +Client::~Client() +{} + +Client::OutsideState +Client::get_outside_state() const noexcept +{ + if (urgent) + return Client::OutsideState::Urgent; + + return m_outside_state; +} + +void +Client::focus() noexcept +{ + focused = true; + last_focused = std::chrono::steady_clock::now(); + + switch (m_outside_state) { + case OutsideState::Unfocused: m_outside_state = OutsideState::Focused; return; + case OutsideState::UnfocusedDisowned: m_outside_state = OutsideState::FocusedDisowned; return; + case OutsideState::UnfocusedSticky: m_outside_state = OutsideState::FocusedSticky; return; + default: return; + } +} + +void +Client::unfocus() noexcept +{ + focused = false; + + switch (m_outside_state) { + case OutsideState::Focused: m_outside_state = OutsideState::Unfocused; return; + case OutsideState::FocusedDisowned: m_outside_state = OutsideState::UnfocusedDisowned; return; + case OutsideState::FocusedSticky: m_outside_state = OutsideState::UnfocusedSticky; return; + default: return; + } +} + +void +Client::stick() noexcept +{ + sticky = true; + + switch (m_outside_state) { + case OutsideState::Focused: m_outside_state = OutsideState::FocusedSticky; return; + case OutsideState::Unfocused: m_outside_state = OutsideState::UnfocusedSticky; return; + default: return; + } +} + +void +Client::unstick() noexcept +{ + sticky = false; + + switch (m_outside_state) { + case OutsideState::FocusedSticky: m_outside_state = OutsideState::Focused; return; + case OutsideState::UnfocusedSticky: m_outside_state = OutsideState::Unfocused; return; + default: return; + } +} + +void +Client::disown() noexcept +{ + disowned = true; + + switch (m_outside_state) { + case OutsideState::Focused: m_outside_state = OutsideState::FocusedDisowned; return; + case OutsideState::Unfocused: m_outside_state = OutsideState::UnfocusedDisowned; return; + default: return; + } +} + +void +Client::reclaim() noexcept +{ + disowned = false; + + switch (m_outside_state) { + case OutsideState::FocusedDisowned: m_outside_state = OutsideState::Focused; return; + case OutsideState::UnfocusedDisowned: m_outside_state = OutsideState::Unfocused; return; + default: return; + } +} + +void +Client::set_tile_region(Region& region) noexcept +{ + tile_region = region; + set_active_region(region); +} + +void +Client::set_free_region(Region& region) noexcept +{ + free_region = region; + set_active_region(region); +} + +void +Client::set_active_region(Region& region) noexcept +{ + previous_region = active_region; + set_inner_region(region); + active_region = region; +} + +void +Client::set_tile_decoration(Decoration const& decoration) noexcept +{ + tile_decoration = decoration; + active_decoration = decoration; +} + +void +Client::set_free_decoration(Decoration const& decoration) noexcept +{ + free_decoration = decoration; + active_decoration = decoration; +} + +void +Client::set_inner_region(Region& region) noexcept +{ + if (active_decoration.frame) { + Frame const& frame = *active_decoration.frame; + + inner_region.pos.x = frame.extents.left; + inner_region.pos.y = frame.extents.top; + inner_region.dim.w = region.dim.w - frame.extents.left - frame.extents.right; + inner_region.dim.h = region.dim.h - frame.extents.top - frame.extents.bottom; + } else { + inner_region.pos.x = 0; + inner_region.pos.y = 0; + inner_region.dim = region.dim; + } +} diff --git a/src/kranewl/main.cc b/src/kranewl/main.cc @@ -8,6 +8,7 @@ #include <kranewl/conf/options.hh> #include <kranewl/model.hh> #include <kranewl/server.hh> +#include <kranewl/decoration.hh> #include <spdlog/spdlog.h> diff --git a/src/kranewl/server.cc b/src/kranewl/server.cc @@ -11,6 +11,7 @@ #include <wayland-util.h> // https://github.com/swaywm/wlroots/issues/682 +#include <pthread.h> #define class class_ #define namespace namespace_ #define static @@ -21,14 +22,27 @@ extern "C" { #include <wlr/types/wlr_compositor.h> #include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_data_device.h> +#include <wlr/types/wlr_idle.h> #include <wlr/types/wlr_input_device.h> +#include <wlr/types/wlr_input_inhibitor.h> #include <wlr/types/wlr_keyboard.h> +#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h> #include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output_layout.h> +#include <wlr/types/wlr_output_management_v1.h> #include <wlr/types/wlr_pointer.h> +#include <wlr/types/wlr_pointer_constraints_v1.h> +#include <wlr/types/wlr_presentation_time.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_seat.h> +#include <wlr/types/wlr_server_decoration.h> +#include <wlr/types/wlr_virtual_keyboard_v1.h> +#include <wlr/types/wlr_virtual_pointer_v1.h> #include <wlr/types/wlr_xcursor_manager.h> +#include <wlr/types/wlr_xdg_decoration_v1.h> +#include <wlr/types/wlr_xdg_output_v1.h> #include <wlr/types/wlr_xdg_shell.h> #include <wlr/util/box.h> #ifdef WLR_HAS_XWAYLAND @@ -55,24 +69,37 @@ Server::Server() return renderer; }(m_display, m_backend)), m_allocator(wlr_allocator_autocreate(m_backend, m_renderer)), + ml_new_xdg_surface({ .notify = Server::new_xdg_surface }), + ml_new_layer_shell_surface({ .notify = Server::new_layer_shell_surface }), + ml_cursor_motion({ .notify = Server::cursor_motion }), + ml_cursor_motion_absolute({ .notify = Server::cursor_motion_absolute }), + ml_cursor_button({ .notify = Server::cursor_button }), + ml_cursor_axis({ .notify = Server::cursor_axis }), + ml_cursor_frame({ .notify = Server::cursor_frame }), + ml_request_set_cursor({ .notify = Server::request_set_cursor }), + ml_request_start_drag({ .notify = Server::request_start_drag }), + ml_start_drag({ .notify = Server::start_drag }), + ml_new_input({ .notify = Server::new_input }), + ml_request_set_selection({ .notify = Server::request_set_selection }), + ml_new_output({ .notify = Server::new_output }), + ml_output_manager_apply({ .notify = Server::output_manager_apply }), + ml_output_manager_test({ .notify = Server::output_manager_test }), m_socket(wl_display_add_socket_auto(m_display)) { - wlr_compositor_create(m_display, m_renderer); - wlr_data_device_manager_create(m_display); + m_compositor = wlr_compositor_create(m_display, m_renderer); + m_data_device_manager = wlr_data_device_manager_create(m_display); m_output_layout = wlr_output_layout_create(); wl_list_init(&m_outputs); - m_new_output.notify = Server::new_output; - wl_signal_add(&m_backend->events.new_output, &m_new_output); + wl_signal_add(&m_backend->events.new_output, &ml_new_output); m_scene = wlr_scene_create(); wlr_scene_attach_output_layout(m_scene, m_output_layout); wl_list_init(&m_views); m_xdg_shell = wlr_xdg_shell_create(m_display); - m_new_xdg_surface.notify = Server::new_xdg_surface; - wl_signal_add(&m_xdg_shell->events.new_surface, &m_new_xdg_surface); + wl_signal_add(&m_xdg_shell->events.new_surface, &ml_new_xdg_surface); m_cursor = wlr_cursor_create(); wlr_cursor_attach_output_layout(m_cursor, m_output_layout); @@ -80,30 +107,47 @@ Server::Server() m_cursor_mgr = wlr_xcursor_manager_create(NULL, 24); wlr_xcursor_manager_load(m_cursor_mgr, 1); - { // set up cursor signals - m_cursor_motion.notify = Server::cursor_motion; - wl_signal_add(&m_cursor->events.motion, &m_cursor_motion); - m_cursor_motion_absolute.notify = Server::cursor_motion_absolute; - wl_signal_add(&m_cursor->events.motion_absolute, &m_cursor_motion_absolute); - m_cursor_button.notify = Server::cursor_button; - wl_signal_add(&m_cursor->events.button, &m_cursor_button); - m_cursor_axis.notify = Server::cursor_axis; - wl_signal_add(&m_cursor->events.axis, &m_cursor_axis); - m_cursor_frame.notify = Server::cursor_frame; - wl_signal_add(&m_cursor->events.frame, &m_cursor_frame); + m_seat = wlr_seat_create(m_display, "seat0"); + m_presentation = wlr_presentation_create(m_display, m_backend); + m_idle = wlr_idle_create(m_display); + + { // set up cursor handling + wl_signal_add(&m_cursor->events.motion, &ml_cursor_motion); + wl_signal_add(&m_cursor->events.motion_absolute, &ml_cursor_motion_absolute); + wl_signal_add(&m_cursor->events.button, &ml_cursor_button); + wl_signal_add(&m_cursor->events.axis, &ml_cursor_axis); + wl_signal_add(&m_cursor->events.frame, &ml_cursor_frame); } - { // set up keyboard signals + { // set up keyboard handling wl_list_init(&m_keyboards); - m_new_input.notify = Server::new_input; - wl_signal_add(&m_backend->events.new_input, &m_new_input); - m_seat = wlr_seat_create(m_display, "seat0"); - m_request_cursor.notify = Server::seat_request_cursor; - wl_signal_add(&m_seat->events.request_set_cursor, &m_request_cursor); - m_request_set_selection.notify = Server::seat_request_set_selection; - wl_signal_add(&m_seat->events.request_set_selection, &m_request_set_selection); + wl_signal_add(&m_backend->events.new_input, &ml_new_input); + wl_signal_add(&m_seat->events.request_set_cursor, &ml_request_set_cursor); + wl_signal_add(&m_seat->events.request_set_selection, &ml_request_set_selection); + wl_signal_add(&m_seat->events.request_set_primary_selection, &ml_request_set_primary_selection); } + m_server_decoration_manager = wlr_server_decoration_manager_create(m_display); + m_xdg_decoration_manager = wlr_xdg_decoration_manager_v1_create(m_display); + + wlr_server_decoration_manager_set_default_mode( + m_server_decoration_manager, + WLR_SERVER_DECORATION_MANAGER_MODE_SERVER + ); + + wlr_xdg_output_manager_v1_create(m_display, m_output_layout); + m_output_manager = wlr_output_manager_v1_create(m_display); + wl_signal_add(&m_output_manager->events.apply, &ml_output_manager_apply); + wl_signal_add(&m_output_manager->events.test, &ml_output_manager_test); + + m_input_inhibit_manager = wlr_input_inhibit_manager_create(m_display); + m_keyboard_shortcuts_inhibit_manager = wlr_keyboard_shortcuts_inhibit_v1_create(m_display); + + m_pointer_constraints = wlr_pointer_constraints_v1_create(m_display); + m_relative_pointer_manager = wlr_relative_pointer_manager_v1_create(m_display); + m_virtual_pointer_manager = wlr_virtual_pointer_manager_v1_create(m_display); + m_virtual_keyboard_manager = wlr_virtual_keyboard_manager_v1_create(m_display); + if (m_socket.empty()) { wlr_backend_destroy(m_backend); std::exit(1); @@ -118,6 +162,11 @@ Server::Server() } 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); } @@ -136,7 +185,7 @@ Server::start() noexcept void Server::new_output(struct wl_listener* listener, void* data) { - Server* server = wl_container_of(listener, server, m_new_output); + Server* server = wl_container_of(listener, server, ml_new_output); struct wlr_output* wlr_output = reinterpret_cast<struct wlr_output*>(data); @@ -154,17 +203,29 @@ Server::new_output(struct wl_listener* listener, void* data) Output* output = reinterpret_cast<Output*>(calloc(1, sizeof(Output))); output->wlr_output = wlr_output; output->server = server; - output->frame.notify = Server::output_frame; - wl_signal_add(&wlr_output->events.frame, &output->frame); + output->l_frame.notify = Server::output_frame; + wl_signal_add(&wlr_output->events.frame, &output->l_frame); wl_list_insert(&server->m_outputs, &output->link); wlr_output_layout_add_auto(server->m_output_layout, wlr_output); } void +Server::output_manager_apply(struct wl_listener* listener, void* data) +{ + // TODO +} + +void +Server::output_manager_test(struct wl_listener* listener, void* data) +{ + // TODO +} + +void Server::new_xdg_surface(struct wl_listener* listener, void* data) { - Server* server = wl_container_of(listener, server, m_new_xdg_surface); + Server* server = wl_container_of(listener, server, ml_new_xdg_surface); struct wlr_xdg_surface* xdg_surface = reinterpret_cast<struct wlr_xdg_surface*>(data); @@ -190,24 +251,30 @@ Server::new_xdg_surface(struct wl_listener* listener, void* data) view->scene_node->data = view; xdg_surface->data = view->scene_node; - view->map.notify = xdg_toplevel_map; - wl_signal_add(&xdg_surface->events.map, &view->map); - view->unmap.notify = xdg_toplevel_unmap; - wl_signal_add(&xdg_surface->events.unmap, &view->unmap); - view->destroy.notify = xdg_toplevel_destroy; - wl_signal_add(&xdg_surface->events.destroy, &view->destroy); + view->l_map.notify = xdg_toplevel_map; + wl_signal_add(&xdg_surface->events.map, &view->l_map); + view->l_unmap.notify = xdg_toplevel_unmap; + wl_signal_add(&xdg_surface->events.unmap, &view->l_unmap); + view->l_destroy.notify = xdg_toplevel_destroy; + wl_signal_add(&xdg_surface->events.destroy, &view->l_destroy); struct wlr_xdg_toplevel* toplevel = xdg_surface->toplevel; - view->request_move.notify = xdg_toplevel_request_move; - wl_signal_add(&toplevel->events.request_move, &view->request_move); - view->request_resize.notify = xdg_toplevel_request_resize; - wl_signal_add(&toplevel->events.request_resize, &view->request_resize); + view->l_request_move.notify = xdg_toplevel_request_move; + wl_signal_add(&toplevel->events.request_move, &view->l_request_move); + view->l_request_resize.notify = xdg_toplevel_request_resize; + wl_signal_add(&toplevel->events.request_resize, &view->l_request_resize); +} + +void +Server::new_layer_shell_surface(struct wl_listener* listener, void* data) +{ + // TODO } void Server::new_input(struct wl_listener* listener, void* data) { - Server* server = wl_container_of(listener, server, m_new_input); + Server* server = wl_container_of(listener, server, ml_new_input); struct wlr_input_device* device = reinterpret_cast<struct wlr_input_device*>(data); switch (device->type) { @@ -253,10 +320,10 @@ Server::new_keyboard(Server* server, struct wlr_input_device* device) xkb_context_unref(context); wlr_keyboard_set_repeat_info(device->keyboard, 25, 600); - keyboard->modifiers.notify = keyboard_handle_modifiers; - wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); - keyboard->key.notify = keyboard_handle_key; - wl_signal_add(&device->keyboard->events.key, &keyboard->key); + keyboard->l_modifiers.notify = keyboard_handle_modifiers; + wl_signal_add(&device->keyboard->events.modifiers, &keyboard->l_modifiers); + keyboard->l_key.notify = keyboard_handle_key; + wl_signal_add(&device->keyboard->events.key, &keyboard->l_key); wlr_seat_set_keyboard(server->m_seat, device); wl_list_insert(&server->m_keyboards, &keyboard->link); @@ -265,7 +332,7 @@ Server::new_keyboard(Server* server, struct wlr_input_device* device) void Server::cursor_motion(struct wl_listener* listener, void* data) { - Server* server = wl_container_of(listener, server, m_cursor_motion); + Server* server = wl_container_of(listener, server, ml_cursor_motion); struct wlr_event_pointer_motion* event = reinterpret_cast<wlr_event_pointer_motion*>(data); @@ -276,7 +343,7 @@ Server::cursor_motion(struct wl_listener* listener, void* data) void Server::cursor_motion_absolute(struct wl_listener* listener, void* data) { - Server* server = wl_container_of(listener, server, m_cursor_motion_absolute); + Server* server = wl_container_of(listener, server, ml_cursor_motion_absolute); struct wlr_event_pointer_motion_absolute* event = reinterpret_cast<wlr_event_pointer_motion_absolute*>(data); @@ -287,7 +354,7 @@ Server::cursor_motion_absolute(struct wl_listener* listener, void* data) void Server::cursor_button(struct wl_listener* listener, void* data) { - Server* server = wl_container_of(listener, server, m_cursor_button); + Server* server = wl_container_of(listener, server, ml_cursor_button); struct wlr_event_pointer_button* event = reinterpret_cast<wlr_event_pointer_button*>(data); @@ -320,7 +387,7 @@ Server::cursor_button(struct wl_listener* listener, void* data) void Server::cursor_axis(struct wl_listener* listener, void* data) { - Server* server = wl_container_of(listener, server, m_cursor_axis); + Server* server = wl_container_of(listener, server, ml_cursor_axis); struct wlr_event_pointer_axis* event = reinterpret_cast<wlr_event_pointer_axis*>(data); @@ -338,12 +405,30 @@ Server::cursor_axis(struct wl_listener* listener, void* data) void Server::cursor_frame(struct wl_listener* listener, void* data) { - Server* server = wl_container_of(listener, server, m_cursor_frame); + Server* server = wl_container_of(listener, server, ml_cursor_frame); wlr_seat_pointer_notify_frame(server->m_seat); } void +Server::request_set_cursor(struct wl_listener* listener, void* data) +{ + Server* server = wl_container_of(listener, server, ml_request_set_cursor); + + struct wlr_seat_pointer_request_set_cursor_event* event + = reinterpret_cast<struct wlr_seat_pointer_request_set_cursor_event*>(data); + struct wlr_seat_client* focused_client = server->m_seat->pointer_state.focused_client; + + if (focused_client == event->seat_client) + wlr_cursor_set_surface( + server->m_cursor, + event->surface, + event->hotspot_x, + event->hotspot_y + ); +} + +void Server::cursor_process_motion(Server* server, uint32_t time) { switch (server->m_cursor_mode) { @@ -439,9 +524,21 @@ Server::cursor_process_resize(Server* server, uint32_t time) } void +Server::request_start_drag(struct wl_listener*, void*) +{ + +} + +void +Server::start_drag(struct wl_listener*, void*) +{ + +} + +void Server::keyboard_handle_modifiers(struct wl_listener* listener, void* data) { - Keyboard* keyboard = wl_container_of(listener, keyboard, modifiers); + Keyboard* keyboard = wl_container_of(listener, keyboard, l_modifiers); wlr_seat_set_keyboard(keyboard->server->m_seat, keyboard->device); wlr_seat_keyboard_notify_modifiers( @@ -453,7 +550,7 @@ Server::keyboard_handle_modifiers(struct wl_listener* listener, void* data) void Server::keyboard_handle_key(struct wl_listener* listener, void* data) { - Keyboard* keyboard = wl_container_of(listener, keyboard, key); + Keyboard* keyboard = wl_container_of(listener, keyboard, l_key); Server* server = keyboard->server; struct wlr_event_keyboard_key* event @@ -517,27 +614,9 @@ Server::keyboard_handle_keybinding(Server* server, xkb_keysym_t sym) } void -Server::seat_request_cursor(struct wl_listener* listener, void* data) -{ - Server* server = wl_container_of(listener, server, m_request_cursor); - - struct wlr_seat_pointer_request_set_cursor_event* event - = reinterpret_cast<struct wlr_seat_pointer_request_set_cursor_event*>(data); - struct wlr_seat_client* focused_client = server->m_seat->pointer_state.focused_client; - - if (focused_client == event->seat_client) - wlr_cursor_set_surface( - server->m_cursor, - event->surface, - event->hotspot_x, - event->hotspot_y - ); -} - -void -Server::seat_request_set_selection(struct wl_listener* listener, void* data) +Server::request_set_selection(struct wl_listener* listener, void* data) { - Server* server = wl_container_of(listener, server, m_request_set_selection); + Server* server = wl_container_of(listener, server, ml_request_set_selection); struct wlr_seat_request_set_selection_event* event = reinterpret_cast<struct wlr_seat_request_set_selection_event*>(data); @@ -548,7 +627,7 @@ Server::seat_request_set_selection(struct wl_listener* listener, void* data) void Server::output_frame(struct wl_listener* listener, void* data) { - Output* output = wl_container_of(listener, output, frame); + Output* output = wl_container_of(listener, output, l_frame); struct wlr_scene* scene = output->server->m_scene; struct wlr_scene_output* scene_output @@ -627,7 +706,7 @@ Server::focus_view(View* view, struct wlr_surface* surface) void Server::xdg_toplevel_map(struct wl_listener* listener, void* data) { - View* view = wl_container_of(listener, view, map); + View* view = wl_container_of(listener, view, l_map); wl_list_insert(&view->server->m_views, &view->link); focus_view(view, view->xdg_surface->surface); @@ -636,20 +715,20 @@ Server::xdg_toplevel_map(struct wl_listener* listener, void* data) void Server::xdg_toplevel_unmap(struct wl_listener* listener, void* data) { - View* view = wl_container_of(listener, view, unmap); + View* view = wl_container_of(listener, view, l_unmap); wl_list_remove(&view->link); } void Server::xdg_toplevel_destroy(struct wl_listener* listener, void* data) { - View* view = wl_container_of(listener, view, destroy); + View* view = wl_container_of(listener, view, l_destroy); - wl_list_remove(&view->map.link); - wl_list_remove(&view->unmap.link); - wl_list_remove(&view->destroy.link); - wl_list_remove(&view->request_move.link); - wl_list_remove(&view->request_resize.link); + wl_list_remove(&view->l_map.link); + wl_list_remove(&view->l_unmap.link); + wl_list_remove(&view->l_destroy.link); + wl_list_remove(&view->l_request_move.link); + wl_list_remove(&view->l_request_resize.link); free(view); } @@ -657,7 +736,7 @@ Server::xdg_toplevel_destroy(struct wl_listener* listener, void* data) void Server::xdg_toplevel_request_move(struct wl_listener* listener, void* data) { - View* view = wl_container_of(listener, view, request_move); + View* view = wl_container_of(listener, view, l_request_move); xdg_toplevel_handle_moveresize(view, Server::CursorMode::Move, 0); } @@ -667,7 +746,7 @@ Server::xdg_toplevel_request_resize(struct wl_listener* listener, void* data) struct wlr_xdg_toplevel_resize_event* event = reinterpret_cast<struct wlr_xdg_toplevel_resize_event*>(data); - View* view = wl_container_of(listener, view, request_resize); + View* view = wl_container_of(listener, view, l_request_resize); xdg_toplevel_handle_moveresize(view, Server::CursorMode::Resize, event->edges); }