Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipc enhancements #2143

Merged
merged 5 commits into from
Feb 16, 2024
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
11 changes: 7 additions & 4 deletions ipc-scripts/inactive-alpha.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@

addr = os.getenv('WAYFIRE_SOCKET')
sock = WayfireSocket(addr)
sock.watch()
sock.watch(['view-focused'])

last_focused_toplevel = -1
while True:
msg = sock.read_message()
# The view-mapped event is emitted when a new window has been opened.
if "event" in msg and msg["event"] == "view-focused":
if "event" in msg:
print(msg["event"])
view = msg["view"]
print(view)
new_focus = view["id"] if view and view["type"] == "toplevel" else -1
if last_focused_toplevel != new_focus:
if last_focused_toplevel != -1 and new_focus != -1:
sock.set_view_alpha(last_focused_toplevel, 0.8)
try:
sock.set_view_alpha(last_focused_toplevel, 0.8)
except:
print("Last focused toplevel was closed?")

if new_focus != -1:
sock.set_view_alpha(new_focus, 1.0)
Expand Down
4 changes: 2 additions & 2 deletions ipc-scripts/ipc-rules-demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
# We could use the same socket, but this would complicate reading responses, as events and query responses would be mixed with just one socket.
events_sock = WayfireSocket(addr)
commands_sock = WayfireSocket(addr)
events_sock.watch()
events_sock.watch(['view-mapped'])

while True:
msg = events_sock.read_message()
# The view-mapped event is emitted when a new window has been opened.
if "event" in msg and msg["event"] == "view-mapped":
if "event" in msg:
view = msg["view"]
if view["app-id"] == "gedit":
output_data = commands_sock.query_output(view["output"])
Expand Down
5 changes: 5 additions & 0 deletions ipc-scripts/list-methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
addr = os.getenv('WAYFIRE_SOCKET')
sock = ws.WayfireSocket(addr)

query = ws.get_msg_template('wayfire/configuration')
response = sock.send_json(query)
print("Wayfire version:")
print(json.dumps(response, indent=4))

query = ws.get_msg_template('list-methods')
response = sock.send_json(query)
print("Supported methods:")
Expand Down
4 changes: 3 additions & 1 deletion ipc-scripts/wayfire_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ def send_json(self, msg):
def close(self):
self.client.close()

def watch(self):
def watch(self, events = None):
message = get_msg_template("window-rules/events/watch")
if events:
message["data"]["events"] = events
return self.send_json(message)

def query_output(self, output_id: int):
Expand Down
21 changes: 4 additions & 17 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ project(
'cpp',
version: '0.9.0',
license: 'MIT',
meson_version: '>=0.56.0',
meson_version: '>=0.63.0',
default_options: [
'cpp_std=c++17',
'c_std=c11',
Expand All @@ -13,6 +13,9 @@ project(
],
)

version = '"@0@"'.format(meson.project_version())
add_project_arguments('-DWAYFIRE_VERSION=@0@'.format(version), language: 'cpp')

wayfire_api_inc = include_directories('src/api')

wayland_server = dependency('wayland-server')
Expand Down Expand Up @@ -83,22 +86,6 @@ backtrace = meson.get_compiler('cpp').find_library('execinfo', required: false)

conf_data = configuration_data()

version = '"@0@"'.format(meson.project_version())
git = find_program('git', native: true, required: false)
if git.found()
git_commit = run_command([git, 'rev-parse', '--short', 'HEAD'], check: false)
git_branch = run_command([git, 'rev-parse', '--abbrev-ref', 'HEAD'], check: false)
if git_commit.returncode() == 0 and git_branch.returncode() == 0
version = '"@0@-@1@ (" __DATE__ ", branch \'@2@\')"'.format(
meson.project_version(),
git_commit.stdout().strip(),
git_branch.stdout().strip(),
)
endif
endif
add_project_arguments('-DWAYFIRE_VERSION=@0@'.format(version), language: 'cpp')
conf_data.set('WAYFIRE_VERSION', '-DWAYFIRE_VERSION=@0@'.format(version))

conf_data.set('INSTALL_PREFIX', get_option('prefix'))
conf_data.set('PLUGIN_PATH', join_paths(get_option('prefix'), get_option('libdir'), 'wayfire'))
metadata_dir_suffix = 'share/wayfire/metadata'
Expand Down
3 changes: 2 additions & 1 deletion plugins/ipc/ipc-method-repository.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ inline nlohmann::json json_error(std::string msg)
#define WFJSON_OPTIONAL_FIELD(data, field, type) \
if (data.count(field) && !data[field].is_ ## type()) \
{ \
return wf::ipc::json_error("Field \"" field "\" does not have the correct type " #type); \
return wf::ipc::json_error("Field \"" + std::string(field) + \
"\" does not have the correct type " #type); \
}
}
}
60 changes: 55 additions & 5 deletions plugins/single_plugins/ipc-rules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "wayfire/window-manager.hpp"
#include "wayfire/workarea.hpp"
#include "config.h"
#include <wayfire/debug.hpp>
#include <wayfire/nonstd/wlroots-full.hpp>


Expand Down Expand Up @@ -128,6 +129,7 @@ class ipc_rules_t : public wf::plugin_interface_t, public wf::per_output_tracker
public:
void init() override
{
method_repository->register_method("wayfire/configuration", get_wayfire_configuration_info);
method_repository->register_method("input/list-devices", list_input_devices);
method_repository->register_method("input/configure-device", configure_input_device);
method_repository->register_method("window-rules/events/watch", on_client_watch);
Expand All @@ -142,11 +144,14 @@ class ipc_rules_t : public wf::plugin_interface_t, public wf::per_output_tracker
wf::get_core().connect(&on_view_mapped);
wf::get_core().connect(&on_view_unmapped);
wf::get_core().connect(&on_kbfocus_changed);
wf::get_core().connect(&on_title_changed);
wf::get_core().connect(&on_app_id_changed);
init_output_tracking();
}

void fini() override
{
method_repository->unregister_method("wayfire/configuration");
method_repository->unregister_method("input/list-devices");
method_repository->unregister_method("input/configure-device");
method_repository->unregister_method("window-rules/events/watch");
Expand All @@ -172,6 +177,20 @@ class ipc_rules_t : public wf::plugin_interface_t, public wf::per_output_tracker
// no-op
}

wf::ipc::method_callback get_wayfire_configuration_info = [=] (nlohmann::json)
{
nlohmann::json response;

response["api-version"] = WAYFIRE_API_ABI_VERSION;
response["plugin-path"] = PLUGIN_PATH;
response["plugin-xml-dir"] = PLUGIN_XML_DIR;
response["xwayland-support"] = WF_HAS_XWAYLAND;

response["build-commit"] = wf::version::git_commit;
response["build-branch"] = wf::version::git_branch;
return response;
};

wf::ipc::method_callback list_views = [=] (nlohmann::json)
{
auto response = nlohmann::json::array();
Expand Down Expand Up @@ -317,12 +336,28 @@ class ipc_rules_t : public wf::plugin_interface_t, public wf::per_output_tracker
wf::shared_data::ref_ptr_t<wf::ipc::method_repository_t> method_repository;

// Track a list of clients which have requested watch
std::set<wf::ipc::client_interface_t*> clients;
std::map<wf::ipc::client_interface_t*, std::set<std::string>> clients;

wf::ipc::method_callback_full on_client_watch =
[=] (nlohmann::json data, wf::ipc::client_interface_t *client)
{
clients.insert(client);
static constexpr const char *EVENTS = "events";
WFJSON_OPTIONAL_FIELD(data, EVENTS, array);
std::set<std::string> subscribed_to;
if (data.contains(EVENTS))
{
for (auto& sub : data[EVENTS])
{
if (!sub.is_string())
{
return wf::ipc::json_error("Event list contains non-string entries!");
}

subscribed_to.insert((std::string)sub);
}
}

clients[client] = subscribed_to;
return wf::ipc::json_ok();
};

Expand All @@ -337,9 +372,12 @@ class ipc_rules_t : public wf::plugin_interface_t, public wf::per_output_tracker
nlohmann::json event;
event["event"] = event_name;
event["view"] = view_to_json(view);
for (auto& client : clients)
for (auto& [client, events] : clients)
{
client->send_json(event);
if (events.empty() || events.count(event_name))
{
client->send_json(event);
}
}
}

Expand Down Expand Up @@ -377,6 +415,18 @@ class ipc_rules_t : public wf::plugin_interface_t, public wf::per_output_tracker
send_view_to_subscribes(ev->view, "view-fullscreen");
};

wf::signal::connection_t<wf::view_title_changed_signal> on_title_changed =
[=] (wf::view_title_changed_signal *ev)
{
send_view_to_subscribes(ev->view, "view-title-changed");
};

wf::signal::connection_t<wf::view_app_id_changed_signal> on_app_id_changed =
[=] (wf::view_app_id_changed_signal *ev)
{
send_view_to_subscribes(ev->view, "view-app-id-changed");
};

std::string get_view_type(wayfire_view view)
{
if (view->role == wf::VIEW_ROLE_TOPLEVEL)
Expand Down Expand Up @@ -504,7 +554,7 @@ class ipc_rules_t : public wf::plugin_interface_t, public wf::per_output_tracker
wl_client_get_credentials(view->get_client(), &pid, 0, 0);
}

return pid;
return pid; // NOLINT
}
};

Expand Down
10 changes: 10 additions & 0 deletions src/api/wayfire/debug.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ namespace wf
*/
void dump_scene(scene::node_ptr root = wf::get_core().scene());

/**
* Information about the version that Wayfire was built with.
* Made available at runtime.
*/
namespace version
{
extern std::string git_commit;
extern std::string git_branch;
}

namespace log
{
/**
Expand Down
4 changes: 2 additions & 2 deletions src/api/wayfire/signal-definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ struct view_set_sticky_signal
};

/**
* on: view
* on: view, core
* when: After the view's title has changed.
*/
struct view_title_changed_signal
Expand All @@ -588,7 +588,7 @@ struct view_title_changed_signal
};

/**
* on: view
* on: view, core
* when: After the view's app-id has changed.
*/
struct view_app_id_changed_signal
Expand Down
7 changes: 2 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,22 @@
#include <iostream>
#include <getopt.h>
#include <signal.h>
#include <map>
#include <fcntl.h>
#include <filesystem>

#include <unistd.h>
#include <wayfire/debug.hpp>
#include "main.hpp"
#include "wayfire/nonstd/safe-list.hpp"

#include <wayland-server.h>

#include "wayfire/config-backend.hpp"
#include "core/plugin-loader.hpp"
#include "core/core-impl.hpp"
#include "wayfire/output.hpp"

static void print_version()
{
std::cout << WAYFIRE_VERSION << std::endl;
std::cout << WAYFIRE_VERSION << "-" << wf::version::git_commit <<
" (" __DATE__ ") branch " << wf::version::git_branch << std::endl;
exit(0);
}

Expand Down
18 changes: 17 additions & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,22 @@ if print_trace
debug_arguments += ['-DPRINT_TRACE']
endif

# Generate information about Wayfire version
git = find_program('git', native: true, required: false)
git_commit_info = vcs_tag(
input: 'version/git-commit.cpp.in',
output: 'git-commit.cpp',
replace_string: '@GIT_COMMIT@',
command: git.found() ? [git, 'rev-parse', '--short', 'HEAD'] : ['echo', 'unknown'],
fallback: 'unknown')

git_branch_info = vcs_tag(
input: 'version/git-branch.cpp.in',
output: 'git-branch.cpp',
replace_string: '@GIT_BRANCH@',
command: git.found() ? [git, 'rev-parse', '--abbrev-ref', 'HEAD'] : ['echo', 'unknown'],
fallback: 'unknown')

# First build a static library of all sources, so that it can be reused
# in tests
libwayfire_sta = static_library('libwayfire', wayfire_sources,
Expand All @@ -105,7 +121,7 @@ libwayfire = declare_dependency(link_whole: libwayfire_sta,
tests_include_dirs = include_directories('.')

# Generate main executable
executable('wayfire', ['main.cpp'],
executable('wayfire', ['main.cpp', git_commit_info, git_branch_info],
dependencies: libwayfire,
install: true,
cpp_args: debug_arguments)
Expand Down
9 changes: 9 additions & 0 deletions src/version/git-branch.cpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <wayfire/debug.hpp>

namespace wf
{
namespace version
{
std::string git_branch = "@GIT_BRANCH@";
}
}
9 changes: 9 additions & 0 deletions src/version/git-commit.cpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <wayfire/debug.hpp>

namespace wf
{
namespace version
{
std::string git_commit = "@GIT_COMMIT@";
}
}
2 changes: 2 additions & 0 deletions src/view/view-impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,15 @@ void wf::view_implementation::emit_title_changed_signal(wayfire_view view)
view_title_changed_signal data;
data.view = view;
view->emit(&data);
wf::get_core().emit(&data);
}

void wf::view_implementation::emit_app_id_changed_signal(wayfire_view view)
{
view_app_id_changed_signal data;
data.view = view;
view->emit(&data);
wf::get_core().emit(&data);
}

void wf::view_implementation::emit_toplevel_state_change_signals(wayfire_toplevel_view view,
Expand Down
Loading