diff options
author | Tony Crisci <tony@dubstepdish.com> | 2018-04-04 22:36:09 -0400 |
---|---|---|
committer | Tony Crisci <tony@dubstepdish.com> | 2018-04-04 22:36:09 -0400 |
commit | 65f254f3fbc83d006d4ec29170ec8a8695345d6c (patch) | |
tree | 3044fb62120ca23499d31275076af50db09a9850 /sway | |
parent | fix focus child (diff) | |
parent | Merge pull request #1732 from emersion/view-children (diff) | |
download | sway-65f254f3fbc83d006d4ec29170ec8a8695345d6c.tar.gz sway-65f254f3fbc83d006d4ec29170ec8a8695345d6c.tar.zst sway-65f254f3fbc83d006d4ec29170ec8a8695345d6c.zip |
Merge branch 'wlroots' into fix-focus-inactive
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands.c | 1 | ||||
-rw-r--r-- | sway/commands/opacity.c | 39 | ||||
-rw-r--r-- | sway/desktop/output.c | 41 | ||||
-rw-r--r-- | sway/desktop/wl_shell.c | 4 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 4 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 4 | ||||
-rw-r--r-- | sway/input/cursor.c | 6 | ||||
-rw-r--r-- | sway/input/input-manager.c | 35 | ||||
-rw-r--r-- | sway/input/seat.c | 75 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/sway.5.txt | 4 | ||||
-rw-r--r-- | sway/tree/container.c | 70 |
12 files changed, 208 insertions, 76 deletions
diff --git a/sway/commands.c b/sway/commands.c index 8156a08e..2786a879 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -163,6 +163,7 @@ static struct cmd_handler command_handlers[] = { | |||
163 | { "kill", cmd_kill }, | 163 | { "kill", cmd_kill }, |
164 | { "layout", cmd_layout }, | 164 | { "layout", cmd_layout }, |
165 | { "move", cmd_move }, | 165 | { "move", cmd_move }, |
166 | { "opacity", cmd_opacity }, | ||
166 | { "reload", cmd_reload }, | 167 | { "reload", cmd_reload }, |
167 | { "split", cmd_split }, | 168 | { "split", cmd_split }, |
168 | { "splith", cmd_splith }, | 169 | { "splith", cmd_splith }, |
diff --git a/sway/commands/opacity.c b/sway/commands/opacity.c new file mode 100644 index 00000000..b8cd1f09 --- /dev/null +++ b/sway/commands/opacity.c | |||
@@ -0,0 +1,39 @@ | |||
1 | #include <assert.h> | ||
2 | #include <stdlib.h> | ||
3 | #include "sway/commands.h" | ||
4 | #include "sway/tree/view.h" | ||
5 | #include "log.h" | ||
6 | |||
7 | static bool parse_opacity(const char *opacity, float *val) { | ||
8 | char *err; | ||
9 | *val = strtof(opacity, &err); | ||
10 | if (*val < 0 || *val > 1 || *err) { | ||
11 | return false; | ||
12 | } | ||
13 | return true; | ||
14 | } | ||
15 | |||
16 | struct cmd_results *cmd_opacity(int argc, char **argv) { | ||
17 | struct cmd_results *error = NULL; | ||
18 | if ((error = checkarg(argc, "layout", EXPECTED_EQUAL_TO, 1))) { | ||
19 | return error; | ||
20 | } | ||
21 | |||
22 | struct sway_container *con = | ||
23 | config->handler_context.current_container; | ||
24 | |||
25 | float opacity = 0.0f; | ||
26 | |||
27 | if (!parse_opacity(argv[0], &opacity)) { | ||
28 | return cmd_results_new(CMD_INVALID, "opacity <value>", | ||
29 | "Invalid value (expected 0..1): %s", argv[0]); | ||
30 | } | ||
31 | |||
32 | con->alpha = opacity; | ||
33 | |||
34 | if (con->type == C_VIEW) { | ||
35 | view_damage_whole(con->sway_view); | ||
36 | } | ||
37 | |||
38 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
39 | } | ||
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 8a4fb4a2..0e8a9485 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -75,7 +75,7 @@ static bool surface_intersect_output(struct wlr_surface *surface, | |||
75 | 75 | ||
76 | static void render_surface(struct wlr_surface *surface, | 76 | static void render_surface(struct wlr_surface *surface, |
77 | struct wlr_output *wlr_output, struct timespec *when, | 77 | struct wlr_output *wlr_output, struct timespec *when, |
78 | double ox, double oy, float rotation) { | 78 | double ox, double oy, float rotation, float alpha) { |
79 | struct wlr_renderer *renderer = | 79 | struct wlr_renderer *renderer = |
80 | wlr_backend_get_renderer(wlr_output->backend); | 80 | wlr_backend_get_renderer(wlr_output->backend); |
81 | 81 | ||
@@ -95,8 +95,8 @@ static void render_surface(struct wlr_surface *surface, | |||
95 | wlr_matrix_project_box(matrix, &box, transform, rotation, | 95 | wlr_matrix_project_box(matrix, &box, transform, rotation, |
96 | wlr_output->transform_matrix); | 96 | wlr_output->transform_matrix); |
97 | 97 | ||
98 | // TODO: configurable alpha | 98 | wlr_render_texture_with_matrix(renderer, surface->texture, |
99 | wlr_render_texture_with_matrix(renderer, surface->texture, matrix, 1.0f); | 99 | matrix, alpha); |
100 | 100 | ||
101 | wlr_surface_send_frame_done(surface, when); | 101 | wlr_surface_send_frame_done(surface, when); |
102 | } | 102 | } |
@@ -110,13 +110,13 @@ static void render_surface(struct wlr_surface *surface, | |||
110 | surface->current->width, surface->current->height, rotation); | 110 | surface->current->width, surface->current->height, rotation); |
111 | 111 | ||
112 | render_surface(subsurface->surface, wlr_output, when, | 112 | render_surface(subsurface->surface, wlr_output, when, |
113 | ox + sx, oy + sy, rotation); | 113 | ox + sx, oy + sy, rotation, alpha); |
114 | } | 114 | } |
115 | } | 115 | } |
116 | 116 | ||
117 | static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, | 117 | static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, |
118 | struct wlr_output *wlr_output, struct timespec *when, double base_x, | 118 | struct wlr_output *wlr_output, struct timespec *when, double base_x, |
119 | double base_y, float rotation) { | 119 | double base_y, float rotation, float alpha) { |
120 | double width = surface->surface->current->width; | 120 | double width = surface->surface->current->width; |
121 | double height = surface->surface->current->height; | 121 | double height = surface->surface->current->height; |
122 | 122 | ||
@@ -136,19 +136,19 @@ static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, | |||
136 | width, height, rotation); | 136 | width, height, rotation); |
137 | 137 | ||
138 | render_surface(popup->surface, wlr_output, when, | 138 | render_surface(popup->surface, wlr_output, when, |
139 | base_x + popup_sx, base_y + popup_sy, rotation); | 139 | base_x + popup_sx, base_y + popup_sy, rotation, alpha); |
140 | render_xdg_v6_popups(popup, wlr_output, when, | 140 | render_xdg_v6_popups(popup, wlr_output, when, |
141 | base_x + popup_sx, base_y + popup_sy, rotation); | 141 | base_x + popup_sx, base_y + popup_sy, rotation, alpha); |
142 | } | 142 | } |
143 | } | 143 | } |
144 | 144 | ||
145 | static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, | 145 | static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, |
146 | struct wlr_output *wlr_output, struct timespec *when, | 146 | struct wlr_output *wlr_output, struct timespec *when, |
147 | double lx, double ly, float rotation, | 147 | double lx, double ly, float rotation, float alpha, |
148 | bool is_child) { | 148 | bool is_child) { |
149 | if (is_child || surface->state != WLR_WL_SHELL_SURFACE_STATE_POPUP) { | 149 | if (is_child || surface->state != WLR_WL_SHELL_SURFACE_STATE_POPUP) { |
150 | render_surface(surface->surface, wlr_output, when, | 150 | render_surface(surface->surface, wlr_output, when, |
151 | lx, ly, rotation); | 151 | lx, ly, rotation, alpha); |
152 | 152 | ||
153 | double width = surface->surface->current->width; | 153 | double width = surface->surface->current->width; |
154 | double height = surface->surface->current->height; | 154 | double height = surface->surface->current->height; |
@@ -164,7 +164,7 @@ static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, | |||
164 | width, height, rotation); | 164 | width, height, rotation); |
165 | 165 | ||
166 | render_wl_shell_surface(popup, wlr_output, when, | 166 | render_wl_shell_surface(popup, wlr_output, when, |
167 | lx + popup_x, ly + popup_y, rotation, true); | 167 | lx + popup_x, ly + popup_y, rotation, alpha, true); |
168 | } | 168 | } |
169 | } | 169 | } |
170 | } | 170 | } |
@@ -181,29 +181,28 @@ static void render_view(struct sway_container *view, void *data) { | |||
181 | struct wlr_output *wlr_output = output->wlr_output; | 181 | struct wlr_output *wlr_output = output->wlr_output; |
182 | struct sway_view *sway_view = view->sway_view; | 182 | struct sway_view *sway_view = view->sway_view; |
183 | struct wlr_surface *surface = sway_view->surface; | 183 | struct wlr_surface *surface = sway_view->surface; |
184 | float alpha = sway_view->swayc->alpha; | ||
184 | 185 | ||
185 | if (!surface) { | 186 | if (!surface) { |
186 | return; | 187 | return; |
187 | } | 188 | } |
188 | 189 | ||
189 | switch (sway_view->type) { | 190 | switch (sway_view->type) { |
190 | case SWAY_XDG_SHELL_V6_VIEW: { | 191 | case SWAY_VIEW_XDG_SHELL_V6: { |
191 | int window_offset_x = view->sway_view->wlr_xdg_surface_v6->geometry.x; | 192 | int window_offset_x = view->sway_view->wlr_xdg_surface_v6->geometry.x; |
192 | int window_offset_y = view->sway_view->wlr_xdg_surface_v6->geometry.y; | 193 | int window_offset_y = view->sway_view->wlr_xdg_surface_v6->geometry.y; |
193 | render_surface(surface, wlr_output, when, | 194 | render_surface(surface, wlr_output, when, |
194 | view->x - window_offset_x, view->y - window_offset_y, 0); | 195 | view->x - window_offset_x, view->y - window_offset_y, 0, alpha); |
195 | render_xdg_v6_popups(sway_view->wlr_xdg_surface_v6, wlr_output, | 196 | render_xdg_v6_popups(sway_view->wlr_xdg_surface_v6, wlr_output, |
196 | when, view->x - window_offset_x, view->y - window_offset_y, 0); | 197 | when, view->x - window_offset_x, view->y - window_offset_y, 0, alpha); |
197 | break; | 198 | break; |
198 | } | 199 | } |
199 | case SWAY_WL_SHELL_VIEW: | 200 | case SWAY_VIEW_WL_SHELL: |
200 | render_wl_shell_surface(sway_view->wlr_wl_shell_surface, wlr_output, | 201 | render_wl_shell_surface(sway_view->wlr_wl_shell_surface, wlr_output, |
201 | when, view->x, view->y, 0, false); | 202 | when, view->x, view->y, 0, alpha, false); |
202 | break; | 203 | break; |
203 | case SWAY_XWAYLAND_VIEW: | 204 | case SWAY_VIEW_XWAYLAND: |
204 | render_surface(surface, wlr_output, when, view->x, view->y, 0); | 205 | render_surface(surface, wlr_output, when, view->x, view->y, 0, alpha); |
205 | break; | ||
206 | default: | ||
207 | break; | 206 | break; |
208 | } | 207 | } |
209 | } | 208 | } |
@@ -214,7 +213,7 @@ static void render_layer(struct sway_output *output, struct timespec *when, | |||
214 | wl_list_for_each(sway_layer, layer, link) { | 213 | wl_list_for_each(sway_layer, layer, link) { |
215 | struct wlr_layer_surface *layer = sway_layer->layer_surface; | 214 | struct wlr_layer_surface *layer = sway_layer->layer_surface; |
216 | render_surface(layer->surface, output->wlr_output, when, | 215 | render_surface(layer->surface, output->wlr_output, when, |
217 | sway_layer->geo.x, sway_layer->geo.y, 0); | 216 | sway_layer->geo.x, sway_layer->geo.y, 0, 1.0f); |
218 | wlr_surface_send_frame_done(layer->surface, when); | 217 | wlr_surface_send_frame_done(layer->surface, when); |
219 | } | 218 | } |
220 | } | 219 | } |
@@ -288,7 +287,7 @@ static void render_output(struct sway_output *output, struct timespec *when, | |||
288 | } | 287 | } |
289 | 288 | ||
290 | render_surface(xsurface->surface, wlr_output, &output->last_frame, | 289 | render_surface(xsurface->surface, wlr_output, &output->last_frame, |
291 | view_box.x - output_box->x, view_box.y - output_box->y, 0); | 290 | view_box.x - output_box->x, view_box.y - output_box->y, 0, 1.0f); |
292 | } | 291 | } |
293 | 292 | ||
294 | // TODO: Consider revising this when fullscreen windows are supported | 293 | // TODO: Consider revising this when fullscreen windows are supported |
diff --git a/sway/desktop/wl_shell.c b/sway/desktop/wl_shell.c index 6528a397..a470674d 100644 --- a/sway/desktop/wl_shell.c +++ b/sway/desktop/wl_shell.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include "log.h" | 12 | #include "log.h" |
13 | 13 | ||
14 | static bool assert_wl_shell(struct sway_view *view) { | 14 | static bool assert_wl_shell(struct sway_view *view) { |
15 | return sway_assert(view->type == SWAY_WL_SHELL_VIEW, | 15 | return sway_assert(view->type == SWAY_VIEW_WL_SHELL, |
16 | "Expecting wl_shell view!"); | 16 | "Expecting wl_shell view!"); |
17 | } | 17 | } |
18 | 18 | ||
@@ -97,7 +97,7 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { | |||
97 | return; | 97 | return; |
98 | } | 98 | } |
99 | 99 | ||
100 | struct sway_view *view = view_create(SWAY_WL_SHELL_VIEW, &view_impl); | 100 | struct sway_view *view = view_create(SWAY_VIEW_WL_SHELL, &view_impl); |
101 | if (!sway_assert(view, "Failed to allocate view")) { | 101 | if (!sway_assert(view, "Failed to allocate view")) { |
102 | return; | 102 | return; |
103 | } | 103 | } |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 49305b39..5cdb8f9f 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include "log.h" | 12 | #include "log.h" |
13 | 13 | ||
14 | static bool assert_xdg(struct sway_view *view) { | 14 | static bool assert_xdg(struct sway_view *view) { |
15 | return sway_assert(view->type == SWAY_XDG_SHELL_V6_VIEW, | 15 | return sway_assert(view->type == SWAY_VIEW_XDG_SHELL_V6, |
16 | "Expected xdg shell v6 view!"); | 16 | "Expected xdg shell v6 view!"); |
17 | } | 17 | } |
18 | 18 | ||
@@ -126,7 +126,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | |||
126 | return; | 126 | return; |
127 | } | 127 | } |
128 | 128 | ||
129 | struct sway_view *view = view_create(SWAY_XDG_SHELL_V6_VIEW, &view_impl); | 129 | struct sway_view *view = view_create(SWAY_VIEW_XDG_SHELL_V6, &view_impl); |
130 | if (!sway_assert(view, "Failed to allocate view")) { | 130 | if (!sway_assert(view, "Failed to allocate view")) { |
131 | return; | 131 | return; |
132 | } | 132 | } |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index bfef68cf..a793928c 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -42,7 +42,7 @@ static void create_unmanaged(struct wlr_xwayland_surface *xsurface) { | |||
42 | 42 | ||
43 | 43 | ||
44 | static bool assert_xwayland(struct sway_view *view) { | 44 | static bool assert_xwayland(struct sway_view *view) { |
45 | return sway_assert(view->type == SWAY_XWAYLAND_VIEW, | 45 | return sway_assert(view->type == SWAY_VIEW_XWAYLAND, |
46 | "Expected xwayland view!"); | 46 | "Expected xwayland view!"); |
47 | } | 47 | } |
48 | 48 | ||
@@ -185,7 +185,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
185 | return; | 185 | return; |
186 | } | 186 | } |
187 | 187 | ||
188 | struct sway_view *view = view_create(SWAY_XWAYLAND_VIEW, &view_impl); | 188 | struct sway_view *view = view_create(SWAY_VIEW_XWAYLAND, &view_impl); |
189 | if (!sway_assert(view, "Failed to allocate view")) { | 189 | if (!sway_assert(view, "Failed to allocate view")) { |
190 | return; | 190 | return; |
191 | } | 191 | } |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 9229e92d..195ddce9 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -146,8 +146,10 @@ static void cursor_send_pointer_motion(struct sway_cursor *cursor, | |||
146 | 146 | ||
147 | // send pointer enter/leave | 147 | // send pointer enter/leave |
148 | if (surface != NULL) { | 148 | if (surface != NULL) { |
149 | wlr_seat_pointer_notify_enter(seat, surface, sx, sy); | 149 | if (seat_is_input_allowed(cursor->seat, surface)) { |
150 | wlr_seat_pointer_notify_motion(seat, time, sx, sy); | 150 | wlr_seat_pointer_notify_enter(seat, surface, sx, sy); |
151 | wlr_seat_pointer_notify_motion(seat, time, sx, sy); | ||
152 | } | ||
151 | } else { | 153 | } else { |
152 | wlr_seat_pointer_clear_focus(seat); | 154 | wlr_seat_pointer_clear_focus(seat); |
153 | } | 155 | } |
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index c3507f65..f71a06e4 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <libinput.h> | 7 | #include <libinput.h> |
8 | #include <math.h> | 8 | #include <math.h> |
9 | #include <wlr/backend/libinput.h> | 9 | #include <wlr/backend/libinput.h> |
10 | #include <wlr/types/wlr_input_inhibitor.h> | ||
10 | #include "sway/config.h" | 11 | #include "sway/config.h" |
11 | #include "sway/input/input-manager.h" | 12 | #include "sway/input/input-manager.h" |
12 | #include "sway/input/seat.h" | 13 | #include "sway/input/seat.h" |
@@ -263,6 +264,32 @@ static void handle_new_input(struct wl_listener *listener, void *data) { | |||
263 | input_device->device_destroy.notify = handle_device_destroy; | 264 | input_device->device_destroy.notify = handle_device_destroy; |
264 | } | 265 | } |
265 | 266 | ||
267 | static void handle_inhibit_activate(struct wl_listener *listener, void *data) { | ||
268 | struct sway_input_manager *input_manager = wl_container_of( | ||
269 | listener, input_manager, inhibit_activate); | ||
270 | struct sway_seat *seat; | ||
271 | wl_list_for_each(seat, &input_manager->seats, link) { | ||
272 | seat_set_exclusive_client(seat, input_manager->inhibit->active_client); | ||
273 | } | ||
274 | } | ||
275 | |||
276 | static void handle_inhibit_deactivate(struct wl_listener *listener, void *data) { | ||
277 | struct sway_input_manager *input_manager = wl_container_of( | ||
278 | listener, input_manager, inhibit_deactivate); | ||
279 | struct sway_seat *seat; | ||
280 | wl_list_for_each(seat, &input_manager->seats, link) { | ||
281 | seat_set_exclusive_client(seat, NULL); | ||
282 | struct sway_container *previous = seat_get_focus(seat); | ||
283 | if (previous) { | ||
284 | wlr_log(L_DEBUG, "Returning focus to %p %s '%s'", previous, | ||
285 | container_type_to_str(previous->type), previous->name); | ||
286 | // Hack to get seat to re-focus the return value of get_focus | ||
287 | seat_set_focus(seat, previous->parent); | ||
288 | seat_set_focus(seat, previous); | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | |||
266 | struct sway_input_manager *input_manager_create( | 293 | struct sway_input_manager *input_manager_create( |
267 | struct sway_server *server) { | 294 | struct sway_server *server) { |
268 | struct sway_input_manager *input = | 295 | struct sway_input_manager *input = |
@@ -281,6 +308,14 @@ struct sway_input_manager *input_manager_create( | |||
281 | input->new_input.notify = handle_new_input; | 308 | input->new_input.notify = handle_new_input; |
282 | wl_signal_add(&server->backend->events.new_input, &input->new_input); | 309 | wl_signal_add(&server->backend->events.new_input, &input->new_input); |
283 | 310 | ||
311 | input->inhibit = wlr_input_inhibit_manager_create(server->wl_display); | ||
312 | input->inhibit_activate.notify = handle_inhibit_activate; | ||
313 | wl_signal_add(&input->inhibit->events.activate, | ||
314 | &input->inhibit_activate); | ||
315 | input->inhibit_deactivate.notify = handle_inhibit_deactivate; | ||
316 | wl_signal_add(&input->inhibit->events.deactivate, | ||
317 | &input->inhibit_deactivate); | ||
318 | |||
284 | return input; | 319 | return input; |
285 | } | 320 | } |
286 | 321 | ||
diff --git a/sway/input/seat.c b/sway/input/seat.c index 50134aae..e3df6955 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -1,5 +1,7 @@ | |||
1 | #define _XOPEN_SOURCE 700 | 1 | #define _XOPEN_SOURCE 700 |
2 | #define _POSIX_C_SOURCE 199309L | ||
2 | #include <assert.h> | 3 | #include <assert.h> |
4 | #include <time.h> | ||
3 | #include <wlr/types/wlr_cursor.h> | 5 | #include <wlr/types/wlr_cursor.h> |
4 | #include <wlr/types/wlr_output_layout.h> | 6 | #include <wlr/types/wlr_output_layout.h> |
5 | #include <wlr/types/wlr_xcursor_manager.h> | 7 | #include <wlr/types/wlr_xcursor_manager.h> |
@@ -9,6 +11,7 @@ | |||
9 | #include "sway/input/input-manager.h" | 11 | #include "sway/input/input-manager.h" |
10 | #include "sway/input/keyboard.h" | 12 | #include "sway/input/keyboard.h" |
11 | #include "sway/ipc-server.h" | 13 | #include "sway/ipc-server.h" |
14 | #include "sway/layers.h" | ||
12 | #include "sway/output.h" | 15 | #include "sway/output.h" |
13 | #include "sway/tree/container.h" | 16 | #include "sway/tree/container.h" |
14 | #include "sway/tree/view.h" | 17 | #include "sway/tree/view.h" |
@@ -63,7 +66,7 @@ static void seat_send_focus(struct sway_seat *seat, | |||
63 | return; | 66 | return; |
64 | } | 67 | } |
65 | struct sway_view *view = con->sway_view; | 68 | struct sway_view *view = con->sway_view; |
66 | if (view->type == SWAY_XWAYLAND_VIEW) { | 69 | if (view->type == SWAY_VIEW_XWAYLAND) { |
67 | struct wlr_xwayland *xwayland = | 70 | struct wlr_xwayland *xwayland = |
68 | seat->input->server->xwayland; | 71 | seat->input->server->xwayland; |
69 | wlr_xwayland_set_seat(xwayland, seat->wlr_seat); | 72 | wlr_xwayland_set_seat(xwayland, seat->wlr_seat); |
@@ -350,6 +353,12 @@ void seat_configure_xcursor(struct sway_seat *seat) { | |||
350 | seat->cursor->cursor->y); | 353 | seat->cursor->cursor->y); |
351 | } | 354 | } |
352 | 355 | ||
356 | bool seat_is_input_allowed(struct sway_seat *seat, | ||
357 | struct wlr_surface *surface) { | ||
358 | struct wl_client *client = wl_resource_get_client(surface->resource); | ||
359 | return !seat->exclusive_client || seat->exclusive_client == client; | ||
360 | } | ||
361 | |||
353 | void seat_set_focus_warp(struct sway_seat *seat, | 362 | void seat_set_focus_warp(struct sway_seat *seat, |
354 | struct sway_container *container, bool warp) { | 363 | struct sway_container *container, bool warp) { |
355 | if (seat->focused_layer) { | 364 | if (seat->focused_layer) { |
@@ -371,6 +380,12 @@ void seat_set_focus_warp(struct sway_seat *seat, | |||
371 | wl_list_remove(&seat_con->link); | 380 | wl_list_remove(&seat_con->link); |
372 | wl_list_insert(&seat->focus_stack, &seat_con->link); | 381 | wl_list_insert(&seat->focus_stack, &seat_con->link); |
373 | 382 | ||
383 | if (container->type == C_VIEW && !seat_is_input_allowed( | ||
384 | seat, container->sway_view->surface)) { | ||
385 | wlr_log(L_DEBUG, "Refusing to set focus, input is inhibited"); | ||
386 | return; | ||
387 | } | ||
388 | |||
374 | if (container->type == C_VIEW) { | 389 | if (container->type == C_VIEW) { |
375 | seat_send_focus(seat, container); | 390 | seat_send_focus(seat, container); |
376 | } | 391 | } |
@@ -424,11 +439,18 @@ void seat_set_focus(struct sway_seat *seat, | |||
424 | 439 | ||
425 | void seat_set_focus_layer(struct sway_seat *seat, | 440 | void seat_set_focus_layer(struct sway_seat *seat, |
426 | struct wlr_layer_surface *layer) { | 441 | struct wlr_layer_surface *layer) { |
427 | if (!layer) { | 442 | if (!layer && seat->focused_layer) { |
428 | seat->focused_layer = NULL; | 443 | seat->focused_layer = NULL; |
444 | struct sway_container *previous = seat_get_focus(seat); | ||
445 | if (previous) { | ||
446 | wlr_log(L_DEBUG, "Returning focus to %p %s '%s'", previous, | ||
447 | container_type_to_str(previous->type), previous->name); | ||
448 | // Hack to get seat to re-focus the return value of get_focus | ||
449 | seat_set_focus(seat, previous->parent); | ||
450 | seat_set_focus(seat, previous); | ||
451 | } | ||
429 | return; | 452 | return; |
430 | } | 453 | } else if (!layer || seat->focused_layer == layer) { |
431 | if (seat->focused_layer == layer) { | ||
432 | return; | 454 | return; |
433 | } | 455 | } |
434 | if (seat->has_focus) { | 456 | if (seat->has_focus) { |
@@ -453,6 +475,51 @@ void seat_set_focus_layer(struct sway_seat *seat, | |||
453 | } | 475 | } |
454 | } | 476 | } |
455 | 477 | ||
478 | void seat_set_exclusive_client(struct sway_seat *seat, | ||
479 | struct wl_client *client) { | ||
480 | if (!client) { | ||
481 | seat->exclusive_client = client; | ||
482 | // Triggers a refocus of the topmost surface layer if necessary | ||
483 | // TODO: Make layer surface focus per-output based on cursor position | ||
484 | for (int i = 0; i < root_container.children->length; ++i) { | ||
485 | struct sway_container *output = root_container.children->items[i]; | ||
486 | if (!sway_assert(output->type == C_OUTPUT, | ||
487 | "root container has non-output child")) { | ||
488 | continue; | ||
489 | } | ||
490 | arrange_layers(output->sway_output); | ||
491 | } | ||
492 | return; | ||
493 | } | ||
494 | if (seat->focused_layer) { | ||
495 | if (wl_resource_get_client(seat->focused_layer->resource) != client) { | ||
496 | seat_set_focus_layer(seat, NULL); | ||
497 | } | ||
498 | } | ||
499 | if (seat->has_focus) { | ||
500 | struct sway_container *focus = seat_get_focus(seat); | ||
501 | if (focus->type == C_VIEW && wl_resource_get_client( | ||
502 | focus->sway_view->surface->resource) != client) { | ||
503 | seat_set_focus(seat, NULL); | ||
504 | } | ||
505 | } | ||
506 | if (seat->wlr_seat->pointer_state.focused_client) { | ||
507 | if (seat->wlr_seat->pointer_state.focused_client->client != client) { | ||
508 | wlr_seat_pointer_clear_focus(seat->wlr_seat); | ||
509 | } | ||
510 | } | ||
511 | struct timespec now; | ||
512 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
513 | struct wlr_touch_point *point; | ||
514 | wl_list_for_each(point, &seat->wlr_seat->touch_state.touch_points, link) { | ||
515 | if (point->client->client != client) { | ||
516 | wlr_seat_touch_point_clear_focus(seat->wlr_seat, | ||
517 | now.tv_nsec / 1000, point->touch_id); | ||
518 | } | ||
519 | } | ||
520 | seat->exclusive_client = client; | ||
521 | } | ||
522 | |||
456 | struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, | 523 | struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, |
457 | struct sway_container *container) { | 524 | struct sway_container *container) { |
458 | return seat_get_focus_by_type(seat, container, C_TYPES); | 525 | return seat_get_focus_by_type(seat, container, C_TYPES); |
diff --git a/sway/meson.build b/sway/meson.build index 91aab0a0..f210c195 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -15,6 +15,7 @@ sway_sources = files( | |||
15 | 'commands/focus.c', | 15 | 'commands/focus.c', |
16 | 'commands/focus_follows_mouse.c', | 16 | 'commands/focus_follows_mouse.c', |
17 | 'commands/kill.c', | 17 | 'commands/kill.c', |
18 | 'commands/opacity.c', | ||
18 | 'commands/include.c', | 19 | 'commands/include.c', |
19 | 'commands/input.c', | 20 | 'commands/input.c', |
20 | 'commands/layout.c', | 21 | 'commands/layout.c', |
diff --git a/sway/sway.5.txt b/sway/sway.5.txt index 900e499a..59c3295a 100644 --- a/sway/sway.5.txt +++ b/sway/sway.5.txt | |||
@@ -413,6 +413,10 @@ The default colors are: | |||
413 | However, any mark that starts with an underscore will not be drawn even if the | 413 | However, any mark that starts with an underscore will not be drawn even if the |
414 | option is on. The default option is _on_. | 414 | option is on. The default option is _on_. |
415 | 415 | ||
416 | **opacity** <value>:: | ||
417 | Set the opacity of the window between 0 (completely transparent) and 1 | ||
418 | (completely opaque). | ||
419 | |||
416 | **unmark** <identifier>:: | 420 | **unmark** <identifier>:: |
417 | **Unmark** will remove _identifier_ from the list of current marks on a window. If | 421 | **Unmark** will remove _identifier_ from the list of current marks on a window. If |
418 | no _identifier_ is specified, then **unmark** will remove all marks. | 422 | no _identifier_ is specified, then **unmark** will remove all marks. |
diff --git a/sway/tree/container.c b/sway/tree/container.c index 92c00f83..8fc9e3e8 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -78,6 +78,8 @@ struct sway_container *container_create(enum sway_container_type type) { | |||
78 | c->layout = L_NONE; | 78 | c->layout = L_NONE; |
79 | c->workspace_layout = L_NONE; | 79 | c->workspace_layout = L_NONE; |
80 | c->type = type; | 80 | c->type = type; |
81 | c->alpha = 1.0f; | ||
82 | |||
81 | if (type != C_VIEW) { | 83 | if (type != C_VIEW) { |
82 | c->children = create_list(); | 84 | c->children = create_list(); |
83 | } | 85 | } |
@@ -416,51 +418,33 @@ struct sway_container *container_at(struct sway_container *parent, | |||
416 | double view_sx = ox - swayc->x; | 418 | double view_sx = ox - swayc->x; |
417 | double view_sy = oy - swayc->y; | 419 | double view_sy = oy - swayc->y; |
418 | 420 | ||
421 | double _sx, _sy; | ||
422 | struct wlr_surface *_surface; | ||
419 | switch (sview->type) { | 423 | switch (sview->type) { |
420 | case SWAY_WL_SHELL_VIEW: | 424 | case SWAY_VIEW_XWAYLAND: |
421 | break; | 425 | _surface = wlr_surface_surface_at(sview->surface, |
422 | case SWAY_XDG_SHELL_V6_VIEW: | 426 | view_sx, view_sy, &_sx, &_sy); |
423 | // the top left corner of the sway container is the | 427 | break; |
424 | // coordinate of the top left corner of the window geometry | 428 | case SWAY_VIEW_WL_SHELL: |
425 | view_sx += sview->wlr_xdg_surface_v6->geometry.x; | 429 | _surface = wlr_wl_shell_surface_surface_at( |
426 | view_sy += sview->wlr_xdg_surface_v6->geometry.y; | 430 | sview->wlr_wl_shell_surface, |
427 | 431 | view_sx, view_sy, &_sx, &_sy); | |
428 | // check for popups | 432 | break; |
429 | double popup_sx, popup_sy; | 433 | case SWAY_VIEW_XDG_SHELL_V6: |
430 | struct wlr_xdg_surface_v6 *popup = | 434 | // the top left corner of the sway container is the |
431 | wlr_xdg_surface_v6_popup_at(sview->wlr_xdg_surface_v6, | 435 | // coordinate of the top left corner of the window geometry |
432 | view_sx, view_sy, &popup_sx, &popup_sy); | 436 | view_sx += sview->wlr_xdg_surface_v6->geometry.x; |
433 | 437 | view_sy += sview->wlr_xdg_surface_v6->geometry.y; | |
434 | if (popup) { | 438 | |
435 | *sx = view_sx - popup_sx; | 439 | _surface = wlr_xdg_surface_v6_surface_at( |
436 | *sy = view_sy - popup_sy; | 440 | sview->wlr_xdg_surface_v6, |
437 | *surface = popup->surface; | 441 | view_sx, view_sy, &_sx, &_sy); |
438 | return swayc; | 442 | break; |
439 | } | ||
440 | break; | ||
441 | case SWAY_XWAYLAND_VIEW: | ||
442 | break; | ||
443 | default: | ||
444 | break; | ||
445 | } | ||
446 | |||
447 | // check for subsurfaces | ||
448 | double sub_x, sub_y; | ||
449 | struct wlr_subsurface *subsurface = | ||
450 | wlr_surface_subsurface_at(sview->surface, | ||
451 | view_sx, view_sy, &sub_x, &sub_y); | ||
452 | if (subsurface) { | ||
453 | *sx = view_sx - sub_x; | ||
454 | *sy = view_sy - sub_y; | ||
455 | *surface = subsurface->surface; | ||
456 | return swayc; | ||
457 | } | 443 | } |
458 | 444 | if (_surface) { | |
459 | if (wlr_surface_point_accepts_input( | 445 | *sx = _sx; |
460 | sview->surface, view_sx, view_sy)) { | 446 | *sy = _sy; |
461 | *sx = view_sx; | 447 | *surface = _surface; |
462 | *sy = view_sy; | ||
463 | *surface = swayc->sway_view->surface; | ||
464 | return swayc; | 448 | return swayc; |
465 | } | 449 | } |
466 | } else { | 450 | } else { |