commit e75f96ea3604a6a9ef9b2b8402100f1f046b4957
parent 41f30261047f42b328fd2068b2486b496d1eb56d
Author: deurzen <m.deurzen@tum.de>
Date: Fri, 20 May 2022 16:06:37 +0200
adds to server->server/model overhaul
Diffstat:
28 files changed, 1195 insertions(+), 687 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -136,8 +136,16 @@ add_custom_target(run ALL
DEPENDS ${CMAKE_SOURCE_DIR}/include/protocols/pointer-constraints-unstable-v1-protocol.h
)
+set_source_files_properties(tags PROPERTIES GENERATED true)
+add_custom_command (OUTPUT tags
+ COMMAND git ls-files | ctags -R --exclude=.git --c++-kinds=+p --links=no --fields=+iaS --extras=+q -L-
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ COMMENT "Generating project tags"
+)
+
add_executable(kranewl
${KRANEWL_SOURCES}
+ tags
)
add_executable(kranec
diff --git a/Makefile b/Makefile
@@ -9,5 +9,6 @@ test: kranewl
.PHONY: clean
clean:
+ @rm -rf ./tags
@rm -rf ./build
@rm -f ./include/protocols/*
diff --git a/include/kranewl/bindings.hh b/include/kranewl/bindings.hh
@@ -1,5 +1,8 @@
#pragma once
+#include <kranewl/input/keyboard.hh>
+#include <kranewl/input/mouse.hh>
+
#include <functional>
#include <optional>
#include <cstdint>
@@ -9,16 +12,16 @@ typedef class Client* Client_ptr;
typedef
std::function<void(Model&)>
- KeyAction;
+ KeyboardAction;
typedef
std::function<bool(Model&, Client_ptr)>
MouseAction;
typedef
- std::unordered_map<uint32_t, KeyAction>
+ std::unordered_map<KeyboardInput, KeyboardAction>
KeyBindings;
typedef
- std::unordered_map<uint32_t, MouseAction>
+ std::unordered_map<MouseInput, MouseAction>
MouseBindings;
diff --git a/include/kranewl/client.hh b/include/kranewl/client.hh
@@ -1,193 +0,0 @@
-#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 Server* Server_ptr;
-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();
- 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;
-
- struct wlr_surface* get_surface() 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;
-
- struct wl_list link;
- Server_ptr server;
-
- 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;
- struct wl_listener l_request_move;
- struct wl_listener l_request_resize;
-#ifdef XWAYLAND
- struct wl_listener l_request_activate;
- struct wl_listener l_request_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
@@ -1,8 +1,10 @@
#pragma once
#include <cstddef>
+#include <cstdint>
typedef unsigned Pid;
+typedef std::uintptr_t Uid;
typedef std::size_t Ident;
typedef std::size_t Index;
diff --git a/include/kranewl/context.hh b/include/kranewl/context.hh
@@ -0,0 +1,184 @@
+#pragma once
+
+#include <kranewl/common.hh>
+#include <kranewl/cycle.hh>
+
+#include <string>
+#include <unordered_set>
+
+typedef class Client* Client_ptr;
+typedef class Workspace* Workspace_ptr;
+typedef class Output* Output_ptr;
+typedef class Context final
+{
+public:
+ Context(Index index, std::string name)
+ : m_index(index),
+ m_name(name),
+ mp_output(nullptr),
+ mp_active(nullptr),
+ mp_prev_active(nullptr),
+ m_workspaces({}, true)
+ {}
+
+ Index
+ index() const
+ {
+ return m_index;
+ }
+
+ std::string const&
+ name() const
+ {
+ return m_name;
+ }
+
+ std::size_t
+ size() const
+ {
+ return m_workspaces.size();
+ }
+
+ Workspace_ptr
+ workspace() const
+ {
+ return mp_active;
+ }
+
+ Workspace_ptr
+ prev_workspace() const
+ {
+ return mp_prev_active;
+ }
+
+ Output_ptr
+ output() const
+ {
+ return mp_output;
+ }
+
+ bool
+ is_outputed() const
+ {
+ return mp_output != nullptr;
+ }
+
+ void
+ set_output(Output_ptr output)
+ {
+ mp_output = output;
+ }
+
+ void
+ register_workspace(Workspace_ptr workspace)
+ {
+ m_workspaces.insert_at_back(workspace);
+ }
+
+ void
+ activate_workspace(Index index)
+ {
+ Workspace_ptr prev_active = mp_active;
+ m_workspaces.activate_at_index(index);
+ mp_active = *m_workspaces.active_element();
+
+ if (prev_active != mp_active)
+ mp_prev_active = prev_active;
+ }
+
+ void
+ activate_workspace(Workspace_ptr workspace)
+ {
+ Workspace_ptr prev_active = mp_active;
+ m_workspaces.activate_element(workspace);
+ mp_active = workspace;
+
+ if (prev_active != mp_active)
+ mp_prev_active = prev_active;
+ }
+
+ Cycle<Workspace_ptr> const&
+ workspaces() const
+ {
+ return m_workspaces;
+ }
+
+ void
+ register_sticky_client(Client_ptr client)
+ {
+ m_sticky_clients.insert(client);
+ }
+
+ void
+ unregister_sticky_client(Client_ptr client)
+ {
+ m_sticky_clients.erase(client);
+ }
+
+ std::unordered_set<Client_ptr> const&
+ sticky_clients() const
+ {
+ return m_sticky_clients;
+ }
+
+ std::deque<Workspace_ptr>::iterator
+ begin()
+ {
+ return m_workspaces.begin();
+ }
+
+ std::deque<Workspace_ptr>::const_iterator
+ begin() const
+ {
+ return m_workspaces.begin();
+ }
+
+ std::deque<Workspace_ptr>::const_iterator
+ cbegin() const
+ {
+ return m_workspaces.cbegin();
+ }
+
+ std::deque<Workspace_ptr>::iterator
+ end()
+ {
+ return m_workspaces.end();
+ }
+
+ std::deque<Workspace_ptr>::const_iterator
+ end() const
+ {
+ return m_workspaces.end();
+ }
+
+ std::deque<Workspace_ptr>::const_iterator
+ cend() const
+ {
+ return m_workspaces.cend();
+ }
+
+ Workspace_ptr
+ operator[](std::size_t i)
+ {
+ return m_workspaces[i];
+ }
+
+ Workspace_ptr
+ operator[](std::size_t i) const
+ {
+ return m_workspaces[i];
+ }
+
+private:
+ Index m_index;
+ std::string m_name;
+
+ Output_ptr mp_output;
+
+ Workspace_ptr mp_active;
+ Workspace_ptr mp_prev_active;
+
+ Cycle<Workspace_ptr> m_workspaces;
+ std::unordered_set<Client_ptr> m_sticky_clients;
+
+}* Context_ptr;
diff --git a/include/kranewl/decoration.hh b/include/kranewl/decoration.hh
@@ -40,6 +40,16 @@ struct ColorScheme final {
RGBA urgent;
};
+const static ColorScheme DEFAULT_COLOR_SCHEME = ColorScheme{
+ .focused = {0x8181A6FF},
+ .fdisowned = {0xc1c1c1FF},
+ .fsticky = {0x5F8787FF},
+ .unfocused = {0x333333FF},
+ .udisowned = {0x999999FF},
+ .usticky = {0x444444FF},
+ .urgent = {0x87875FFF},
+};
+
struct Frame final {
Extents extents;
ColorScheme colorscheme;
@@ -56,3 +66,14 @@ struct Decoration final {
return Extents{0, 0, 0, 0};
}
};
+
+const Decoration NO_DECORATION = Decoration{
+ std::nullopt,
+};
+
+const Decoration FREE_DECORATION = Decoration{
+ Frame {
+ Extents{ 3, 1, 1, 1 },
+ DEFAULT_COLOR_SCHEME
+ }
+};
diff --git a/include/kranewl/geometry.hh b/include/kranewl/geometry.hh
@@ -108,6 +108,15 @@ operator<<(std::ostream& os, Padding const& padding)
struct Region final {
Pos pos;
Dim dim;
+
+ void apply_minimum_dim(Dim const&);
+ void apply_extents(Extents const&);
+ void remove_extents(Extents const&);
+
+ bool contains(Pos) const;
+ bool contains(Region const&) const;
+
+ Pos center() const;
};
inline bool
diff --git a/include/kranewl/input/keyboard.hh b/include/kranewl/input/keyboard.hh
@@ -2,16 +2,39 @@
extern "C" {
#include <wlr/backend.h>
+#include <xkbcommon/xkbcommon.h>
}
-class Server;
-struct Keyboard {
- struct wl_list link;
+#include <cstdint>
+#include <unordered_set>
- Server* server;
+typedef class Server* Server_ptr;
+struct Keyboard {
+ Server_ptr p_server;
- struct wlr_input_device* device;
+ struct wl_list link;
+ struct wlr_input_device* p_device;
struct wl_listener l_modifiers;
struct wl_listener l_key;
};
+
+struct KeyboardInput {
+ uint32_t mod;
+ xkb_keysym_t keysym;
+};
+
+namespace std
+{
+ template <>
+ struct hash<KeyboardInput> {
+ std::size_t
+ operator()(KeyboardInput const& input) const
+ {
+ std::size_t mod_hash = std::hash<uint32_t>()(input.mod);
+ std::size_t key_hash = std::hash<xkb_keysym_t>()(input.keysym);
+
+ return mod_hash ^ key_hash;
+ }
+ };
+}
diff --git a/include/kranewl/input/mouse.hh b/include/kranewl/input/mouse.hh
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <cstdint>
+#include <unordered_set>
+
+struct MouseInput {
+ uint32_t mod;
+ unsigned button;
+};
+
+namespace std
+{
+ template <>
+ struct hash<MouseInput> {
+ std::size_t
+ operator()(MouseInput const& input) const
+ {
+ std::size_t mod_hash = std::hash<uint32_t>()(input.mod);
+ std::size_t button_hash = std::hash<unsigned>()(input.button);
+
+ return mod_hash ^ button_hash;
+ }
+ };
+}
diff --git a/include/kranewl/input/pointer.hh b/include/kranewl/input/pointer.hh
@@ -1,3 +0,0 @@
-#pragma once
-
-
diff --git a/include/kranewl/layout.hh b/include/kranewl/layout.hh
@@ -9,14 +9,12 @@
#include <deque>
#include <unordered_map>
-class LayoutHandler final
-{
+class LayoutHandler final {
typedef std::deque<Client_ptr>::const_iterator client_iter;
typedef std::vector<Placement>& placement_vector;
public:
- enum class LayoutKind
- {
+ enum class LayoutKind {
/// free layouts
Float,
FramelessFloat,
@@ -42,19 +40,16 @@ public:
};
private:
- typedef struct Layout final
- {
- typedef struct LayoutData final
- {
- constexpr static std::size_t MAX_MAIN_COUNT = 16;
- constexpr static std::size_t MAX_GAP_SIZE = 300;
- constexpr static Extents MAX_MARGIN
- = Extents { 700, 700, 400, 400 };
+ typedef struct Layout final {
+ typedef struct LayoutData final {
+ constexpr static int MAX_MAIN_COUNT = 16;
+ constexpr static int MAX_GAP_SIZE = 300;
+ constexpr static Extents MAX_MARGIN = Extents{700, 700, 400, 400};
LayoutData(
Extents margin,
- std::size_t gap_size,
- std::size_t main_count,
+ int gap_size,
+ int main_count,
float main_factor
)
: margin(margin),
@@ -65,10 +60,10 @@ private:
// generic layout data
Extents margin;
- std::size_t gap_size;
+ int gap_size;
// tiled layout data
- std::size_t main_count;
+ int main_count;
float main_factor;
}* LayoutData_ptr;
@@ -122,8 +117,8 @@ public:
bool layout_is_single() const;
bool layout_wraps() const;
- std::size_t gap_size() const;
- std::size_t main_count() const;
+ int gap_size() const;
+ int main_count() const;
float main_factor() const;
Extents margin() const;
@@ -140,8 +135,8 @@ public:
void reset_layout_data();
void cycle_layout_data(Direction);
- void save_layout(std::size_t) const;
- void load_layout(std::size_t);
+ void save_layout(int) const;
+ void load_layout(int);
private:
LayoutKind m_kind;
diff --git a/include/kranewl/model.hh b/include/kranewl/model.hh
@@ -1,10 +1,19 @@
#pragma once
+#include <kranewl/bindings.hh>
+#include <kranewl/common.hh>
#include <kranewl/cycle.hh>
+#include <kranewl/geometry.hh>
+#include <kranewl/tree/client.hh>
#include <optional>
#include <string>
+#include <unordered_map>
+#include <variant>
+typedef class Output* Output_ptr;
+typedef class Context* Context_ptr;
+typedef class Workspace* Workspace_ptr;
class Server;
class Config;
class Model final
@@ -16,14 +25,44 @@ public:
void run();
void exit();
+ Output_ptr create_output(Surface);
+ void register_output(Output_ptr);
+ void unregister_output(Output_ptr);
+
+ Client_ptr create_client(Surface);
+ void register_client(Client_ptr);
+ void unregister_client(Client_ptr);
+
void spawn_external(std::string&&) const;
private:
Server& m_server;
Config const& m_config;
- /* Cycle<Partition_ptr> m_partitions; */
- /* Cycle<Context_ptr> m_contexts; */
- /* Cycle<Workspace_ptr> m_workspaces; */
+ bool m_running;
+
+ Cycle<Output_ptr> m_outputs;
+ Cycle<Context_ptr> m_contexts;
+ Cycle<Workspace_ptr> m_workspaces;
+
+ Output_ptr mp_output;
+ Context_ptr mp_context;
+ Workspace_ptr mp_workspace;
+
+ Output_ptr mp_prev_output;
+ Context_ptr mp_prev_context;
+ Workspace_ptr mp_prev_workspace;
+
+ std::unordered_map<Uid, Client_ptr> m_client_map;
+ std::unordered_map<Pid, Client_ptr> m_pid_map;
+ std::unordered_map<Client_ptr, Region> m_fullscreen_map;
+
+ std::vector<Client_ptr> m_sticky_clients;
+ std::vector<Client_ptr> m_unmanaged_clients;
+
+ Client_ptr mp_focus;
+
+ KeyBindings m_key_bindings;
+ MouseBindings m_mouse_bindings;
};
diff --git a/include/kranewl/tree/client.hh b/include/kranewl/tree/client.hh
@@ -0,0 +1,188 @@
+#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 <cstdint>
+#include <optional>
+#include <string>
+#include <vector>
+
+typedef class Server* Server_ptr;
+typedef class Output* Output_ptr;
+typedef class Context* Context_ptr;
+typedef class Workspace* Workspace_ptr;
+typedef struct Client* Client_ptr;
+typedef struct Client final {
+ static constexpr Dim MIN_CLIENT_DIM = Dim{25, 10};
+ static constexpr Dim PREFERRED_INIT_CLIENT_DIM = Dim{480, 260};
+
+ 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(
+ Server_ptr server,
+ Surface surface,
+ Output_ptr output,
+ Context_ptr context,
+ Workspace_ptr workspace
+ );
+
+ ~Client();
+
+ Client(Client const&) = default;
+ Client& operator=(Client const&) = default;
+
+ OutsideState get_outside_state() const noexcept;
+
+ struct wlr_surface* get_surface() 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;
+
+ Server_ptr p_server;
+
+ Uid uid;
+ Surface surface;
+
+ struct wlr_scene_node* p_scene;
+ struct wlr_scene_node* p_scene_surface;
+ struct wlr_scene_rect* protrusions[4]; // top, bottom, left, right
+
+ std::string title;
+
+ Output_ptr p_output;
+ Context_ptr p_context;
+ Workspace_ptr p_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 p_parent;
+ std::vector<Client_ptr> children;
+ Client_ptr p_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::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;
+ struct wl_listener l_request_move;
+ struct wl_listener l_request_resize;
+#ifdef XWAYLAND
+ struct wl_listener l_request_activate;
+ struct wl_listener l_request_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/tree/output.hh b/include/kranewl/tree/output.hh
@@ -1,15 +1,86 @@
#pragma once
+#include <kranewl/common.hh>
+#include <kranewl/geometry.hh>
+#include <kranewl/context.hh>
+#include <kranewl/util.hh>
+
+#include <spdlog/spdlog.h>
+
extern "C" {
#include <wlr/backend.h>
}
-class Server;
-struct Output {
- struct wl_list link;
+typedef class Server* Server_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);
+ }
+
+private:
+ Context_ptr mp_context;
+ Region m_full_region;
+ Region m_placeable_region;
+
+public:
+ Server_ptr mp_server;
+
+ struct wlr_output* mp_wlr_output;
+ struct wlr_scene_output* mp_wlr_scene_output;
- Server* server;
+ struct wl_listener ml_frame;
+ struct wl_listener ml_destroy;
- struct wlr_output* wlr_output;
- struct wl_listener l_frame;
-};
+}* Output_ptr;
diff --git a/include/kranewl/tree/surface.hh b/include/kranewl/tree/surface.hh
@@ -1,5 +1,7 @@
#pragma once
+#include <kranewl/common.hh>
+
enum class SurfaceType {
XDGShell,
LayerShell,
@@ -7,7 +9,38 @@ enum class SurfaceType {
X11Unmanaged
};
-union Surface {
- struct wlr_xdg_surface* xdg;
- struct wlr_xwayland_surface* xwayland;
+struct Surface {
+ Surface(struct wlr_xdg_surface* xdg, bool toplevel)
+ : type{toplevel
+ ? SurfaceType::XDGShell
+ : SurfaceType::LayerShell},
+ xdg{xdg}
+ {}
+
+ Surface(struct wlr_xwayland_surface* xwayland, bool managed)
+ : type{managed
+ ? SurfaceType::X11Managed
+ : SurfaceType::X11Unmanaged},
+ xwayland{xwayland}
+ {}
+
+ Uid
+ uid() const
+ {
+ switch (type) {
+ case SurfaceType::XDGShell: // fallthrough
+ case SurfaceType::LayerShell: return reinterpret_cast<Uid>(xdg);
+ case SurfaceType::X11Managed: // fallthrough
+ case SurfaceType::X11Unmanaged: return reinterpret_cast<Uid>(xwayland);
+ default: break;
+ }
+
+ return 0;
+ }
+
+ SurfaceType type;
+ union {
+ struct wlr_xdg_surface* xdg;
+ struct wlr_xwayland_surface* xwayland;
+ };
};
diff --git a/include/kranewl/util.hh b/include/kranewl/util.hh
@@ -11,10 +11,6 @@
namespace Util
{
- void die(const std::string&&);
- void warn(const std::string&&);
- void assert(bool, const std::string&&);
-
template <
typename T,
typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type
diff --git a/include/kranewl/workspace.hh b/include/kranewl/workspace.hh
@@ -1,9 +1,10 @@
#pragma once
#include <kranewl/common.hh>
+#include <kranewl/cycle.hh>
#include <kranewl/geometry.hh>
+#include <kranewl/layout.hh>
#include <kranewl/placement.hh>
-#include <kranewl/cycle.hh>
#include <kranewl/util.hh>
typedef class Client* Client_ptr;
diff --git a/include/version.hh b/include/version.hh
@@ -1 +1 @@
-#define VERSION "master/23f214f+"
-\ No newline at end of file
+#define VERSION "master/41f3026+"
+\ No newline at end of file
diff --git a/src/kranewl/client.cc b/src/kranewl/client.cc
@@ -1,221 +0,0 @@
-#include <kranewl/client.hh>
-
-// https://github.com/swaywm/wlroots/issues/682
-#include <pthread.h>
-#define class class_
-#define namespace namespace_
-#define static
-extern "C" {
-#include <wlr/types/wlr_xdg_shell.h>
-#ifdef XWAYLAND
-#include <wlr/xwayland.h>
-#endif
-}
-#undef static
-#undef class
-#undef namespace
-
-Client::Client()
-{
- wl_list_init(&link);
-}
-
-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)
-{
- wl_list_init(&link);
-}
-
-Client::~Client()
-{}
-
-Client::OutsideState
-Client::get_outside_state() const noexcept
-{
- if (urgent)
- return Client::OutsideState::Urgent;
-
- return m_outside_state;
-}
-
-struct wlr_surface*
-Client::get_surface() noexcept
-{
- switch (surface_type) {
- case SurfaceType::XDGShell: //fallthrough
- case SurfaceType::LayerShell: return surface.xdg->surface;
- case SurfaceType::X11Managed: //fallthrough
- case SurfaceType::X11Unmanaged: return surface.xwayland->surface;
- }
-
- return nullptr;
-}
-
-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/geometry.cc b/src/kranewl/geometry.cc
@@ -1,3 +1,48 @@
#include <kranewl/geometry.hh>
+void
+Region::apply_minimum_dim(Dim const& dim)
+{
+ this->dim.w = std::max(this->dim.w, dim.w);
+ this->dim.h = std::max(this->dim.h, dim.h);
+}
+void
+Region::apply_extents(Extents const& extents)
+{
+ pos.x -= extents.left;
+ pos.y -= extents.top;
+ dim.w += extents.left + extents.right;
+ dim.h += extents.top + extents.bottom;
+}
+
+void
+Region::remove_extents(Extents const& extents)
+{
+ pos.x += extents.left;
+ pos.y += extents.top;
+ dim.w -= extents.left + extents.right;
+ dim.h -= extents.top + extents.bottom;
+}
+
+bool
+Region::contains(Pos pos) const
+{
+ return pos.x >= this->pos.x
+ && pos.y >= this->pos.y
+ && pos.x < this->pos.x + this->dim.w
+ && pos.y < this->pos.y + this->dim.h;
+}
+
+bool
+Region::contains(Region const& region) const
+{
+ return contains(region.pos)
+ && contains(region.pos + region.dim);
+}
+
+Pos
+Region::center() const
+{
+ return pos + Pos::from_center_of_dim(dim);
+}
diff --git a/src/kranewl/input/keyboard.cc b/src/kranewl/input/keyboard.cc
@@ -1,3 +0,0 @@
-#include <kranewl/input/keyboard.hh>
-
-
diff --git a/src/kranewl/input/pointer.cc b/src/kranewl/input/pointer.cc
@@ -1,3 +0,0 @@
-#include <kranewl/input/pointer.hh>
-
-
diff --git a/src/kranewl/layout.cc b/src/kranewl/layout.cc
@@ -1,8 +1,10 @@
#include <kranewl/layout.hh>
-#include <kranewl/util.hh>
-#include <kranewl/client.hh>
#include <kranewl/cycle.t.hh>
+#include <kranewl/tree/client.hh>
+#include <kranewl/util.hh>
+
+#include <spdlog/spdlog.h>
#include <algorithm>
#include <cmath>
@@ -256,13 +258,13 @@ LayoutHandler::layout_wraps() const
}
-std::size_t
+int
LayoutHandler::gap_size() const
{
return (*mp_layout->data.active_element())->gap_size;
}
-std::size_t
+int
LayoutHandler::main_count() const
{
return (*mp_layout->data.active_element())->main_count;
@@ -307,10 +309,10 @@ LayoutHandler::change_gap_size(Util::Change<int> change)
if (value <= 0)
data->gap_size = 0;
- else if (static_cast<std::size_t>(value) >= Layout::LayoutData::MAX_GAP_SIZE)
+ else if (static_cast<int>(value) >= Layout::LayoutData::MAX_GAP_SIZE)
data->gap_size = Layout::LayoutData::MAX_GAP_SIZE;
else
- data->gap_size = static_cast<std::size_t>(value);
+ data->gap_size = static_cast<int>(value);
}
void
@@ -321,10 +323,10 @@ LayoutHandler::change_main_count(Util::Change<int> change)
if (value <= 0)
data->main_count = 0;
- else if (static_cast<std::size_t>(value) >= Layout::LayoutData::MAX_MAIN_COUNT)
+ else if (static_cast<int>(value) >= Layout::LayoutData::MAX_MAIN_COUNT)
data->main_count = Layout::LayoutData::MAX_MAIN_COUNT;
else
- data->main_count = static_cast<std::size_t>(value);
+ data->main_count = static_cast<int>(value);
}
void
@@ -423,16 +425,17 @@ LayoutHandler::cycle_layout_data(Direction direction)
void
-LayoutHandler::save_layout(std::size_t number) const
+LayoutHandler::save_layout(int number) const
{
std::stringstream datadir_ss;
std::string home_path = std::getenv("HOME");
if (const char* env_xdgdata = std::getenv("XDG_DATA_HOME"))
- datadir_ss << env_xdgdata << "/" << WM_NAME << "/";
+ datadir_ss << env_xdgdata << "/kranewl/";
else
- datadir_ss << home_path << "/.local/share/" << WM_NAME << "/"
- << "layout_" << number;
+ datadir_ss << home_path << "/.local/share/kranewl/";
+
+ datadir_ss << "layout_" << number;
std::string file_path = datadir_ss.str();
@@ -448,21 +451,22 @@ LayoutHandler::save_layout(std::size_t number) const
out.write(reinterpret_cast<const char*>(&m_kind), sizeof(LayoutKind));
out.write(reinterpret_cast<const char*>(&size), sizeof(size));
out.write(reinterpret_cast<const char*>(&data[0]),
- data.size() * sizeof(Layout::LayoutData));
+ static_cast<long>(data.size() * sizeof(Layout::LayoutData)));
out.close();
}
void
-LayoutHandler::load_layout(std::size_t number)
+LayoutHandler::load_layout(int number)
{
std::stringstream datadir_ss;
std::string home_path = std::getenv("HOME");
if (const char* env_xdgdata = std::getenv("XDG_DATA_HOME"))
- datadir_ss << env_xdgdata << "/" << WM_NAME << "/";
+ datadir_ss << env_xdgdata << "/kranewl/";
else
- datadir_ss << home_path << "/.local/share/" << WM_NAME << "/"
- << "layout_" << number;
+ datadir_ss << home_path << "/.local/share/kranewl/";
+
+ datadir_ss << "layout_" << number;
std::string file_path = datadir_ss.str();
@@ -477,7 +481,7 @@ LayoutHandler::load_layout(std::size_t number)
data.resize(size, mp_layout->default_data);
in.read(reinterpret_cast<char*>(&data[0]),
- data.size() * sizeof(Layout::LayoutData));
+ static_cast<long>(data.size() * sizeof(Layout::LayoutData)));
set_kind(kind);
for (Layout::LayoutData_ptr data : mp_layout->data)
@@ -569,8 +573,8 @@ LayoutHandler::arrange_center(
{
const Layout::LayoutData_ptr data = *mp_layout->data.active_element();
- std::size_t h_comp = Layout::LayoutData::MAX_MAIN_COUNT;
- float w_ratio = data->main_factor / 0.95;
+ int h_comp = Layout::LayoutData::MAX_MAIN_COUNT;
+ float w_ratio = data->main_factor / 0.95f;
float h_ratio = static_cast<float>((h_comp - data->main_count))
/ static_cast<float>(h_comp);
@@ -581,14 +585,14 @@ LayoutHandler::arrange_center(
[=,this](Client_ptr client) -> Placement {
Region region = screen_region;
- int w = region.dim.w * w_ratio;
- int h = region.dim.h * h_ratio;
+ int w = static_cast<int>(static_cast<float>(region.dim.w) * w_ratio);
+ int h = static_cast<int>(static_cast<float>(region.dim.h) * h_ratio);
if (w <= region.dim.w)
- region.pos.x += (region.dim.w - w) / 2.f;
+ region.pos.x += static_cast<int>(static_cast<float>(region.dim.w - w) / 2.f);
if (h <= region.dim.h)
- region.pos.y += (region.dim.h - h) / 2.f;
+ region.pos.y += static_cast<int>(static_cast<float>(region.dim.h - h) / 2.f);
region.dim = { w, h };
@@ -634,21 +638,21 @@ LayoutHandler::arrange_main_deck(
) const
{
const Layout::LayoutData_ptr data = *mp_layout->data.active_element();
- std::size_t n = end - begin;
+ int n = static_cast<int>(end - begin);
if (n == 1) {
placements.emplace_back(Placement {
mp_layout->config.method,
*begin,
- Decoration::NO_DECORATION,
+ NO_DECORATION,
screen_region
});
return;
}
- std::size_t n_main;
- std::size_t n_stack;
+ int n_main;
+ int n_stack;
if (n <= data->main_count) {
n_main = n;
@@ -660,15 +664,17 @@ LayoutHandler::arrange_main_deck(
int w_main
= data->main_count > 0
- ? static_cast<float>(screen_region.dim.w) * data->main_factor
+ ? static_cast<int>(static_cast<float>(screen_region.dim.w) * data->main_factor)
: 0;
int x_stack = screen_region.pos.x + w_main;
int w_stack = screen_region.dim.w - w_main;
int h_main = n_main > 0 ? screen_region.dim.h : 0;
- int h_stack = n_stack > 0 ? screen_region.dim.h / n_stack : 0;
+ int h_stack = n_stack > 0
+ ? screen_region.dim.h / n_stack
+ : 0;
- std::size_t i = 0;
+ int i = 0;
std::transform(
begin,
@@ -723,21 +729,21 @@ LayoutHandler::arrange_stack_deck(
) const
{
const Layout::LayoutData_ptr data = *mp_layout->data.active_element();
- std::size_t n = end - begin;
+ int n = static_cast<int>(end - begin);
if (n == 1) {
placements.emplace_back(Placement {
mp_layout->config.method,
*begin,
- Decoration::NO_DECORATION,
+ NO_DECORATION,
screen_region
});
return;
}
- std::size_t n_main;
- std::size_t n_stack;
+ int n_main;
+ int n_stack;
if (n <= data->main_count) {
n_main = n;
@@ -749,7 +755,7 @@ LayoutHandler::arrange_stack_deck(
int w_main
= data->main_count > 0
- ? static_cast<float>(screen_region.dim.w) * data->main_factor
+ ? static_cast<int>(static_cast<float>(screen_region.dim.w) * data->main_factor)
: 0;
int x_stack = screen_region.pos.x + w_main;
@@ -757,7 +763,7 @@ LayoutHandler::arrange_stack_deck(
int h_main = n_main > 0 ? screen_region.dim.h / n_main : 0;
int h_stack = n_stack > 0 ? screen_region.dim.h : 0;
- std::size_t i = 0;
+ int i = 0;
std::transform(
begin,
@@ -812,21 +818,21 @@ LayoutHandler::arrange_double_deck(
) const
{
const Layout::LayoutData_ptr data = *mp_layout->data.active_element();
- std::size_t n = end - begin;
+ int n = static_cast<int>(end - begin);
if (n == 1) {
placements.emplace_back(Placement {
mp_layout->config.method,
*begin,
- Decoration::NO_DECORATION,
+ NO_DECORATION,
screen_region
});
return;
}
- std::size_t n_main;
- std::size_t n_stack;
+ int n_main;
+ int n_stack;
if (n <= data->main_count) {
n_main = n;
@@ -838,7 +844,7 @@ LayoutHandler::arrange_double_deck(
int w_main
= data->main_count > 0
- ? static_cast<float>(screen_region.dim.w) * data->main_factor
+ ? static_cast<int>(static_cast<float>(screen_region.dim.w) * data->main_factor)
: 0;
int x_stack = screen_region.pos.x + w_main;
@@ -846,7 +852,7 @@ LayoutHandler::arrange_double_deck(
int h_main = n_main > 0 ? screen_region.dim.h : 0;
int h_stack = n_stack > 0 ? screen_region.dim.h : 0;
- std::size_t i = 0;
+ int i = 0;
std::transform(
begin,
@@ -901,13 +907,13 @@ LayoutHandler::arrange_paper(
static const float MIN_W_RATIO = 0.5;
const Layout::LayoutData_ptr data = *mp_layout->data.active_element();
- std::size_t n = end - begin;
+ int n = static_cast<int>(end - begin);
if (n == 1) {
placements.emplace_back(Placement {
mp_layout->config.method,
*begin,
- Decoration::NO_DECORATION,
+ NO_DECORATION,
screen_region
});
@@ -916,13 +922,13 @@ LayoutHandler::arrange_paper(
int cw;
if (data->main_factor > MIN_W_RATIO) {
- cw = screen_region.dim.w * data->main_factor;
+ cw = static_cast<int>(static_cast<float>(screen_region.dim.w) * data->main_factor);
} else {
- cw = screen_region.dim.w * MIN_W_RATIO;
+ cw = static_cast<int>(static_cast<float>(screen_region.dim.w) * MIN_W_RATIO);
}
- int w = static_cast<float>(screen_region.dim.w - cw)
- / static_cast<float>(n - 1);
+ int w = static_cast<int>(static_cast<float>(screen_region.dim.w - cw)
+ / static_cast<float>(n - 1));
bool contains_active = false;
const auto last_active = std::max_element(
@@ -942,7 +948,7 @@ LayoutHandler::arrange_paper(
);
bool after_active = false;
- std::size_t i = 0;
+ int i = 0;
std::transform(
begin,
@@ -1013,21 +1019,21 @@ LayoutHandler::arrange_double_stack(
) const
{
const Layout::LayoutData_ptr data = *mp_layout->data.active_element();
- std::size_t n = end - begin;
+ int n = static_cast<int>(end - begin);
if (n == 1) {
placements.emplace_back(Placement {
mp_layout->config.method,
*begin,
- Decoration::NO_DECORATION,
+ NO_DECORATION,
screen_region
});
return;
}
- std::size_t n_main;
- std::size_t n_stack;
+ int n_main;
+ int n_stack;
if (n <= data->main_count) {
n_main = n;
@@ -1039,7 +1045,7 @@ LayoutHandler::arrange_double_stack(
int w_main
= data->main_count > 0
- ? static_cast<float>(screen_region.dim.w) * data->main_factor
+ ? static_cast<int>(static_cast<float>(screen_region.dim.w) * data->main_factor)
: 0;
int x_stack = screen_region.pos.x + w_main;
@@ -1047,7 +1053,7 @@ LayoutHandler::arrange_double_stack(
int h_main = n_main > 0 ? screen_region.dim.h / n_main : 0;
int h_stack = n_stack > 0 ? screen_region.dim.h / n_stack : 0;
- std::size_t i = 0;
+ int i = 0;
std::transform(
begin,
@@ -1112,21 +1118,21 @@ LayoutHandler::arrange_horizontal_stack(
client_iter end
) const
{
- std::size_t n = end - begin;
+ int n = static_cast<int>(end - begin);
if (n == 1) {
placements.emplace_back(Placement {
mp_layout->config.method,
*begin,
- Decoration::NO_DECORATION,
+ NO_DECORATION,
screen_region
});
return;
}
- int w = std::lround(static_cast<float>(screen_region.dim.w) / n);
- std::size_t i = 0;
+ int w = static_cast<int>(std::lround(screen_region.dim.w / n));
+ int i = 0;
std::transform(
begin,
@@ -1171,21 +1177,21 @@ LayoutHandler::arrange_vertical_stack(
client_iter end
) const
{
- std::size_t n = end - begin;
+ int n = static_cast<int>(end - begin);
if (n == 1) {
placements.emplace_back(Placement {
mp_layout->config.method,
*begin,
- Decoration::NO_DECORATION,
+ NO_DECORATION,
screen_region
});
return;
}
- int h = std::lround(static_cast<float>(screen_region.dim.h) / n);
- std::size_t i = 0;
+ int h = static_cast<int>(std::lround(screen_region.dim.h / n));
+ int i = 0;
std::transform(
begin,
@@ -1229,9 +1235,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
switch (kind) {
case LayoutKind::Float:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Free,
- Decoration::FREE_DECORATION,
+ FREE_DECORATION,
false,
false,
false,
@@ -1241,9 +1247,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::FramelessFloat:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Free,
- Decoration::NO_DECORATION,
+ NO_DECORATION,
false,
false,
false,
@@ -1253,9 +1259,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::SingleFloat:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Free,
- Decoration::FREE_DECORATION,
+ FREE_DECORATION,
false,
false,
true,
@@ -1265,9 +1271,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::FramelessSingleFloat:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Free,
- Decoration::NO_DECORATION,
+ NO_DECORATION,
false,
false,
true,
@@ -1277,9 +1283,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::Center:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration::NO_DECORATION,
+ NO_DECORATION,
true,
true,
false,
@@ -1289,9 +1295,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::Monocle:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration::NO_DECORATION,
+ NO_DECORATION,
true,
true,
false,
@@ -1301,13 +1307,12 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::MainDeck:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration {
- std::nullopt,
- Frame {
- Extents { 0, 0, 3, 0 },
- ColorScheme::DEFAULT_COLOR_SCHEME
+ Decoration{
+ Frame{
+ Extents{0, 0, 3, 0},
+ DEFAULT_COLOR_SCHEME
}
},
true,
@@ -1319,13 +1324,12 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::StackDeck:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration {
- std::nullopt,
- Frame {
- Extents { 0, 0, 3, 0 },
- ColorScheme::DEFAULT_COLOR_SCHEME
+ Decoration{
+ Frame{
+ Extents{0, 0, 3, 0},
+ DEFAULT_COLOR_SCHEME
}
},
true,
@@ -1337,13 +1341,12 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::DoubleDeck:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration {
- std::nullopt,
- Frame {
- Extents { 0, 0, 3, 0 },
- ColorScheme::DEFAULT_COLOR_SCHEME
+ Decoration{
+ Frame{
+ Extents{0, 0, 3, 0},
+ DEFAULT_COLOR_SCHEME
}
},
true,
@@ -1355,13 +1358,12 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::Paper:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration {
- std::nullopt,
- Frame {
- Extents { 1, 1, 0, 0 },
- ColorScheme::DEFAULT_COLOR_SCHEME
+ Decoration{
+ Frame{
+ Extents{1, 1, 0, 0},
+ DEFAULT_COLOR_SCHEME
}
},
true,
@@ -1373,13 +1375,12 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::CompactPaper:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration {
- std::nullopt,
- Frame {
- Extents { 1, 1, 0, 0 },
- ColorScheme::DEFAULT_COLOR_SCHEME
+ Decoration{
+ Frame{
+ Extents{1, 1, 0, 0},
+ DEFAULT_COLOR_SCHEME
}
},
true,
@@ -1391,13 +1392,12 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::DoubleStack:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration {
- std::nullopt,
- Frame {
- Extents { 0, 0, 3, 0 },
- ColorScheme::DEFAULT_COLOR_SCHEME
+ Decoration{
+ Frame{
+ Extents{0, 0, 3, 0},
+ DEFAULT_COLOR_SCHEME
}
},
true,
@@ -1409,13 +1409,12 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::CompactDoubleStack:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration {
- std::nullopt,
- Frame {
- Extents { 0, 0, 3, 0 },
- ColorScheme::DEFAULT_COLOR_SCHEME
+ Decoration{
+ Frame{
+ Extents{0, 0, 3, 0},
+ DEFAULT_COLOR_SCHEME
}
},
true,
@@ -1427,13 +1426,12 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::HorizontalStack:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration {
- std::nullopt,
- Frame {
- Extents { 0, 0, 3, 0 },
- ColorScheme::DEFAULT_COLOR_SCHEME
+ Decoration{
+ Frame{
+ Extents{0, 0, 3, 0},
+ DEFAULT_COLOR_SCHEME
}
},
true,
@@ -1445,13 +1443,12 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::CompactHorizontalStack:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration {
- std::nullopt,
- Frame {
- Extents { 0, 0, 3, 0 },
- ColorScheme::DEFAULT_COLOR_SCHEME
+ Decoration{
+ Frame{
+ Extents{0, 0, 3, 0},
+ DEFAULT_COLOR_SCHEME
}
},
true,
@@ -1463,13 +1460,12 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::VerticalStack:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration {
- std::nullopt,
- Frame {
- Extents { 3, 0, 0, 0 },
- ColorScheme::DEFAULT_COLOR_SCHEME
+ Decoration{
+ Frame{
+ Extents{3, 0, 0, 0},
+ DEFAULT_COLOR_SCHEME
}
},
true,
@@ -1481,13 +1477,12 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
case LayoutKind::CompactVerticalStack:
{
- return LayoutConfig {
+ return LayoutConfig{
Placement::PlacementMethod::Tile,
- Decoration {
- std::nullopt,
- Frame {
- Extents { 3, 0, 0, 0 },
- ColorScheme::DEFAULT_COLOR_SCHEME
+ Decoration{
+ Frame{
+ Extents{3, 0, 0, 0},
+ DEFAULT_COLOR_SCHEME
}
},
true,
@@ -1497,7 +1492,11 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
true
};
}
- default: Util::die("no associated configuration defined");
+ default:
+ {
+ spdlog::critical("no associated configuration defined");
+ std::exit(EXIT_FAILURE);
+ }
}
return kind_to_config(LayoutKind::Float);
@@ -1510,7 +1509,7 @@ LayoutHandler::Layout::kind_to_default_data(LayoutKind kind)
case LayoutKind::Center:
{
return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
+ Extents{0, 0, 0, 0},
0,
5,
.40f
@@ -1534,13 +1533,17 @@ LayoutHandler::Layout::kind_to_default_data(LayoutKind kind)
case LayoutKind::CompactVerticalStack:
{
return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
+ Extents{0, 0, 0, 0},
0,
1,
.50f
};
}
- default: Util::die("no associated default data defined");
+ default:
+ {
+ spdlog::critical("no associated default data defined");
+ std::exit(EXIT_FAILURE);
+ }
}
return kind_to_default_data(LayoutKind::Float);
diff --git a/src/kranewl/model.cc b/src/kranewl/model.cc
@@ -1,8 +1,16 @@
#include <kranewl/model.hh>
+#include <kranewl/common.hh>
#include <kranewl/conf/config.hh>
+#include <kranewl/context.hh>
+#include <kranewl/context.hh>
+#include <kranewl/cycle.t.hh>
#include <kranewl/exec.hh>
+#include <kranewl/input/keyboard.hh>
+#include <kranewl/input/mouse.hh>
#include <kranewl/server.hh>
+#include <kranewl/tree/output.hh>
+#include <kranewl/workspace.hh>
#include <spdlog/spdlog.h>
@@ -11,8 +19,26 @@ Model::Model(
Config const& config,
[[maybe_unused]] std::optional<std::string> autostart_path
)
- : m_server(server),
- m_config(config)
+ : m_server{server},
+ m_config{config},
+ m_running{true},
+ m_outputs{{}, true},
+ m_contexts{{}, true},
+ m_workspaces{{}, true},
+ mp_output{nullptr},
+ mp_context{nullptr},
+ mp_workspace{nullptr},
+ mp_prev_output{nullptr},
+ mp_prev_context{nullptr},
+ mp_prev_workspace{nullptr},
+ m_client_map{},
+ m_pid_map{},
+ m_fullscreen_map{},
+ m_sticky_clients{},
+ m_unmanaged_clients{},
+ mp_focus(nullptr),
+ m_key_bindings{},
+ m_mouse_bindings{}
{
#ifdef NDEBUG
if (autostart_path) {
@@ -21,6 +47,40 @@ Model::Model(
}
#endif
+ static const std::vector<std::string> context_names{
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j"
+ };
+
+ static const std::vector<std::string> workspace_names{
+ "main", "web", "term", {}, {}, {}, {}, {}, {}, {}
+ };
+
+ for (std::size_t i = 0; i < context_names.size(); ++i) {
+ Context_ptr context = new Context(i, context_names[i]);
+ m_contexts.insert_at_back(context);
+
+ for (std::size_t j = 0; j < workspace_names.size(); ++j) {
+ Workspace_ptr workspace = new Workspace(
+ workspace_names.size() * i + j,
+ workspace_names[j],
+ context
+ );
+
+ m_workspaces.insert_at_back(workspace);
+ context->register_workspace(workspace);
+ }
+
+ context->activate_workspace(Index{0});
+ }
+
+ /* acquire_outputs(); */
+
+ m_contexts.activate_at_index(0);
+ m_workspaces.activate_at_index(0);
+
+ mp_context = *m_contexts.active_element();
+ mp_workspace = *m_workspaces.active_element();
+
m_server.start();
}
@@ -32,3 +92,45 @@ Model::run()
{
// TODO
}
+
+Output_ptr
+Model::create_output(Surface)
+{
+ Output_ptr output = new Output();
+
+}
+
+void
+Model::register_output(Output_ptr)
+{
+
+}
+
+void
+Model::unregister_output(Output_ptr)
+{
+
+}
+
+Client_ptr
+Model::create_client(Surface surface)
+{
+ Client_ptr client = new Client(
+ &m_server,
+ surface,
+ mp_output,
+ mp_context,
+ mp_workspace
+ );
+
+ register_client(client);
+}
+
+void
+Model::register_client(Client_ptr client)
+{
+}
+
+void
+Model::unregister_client(Client_ptr client)
+{}
diff --git a/src/kranewl/server.cc b/src/kranewl/server.cc
@@ -1,8 +1,8 @@
#include <kranewl/server.hh>
-#include <kranewl/client.hh>
#include <kranewl/exec.hh>
#include <kranewl/input/keyboard.hh>
+#include <kranewl/tree/client.hh>
#include <kranewl/tree/output.hh>
#include <spdlog/spdlog.h>
@@ -241,23 +241,23 @@ Server::new_output(struct wl_listener* listener, void* data)
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->m_allocator, server->m_renderer);
if (!wl_list_empty(&wlr_output->modes)) {
struct wlr_output_mode* mode = wlr_output_preferred_mode(wlr_output);
+
wlr_output_set_mode(wlr_output, mode);
wlr_output_enable(wlr_output, true);
- if (!wlr_output_commit(wlr_output)) {
+
+ if (!wlr_output_commit(wlr_output))
return;
- }
}
Output* output = reinterpret_cast<Output*>(calloc(1, sizeof(Output)));
output->wlr_output = wlr_output;
output->server = server;
- output->l_frame.notify = Server::output_frame;
- wl_signal_add(&wlr_output->events.frame, &output->l_frame);
+ output->ml_frame.notify = Server::output_frame;
+ wl_signal_add(&wlr_output->events.frame, &output->ml_frame);
wl_list_insert(&server->m_outputs, &output->link);
wlr_output_layout_add_auto(server->m_output_layout, wlr_output);
@@ -300,18 +300,20 @@ Server::new_xdg_surface(struct wl_listener* listener, void* data)
}
assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
- Client_ptr client = new Client;
+ Client_ptr client = new Client(
+ server,
+ Surface{xdg_surface, true},
+ nullptr,
+ nullptr,
+ nullptr
+ );
- client->server = server;
xdg_surface->data = client->scene;
-
- client->surface = Surface{ .xdg = xdg_surface };
- client->surface_type = SurfaceType::XDGShell;
-
client->scene = wlr_scene_xdg_surface_create(
&client->server->m_scene->node,
client->surface.xdg
);
+
client->scene->data = client;
client->l_map.notify = xdg_toplevel_map;
@@ -705,16 +707,16 @@ Server::keyboard_handle_keybinding(Server_ptr server, xkb_keysym_t sym)
if (wl_list_length(&server->m_clients) < 2)
break;
- Client_ptr prev_client = wl_container_of(
- server->m_clients.prev,
- prev_client,
- link
- );
+ /* Client_ptr prev_client = wl_container_of( */
+ /* server->m_clients.prev, */
+ /* prev_client, */
+ /* link */
+ /* ); */
- focus_client(
- prev_client,
- prev_client->get_surface()
- );
+ /* focus_client( */
+ /* prev_client, */
+ /* prev_client->get_surface() */
+ /* ); */
}
break;
case XKB_KEY_Return:
@@ -760,11 +762,11 @@ Server::request_set_primary_selection(struct wl_listener* listener, void* data)
void
Server::output_frame(struct wl_listener* listener, void* data)
{
- Output* output = wl_container_of(listener, output, l_frame);
- struct wlr_scene* scene = output->server->m_scene;
+ Output* output = wl_container_of(listener, output, ml_frame);
+ struct wlr_scene* scene = output->m_server->m_scene;
struct wlr_scene_output* scene_output
- = wlr_scene_get_scene_output(scene, output->wlr_output);
+ = wlr_scene_get_scene_output(scene, output->m_wlr_output);
wlr_scene_output_commit(scene_output);
@@ -826,10 +828,10 @@ Server::focus_client(Client_ptr client, struct wlr_surface* surface)
if (client->scene)
wlr_scene_node_raise_to_top(client->scene);
- wl_list_remove(&client->link);
- wl_list_insert(&server->m_clients, &client->link);
+ /* wl_list_remove(&client->link); */
+ /* wl_list_insert(&server->m_clients, &client->link); */
- if (client->surface_type == SurfaceType::XDGShell || client->surface_type == SurfaceType::LayerShell)
+ if (client->surface.type == SurfaceType::XDGShell || client->surface.type == SurfaceType::LayerShell)
wlr_xdg_toplevel_set_activated(client->surface.xdg, true);
wlr_seat_keyboard_notify_enter(
@@ -846,9 +848,7 @@ Server::xdg_toplevel_map(struct wl_listener* listener, void* data)
{
Client_ptr client = wl_container_of(listener, client, l_map);
- printf("Address of x is %p\n", (void *)client);
-
- wl_list_insert(&client->server->m_clients, &client->link);
+ /* wl_list_insert(&client->server->m_clients, &client->link); */
focus_client(client, client->get_surface());
}
@@ -856,7 +856,7 @@ void
Server::xdg_toplevel_unmap(struct wl_listener* listener, void* data)
{
Client_ptr client = wl_container_of(listener, client, l_unmap);
- wl_list_remove(&client->link);
+ /* wl_list_remove(&client->link); */
}
void
@@ -976,16 +976,16 @@ Server::new_xwayland_surface(struct wl_listener* listener, void* data)
struct wlr_xwayland_surface* xwayland_surface
= reinterpret_cast<wlr_xwayland_surface*>(data);
- Client_ptr client = new Client;
+ Client_ptr client = new Client(
+ server,
+ Surface{xwayland_surface, xwayland_surface->override_redirect},
+ nullptr,
+ nullptr,
+ nullptr
+ );
- client->server = server;
xwayland_surface->data = client;
- client->surface = Surface{ .xwayland = xwayland_surface };
- client->surface_type = xwayland_surface->override_redirect
- ? SurfaceType::X11Unmanaged
- : SurfaceType::X11Managed;
-
client->l_map = { .notify = Server::xdg_toplevel_map };
client->l_unmap = { .notify = Server::xdg_toplevel_unmap };
client->l_destroy = { .notify = Server::xdg_toplevel_destroy };
diff --git a/src/kranewl/tree/client.cc b/src/kranewl/tree/client.cc
@@ -0,0 +1,213 @@
+#include <kranewl/tree/client.hh>
+
+// https://github.com/swaywm/wlroots/issues/682
+#include <pthread.h>
+#define class class_
+#define namespace namespace_
+#define static
+extern "C" {
+#include <wlr/types/wlr_xdg_shell.h>
+#ifdef XWAYLAND
+#include <wlr/xwayland.h>
+#endif
+}
+#undef static
+#undef class
+#undef namespace
+
+Client::Client(
+ Server_ptr server,
+ Surface surface,
+ Output_ptr output,
+ Context_ptr context,
+ Workspace_ptr workspace
+)
+ : uid{surface.uid()},
+ server{server},
+ surface{surface},
+ output{output},
+ 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},
+ 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;
+}
+
+struct wlr_surface*
+Client::get_surface() noexcept
+{
+ switch (surface.type) {
+ case SurfaceType::XDGShell: //fallthrough
+ case SurfaceType::LayerShell: return surface.xdg->surface;
+ case SurfaceType::X11Managed: //fallthrough
+ case SurfaceType::X11Unmanaged: return surface.xwayland->surface;
+ }
+
+ return nullptr;
+}
+
+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/util.cc b/src/kranewl/util.cc
@@ -1,30 +0,0 @@
-#include <kranewl/util.hh>
-
-#define assert assert_
-#include <spdlog/spdlog.h>
-#undef assert
-
-#include <utility>
-extern "C" {
-#include <unistd.h>
-}
-
-void
-Util::die(const std::string&& msg)
-{
- spdlog::critical(msg);
- exit(1);
-}
-
-void
-Util::warn(const std::string&& msg)
-{
- spdlog::warn(msg);
-}
-
-void
-Util::assert(bool condition, std::string const&& msg)
-{
- if (!condition)
- Util::die(std::forward<const std::string&&>(msg));
-}