diff --git a/src/panel/panel.cpp b/src/panel/panel.cpp index 0864fb1f..e31615c6 100644 --- a/src/panel/panel.cpp +++ b/src/panel/panel.cpp @@ -200,7 +200,15 @@ class WayfirePanel::impl if (name == "language") { - return Widget(new WayfireLanguage()); + if (WayfireIPC::get_instance()->connected) + { + return Widget(new WayfireLanguage()); + } else + { + std::cerr << "Wayfire IPC not connected, which is required to load language widget." << + std::endl; + return nullptr; + } } if (auto pixel = widget_with_value(name, "spacing")) diff --git a/src/panel/widgets/language.cpp b/src/panel/widgets/language.cpp index 1d4432ec..00c65308 100644 --- a/src/panel/widgets/language.cpp +++ b/src/panel/widgets/language.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -25,6 +26,13 @@ void WayfireLanguage::init(Gtk::Box *container) ipc_client->subscribe(this, {"keyboard-modifier-state-changed"}); ipc_client->send("{\"method\":\"wayfire/get-keyboard-state\"}", [=] (wf::json_t data) { + if (data.serialize().find( + "error") != std::string::npos) + { + std::cerr << "Error getting keyboard state for language widget. Is wayfire ipc-rules plugin enabled?" << std::endl; + return; + } + set_available(data["possible-layouts"]); set_current(data["layout-index"]); }); diff --git a/src/util/wf-ipc.cpp b/src/util/wf-ipc.cpp index f5c1c4d9..0d81dc85 100644 --- a/src/util/wf-ipc.cpp +++ b/src/util/wf-ipc.cpp @@ -1,63 +1,70 @@ +#include +#include +#include +#include + +#include +#include #include #include -#include -#include -#include -#include #include #include -#include -#include #include -#include -#include -#include -#include -#include -#include + #include #include "wf-ipc.hpp" -#include "giomm/cancellable.h" -#include "giomm/error.h" -#include "giomm/socketclient.h" -#include "giomm/unixsocketaddress.h" -#include "glibconfig.h" -#include "glibmm/error.h" -#include "glibmm/iochannel.h" -#include "glibmm/main.h" -#include "sigc++/functors/mem_fun.h" WayfireIPC::WayfireIPC() { - connect(); + if (connect()) + { + sig_connection = Glib::signal_io().connect( + sigc::mem_fun(*this, &WayfireIPC::receive), + connection->get_socket()->get_fd(), + Glib::IOCondition::IO_IN); - sig_connection = Glib::signal_io().connect( - sigc::mem_fun(*this, &WayfireIPC::receive), - connection->get_socket()->get_fd(), - Glib::IOCondition::IO_IN); + connected = true; + } else + { + std::cerr << "Failed to connect to WAYFIRE_SOCKET. Is wayfire ipc plugin enabled?" << std::endl; + } } WayfireIPC::~WayfireIPC() { - disconnect(); + if (connected) + { + disconnect(); + } } -void WayfireIPC::connect() +bool WayfireIPC::connect() { const char *socket_path = getenv("WAYFIRE_SOCKET"); - if (socket_path == nullptr) + if (!socket_path || std::string(socket_path).empty()) + { + std::cerr << "Wayfire socket not found" << std::endl; + return false; + } + + try { + auto client = Gio::SocketClient::create(); + auto address = Gio::UnixSocketAddress::create(socket_path); + connection = client->connect(address); + connection->get_socket()->set_blocking(false); + output = connection->get_output_stream(); + input = connection->get_input_stream(); + cancel = Gio::Cancellable::create(); + + return true; + } catch (const Glib::Error& ex) { - throw std::runtime_error("Wayfire socket not found"); + std::cerr << "Error connecting to WAYFIRE_SOCKET at path \"" << socket_path << "\": " << ex.what(); + return false; } - auto client = Gio::SocketClient::create(); - auto address = Gio::UnixSocketAddress::create(socket_path); - connection = client->connect(address); - connection->get_socket()->set_blocking(false); - output = connection->get_output_stream(); - input = connection->get_input_stream(); - cancel = Gio::Cancellable::create(); + return false; } void WayfireIPC::disconnect() diff --git a/src/util/wf-ipc.hpp b/src/util/wf-ipc.hpp index 35a4f7e3..d9496a14 100644 --- a/src/util/wf-ipc.hpp +++ b/src/util/wf-ipc.hpp @@ -1,11 +1,8 @@ #pragma once -#include -#include -#include -#include -#include -#include +#include +#include + #include #include #include @@ -15,6 +12,8 @@ #include #include +#include + class IIPCSubscriber { public: @@ -26,6 +25,7 @@ using response_handler = std::function; class WayfireIPC; class IPCClient { + private: int id; std::shared_ptr ipc; std::queue response_handlers; @@ -44,6 +44,7 @@ class IPCClient class WayfireIPC : public std::enable_shared_from_this { + private: std::queue response_handlers; std::set subscribers; std::unordered_map> subscriptions; @@ -57,7 +58,7 @@ class WayfireIPC : public std::enable_shared_from_this std::queue write_queue; bool writing = false; - void connect(); + bool connect(); void disconnect(); void send_message(const std::string& message); bool send_queue(Glib::IOCondition cond); @@ -75,6 +76,7 @@ class WayfireIPC : public std::enable_shared_from_this void client_destroyed(int id); static std::shared_ptr get_instance(); + bool connected = false; WayfireIPC(); ~WayfireIPC(); };