diff options
Diffstat (limited to 'sway/desktop/idle_inhibit_v1.c')
-rw-r--r-- | sway/desktop/idle_inhibit_v1.c | 99 |
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 | ||
11 | static 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 | |||
9 | static void handle_destroy(struct wl_listener *listener, void *data) { | 18 | static 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 | ||
19 | void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) { | 25 | void 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 | |||
48 | void 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 | |||
67 | struct 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 | ||
42 | void idle_inhibit_v1_check_active( | 80 | void 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 | |||
92 | static 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 | |||
119 | void 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 | } |