mirror of
https://github.com/hyprwm/hyprpaper.git
synced 2025-12-20 04:30:02 +01:00
fix for api
This commit is contained in:
parent
9dcadcb0ea
commit
621bc728e1
2 changed files with 60 additions and 115 deletions
|
|
@ -6,67 +6,11 @@
|
|||
|
||||
using namespace IPC;
|
||||
|
||||
constexpr const uint32_t PROTOCOL_VERSION = 1;
|
||||
constexpr const uint32_t TAVERN_PROTOCOL_VERSION = 1;
|
||||
constexpr const uint32_t PAPER_PROTOCOL_VERSION = 1;
|
||||
|
||||
static SP<CCHpHyprtavernCoreV1Impl> impl = makeShared<CCHpHyprtavernCoreV1Impl>(PROTOCOL_VERSION);
|
||||
|
||||
CTavernPeer::CTavernPeer(SP<Hyprwire::IServerSocket> sock, WP<CTavernConnection> conn) : m_socket(sock), m_connection(conn) {
|
||||
m_impl = makeShared<CHyprpaperCoreImpl>(1, [this](SP<Hyprwire::IObject> obj) {
|
||||
auto manager = m_managers.emplace_back(makeShared<CHyprpaperCoreManagerObject>(std::move(obj)));
|
||||
|
||||
// We disconnect on destroying the manager. TODO: disconnect when the peer disconnects?
|
||||
manager->setDestroy([this, weak = WP<CHyprpaperCoreManagerObject>{manager}] {
|
||||
m_connection->dropPeer(this);
|
||||
std::erase(m_managers, weak);
|
||||
});
|
||||
manager->setOnDestroy([this, weak = WP<CHyprpaperCoreManagerObject>{manager}] {
|
||||
m_connection->dropPeer(this);
|
||||
std::erase(m_managers, weak);
|
||||
});
|
||||
|
||||
manager->setGetWallpaperObject([this, weak = WP<CHyprpaperCoreManagerObject>{manager}](uint32_t id) {
|
||||
if (!weak)
|
||||
return;
|
||||
|
||||
m_wallpaperObjects.emplace_back(makeShared<CWallpaperObject>(
|
||||
makeShared<CHyprpaperWallpaperObject>(m_socket->createObject(weak->getObject()->client(), weak->getObject(), "hyprpaper_wallpaper", id))));
|
||||
});
|
||||
});
|
||||
|
||||
m_socket->addImplementation(m_impl);
|
||||
}
|
||||
|
||||
CTavernPeer::~CTavernPeer() {
|
||||
if (!g_ui || m_fd < 0)
|
||||
return;
|
||||
|
||||
g_ui->backend()->removeFd(m_fd);
|
||||
}
|
||||
|
||||
void CTavernPeer::onNewDisplay(const std::string& sv) {
|
||||
for (const auto& m : m_managers) {
|
||||
m->sendAddMonitor(sv.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CTavernPeer::onRemovedDisplay(const std::string& sv) {
|
||||
for (const auto& m : m_managers) {
|
||||
m->sendRemoveMonitor(sv.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
int CTavernPeer::extractFD() {
|
||||
if (m_fd >= 0)
|
||||
return m_fd;
|
||||
|
||||
m_fd = m_socket->extractLoopFD();
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
void CTavernPeer::dispatch() {
|
||||
if (!m_socket->dispatchEvents())
|
||||
m_connection->dropPeer(this);
|
||||
}
|
||||
static SP<CCHpHyprtavernCoreV1Impl> tavernImpl = makeShared<CCHpHyprtavernCoreV1Impl>(TAVERN_PROTOCOL_VERSION);
|
||||
static SP<CHyprpaperCoreImpl> hyprpaperImpl;
|
||||
|
||||
CTavernConnection::CTavernConnection() = default;
|
||||
|
||||
|
|
@ -80,74 +24,91 @@ void CTavernConnection::init() {
|
|||
|
||||
const auto WL_DISPLAY = getenv("WAYLAND_DISPLAY");
|
||||
|
||||
m_socket = Hyprwire::IClientSocket::open(XDG_RUNTIME_DIR + std::string{"/hyprtavern/ht.sock"});
|
||||
m_tavern.socket = Hyprwire::IClientSocket::open(XDG_RUNTIME_DIR + std::string{"/hyprtavern/ht.sock"});
|
||||
|
||||
if (!m_socket) {
|
||||
if (!m_tavern.socket) {
|
||||
g_logger->log(LOG_ERR, "CTavernConnection: tavern is not serving beer, ignoring tavern");
|
||||
return;
|
||||
}
|
||||
|
||||
m_socket->addImplementation(impl);
|
||||
m_tavern.socket->addImplementation(tavernImpl);
|
||||
|
||||
if (!m_socket->waitForHandshake()) {
|
||||
if (!m_tavern.socket->waitForHandshake()) {
|
||||
g_logger->log(LOG_ERR, "CTavernConnection: failed a handshake to tavern");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto SPEC = m_socket->getSpec(impl->protocol()->specName());
|
||||
const auto SPEC = m_tavern.socket->getSpec(tavernImpl->protocol()->specName());
|
||||
|
||||
if (!SPEC) {
|
||||
g_logger->log(LOG_ERR, "CTavernConnection: tavern is bad (no protocol)");
|
||||
return;
|
||||
}
|
||||
|
||||
m_manager = makeShared<CCHpHyprtavernCoreManagerV1Object>(m_socket->bindProtocol(impl->protocol(), PROTOCOL_VERSION));
|
||||
m_tavern.manager = makeShared<CCHpHyprtavernCoreManagerV1Object>(m_tavern.socket->bindProtocol(tavernImpl->protocol(), TAVERN_PROTOCOL_VERSION));
|
||||
|
||||
m_busObject = makeShared<CCHpHyprtavernBusObjectV1Object>(m_manager->sendGetBusObject("hyprpaper"));
|
||||
m_tavern.busObject = makeShared<CCHpHyprtavernBusObjectV1Object>(m_tavern.manager->sendGetBusObject("hyprpaper"));
|
||||
|
||||
if (WL_DISPLAY)
|
||||
m_busObject->sendExposeProperty("GLOBAL:WAYLAND_DISPLAY", WL_DISPLAY);
|
||||
m_busObject->sendExposeProtocol("hyprpaper_core", 1);
|
||||
m_tavern.busObject->sendExposeProperty("GLOBAL:WAYLAND_DISPLAY", WL_DISPLAY);
|
||||
m_tavern.busObject->sendExposeProtocol("hyprpaper_core", 1);
|
||||
|
||||
m_busObject->setNewFd([this](int fd) {
|
||||
auto sock = Hyprwire::IServerSocket::open(fd);
|
||||
|
||||
if (!sock) {
|
||||
m_tavern.busObject->setNewFd([this](int fd) {
|
||||
if (!m_object.socket->addClient(fd)) {
|
||||
g_logger->log(LOG_ERR, "CTavernConnection: received a fd {} but it's dead", fd);
|
||||
return;
|
||||
}
|
||||
|
||||
auto x = m_peers.emplace_back(makeShared<CTavernPeer>(sock, m_self));
|
||||
g_logger->log(LOG_DEBUG, "CTavernConnection: new client at fd {}", fd);
|
||||
});
|
||||
|
||||
g_ui->backend()->addFd(x->extractFD(), [w = WP<CTavernPeer>{x}] {
|
||||
if (!w)
|
||||
g_ui->backend()->addFd(m_tavern.socket->extractLoopFD(), [this] { //
|
||||
m_tavern.socket->dispatchEvents();
|
||||
});
|
||||
|
||||
// open empty socket for paper protocol
|
||||
|
||||
m_object.socket = Hyprwire::IServerSocket::open();
|
||||
|
||||
if (!m_object.socket) {
|
||||
g_logger->log(LOG_ERR, "CTavernConnection: failed to open an empty socket for incoming connections");
|
||||
return;
|
||||
}
|
||||
|
||||
hyprpaperImpl = makeShared<CHyprpaperCoreImpl>(PAPER_PROTOCOL_VERSION, [this](SP<Hyprwire::IObject> obj) {
|
||||
auto manager = m_object.managers.emplace_back(makeShared<CHyprpaperCoreManagerObject>(std::move(obj)));
|
||||
|
||||
manager->setDestroy([this, weak = WP<CHyprpaperCoreManagerObject>{manager}] { std::erase(m_object.managers, weak); });
|
||||
manager->setOnDestroy([this, weak = WP<CHyprpaperCoreManagerObject>{manager}] { std::erase(m_object.managers, weak); });
|
||||
|
||||
manager->setGetWallpaperObject([this, weak = WP<CHyprpaperCoreManagerObject>{manager}](uint32_t id) {
|
||||
if (!weak)
|
||||
return;
|
||||
|
||||
w->dispatch();
|
||||
m_object.wallpaperObjects.emplace_back(makeShared<CWallpaperObject>(
|
||||
makeShared<CHyprpaperWallpaperObject>(m_object.socket->createObject(weak->getObject()->client(), weak->getObject(), "hyprpaper_wallpaper", id))));
|
||||
});
|
||||
});
|
||||
|
||||
g_ui->backend()->addFd(m_socket->extractLoopFD(), [this] { //
|
||||
m_socket->dispatchEvents();
|
||||
m_object.socket->addImplementation(hyprpaperImpl);
|
||||
|
||||
g_ui->backend()->addFd(m_object.socket->extractLoopFD(), [this] { //
|
||||
m_object.socket->dispatchEvents();
|
||||
});
|
||||
}
|
||||
|
||||
bool CTavernConnection::connected() {
|
||||
return m_busObject;
|
||||
}
|
||||
|
||||
void CTavernConnection::dropPeer(CTavernPeer* peer) {
|
||||
std::erase_if(m_peers, [peer](const auto& e) { return e.get() == peer; });
|
||||
return m_object.socket;
|
||||
}
|
||||
|
||||
void CTavernConnection::onNewDisplay(const std::string& sv) {
|
||||
for (const auto& p : m_peers) {
|
||||
p->onNewDisplay(sv);
|
||||
for (const auto& p : m_object.managers) {
|
||||
p->sendAddMonitor(sv.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CTavernConnection::onRemovedDisplay(const std::string& sv) {
|
||||
for (const auto& p : m_peers) {
|
||||
p->onRemovedDisplay(sv);
|
||||
for (const auto& p : m_object.managers) {
|
||||
p->sendRemoveMonitor(sv.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,28 +10,6 @@ namespace IPC {
|
|||
class CWallpaperObject;
|
||||
class CTavernConnection;
|
||||
|
||||
class CTavernPeer {
|
||||
public:
|
||||
CTavernPeer(SP<Hyprwire::IServerSocket> sock, WP<CTavernConnection> conn);
|
||||
~CTavernPeer();
|
||||
|
||||
int extractFD();
|
||||
|
||||
void onNewDisplay(const std::string& sv);
|
||||
void onRemovedDisplay(const std::string& sv);
|
||||
|
||||
void dispatch();
|
||||
|
||||
private:
|
||||
SP<Hyprwire::IServerSocket> m_socket;
|
||||
int m_fd = -1;
|
||||
SP<CHyprpaperCoreImpl> m_impl;
|
||||
WP<CTavernConnection> m_connection;
|
||||
|
||||
std::vector<SP<CHyprpaperCoreManagerObject>> m_managers;
|
||||
std::vector<SP<CWallpaperObject>> m_wallpaperObjects;
|
||||
};
|
||||
|
||||
class CTavernConnection {
|
||||
public:
|
||||
CTavernConnection();
|
||||
|
|
@ -42,17 +20,23 @@ namespace IPC {
|
|||
WP<CTavernConnection> m_self;
|
||||
|
||||
bool connected();
|
||||
void dropPeer(CTavernPeer* peer);
|
||||
|
||||
void onNewDisplay(const std::string& sv);
|
||||
void onRemovedDisplay(const std::string& sv);
|
||||
|
||||
private:
|
||||
SP<Hyprwire::IClientSocket> m_socket;
|
||||
SP<CCHpHyprtavernCoreManagerV1Object> m_manager;
|
||||
SP<CCHpHyprtavernBusObjectV1Object> m_busObject;
|
||||
struct {
|
||||
SP<Hyprwire::IClientSocket> socket;
|
||||
SP<CCHpHyprtavernCoreManagerV1Object> manager;
|
||||
SP<CCHpHyprtavernBusObjectV1Object> busObject;
|
||||
} m_tavern;
|
||||
|
||||
std::vector<SP<CTavernPeer>> m_peers;
|
||||
struct {
|
||||
SP<Hyprwire::IServerSocket> socket;
|
||||
|
||||
std::vector<SP<CHyprpaperCoreManagerObject>> managers;
|
||||
std::vector<SP<CWallpaperObject>> wallpaperObjects;
|
||||
} m_object;
|
||||
};
|
||||
|
||||
inline UP<CTavernConnection> g_tavernConnection;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue