summaryrefslogtreecommitdiffstats
path: root/sway/desktop/idle_inhibit_v1.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/idle_inhibit_v1.c')
-rw-r--r--sway/desktop/idle_inhibit_v1.c99
1 files changed, 85 insertions, 14 deletions
diff --git a/sway/desktop/idle_inhibit_v1.c b/sway/desktop/idle_inhibit_v1.c
index 87b4ef43..b981e5e5 100644
--- a/sway/desktop/idle_inhibit_v1.c
+++ b/sway/desktop/idle_inhibit_v1.c
@@ -2,18 +2,24 @@
2#include <wlr/types/wlr_idle.h> 2#include <wlr/types/wlr_idle.h>
3#include "log.h" 3#include "log.h"
4#include "sway/desktop/idle_inhibit_v1.h" 4#include "sway/desktop/idle_inhibit_v1.h"
5#include "sway/input/seat.h"
6#include "sway/tree/container.h"
5#include "sway/tree/view.h" 7#include "sway/tree/view.h"
6#include "sway/server.h" 8#include "sway/server.h"
7 9
8 10
11static void destroy_inhibitor(struct sway_idle_inhibitor_v1 *inhibitor) {
12 wl_list_remove(&inhibitor->link);
13 wl_list_remove(&inhibitor->destroy.link);
14 sway_idle_inhibit_v1_check_active(inhibitor->manager);
15 free(inhibitor);
16}
17
9static void handle_destroy(struct wl_listener *listener, void *data) { 18static void handle_destroy(struct wl_listener *listener, void *data) {
10 struct sway_idle_inhibitor_v1 *inhibitor = 19 struct sway_idle_inhibitor_v1 *inhibitor =
11 wl_container_of(listener, inhibitor, destroy); 20 wl_container_of(listener, inhibitor, destroy);
12 sway_log(SWAY_DEBUG, "Sway idle inhibitor destroyed"); 21 sway_log(SWAY_DEBUG, "Sway idle inhibitor destroyed");
13 wl_list_remove(&inhibitor->link); 22 destroy_inhibitor(inhibitor);
14 wl_list_remove(&inhibitor->destroy.link);
15 idle_inhibit_v1_check_active(inhibitor->manager);
16 free(inhibitor);
17} 23}
18 24
19void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) { 25void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) {
@@ -29,28 +35,93 @@ void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) {
29 } 35 }
30 36
31 inhibitor->manager = manager; 37 inhibitor->manager = manager;
38 inhibitor->mode = INHIBIT_IDLE_APPLICATION;
32 inhibitor->view = view_from_wlr_surface(wlr_inhibitor->surface); 39 inhibitor->view = view_from_wlr_surface(wlr_inhibitor->surface);
33 wl_list_insert(&manager->inhibitors, &inhibitor->link); 40 wl_list_insert(&manager->inhibitors, &inhibitor->link);
34 41
35
36 inhibitor->destroy.notify = handle_destroy; 42 inhibitor->destroy.notify = handle_destroy;
37 wl_signal_add(&wlr_inhibitor->events.destroy, &inhibitor->destroy); 43 wl_signal_add(&wlr_inhibitor->events.destroy, &inhibitor->destroy);
38 44
39 idle_inhibit_v1_check_active(manager); 45 sway_idle_inhibit_v1_check_active(manager);
46}
47
48void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view,
49 enum sway_idle_inhibit_mode mode) {
50 struct sway_idle_inhibitor_v1 *inhibitor =
51 calloc(1, sizeof(struct sway_idle_inhibitor_v1));
52 if (!inhibitor) {
53 return;
54 }
55
56 inhibitor->manager = server.idle_inhibit_manager_v1;
57 inhibitor->mode = mode;
58 inhibitor->view = view;
59 wl_list_insert(&inhibitor->manager->inhibitors, &inhibitor->link);
60
61 inhibitor->destroy.notify = handle_destroy;
62 wl_signal_add(&view->events.unmap, &inhibitor->destroy);
63
64 sway_idle_inhibit_v1_check_active(inhibitor->manager);
65}
66
67struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view(
68 struct sway_view *view) {
69 struct sway_idle_inhibitor_v1 *inhibitor;
70 wl_list_for_each(inhibitor, &server.idle_inhibit_manager_v1->inhibitors,
71 link) {
72 if (inhibitor->view == view &&
73 inhibitor->mode != INHIBIT_IDLE_APPLICATION) {
74 return inhibitor;
75 }
76 }
77 return NULL;
40} 78}
41 79
42void idle_inhibit_v1_check_active( 80void sway_idle_inhibit_v1_user_inhibitor_destroy(
81 struct sway_idle_inhibitor_v1 *inhibitor) {
82 if (!inhibitor) {
83 return;
84 }
85 if (!sway_assert(inhibitor->mode != INHIBIT_IDLE_APPLICATION,
86 "User should not be able to destroy application inhibitor")) {
87 return;
88 }
89 destroy_inhibitor(inhibitor);
90}
91
92static bool check_active(struct sway_idle_inhibitor_v1 *inhibitor) {
93 switch (inhibitor->mode) {
94 case INHIBIT_IDLE_APPLICATION:
95 // If there is no view associated with the inhibitor, assume visible
96 return !inhibitor->view || view_is_visible(inhibitor->view);
97 case INHIBIT_IDLE_FOCUS:;
98 struct sway_seat *seat = NULL;
99 wl_list_for_each(seat, &server.input->seats, link) {
100 struct sway_container *con = seat_get_focused_container(seat);
101 if (con && con->view && con->view == inhibitor->view) {
102 return true;
103 }
104 }
105 return false;
106 case INHIBIT_IDLE_FULLSCREEN:
107 return inhibitor->view->container &&
108 container_is_fullscreen_or_child(inhibitor->view->container) &&
109 view_is_visible(inhibitor->view);
110 case INHIBIT_IDLE_OPEN:
111 // Inhibitor is destroyed on unmap so it must be open/mapped
112 return true;
113 case INHIBIT_IDLE_VISIBLE:
114 return view_is_visible(inhibitor->view);
115 }
116 return false;
117}
118
119void sway_idle_inhibit_v1_check_active(
43 struct sway_idle_inhibit_manager_v1 *manager) { 120 struct sway_idle_inhibit_manager_v1 *manager) {
44 struct sway_idle_inhibitor_v1 *inhibitor; 121 struct sway_idle_inhibitor_v1 *inhibitor;
45 bool inhibited = false; 122 bool inhibited = false;
46 wl_list_for_each(inhibitor, &manager->inhibitors, link) { 123 wl_list_for_each(inhibitor, &manager->inhibitors, link) {
47 if (!inhibitor->view || !inhibitor->view->container) { 124 if ((inhibited = check_active(inhibitor))) {
48 /* Cannot guess if view is visible so assume it is */
49 inhibited = true;
50 break;
51 }
52 if (view_is_visible(inhibitor->view)) {
53 inhibited = true;
54 break; 125 break;
55 } 126 }
56 } 127 }