Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2025-10-05 04:50:09 +03:00
parent 8653b02c44
commit 1414a66e56
6 changed files with 226 additions and 173 deletions

26
.clang-format Normal file
View File

@@ -0,0 +1,26 @@
UseTab: ForIndentation
TabWidth: 4
IndentWidth: 4
ColumnLimit: 80
AlignEscapedNewlines: DontAlign
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
BasedOnStyle: WebKit
BraceWrapping:
AfterFunction: true
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: true
BreakConstructorInitializers: BeforeComma
IndentPPDirectives: AfterHash
IndentRequiresClause: false
InsertNewlineAtEOF: true
LineEnding: LF
NamespaceIndentation: None
PointerAlignment: Right # east pointer
QualifierAlignment: Right # east const
RemoveSemicolon: true
RequiresClausePosition: WithFollowing
RequiresExpressionIndentation: OuterScope
SpaceAfterTemplateKeyword: false

View File

@@ -22,119 +22,130 @@ extern "C" {
#include "common.hpp" #include "common.hpp"
struct TypingBuffer : std::pmr::vector<u32> { struct TypingBuffer : std::pmr::vector<u32> {
void push_utf8(const char *s); void push_utf8(char const *s);
}; };
struct App { struct App {
App(); App();
~App(); ~App();
auto run() -> void; auto run() -> void;
auto set_visible(bool visible) -> void; auto set_visible(bool visible) -> void;
auto visible() const -> bool { return m_visible; } auto visible() const -> bool { return m_visible; }
auto stop() -> void { m_running = false; } auto stop() -> void { m_running = false; }
private: private:
auto init_wayland() -> void; auto init_wayland() -> void;
auto init_egl() -> void; auto init_egl() -> void;
auto init_signal() -> void; auto init_signal() -> void;
auto init_theme_portal() -> void; auto init_theme_portal() -> void;
auto pump_events() -> void; auto pump_events() -> void;
auto render_frame() -> void; auto render_frame() -> void;
auto create_layer_surface() -> void; auto create_layer_surface() -> void;
auto destroy_layer_surface() -> void; auto destroy_layer_surface() -> void;
auto ensure_egl_surface() -> void; auto ensure_egl_surface() -> void;
auto update_blur_region() -> void; auto update_blur_region() -> void;
auto theme() const -> ColorScheme const & { return m_themes[m_active_theme]; } auto theme() const -> ColorScheme const &
{
return m_themes[m_active_theme];
}
static void on_settings_changed(XdpSettings * /*self*/, const char *ns, static void on_settings_changed(XdpSettings * /*self*/, char const *ns,
const char *key, GVariant * /*value*/, char const *key, GVariant * /*value*/, gpointer data);
gpointer data);
struct { struct {
wl_display *display{}; wl_display *display {};
wl_registry *registry{}; wl_registry *registry {};
wl_compositor *compositor{}; wl_compositor *compositor {};
wl_seat *seat{}; wl_seat *seat {};
wl_keyboard *kbd{}; wl_keyboard *kbd {};
wl_surface *wl_surface{}; wl_surface *wl_surface {};
zwlr_layer_shell_v1 *layer_shell{}; zwlr_layer_shell_v1 *layer_shell {};
zwlr_layer_surface_v1 *layer_surface{}; zwlr_layer_surface_v1 *layer_surface {};
ext_background_effect_manager_v1 *mgr{}; ext_background_effect_manager_v1 *mgr {};
ext_background_effect_surface_v1 *eff{}; ext_background_effect_surface_v1 *eff {};
org_kde_kwin_blur_manager *kde_blur_mgr{}; org_kde_kwin_blur_manager *kde_blur_mgr {};
org_kde_kwin_blur *kde_blur{}; org_kde_kwin_blur *kde_blur {};
} m_wayland; } m_wayland;
struct { struct {
EGLDisplay edpy{EGL_NO_DISPLAY}; EGLDisplay edpy { EGL_NO_DISPLAY };
EGLConfig ecfg{}; EGLConfig ecfg {};
EGLContext ectx{EGL_NO_CONTEXT}; EGLContext ectx { EGL_NO_CONTEXT };
EGLSurface esurf{EGL_NO_SURFACE}; EGLSurface esurf { EGL_NO_SURFACE };
wl_egl_window *wegl{}; wl_egl_window *wegl {};
} m_gl; } m_gl;
struct { struct {
XdpPortal *portal{}; XdpPortal *portal {};
XdpSettings *settings{}; XdpSettings *settings {};
} m_xdp; } m_xdp;
struct { struct {
TypingBuffer typing{}; TypingBuffer typing {};
xkb_context *xkb_ctx{}; xkb_context *xkb_ctx {};
xkb_keymap *xkb_keymap{}; xkb_keymap *xkb_keymap {};
xkb_state *xkb_state{}; xkb_state *xkb_state {};
std::unordered_set<u32> held; std::unordered_set<u32> held;
std::unordered_set<u32> pressed_syms; std::unordered_set<u32> pressed_syms;
std::unordered_set<u32> released_syms; std::unordered_set<u32> released_syms;
auto is_down_evdev(u32 evdev) const -> bool { auto is_down_evdev(u32 evdev) const -> bool
return held.find(evdev) != held.end(); {
} return held.find(evdev) != held.end();
}
auto is_down_sym(xkb_keysym_t sym) const -> bool { auto is_down_sym(xkb_keysym_t sym) const -> bool
if (!xkb_state) {
return false; if (!xkb_state)
for (auto k : held) { return false;
if (xkb_state_key_get_one_sym(xkb_state, for (auto k : held) {
static_cast<xkb_keycode_t>(k + 8)) == sym) if (xkb_state_key_get_one_sym(
return true; xkb_state, static_cast<xkb_keycode_t>(k + 8))
} == sym)
return false; return true;
} }
return false;
}
auto is_sym_pressed(xkb_keysym_t sym) const -> bool { auto is_sym_pressed(xkb_keysym_t sym) const -> bool
return pressed_syms.find(sym) != pressed_syms.end(); {
} return pressed_syms.find(sym) != pressed_syms.end();
}
auto is_sym_released(xkb_keysym_t sym) const -> bool { auto is_sym_released(xkb_keysym_t sym) const -> bool
return released_syms.find(sym) != released_syms.end(); {
} return released_syms.find(sym) != released_syms.end();
}
auto mod_active(const char *name) const -> bool { auto mod_active(char const *name) const -> bool
return xkb_state && xkb_state_mod_name_is_active( {
xkb_state, name, XKB_STATE_MODS_EFFECTIVE) > 0; return xkb_state
} && xkb_state_mod_name_is_active(
xkb_state, name, XKB_STATE_MODS_EFFECTIVE)
> 0;
}
auto ctrl() const -> bool { return mod_active("Control"); } auto ctrl() const -> bool { return mod_active("Control"); }
auto shift() const -> bool { return mod_active("Shift"); } auto shift() const -> bool { return mod_active("Shift"); }
void clear_transients() { void clear_transients()
pressed_syms.clear(); {
released_syms.clear(); pressed_syms.clear();
} released_syms.clear();
} m_kbd; }
} m_kbd;
enum_array<Theme, ColorScheme> m_themes{make_default_themes()}; enum_array<Theme, ColorScheme> m_themes { make_default_themes() };
Theme m_active_theme{Theme::Light}; Theme m_active_theme { Theme::Light };
int m_win_w{800}; int m_win_w { 800 };
int m_win_h{600}; int m_win_h { 600 };
bool m_running{true}; bool m_running { true };
bool m_visible{true}; bool m_visible { true };
int m_sfd{-1}; int m_sfd { -1 };
}; };

View File

@@ -5,31 +5,32 @@
#include "enum_array.hpp" #include "enum_array.hpp"
struct ColorScheme { struct ColorScheme {
struct { struct {
Color background; Color background;
} window; } window;
}; };
enum class Theme : int { Light = 0, Dark, _last = Dark }; enum class Theme : int { Light = 0, Dark, _last = Dark };
template <> struct enum_traits<Theme> { template<> struct enum_traits<Theme> {
static constexpr Theme first = Theme::Light; static constexpr Theme first = Theme::Light;
static constexpr Theme last = Theme::_last; static constexpr Theme last = Theme::_last;
}; };
constexpr auto make_default_themes() -> enum_array<Theme, ColorScheme> const { constexpr auto make_default_themes() -> enum_array<Theme, ColorScheme> const
enum_array<Theme, ColorScheme> array; {
array[Theme::Light] = { enum_array<Theme, ColorScheme> array;
array[Theme::Light] = {
.window = .window =
{ {
.background = {255, 255, 255, 100}, .background = {255, 255, 255, 100},
}, },
}; };
array[Theme::Dark] = { array[Theme::Dark] = {
.window = .window =
{ {
.background = {0, 0, 0, 100}, .background = {0, 0, 0, 100},
}, },
}; };
return array; return array;
} }

View File

@@ -11,26 +11,27 @@ using i64 = std::int64_t;
using usize = std::uintptr_t; using usize = std::uintptr_t;
using isize = std::intptr_t; using isize = std::intptr_t;
inline auto rune_to_string(uint32_t cp) -> char const * { inline auto rune_to_string(uint32_t cp) -> char const *
static char utf8[5] = {0}; {
for (auto &c : utf8) static char utf8[5] = { 0 };
c = 0; for (auto &c : utf8)
c = 0;
if (cp < 0x80) { if (cp < 0x80) {
utf8[0] = cp; utf8[0] = cp;
} else if (cp < 0x800) { } else if (cp < 0x800) {
utf8[0] = 0xC0 | (cp >> 6); utf8[0] = 0xC0 | (cp >> 6);
utf8[1] = 0x80 | (cp & 0x3F); utf8[1] = 0x80 | (cp & 0x3F);
} else if (cp < 0x10000) { } else if (cp < 0x10000) {
utf8[0] = 0xE0 | (cp >> 12); utf8[0] = 0xE0 | (cp >> 12);
utf8[1] = 0x80 | ((cp >> 6) & 0x3F); utf8[1] = 0x80 | ((cp >> 6) & 0x3F);
utf8[2] = 0x80 | (cp & 0x3F); utf8[2] = 0x80 | (cp & 0x3F);
} else { } else {
utf8[0] = 0xF0 | (cp >> 18); utf8[0] = 0xF0 | (cp >> 18);
utf8[1] = 0x80 | ((cp >> 12) & 0x3F); utf8[1] = 0x80 | ((cp >> 12) & 0x3F);
utf8[2] = 0x80 | ((cp >> 6) & 0x3F); utf8[2] = 0x80 | ((cp >> 6) & 0x3F);
utf8[3] = 0x80 | (cp & 0x3F); utf8[3] = 0x80 | (cp & 0x3F);
} }
return utf8; return utf8;
} }

View File

@@ -5,69 +5,75 @@
#include <stdexcept> #include <stdexcept>
#include <type_traits> #include <type_traits>
template <class E> struct enum_traits; template<class E> struct enum_traits;
template <class E> template<class E>
concept EnumLike = std::is_enum_v<E>; concept EnumLike = std::is_enum_v<E>;
template <EnumLike E> template<EnumLike E>
constexpr std::size_t enum_count_v = constexpr std::size_t enum_count_v
static_cast<std::size_t>(enum_traits<E>::last) - = static_cast<std::size_t>(enum_traits<E>::last)
static_cast<std::size_t>(enum_traits<E>::first) + 1; - static_cast<std::size_t>(enum_traits<E>::first) + 1;
template <EnumLike E, class T> struct enum_array { template<EnumLike E, class T> struct enum_array {
using value_type = T; using value_type = T;
using enum_type = E; using enum_type = E;
using underlying_index_type = std::size_t; using underlying_index_type = std::size_t;
static constexpr E first = enum_traits<E>::first; static constexpr E first = enum_traits<E>::first;
static constexpr E last = enum_traits<E>::last; static constexpr E last = enum_traits<E>::last;
static constexpr std::size_t size_value = enum_count_v<E>; static constexpr std::size_t size_value = enum_count_v<E>;
std::array<T, size_value> _data{}; std::array<T, size_value> _data {};
static constexpr std::size_t size() noexcept { return size_value; } static constexpr std::size_t size() noexcept { return size_value; }
constexpr T *data() noexcept { return _data.data(); } constexpr T *data() noexcept { return _data.data(); }
constexpr const T *data() const noexcept { return _data.data(); } constexpr T const *data() const noexcept { return _data.data(); }
constexpr T *begin() noexcept { return _data.begin().operator->(); } constexpr T *begin() noexcept { return _data.begin().operator->(); }
constexpr const T *begin() const noexcept { constexpr T const *begin() const noexcept
return _data.begin().operator->(); {
} return _data.begin().operator->();
constexpr T *end() noexcept { return _data.end().operator->(); } }
constexpr const T *end() const noexcept { return _data.end().operator->(); } constexpr T *end() noexcept { return _data.end().operator->(); }
constexpr T const *end() const noexcept { return _data.end().operator->(); }
constexpr T &operator[](E e) noexcept { return _data[to_index(e)]; } constexpr T &operator[](E e) noexcept { return _data[to_index(e)]; }
constexpr const T &operator[](E e) const noexcept { constexpr T const &operator[](E e) const noexcept
return _data[to_index(e)]; {
} return _data[to_index(e)];
}
constexpr T &at(E e) { constexpr T &at(E e)
auto i = to_index(e); {
if (i >= size_value) auto i = to_index(e);
throw std::out_of_range("enum_array::at"); if (i >= size_value)
return _data[i]; throw std::out_of_range("enum_array::at");
} return _data[i];
constexpr const T &at(E e) const { }
auto i = to_index(e); constexpr T const &at(E e) const
if (i >= size_value) {
throw std::out_of_range("enum_array::at"); auto i = to_index(e);
return _data[i]; if (i >= size_value)
} throw std::out_of_range("enum_array::at");
return _data[i];
}
constexpr void fill(const T &v) { _data.fill(v); } constexpr void fill(T const &v) { _data.fill(v); }
private: private:
static constexpr std::size_t to_index(E e) noexcept { static constexpr std::size_t to_index(E e) noexcept
return static_cast<std::size_t>(e) - static_cast<std::size_t>(first); {
} return static_cast<std::size_t>(e) - static_cast<std::size_t>(first);
}
}; };
template <class E, class T, class... U> template<class E, class T, class... U>
requires EnumLike<E> && (std::is_same_v<T, U> && ...) requires EnumLike<E> && (std::is_same_v<T, U> && ...)
constexpr auto make_enum_array(T &&first_val, U &&...rest) { constexpr auto make_enum_array(T &&first_val, U &&...rest)
enum_array<E, std::decay_t<T>> arr; {
static_assert(sizeof...(rest) + 1 == enum_count_v<E>, enum_array<E, std::decay_t<T>> arr;
"initializer count must match enum range"); static_assert(sizeof...(rest) + 1 == enum_count_v<E>,
arr._data = {std::forward<T>(first_val), std::forward<U>(rest)...}; "initializer count must match enum range");
return arr; arr._data = { std::forward<T>(first_val), std::forward<U>(rest)... };
return arr;
} }

8
tools/format.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(git rev-parse --show-toplevel)"
find "$ROOT/src" -type f -name '*.cpp' -o -name '*.hpp' -print0 | while IFS= read -r -d '' f; do
clang-format -i --style=file "$f"
done