fix: some crashes

This commit is contained in:
Alex
2026-02-24 00:49:03 +01:00
parent a32413a74f
commit ef3d55980e
40 changed files with 216 additions and 103 deletions

View File

@@ -9,6 +9,7 @@
#include <bit>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <exception>
#include <ranges>
#include <thread>
@@ -32,7 +33,13 @@ auto pack_and_write(Sock& sock, std::string&& buf) -> void {
auto read_exact(Sock& sock, size_t n) -> std::string {
auto buf = std::string(n, 0);
for (size_t i = 0; i < n;) i += read(sock.fd, &buf[i], n - i);
for (size_t i = 0; i < n;) {
auto r = read(sock.fd, &buf[i], n - i);
if (r <= 0) {
throw std::runtime_error("Wayfire IPC: read failed");
}
i += static_cast<size_t>(r);
}
return buf;
}
@@ -53,6 +60,9 @@ auto State::Wset::locate_ws(const Json::Value& geo) -> Workspace& {
}
auto State::Wset::locate_ws(const Json::Value& geo) const -> const Workspace& {
if (!output.has_value()) {
throw std::runtime_error("Wayfire IPC: wset has no output assigned");
}
const auto& out = output.value().get();
auto [qx, rx] = std::div(geo["x"].asInt(), out.w);
auto [qy, ry] = std::div(geo["y"].asInt(), out.h);
@@ -88,7 +98,10 @@ auto State::update_view(const Json::Value& view) -> void {
auto IPC::get_instance() -> std::shared_ptr<IPC> {
auto p = instance.lock();
if (!p) instance = p = std::shared_ptr<IPC>(new IPC);
if (!p) {
instance = p = std::shared_ptr<IPC>(new IPC);
p->start();
}
return p;
}
@@ -116,7 +129,9 @@ auto IPC::connect() -> Sock {
}
auto IPC::receive(Sock& sock) -> Json::Value {
auto len = *reinterpret_cast<uint32_t*>(read_exact(sock, 4).data());
auto len_buf = read_exact(sock, 4);
uint32_t len;
std::memcpy(&len, len_buf.data(), sizeof(len));
if constexpr (std::endian::native != std::endian::little) len = byteswap(len);
auto buf = read_exact(sock, len);
@@ -153,15 +168,15 @@ auto IPC::start() -> void {
send("window-rules/get-focused-view", {});
send("window-rules/get-focused-output", {});
std::thread([&] {
std::thread([self = shared_from_this()] {
auto sock = connect();
{
Json::Value json;
json["method"] = "window-rules/events/watch";
pack_and_write(sock, Json::writeString(writer_builder, json));
if (receive(sock)["result"] != "ok") {
pack_and_write(sock, Json::writeString(self->writer_builder, json));
if (self->receive(sock)["result"] != "ok") {
spdlog::error(
"Wayfire IPC: method \"window-rules/events/watch\""
" have failed");
@@ -169,10 +184,10 @@ auto IPC::start() -> void {
}
}
while (auto json = receive(sock)) {
while (auto json = self->receive(sock)) {
auto ev = json["event"].asString();
spdlog::debug("Wayfire IPC: received event \"{}\"", ev);
root_event_handler(ev, json);
self->root_event_handler(ev, json);
}
}).detach();
}