diff --git a/include/ipc.h b/include/ipc.h index ff011750..9deafff4 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 84cc666d..04776245 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 bc9f4985..66520350 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 d4c00942..8e5336f1 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 6125736a..23cdb7f8 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 f3af7aa1..2f2306fa 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 666468e7..6f6a3dc6 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 9692a77f..8a452567 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));