26
.clang-format
Normal file
26
.clang-format
Normal 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
|
||||||
193
src/App.hpp
193
src/App.hpp
@@ -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 };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
8
tools/format.sh
Executable 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
|
||||||
Reference in New Issue
Block a user