commit 9561b895db55cf5acb38d948564d511ebd0b6a4a
parent 79fe78836bbd78fdeb49ac4e00333d19e83f7671
Author: deurzen <m.deurzen@tum.de>
Date: Thu, 19 May 2022 01:23:44 +0200
adds signals
Diffstat:
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);
}