Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/panel/panel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand Down
8 changes: 8 additions & 0 deletions src/panel/widgets/language.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <iostream>
#include <cstddef>
#include <cstdint>

Expand Down Expand Up @@ -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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did uncrustify separate this into two lines? Doesn't seem necessary..

{
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"]);
});
Expand Down
81 changes: 44 additions & 37 deletions src/util/wf-ipc.cpp
Original file line number Diff line number Diff line change
@@ -1,63 +1,70 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <poll.h>

#include <sigc++/functors/mem_fun.h>
#include <iostream>
#include <cstdint>
#include <cstdlib>
#include <fcntl.h>
#include <functional>
#include <giomm/enums.h>
#include <glibmm/iochannel.h>
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <string_view>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <poll.h>
#include <vector>
#include <wayfire/nonstd/json.hpp>

#include <wayfire/util/log.hpp>

#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()
Expand Down
16 changes: 9 additions & 7 deletions src/util/wf-ipc.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
#pragma once

#include <giomm/cancellable.h>
#include <giomm/outputstream.h>
#include <giomm/socketconnection.h>
#include <glibmm/iochannel.h>
#include <glibmm/refptr.h>
#include <wayfire/nonstd/json.hpp>
#include <glibmm.h>
#include <giomm.h>

#include <sigc++/connection.h>
#include <functional>
#include <memory>
Expand All @@ -15,6 +12,8 @@
#include <unordered_map>
#include <vector>

#include <wayfire/nonstd/json.hpp>

class IIPCSubscriber
{
public:
Expand All @@ -26,6 +25,7 @@ using response_handler = std::function<void (wf::json_t)>;
class WayfireIPC;
class IPCClient
{
private:
int id;
std::shared_ptr<WayfireIPC> ipc;
std::queue<response_handler> response_handlers;
Expand All @@ -44,6 +44,7 @@ class IPCClient

class WayfireIPC : public std::enable_shared_from_this<WayfireIPC>
{
private:
std::queue<int> response_handlers;
std::set<IIPCSubscriber*> subscribers;
std::unordered_map<std::string, std::set<IIPCSubscriber*>> subscriptions;
Expand All @@ -57,7 +58,7 @@ class WayfireIPC : public std::enable_shared_from_this<WayfireIPC>
std::queue<std::string> write_queue;
bool writing = false;

void connect();
bool connect();
void disconnect();
void send_message(const std::string& message);
bool send_queue(Glib::IOCondition cond);
Expand All @@ -75,6 +76,7 @@ class WayfireIPC : public std::enable_shared_from_this<WayfireIPC>
void client_destroyed(int id);

static std::shared_ptr<WayfireIPC> get_instance();
bool connected = false;
WayfireIPC();
~WayfireIPC();
};
Loading