144
src/App.cpp
144
src/App.cpp
@@ -34,7 +34,7 @@
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr std::size_t MAX_SURROUNDING_BYTES = 4000;
|
||||
constexpr usize MAX_SURROUNDING_BYTES = 4000;
|
||||
|
||||
inline auto is_utf8_continuation(char c) -> bool
|
||||
{
|
||||
@@ -44,8 +44,8 @@ inline auto is_utf8_continuation(char c) -> bool
|
||||
inline auto adjust_utf8_backward(std::string const &text, int index) -> int
|
||||
{
|
||||
index = std::clamp(index, 0, static_cast<int>(text.size()));
|
||||
while (index > 0
|
||||
&& is_utf8_continuation(text[static_cast<std::size_t>(index - 1)]))
|
||||
while (
|
||||
index > 0 && is_utf8_continuation(text[static_cast<usize>(index - 1)]))
|
||||
--index;
|
||||
return index;
|
||||
}
|
||||
@@ -54,8 +54,8 @@ inline auto adjust_utf8_forward(std::string const &text, int index) -> int
|
||||
{
|
||||
int const size = static_cast<int>(text.size());
|
||||
index = std::clamp(index, 0, size);
|
||||
while (index < size
|
||||
&& is_utf8_continuation(text[static_cast<std::size_t>(index)]))
|
||||
while (
|
||||
index < size && is_utf8_continuation(text[static_cast<usize>(index)]))
|
||||
++index;
|
||||
return index;
|
||||
}
|
||||
@@ -221,9 +221,9 @@ auto App::init_wayland() -> void
|
||||
|
||||
static wl_keyboard_listener keyboard_listener {};
|
||||
{
|
||||
auto kb_keymap = [](void *data, wl_keyboard *, u32 format, i32 fd,
|
||||
u32 size) -> void {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto kb_keymap { [](void *data, wl_keyboard *, u32 format, i32 fd,
|
||||
u32 size) -> void {
|
||||
auto *app { static_cast<App *>(data) };
|
||||
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
|
||||
close(fd);
|
||||
return;
|
||||
@@ -247,18 +247,18 @@ auto App::init_wayland() -> void
|
||||
: nullptr;
|
||||
munmap(map, size);
|
||||
close(fd);
|
||||
};
|
||||
} };
|
||||
|
||||
auto kb_enter = [](void *, wl_keyboard *, u32, wl_surface *,
|
||||
wl_array *) -> void { };
|
||||
auto kb_enter { [](void *, wl_keyboard *, u32, wl_surface *,
|
||||
wl_array *) -> void { } };
|
||||
auto kb_leave
|
||||
= [](void *data, wl_keyboard *, u32, wl_surface *) -> void {
|
||||
static_cast<App *>(data)->m_kbd.held.clear();
|
||||
};
|
||||
|
||||
auto kb_key = [](void *data, wl_keyboard *, u32, u32, u32 key,
|
||||
u32 state) -> void {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto kb_key { [](void *data, wl_keyboard *, u32, u32, u32 key,
|
||||
u32 state) -> void {
|
||||
auto *app { static_cast<App *>(data) };
|
||||
if (!app->m_kbd.xkb_state_v)
|
||||
return;
|
||||
|
||||
@@ -336,18 +336,18 @@ auto App::init_wayland() -> void
|
||||
app->m_kbd.held.erase(key);
|
||||
xkb_state_update_key(app->m_kbd.xkb_state_v, kc, XKB_KEY_UP);
|
||||
}
|
||||
};
|
||||
} };
|
||||
|
||||
auto kb_mods = [](void *data, wl_keyboard *, u32, u32 depressed,
|
||||
u32 latched, u32 locked, u32 group) -> void {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto kb_mods { [](void *data, wl_keyboard *, u32, u32 depressed,
|
||||
u32 latched, u32 locked, u32 group) -> void {
|
||||
auto *app { static_cast<App *>(data) };
|
||||
if (!app->m_kbd.xkb_state_v)
|
||||
return;
|
||||
xkb_state_update_mask(app->m_kbd.xkb_state_v, depressed, latched,
|
||||
locked, 0, 0, group);
|
||||
};
|
||||
} };
|
||||
|
||||
auto kb_repeat_info = [](void *, wl_keyboard *, i32, i32) -> void { };
|
||||
auto kb_repeat_info { [](void *, wl_keyboard *, i32, i32) -> void { } };
|
||||
|
||||
keyboard_listener = { kb_keymap, kb_enter, kb_leave, kb_key, kb_mods,
|
||||
kb_repeat_info };
|
||||
@@ -357,7 +357,7 @@ auto App::init_wayland() -> void
|
||||
{
|
||||
auto ti_enter
|
||||
= [](void *data, zwp_text_input_v3 *, wl_surface *surface) -> void {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto *app { static_cast<App *>(data) };
|
||||
bool const focused_surface
|
||||
= surface && surface == app->m_wayland.surface;
|
||||
app->m_ime.seat_focus = focused_surface;
|
||||
@@ -373,9 +373,9 @@ auto App::init_wayland() -> void
|
||||
}
|
||||
};
|
||||
|
||||
auto ti_leave
|
||||
= [](void *data, zwp_text_input_v3 *, wl_surface *) -> void {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto ti_leave { [](void *data, zwp_text_input_v3 *,
|
||||
wl_surface *) -> void {
|
||||
auto *app { static_cast<App *>(data) };
|
||||
app->m_ime.seat_focus = false;
|
||||
app->m_ime.enabled = false;
|
||||
app->m_ime.pending = {};
|
||||
@@ -383,39 +383,39 @@ auto App::init_wayland() -> void
|
||||
app->m_ime.last_surrounding.clear();
|
||||
if (app->m_gui)
|
||||
app->m_gui->ime_clear_preedit();
|
||||
};
|
||||
} };
|
||||
|
||||
auto ti_preedit
|
||||
= [](void *data, zwp_text_input_v3 *, char const *text,
|
||||
int32_t cursor_begin, int32_t cursor_end) -> void {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto &pending = app->m_ime.pending;
|
||||
auto ti_preedit { [](void *data, zwp_text_input_v3 *, char const *text,
|
||||
int32_t cursor_begin,
|
||||
int32_t cursor_end) -> void {
|
||||
auto *app { static_cast<App *>(data) };
|
||||
auto &pending { app->m_ime.pending };
|
||||
pending.has_preedit = true;
|
||||
pending.preedit_text = text ? text : "";
|
||||
pending.cursor_begin = cursor_begin;
|
||||
pending.cursor_end = cursor_end;
|
||||
};
|
||||
} };
|
||||
|
||||
auto ti_commit
|
||||
= [](void *data, zwp_text_input_v3 *, char const *text) -> void {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto &pending = app->m_ime.pending;
|
||||
auto ti_commit { [](void *data, zwp_text_input_v3 *,
|
||||
char const *text) -> void {
|
||||
auto *app { static_cast<App *>(data) };
|
||||
auto &pending { app->m_ime.pending };
|
||||
pending.has_commit = true;
|
||||
pending.commit_text = text ? text : "";
|
||||
};
|
||||
} };
|
||||
|
||||
auto ti_delete = [](void *data, zwp_text_input_v3 *, uint32_t before,
|
||||
uint32_t after) -> void {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto &pending = app->m_ime.pending;
|
||||
auto ti_delete { [](void *data, zwp_text_input_v3 *, uint32_t before,
|
||||
uint32_t after) -> void {
|
||||
auto *app { static_cast<App *>(data) };
|
||||
auto &pending { app->m_ime.pending };
|
||||
pending.has_delete = true;
|
||||
pending.before = before;
|
||||
pending.after = after;
|
||||
};
|
||||
} };
|
||||
|
||||
auto ti_done
|
||||
= [](void *data, zwp_text_input_v3 *, uint32_t serial) -> void {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto *app { static_cast<App *>(data) };
|
||||
app->m_ime.pending_done = true;
|
||||
app->m_ime.pending_serial = serial;
|
||||
app->m_ime.surrounding_dirty = true;
|
||||
@@ -425,7 +425,7 @@ auto App::init_wayland() -> void
|
||||
= { ti_enter, ti_leave, ti_preedit, ti_commit, ti_delete, ti_done };
|
||||
}
|
||||
|
||||
static auto ensure_text_input = +[](App *app) -> void {
|
||||
static auto ensure_text_input { +[](App *app) -> void {
|
||||
if (!app->m_wayland.text_input_mgr || !app->m_wayland.seat
|
||||
|| app->m_wayland.text_input)
|
||||
return;
|
||||
@@ -439,12 +439,12 @@ auto App::init_wayland() -> void
|
||||
app->m_ime.enabled = false;
|
||||
app->m_ime.last_surrounding.clear();
|
||||
app->m_ime.sent_serial = 0;
|
||||
};
|
||||
} };
|
||||
|
||||
auto handle_registry_global
|
||||
= [](void *data, wl_registry *registry, u32 name, char const *interface,
|
||||
u32 version) -> void {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto *app { static_cast<App *>(data) };
|
||||
if (std::strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||
app->m_wayland.compositor = static_cast<wl_compositor *>(
|
||||
wl_registry_bind(registry, name, &wl_compositor_interface, 4));
|
||||
@@ -454,7 +454,7 @@ auto App::init_wayland() -> void
|
||||
static struct wl_seat_listener const seat_listener = {
|
||||
.capabilities =
|
||||
[](void *data, struct wl_seat *seat, u32 caps) {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto *app { static_cast<App *>(data) };
|
||||
if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
|
||||
app->m_wayland.kbd = wl_seat_get_keyboard(seat);
|
||||
wl_keyboard_add_listener(
|
||||
@@ -530,11 +530,11 @@ auto App::init_egl() -> void
|
||||
|
||||
m_tr = std::make_shared<TextRenderer>();
|
||||
m_gui = std::make_shared<ImGui>(m_tr);
|
||||
auto const font = find_font_path();
|
||||
auto const font { find_font_path() };
|
||||
assert(font && "Could not find font");
|
||||
std::vector<std::filesystem::path> fallback_paths;
|
||||
std::unordered_set<std::string> seen_paths;
|
||||
auto const primary_path_str = font->string();
|
||||
auto const primary_path_str { font->string() };
|
||||
|
||||
constexpr char const *fallback_candidates[] = {
|
||||
"Noto Sans CJK JP:style=Regular",
|
||||
@@ -546,10 +546,11 @@ auto App::init_egl() -> void
|
||||
"sans-serif:lang=zh-cn",
|
||||
"sans-serif:lang=zh-tw",
|
||||
"sans-serif:lang=zh-hk",
|
||||
"Noto Color Emoji:style=Regular",
|
||||
};
|
||||
for (auto const *name : fallback_candidates) {
|
||||
if (auto fallback = find_font_path(name)) {
|
||||
auto const path_str = fallback->string();
|
||||
if (auto fallback { find_font_path(name) }) {
|
||||
auto const path_str { fallback->string() };
|
||||
if (path_str == primary_path_str)
|
||||
continue;
|
||||
if (!seen_paths.emplace(path_str).second)
|
||||
@@ -561,7 +562,8 @@ auto App::init_egl() -> void
|
||||
TraceLog(LOG_WARNING,
|
||||
"No fallback fonts found; some glyphs may render as missing");
|
||||
}
|
||||
auto const font_handle = m_tr->load_font(*font, std::span(fallback_paths));
|
||||
auto const font_handle { m_tr->load_font(
|
||||
*font, std::span(fallback_paths)) };
|
||||
assert(font_handle && "Could not load font");
|
||||
m_font = *font_handle;
|
||||
m_gui->set_font(m_font);
|
||||
@@ -588,7 +590,7 @@ auto App::init_signal() -> void
|
||||
void App::on_settings_changed(XdpSettings * /*self*/, char const *ns,
|
||||
char const *key, GVariant * /*value*/, gpointer data)
|
||||
{
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto *app { static_cast<App *>(data) };
|
||||
if (g_strcmp0(ns, "org.freedesktop.appearance") == 0) {
|
||||
if (g_strcmp0(key, "color-scheme") == 0) {
|
||||
guint v = xdp_settings_read_uint(app->m_xdp.settings,
|
||||
@@ -599,8 +601,8 @@ void App::on_settings_changed(XdpSettings * /*self*/, char const *ns,
|
||||
else
|
||||
app->m_active_theme = Theme::Light;
|
||||
} else if (g_strcmp0(key, "accent-color") == 0) {
|
||||
auto val = xdp_settings_read_value(app->m_xdp.settings,
|
||||
"org.freedesktop.appearance", "accent-color", NULL, NULL);
|
||||
auto val { xdp_settings_read_value(app->m_xdp.settings,
|
||||
"org.freedesktop.appearance", "accent-color", NULL, NULL) };
|
||||
if (val) {
|
||||
gdouble r, g, b;
|
||||
g_variant_get(val, "(ddd)", &r, &g, &b);
|
||||
@@ -625,8 +627,8 @@ auto App::init_theme_portal() -> void
|
||||
else
|
||||
m_active_theme = Theme::Light;
|
||||
|
||||
auto val = xdp_settings_read_value(m_xdp.settings,
|
||||
"org.freedesktop.appearance", "accent-color", NULL, NULL);
|
||||
auto val { xdp_settings_read_value(m_xdp.settings,
|
||||
"org.freedesktop.appearance", "accent-color", NULL, NULL) };
|
||||
if (val) {
|
||||
gdouble r, g, b;
|
||||
g_variant_get(val, "(ddd)", &r, &g, &b);
|
||||
@@ -689,9 +691,9 @@ auto App::create_layer_surface() -> void
|
||||
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND);
|
||||
}
|
||||
|
||||
auto handle_layer_configure = [](void *data, zwlr_layer_surface_v1 *ls,
|
||||
u32 serial, u32 w, u32 h) -> void {
|
||||
auto *app = static_cast<App *>(data);
|
||||
auto handle_layer_configure { [](void *data, zwlr_layer_surface_v1 *ls,
|
||||
u32 serial, u32 w, u32 h) -> void {
|
||||
auto *app { static_cast<App *>(data) };
|
||||
if (w)
|
||||
app->m_win_w = static_cast<int>(w);
|
||||
if (h)
|
||||
@@ -714,11 +716,11 @@ auto App::create_layer_surface() -> void
|
||||
|
||||
if (app->m_wayland.surface)
|
||||
wl_surface_commit(app->m_wayland.surface);
|
||||
};
|
||||
} };
|
||||
|
||||
auto handle_layer_closed = [](void *data, zwlr_layer_surface_v1 *) -> void {
|
||||
auto handle_layer_closed { [](void *data, zwlr_layer_surface_v1 *) -> void {
|
||||
static_cast<App *>(data)->m_running = false;
|
||||
};
|
||||
} };
|
||||
|
||||
static zwlr_layer_surface_v1_listener const lsl = {
|
||||
.configure = handle_layer_configure,
|
||||
@@ -837,7 +839,7 @@ auto App::process_pending_text_input() -> void
|
||||
if (!m_wayland.text_input)
|
||||
return;
|
||||
|
||||
auto focused = m_gui->focused_text_input();
|
||||
auto focused { m_gui->focused_text_input() };
|
||||
if (!focused || *focused != m_ime.bound_id) {
|
||||
m_ime.pending = {};
|
||||
m_ime.pending_done = false;
|
||||
@@ -868,16 +870,16 @@ auto App::process_pending_text_input() -> void
|
||||
}
|
||||
|
||||
auto App::update_text_input_state(
|
||||
std::pmr::string const &text, std::size_t id, Rectangle field_rect) -> void
|
||||
std::pmr::string const &text, usize id, Rectangle field_rect) -> void
|
||||
{
|
||||
if (!m_wayland.text_input || !m_ime.supported || !m_gui)
|
||||
return;
|
||||
|
||||
m_ime.bound_rect = field_rect;
|
||||
|
||||
auto focused = m_gui->focused_text_input();
|
||||
bool const has_focus = focused && (*focused == id);
|
||||
bool const should_enable = has_focus && m_ime.seat_focus;
|
||||
auto focused { m_gui->focused_text_input() };
|
||||
bool const has_focus { focused && (*focused == id) };
|
||||
bool const should_enable { has_focus && m_ime.seat_focus };
|
||||
|
||||
if (!should_enable) {
|
||||
if (m_ime.enabled) {
|
||||
@@ -902,7 +904,7 @@ auto App::update_text_input_state(
|
||||
state_dirty = true;
|
||||
}
|
||||
|
||||
if (auto info = m_gui->text_input_surrounding(id, text)) {
|
||||
if (auto info { m_gui->text_input_surrounding(id, text) }) {
|
||||
auto slice
|
||||
= clamp_surrounding_text(info->text, info->cursor, info->anchor);
|
||||
if (m_ime.surrounding_dirty || slice.text != m_ime.last_surrounding
|
||||
@@ -917,7 +919,7 @@ auto App::update_text_input_state(
|
||||
}
|
||||
}
|
||||
|
||||
if (auto cursor_info = m_gui->text_input_cursor(id)) {
|
||||
if (auto cursor_info { m_gui->text_input_cursor(id) }) {
|
||||
Rectangle rect = cursor_info->rect;
|
||||
int32_t const x = static_cast<int32_t>(std::round(rect.x));
|
||||
int32_t const y = static_cast<int32_t>(std::round(rect.y));
|
||||
@@ -958,8 +960,8 @@ auto App::pump_events() -> void
|
||||
pollfd fds[2] { { wl_display_get_fd(m_wayland.display), POLLIN, 0 },
|
||||
{ m_sfd, POLLIN, 0 } };
|
||||
|
||||
auto prepared = (wl_display_prepare_read(m_wayland.display) == 0);
|
||||
auto ret = poll(fds, 2, 0);
|
||||
auto prepared { (wl_display_prepare_read(m_wayland.display) == 0) };
|
||||
auto ret { poll(fds, 2, 0) };
|
||||
|
||||
if (ret > 0 && (fds[0].revents & POLLIN)) {
|
||||
if (prepared) {
|
||||
|
||||
Reference in New Issue
Block a user