From d48c2998e30e08b4cf151d3d1d7b2ea71978bc33 Mon Sep 17 00:00:00 2001 From: Michael Weiser Date: Thu, 15 Apr 2021 19:34:56 +0200 Subject: [PATCH] Add idle-inhibitor ipc subscription type Add a new type of ipc subscription so clients can be notified of changes in idle inhibitors. This allows to react to those events by e.g. changing container properties (title, ...) to notify the user about this circumstance (add marker, change color, ...). For this reason the event includes information about the affected container as well. Signed-off-by: Michael Weiser --- include/ipc.h | 1 + include/sway/desktop/idle_inhibit_v1.h | 4 +++ include/sway/ipc-json.h | 4 +++ include/sway/ipc-server.h | 2 ++ sway/commands/inhibit_idle.c | 2 +- sway/desktop/idle_inhibit_v1.c | 15 ++++++++++++ sway/ipc-json.c | 34 ++++++++++++++++++++++++++ sway/ipc-server.c | 17 +++++++++++++ 8 files changed, 78 insertions(+), 1 deletion(-) diff --git a/include/ipc.h b/include/ipc.h index ff0117502..9deafff43 100644 --- a/include/ipc.h +++ b/include/ipc.h @@ -36,6 +36,7 @@ enum ipc_command_type { // sway-specific event types IPC_EVENT_BAR_STATE_UPDATE = ((1<<31) | 20), IPC_EVENT_INPUT = ((1<<31) | 21), + IPC_EVENT_IDLE_INHIBITOR = ((1<<31) | 22), }; #endif diff --git a/include/sway/desktop/idle_inhibit_v1.h b/include/sway/desktop/idle_inhibit_v1.h index 84cc666d0..047762450 100644 --- a/include/sway/desktop/idle_inhibit_v1.h +++ b/include/sway/desktop/idle_inhibit_v1.h @@ -39,6 +39,10 @@ struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view( struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_application_inhibitor_for_view( struct sway_view *view); +void sway_idle_inhibit_v1_user_inhibitor_update_mode( + struct sway_idle_inhibitor_v1 *inhibitor, + enum sway_idle_inhibit_mode mode); + void sway_idle_inhibit_v1_user_inhibitor_destroy( struct sway_idle_inhibitor_v1 *inhibitor); diff --git a/include/sway/ipc-json.h b/include/sway/ipc-json.h index bc9f49856..665203503 100644 --- a/include/sway/ipc-json.h +++ b/include/sway/ipc-json.h @@ -3,7 +3,9 @@ #include #include "sway/output.h" #include "sway/tree/container.h" +#include "sway/desktop/idle_inhibit_v1.h" #include "sway/input/input-manager.h" +#include "sway/tree/container.h" json_object *ipc_json_get_version(void); @@ -16,5 +18,7 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node); json_object *ipc_json_describe_input(struct sway_input_device *device); json_object *ipc_json_describe_seat(struct sway_seat *seat); json_object *ipc_json_describe_bar_config(struct bar_config *bar); +json_object *ipc_json_describe_idle_inhibitor( + struct sway_idle_inhibitor_v1 *sway_inhibitor); #endif diff --git a/include/sway/ipc-server.h b/include/sway/ipc-server.h index d4c009427..8e5336f1d 100644 --- a/include/sway/ipc-server.h +++ b/include/sway/ipc-server.h @@ -2,6 +2,7 @@ #define _SWAY_IPC_SERVER_H #include #include "sway/config.h" +#include "sway/desktop/idle_inhibit_v1.h" #include "sway/input/input-manager.h" #include "sway/tree/container.h" #include "ipc.h" @@ -22,5 +23,6 @@ void ipc_event_shutdown(const char *reason); void ipc_event_binding(struct sway_binding *binding); void ipc_event_input(const char *change, struct sway_input_device *device); void ipc_event_output(void); +void ipc_event_idle_inhibitor(struct sway_idle_inhibitor_v1 *inhibitor, const char *change); #endif diff --git a/sway/commands/inhibit_idle.c b/sway/commands/inhibit_idle.c index 6125736ac..23cdb7f8d 100644 --- a/sway/commands/inhibit_idle.c +++ b/sway/commands/inhibit_idle.c @@ -40,7 +40,7 @@ struct cmd_results *cmd_inhibit_idle(int argc, char **argv) { if (clear) { sway_idle_inhibit_v1_user_inhibitor_destroy(inhibitor); } else { - inhibitor->mode = mode; + sway_idle_inhibit_v1_user_inhibitor_update_mode(inhibitor, mode); sway_idle_inhibit_v1_check_active(); } } else if (!clear) { diff --git a/sway/desktop/idle_inhibit_v1.c b/sway/desktop/idle_inhibit_v1.c index f3af7aa1b..2f2306fa9 100644 --- a/sway/desktop/idle_inhibit_v1.c +++ b/sway/desktop/idle_inhibit_v1.c @@ -3,12 +3,14 @@ #include "log.h" #include "sway/desktop/idle_inhibit_v1.h" #include "sway/input/seat.h" +#include "sway/ipc-server.h" #include "sway/tree/container.h" #include "sway/tree/view.h" #include "sway/server.h" static void destroy_inhibitor(struct sway_idle_inhibitor_v1 *inhibitor) { + ipc_event_idle_inhibitor(inhibitor, "destroy"); wl_list_remove(&inhibitor->link); wl_list_remove(&inhibitor->destroy.link); sway_idle_inhibit_v1_check_active(); @@ -36,6 +38,9 @@ void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) { inhibitor->mode = INHIBIT_IDLE_APPLICATION; inhibitor->wlr_inhibitor = wlr_inhibitor; + + ipc_event_idle_inhibitor(inhibitor, "create"); + wl_list_insert(&manager->inhibitors, &inhibitor->link); inhibitor->destroy.notify = handle_destroy; @@ -56,6 +61,9 @@ void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view, inhibitor->mode = mode; inhibitor->view = view; + + ipc_event_idle_inhibitor(inhibitor, "create"); + wl_list_insert(&manager->inhibitors, &inhibitor->link); inhibitor->destroy.notify = handle_destroy; @@ -90,6 +98,13 @@ struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_application_inhibitor_for_vi return NULL; } +void sway_idle_inhibit_v1_user_inhibitor_update_mode( + struct sway_idle_inhibitor_v1 *inhibitor, + enum sway_idle_inhibit_mode mode) { + inhibitor->mode = mode; + ipc_event_idle_inhibitor(inhibitor, "mode"); +} + void sway_idle_inhibit_v1_user_inhibitor_destroy( struct sway_idle_inhibitor_v1 *inhibitor) { if (!inhibitor) { diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 666468e7e..6f6a3dc6a 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -1434,3 +1434,37 @@ json_object *ipc_json_get_binding_mode(void) { json_object_new_string(config->current_mode->name)); return current_mode; } + +json_object *ipc_json_describe_idle_inhibitor( + struct sway_idle_inhibitor_v1 *sway_inhibitor) { + json_object *object = json_object_new_object(); + + json_object_object_add(object, "active", + json_object_new_boolean( + sway_idle_inhibit_v1_is_active(sway_inhibitor))); + + const char *type = NULL; + struct sway_view *view = NULL; + if (sway_inhibitor->mode == INHIBIT_IDLE_APPLICATION) { + type = "application"; + view = view_from_wlr_surface(sway_inhibitor->wlr_inhibitor->surface); + } else { + type = "user"; + view = sway_inhibitor->view; + json_object_object_add(object, "mode", + json_object_new_string( + ipc_json_user_idle_inhibitor_description( + sway_inhibitor->mode))); + } + + if (type) { + json_object_object_add(object, "type", json_object_new_string(type)); + } + + if (view && view->container) { + json_object_object_add(object, "container", + ipc_json_describe_node(&view->container->node)); + } + + return object; +} diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 9692a77fd..8a4525676 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -522,6 +522,21 @@ void ipc_event_output(void) { json_object_put(json); } +void ipc_event_idle_inhibitor(struct sway_idle_inhibitor_v1 *inhibitor, const char *change) { + if (!ipc_has_event_listeners(IPC_EVENT_IDLE_INHIBITOR)) { + return; + } + sway_log(SWAY_DEBUG, "Sending idle inhibitor::%s event", change); + json_object *obj = json_object_new_object(); + json_object_object_add(obj, "change", json_object_new_string(change)); + json_object_object_add(obj, "idle_inhibitor", + ipc_json_describe_idle_inhibitor(inhibitor)); + + const char *json_string = json_object_to_json_string(obj); + ipc_send_event(json_string, IPC_EVENT_IDLE_INHIBITOR); + json_object_put(obj); +} + int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { struct ipc_client *client = data; @@ -758,6 +773,8 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt is_tick = true; } else if (strcmp(event_type, "input") == 0) { client->subscribed_events |= event_mask(IPC_EVENT_INPUT); + } else if (strcmp(event_type, "idle_inhibitor") == 0) { + client->subscribed_events |= event_mask(IPC_EVENT_IDLE_INHIBITOR); } else { const char msg[] = "{\"success\": false}"; ipc_send_reply(client, payload_type, msg, strlen(msg));