From 0cbd26f0dae32db38160a82d557017edab8bb632 Mon Sep 17 00:00:00 2001 From: Damien Tardy-Panis Date: Tue, 5 May 2020 18:35:03 +0200 Subject: [PATCH] Add views idle inhibition status in get_tree output Fixes #5286 --- include/sway/desktop/idle_inhibit_v1.h | 6 ++++ include/sway/tree/view.h | 2 ++ sway/desktop/idle_inhibit_v1.c | 17 ++++++++-- sway/ipc-json.c | 47 ++++++++++++++++++++++++++ sway/sway-ipc.7.scd | 18 ++++++++++ sway/tree/view.c | 24 +++++++++++++ 6 files changed, 112 insertions(+), 2 deletions(-) diff --git a/include/sway/desktop/idle_inhibit_v1.h b/include/sway/desktop/idle_inhibit_v1.h index 4d4e59b0..0adafdb9 100644 --- a/include/sway/desktop/idle_inhibit_v1.h +++ b/include/sway/desktop/idle_inhibit_v1.h @@ -29,6 +29,9 @@ struct sway_idle_inhibitor_v1 { struct wl_listener destroy; }; +bool sway_idle_inhibit_v1_is_active( + struct sway_idle_inhibitor_v1 *inhibitor); + void sway_idle_inhibit_v1_check_active( struct sway_idle_inhibit_manager_v1 *manager); @@ -38,6 +41,9 @@ void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view, struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view( struct sway_view *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_destroy( struct sway_idle_inhibitor_v1 *inhibitor); diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 9230f456..ab2dc8e4 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -232,6 +232,8 @@ void view_get_constraints(struct sway_view *view, double *min_width, uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, int height); +bool view_inhibit_idle(struct sway_view *view); + /** * Whether or not the view is the only visible view in its tree. If the view * is tiling, there may be floating views. If the view is floating, there may diff --git a/sway/desktop/idle_inhibit_v1.c b/sway/desktop/idle_inhibit_v1.c index 73e46a8f..a5cfd5b2 100644 --- a/sway/desktop/idle_inhibit_v1.c +++ b/sway/desktop/idle_inhibit_v1.c @@ -77,6 +77,19 @@ struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view( return NULL; } +struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_application_inhibitor_for_view( + struct sway_view *view) { + struct sway_idle_inhibitor_v1 *inhibitor; + wl_list_for_each(inhibitor, &server.idle_inhibit_manager_v1->inhibitors, + link) { + if (inhibitor->view == view && + inhibitor->mode == INHIBIT_IDLE_APPLICATION) { + return inhibitor; + } + } + return NULL; +} + void sway_idle_inhibit_v1_user_inhibitor_destroy( struct sway_idle_inhibitor_v1 *inhibitor) { if (!inhibitor) { @@ -89,7 +102,7 @@ void sway_idle_inhibit_v1_user_inhibitor_destroy( destroy_inhibitor(inhibitor); } -static bool check_active(struct sway_idle_inhibitor_v1 *inhibitor) { +bool sway_idle_inhibit_v1_is_active(struct sway_idle_inhibitor_v1 *inhibitor) { switch (inhibitor->mode) { case INHIBIT_IDLE_APPLICATION: // If there is no view associated with the inhibitor, assume visible @@ -122,7 +135,7 @@ void sway_idle_inhibit_v1_check_active( struct sway_idle_inhibitor_v1 *inhibitor; bool inhibited = false; wl_list_for_each(inhibitor, &manager->inhibitors, link) { - if ((inhibited = check_active(inhibitor))) { + if ((inhibited = sway_idle_inhibit_v1_is_active(inhibitor))) { break; } } diff --git a/sway/ipc-json.c b/sway/ipc-json.c index c2e43f6e..066fd8db 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -18,6 +18,7 @@ #include #include #include "wlr-layer-shell-unstable-v1-protocol.h" +#include "sway/desktop/idle_inhibit_v1.h" static const int i3_output_id = INT32_MAX; static const int i3_scratch_id = INT32_MAX - 1; @@ -139,6 +140,22 @@ static const char *ipc_json_xwindow_type_description(struct sway_view *view) { } #endif +static const char *ipc_json_user_idle_inhibitor_description(enum sway_idle_inhibit_mode mode) { + switch (mode) { + case INHIBIT_IDLE_FOCUS: + return "focus"; + case INHIBIT_IDLE_FULLSCREEN: + return "fullscreen"; + case INHIBIT_IDLE_OPEN: + return "open"; + case INHIBIT_IDLE_VISIBLE: + return "visible"; + case INHIBIT_IDLE_APPLICATION: + return NULL; + } + return NULL; +} + json_object *ipc_json_get_version(void) { int major = 0, minor = 0, patch = 0; json_object *version = json_object_new_object(); @@ -492,6 +509,36 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object json_object_object_add(object, "shell", json_object_new_string(view_get_shell(c->view))); + json_object_object_add(object, "inhibit_idle", + json_object_new_boolean(view_inhibit_idle(c->view))); + + json_object *idle_inhibitors = json_object_new_object(); + + struct sway_idle_inhibitor_v1 *user_inhibitor = + sway_idle_inhibit_v1_user_inhibitor_for_view(c->view); + + if (user_inhibitor) { + json_object_object_add(idle_inhibitors, "user", + json_object_new_string( + ipc_json_user_idle_inhibitor_description(user_inhibitor->mode))); + } else { + json_object_object_add(idle_inhibitors, "user", + json_object_new_string("none")); + } + + struct sway_idle_inhibitor_v1 *application_inhibitor = + sway_idle_inhibit_v1_application_inhibitor_for_view(c->view); + + if (application_inhibitor) { + json_object_object_add(idle_inhibitors, "application", + json_object_new_string("enabled")); + } else { + json_object_object_add(idle_inhibitors, "application", + json_object_new_string("none")); + } + + json_object_object_add(object, "idle_inhibitors", idle_inhibitors); + #if HAVE_XWAYLAND if (c->view->type == SWAY_VIEW_XWAYLAND) { json_object_object_add(object, "window", diff --git a/sway/sway-ipc.7.scd b/sway/sway-ipc.7.scd index 5cef0bb4..63e3ceb6 100644 --- a/sway/sway-ipc.7.scd +++ b/sway/sway-ipc.7.scd @@ -379,6 +379,14 @@ node and will have the following properties: |- shell : string : (Only views) The shell of the view, such as _xdg\_shell_ or _xwayland_ +|- inhibit_idle +: boolean +: (Only views) Whether the view is inhibiting the idle state +|- idle_inhibitors +: object +: (Only views) An object containing the state of the _application_ and _user_ idle inhibitors. + _application_ can be _enabled_ or _none_. + _user_ can be _focus_, _fullscreen_, _open_, _visible_ or _none_. |- window : integer : (Only xwayland views) The X11 window ID for the xwayland view @@ -676,6 +684,11 @@ node and will have the following properties: "app_id": null, "visible": true, "shell": "xwayland", + "inhibit_idle": true, + "idle_inhibitors": { + "application": "none", + "user": "visible", + }, "window_properties": { "class": "URxvt", "instance": "urxvt", @@ -731,6 +744,11 @@ node and will have the following properties: "app_id": "termite", "visible": true, "shell": "xdg_shell", + "inhibit_idle": false, + "idle_inhibitors": { + "application": "none", + "user": "fullscreen", + }, "nodes": [ ] } diff --git a/sway/tree/view.c b/sway/tree/view.c index 2b4b6c09..8e12a229 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -17,6 +17,7 @@ #include "sway/commands.h" #include "sway/desktop.h" #include "sway/desktop/transaction.h" +#include "sway/desktop/idle_inhibit_v1.h" #include "sway/input/cursor.h" #include "sway/ipc-server.h" #include "sway/output.h" @@ -164,6 +165,29 @@ uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, return 0; } +bool view_inhibit_idle(struct sway_view *view) { + struct sway_idle_inhibitor_v1 *user_inhibitor = + sway_idle_inhibit_v1_user_inhibitor_for_view(view); + + struct sway_idle_inhibitor_v1 *application_inhibitor = + sway_idle_inhibit_v1_application_inhibitor_for_view(view); + + if (!user_inhibitor && !application_inhibitor) { + return false; + } + + if (!user_inhibitor) { + return sway_idle_inhibit_v1_is_active(application_inhibitor); + } + + if (!application_inhibitor) { + return sway_idle_inhibit_v1_is_active(user_inhibitor); + } + + return sway_idle_inhibit_v1_is_active(user_inhibitor) + || sway_idle_inhibit_v1_is_active(application_inhibitor); +} + bool view_is_only_visible(struct sway_view *view) { bool only_view = true; struct sway_container *con = view->container;