diff options
Diffstat (limited to 'sway/desktop')
-rw-r--r-- | sway/desktop/launcher.c | 16 | ||||
-rw-r--r-- | sway/desktop/layer_shell.c | 29 | ||||
-rw-r--r-- | sway/desktop/output.c | 139 | ||||
-rw-r--r-- | sway/desktop/transaction.c | 21 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 19 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 1 |
6 files changed, 148 insertions, 77 deletions
diff --git a/sway/desktop/launcher.c b/sway/desktop/launcher.c index 00a7e38a..28043d19 100644 --- a/sway/desktop/launcher.c +++ b/sway/desktop/launcher.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdlib.h> | 1 | #include <stdlib.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include <wlr/types/wlr_xdg_activation_v1.h> | 3 | #include <wlr/types/wlr_xdg_activation_v1.h> |
@@ -67,6 +66,9 @@ void launcher_ctx_destroy(struct launcher_ctx *ctx) { | |||
67 | } | 66 | } |
68 | wl_list_remove(&ctx->node_destroy.link); | 67 | wl_list_remove(&ctx->node_destroy.link); |
69 | wl_list_remove(&ctx->token_destroy.link); | 68 | wl_list_remove(&ctx->token_destroy.link); |
69 | if (ctx->seat) { | ||
70 | wl_list_remove(&ctx->seat_destroy.link); | ||
71 | } | ||
70 | wl_list_remove(&ctx->link); | 72 | wl_list_remove(&ctx->link); |
71 | wlr_xdg_activation_token_v1_destroy(ctx->token); | 73 | wlr_xdg_activation_token_v1_destroy(ctx->token); |
72 | free(ctx->fallback_name); | 74 | free(ctx->fallback_name); |
@@ -213,6 +215,8 @@ struct launcher_ctx *launcher_ctx_create(struct wlr_xdg_activation_token_v1 *tok | |||
213 | ctx->fallback_name = strdup(fallback_name); | 215 | ctx->fallback_name = strdup(fallback_name); |
214 | ctx->token = token; | 216 | ctx->token = token; |
215 | ctx->node = node; | 217 | ctx->node = node; |
218 | // Having surface set means that the focus check in wlroots has passed | ||
219 | ctx->had_focused_surface = token->surface != NULL; | ||
216 | 220 | ||
217 | ctx->node_destroy.notify = ctx_handle_node_destroy; | 221 | ctx->node_destroy.notify = ctx_handle_node_destroy; |
218 | wl_signal_add(&ctx->node->events.destroy, &ctx->node_destroy); | 222 | wl_signal_add(&ctx->node->events.destroy, &ctx->node_destroy); |
@@ -227,6 +231,12 @@ struct launcher_ctx *launcher_ctx_create(struct wlr_xdg_activation_token_v1 *tok | |||
227 | return ctx; | 231 | return ctx; |
228 | } | 232 | } |
229 | 233 | ||
234 | static void launch_ctx_handle_seat_destroy(struct wl_listener *listener, void *data) { | ||
235 | struct launcher_ctx *ctx = wl_container_of(listener, ctx, seat_destroy); | ||
236 | ctx->seat = NULL; | ||
237 | wl_list_remove(&ctx->seat_destroy.link); | ||
238 | } | ||
239 | |||
230 | // Creates a context with a new token for the internal launcher | 240 | // Creates a context with a new token for the internal launcher |
231 | struct launcher_ctx *launcher_ctx_create_internal(void) { | 241 | struct launcher_ctx *launcher_ctx_create_internal(void) { |
232 | struct sway_seat *seat = input_manager_current_seat(); | 242 | struct sway_seat *seat = input_manager_current_seat(); |
@@ -238,13 +248,15 @@ struct launcher_ctx *launcher_ctx_create_internal(void) { | |||
238 | 248 | ||
239 | struct wlr_xdg_activation_token_v1 *token = | 249 | struct wlr_xdg_activation_token_v1 *token = |
240 | wlr_xdg_activation_token_v1_create(server.xdg_activation_v1); | 250 | wlr_xdg_activation_token_v1_create(server.xdg_activation_v1); |
241 | token->seat = seat->wlr_seat; | ||
242 | 251 | ||
243 | struct launcher_ctx *ctx = launcher_ctx_create(token, &ws->node); | 252 | struct launcher_ctx *ctx = launcher_ctx_create(token, &ws->node); |
244 | if (!ctx) { | 253 | if (!ctx) { |
245 | wlr_xdg_activation_token_v1_destroy(token); | 254 | wlr_xdg_activation_token_v1_destroy(token); |
246 | return NULL; | 255 | return NULL; |
247 | } | 256 | } |
257 | ctx->seat = seat; | ||
258 | ctx->seat_destroy.notify = launch_ctx_handle_seat_destroy; | ||
259 | wl_signal_add(&seat->wlr_seat->events.destroy, &ctx->seat_destroy); | ||
248 | 260 | ||
249 | return ctx; | 261 | return ctx; |
250 | } | 262 | } |
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index c71abce7..6221b7b9 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -2,9 +2,12 @@ | |||
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <string.h> | 3 | #include <string.h> |
4 | #include <wayland-server-core.h> | 4 | #include <wayland-server-core.h> |
5 | #include <wlr/types/wlr_fractional_scale_v1.h> | ||
5 | #include <wlr/types/wlr_layer_shell_v1.h> | 6 | #include <wlr/types/wlr_layer_shell_v1.h> |
6 | #include <wlr/types/wlr_output.h> | 7 | #include <wlr/types/wlr_output.h> |
8 | #include <wlr/types/wlr_scene.h> | ||
7 | #include <wlr/types/wlr_subcompositor.h> | 9 | #include <wlr/types/wlr_subcompositor.h> |
10 | #include <wlr/types/wlr_xdg_shell.h> | ||
8 | #include "log.h" | 11 | #include "log.h" |
9 | #include "sway/scene_descriptor.h" | 12 | #include "sway/scene_descriptor.h" |
10 | #include "sway/desktop/transaction.h" | 13 | #include "sway/desktop/transaction.h" |
@@ -16,7 +19,6 @@ | |||
16 | #include "sway/server.h" | 19 | #include "sway/server.h" |
17 | #include "sway/tree/arrange.h" | 20 | #include "sway/tree/arrange.h" |
18 | #include "sway/tree/workspace.h" | 21 | #include "sway/tree/workspace.h" |
19 | #include <wlr/types/wlr_scene.h> | ||
20 | 22 | ||
21 | struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface( | 23 | struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface( |
22 | struct wlr_surface *surface) { | 24 | struct wlr_surface *surface) { |
@@ -85,6 +87,8 @@ void arrange_layers(struct sway_output *output) { | |||
85 | sway_log(SWAY_DEBUG, "Usable area changed, rearranging output"); | 87 | sway_log(SWAY_DEBUG, "Usable area changed, rearranging output"); |
86 | output->usable_area = usable_area; | 88 | output->usable_area = usable_area; |
87 | arrange_output(output); | 89 | arrange_output(output); |
90 | } else { | ||
91 | arrange_popups(root->layers.popup); | ||
88 | } | 92 | } |
89 | } | 93 | } |
90 | 94 | ||
@@ -120,10 +124,21 @@ static struct sway_layer_surface *sway_layer_surface_create( | |||
120 | return NULL; | 124 | return NULL; |
121 | } | 125 | } |
122 | 126 | ||
127 | surface->desc.relative = &scene->tree->node; | ||
128 | |||
129 | if (!scene_descriptor_assign(&popups->node, | ||
130 | SWAY_SCENE_DESC_POPUP, &surface->desc)) { | ||
131 | sway_log(SWAY_ERROR, "Failed to allocate a popup scene descriptor"); | ||
132 | wlr_scene_node_destroy(&popups->node); | ||
133 | free(surface); | ||
134 | return NULL; | ||
135 | } | ||
136 | |||
123 | surface->tree = scene->tree; | 137 | surface->tree = scene->tree; |
124 | surface->scene = scene; | 138 | surface->scene = scene; |
125 | surface->layer_surface = scene->layer_surface; | 139 | surface->layer_surface = scene->layer_surface; |
126 | surface->popups = popups; | 140 | surface->popups = popups; |
141 | surface->layer_surface->data = surface; | ||
127 | 142 | ||
128 | return surface; | 143 | return surface; |
129 | } | 144 | } |
@@ -197,6 +212,8 @@ static void handle_node_destroy(struct wl_listener *listener, void *data) { | |||
197 | wl_list_remove(&layer->node_destroy.link); | 212 | wl_list_remove(&layer->node_destroy.link); |
198 | wl_list_remove(&layer->output_destroy.link); | 213 | wl_list_remove(&layer->output_destroy.link); |
199 | 214 | ||
215 | layer->layer_surface->data = NULL; | ||
216 | |||
200 | free(layer); | 217 | free(layer); |
201 | } | 218 | } |
202 | 219 | ||
@@ -222,10 +239,6 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { | |||
222 | arrange_layers(surface->output); | 239 | arrange_layers(surface->output); |
223 | transaction_commit_dirty(); | 240 | transaction_commit_dirty(); |
224 | } | 241 | } |
225 | |||
226 | int lx, ly; | ||
227 | wlr_scene_node_coords(&surface->scene->tree->node, &lx, &ly); | ||
228 | wlr_scene_node_set_position(&surface->popups->node, lx, ly); | ||
229 | } | 242 | } |
230 | 243 | ||
231 | static void handle_map(struct wl_listener *listener, void *data) { | 244 | static void handle_map(struct wl_listener *listener, void *data) { |
@@ -420,6 +433,12 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { | |||
420 | 433 | ||
421 | surface->output = output; | 434 | surface->output = output; |
422 | 435 | ||
436 | // now that the surface's output is known, we can advertise its scale | ||
437 | wlr_fractional_scale_v1_notify_scale(surface->layer_surface->surface, | ||
438 | layer_surface->output->scale); | ||
439 | wlr_surface_set_preferred_buffer_scale(surface->layer_surface->surface, | ||
440 | ceil(layer_surface->output->scale)); | ||
441 | |||
423 | surface->surface_commit.notify = handle_surface_commit; | 442 | surface->surface_commit.notify = handle_surface_commit; |
424 | wl_signal_add(&layer_surface->surface->events.commit, | 443 | wl_signal_add(&layer_surface->surface->events.commit, |
425 | &surface->surface_commit); | 444 | &surface->surface_commit); |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 9c4baafd..2722e556 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <stdlib.h> | 2 | #include <stdlib.h> |
4 | #include <strings.h> | 3 | #include <strings.h> |
@@ -12,6 +11,8 @@ | |||
12 | #include <wlr/types/wlr_gamma_control_v1.h> | 11 | #include <wlr/types/wlr_gamma_control_v1.h> |
13 | #include <wlr/types/wlr_matrix.h> | 12 | #include <wlr/types/wlr_matrix.h> |
14 | #include <wlr/types/wlr_output_layout.h> | 13 | #include <wlr/types/wlr_output_layout.h> |
14 | #include <wlr/types/wlr_output_management_v1.h> | ||
15 | #include <wlr/types/wlr_output_power_management_v1.h> | ||
15 | #include <wlr/types/wlr_output.h> | 16 | #include <wlr/types/wlr_output.h> |
16 | #include <wlr/types/wlr_presentation_time.h> | 17 | #include <wlr/types/wlr_presentation_time.h> |
17 | #include <wlr/types/wlr_compositor.h> | 18 | #include <wlr/types/wlr_compositor.h> |
@@ -182,7 +183,15 @@ static void send_frame_done_iterator(struct wlr_scene_buffer *buffer, | |||
182 | } | 183 | } |
183 | } | 184 | } |
184 | 185 | ||
185 | static enum wlr_scale_filter_mode get_scale_filter(struct sway_output *output) { | 186 | static enum wlr_scale_filter_mode get_scale_filter(struct sway_output *output, |
187 | struct wlr_scene_buffer *buffer) { | ||
188 | // if we are scaling down, we should always choose linear | ||
189 | if (buffer->dst_width > 0 && buffer->dst_height > 0 && ( | ||
190 | buffer->dst_width < buffer->buffer_width || | ||
191 | buffer->dst_height < buffer->buffer_height)) { | ||
192 | return WLR_SCALE_FILTER_BILINEAR; | ||
193 | } | ||
194 | |||
186 | switch (output->scale_filter) { | 195 | switch (output->scale_filter) { |
187 | case SCALE_FILTER_LINEAR: | 196 | case SCALE_FILTER_LINEAR: |
188 | return WLR_SCALE_FILTER_BILINEAR; | 197 | return WLR_SCALE_FILTER_BILINEAR; |
@@ -211,7 +220,7 @@ static void output_configure_scene(struct sway_output *output, | |||
211 | // hack: don't call the scene setter because that will damage all outputs | 220 | // hack: don't call the scene setter because that will damage all outputs |
212 | // We don't want to damage outputs that aren't our current output that | 221 | // We don't want to damage outputs that aren't our current output that |
213 | // we're configuring | 222 | // we're configuring |
214 | buffer->filter_mode = get_scale_filter(output); | 223 | buffer->filter_mode = get_scale_filter(output, buffer); |
215 | 224 | ||
216 | wlr_scene_buffer_set_opacity(buffer, opacity); | 225 | wlr_scene_buffer_set_opacity(buffer, opacity); |
217 | } else if (node->type == WLR_SCENE_NODE_TREE) { | 226 | } else if (node->type == WLR_SCENE_NODE_TREE) { |
@@ -512,9 +521,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
512 | sway_session_lock_add_output(server->session_lock.lock, output); | 521 | sway_session_lock_add_output(server->session_lock.lock, output); |
513 | } | 522 | } |
514 | 523 | ||
515 | struct output_config *oc = find_output_config(output); | 524 | apply_all_output_configs(); |
516 | apply_output_config(oc, output); | ||
517 | free_output_config(oc); | ||
518 | 525 | ||
519 | transaction_commit_dirty(); | 526 | transaction_commit_dirty(); |
520 | 527 | ||
@@ -543,63 +550,89 @@ void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) { | |||
543 | wlr_output_schedule_frame(output->wlr_output); | 550 | wlr_output_schedule_frame(output->wlr_output); |
544 | } | 551 | } |
545 | 552 | ||
553 | static struct output_config *output_config_for_config_head( | ||
554 | struct wlr_output_configuration_head_v1 *config_head, | ||
555 | struct sway_output *output) { | ||
556 | struct output_config *oc = new_output_config(output->wlr_output->name); | ||
557 | oc->enabled = config_head->state.enabled; | ||
558 | if (!oc->enabled) { | ||
559 | return oc; | ||
560 | } | ||
561 | |||
562 | if (config_head->state.mode != NULL) { | ||
563 | struct wlr_output_mode *mode = config_head->state.mode; | ||
564 | oc->width = mode->width; | ||
565 | oc->height = mode->height; | ||
566 | oc->refresh_rate = mode->refresh / 1000.f; | ||
567 | } else { | ||
568 | oc->width = config_head->state.custom_mode.width; | ||
569 | oc->height = config_head->state.custom_mode.height; | ||
570 | oc->refresh_rate = | ||
571 | config_head->state.custom_mode.refresh / 1000.f; | ||
572 | } | ||
573 | oc->x = config_head->state.x; | ||
574 | oc->y = config_head->state.y; | ||
575 | oc->transform = config_head->state.transform; | ||
576 | oc->scale = config_head->state.scale; | ||
577 | oc->adaptive_sync = config_head->state.adaptive_sync_enabled; | ||
578 | return oc; | ||
579 | } | ||
580 | |||
546 | static void output_manager_apply(struct sway_server *server, | 581 | static void output_manager_apply(struct sway_server *server, |
547 | struct wlr_output_configuration_v1 *config, bool test_only) { | 582 | struct wlr_output_configuration_v1 *config, bool test_only) { |
548 | // TODO: perform atomic tests on the whole backend atomically | 583 | size_t configs_len = wl_list_length(&root->all_outputs); |
549 | 584 | struct matched_output_config *configs = calloc(configs_len, sizeof(*configs)); | |
550 | struct wlr_output_configuration_head_v1 *config_head; | 585 | if (!configs) { |
551 | // First disable outputs we need to disable | 586 | return; |
552 | bool ok = true; | 587 | } |
553 | wl_list_for_each(config_head, &config->heads, link) { | 588 | |
554 | struct wlr_output *wlr_output = config_head->state.output; | 589 | int config_idx = 0; |
555 | struct sway_output *output = wlr_output->data; | 590 | struct sway_output *sway_output; |
556 | if (!output->enabled || config_head->state.enabled) { | 591 | wl_list_for_each(sway_output, &root->all_outputs, link) { |
592 | if (sway_output == root->fallback_output) { | ||
593 | configs_len--; | ||
557 | continue; | 594 | continue; |
558 | } | 595 | } |
559 | struct output_config *oc = new_output_config(output->wlr_output->name); | ||
560 | oc->enabled = false; | ||
561 | 596 | ||
562 | if (test_only) { | 597 | struct matched_output_config *cfg = &configs[config_idx++]; |
563 | ok &= test_output_config(oc, output); | 598 | cfg->output = sway_output; |
564 | } else { | 599 | |
565 | oc = store_output_config(oc); | 600 | struct wlr_output_configuration_head_v1 *config_head; |
566 | ok &= apply_output_config(oc, output); | 601 | wl_list_for_each(config_head, &config->heads, link) { |
602 | if (config_head->state.output == sway_output->wlr_output) { | ||
603 | cfg->config = output_config_for_config_head(config_head, sway_output); | ||
604 | break; | ||
605 | } | ||
606 | } | ||
607 | if (!cfg->config) { | ||
608 | cfg->config = find_output_config(sway_output); | ||
567 | } | 609 | } |
568 | } | 610 | } |
569 | 611 | ||
570 | // Then enable outputs that need to | 612 | sort_output_configs_by_priority(configs, configs_len); |
571 | wl_list_for_each(config_head, &config->heads, link) { | 613 | bool ok = apply_output_configs(configs, configs_len, test_only, false); |
572 | struct wlr_output *wlr_output = config_head->state.output; | 614 | for (size_t idx = 0; idx < configs_len; idx++) { |
573 | struct sway_output *output = wlr_output->data; | 615 | struct matched_output_config *cfg = &configs[idx]; |
574 | if (!config_head->state.enabled) { | 616 | |
575 | continue; | 617 | // Only store new configs for successful non-test commits. Old configs, |
576 | } | 618 | // test-only and failed commits just get freed. |
577 | struct output_config *oc = new_output_config(output->wlr_output->name); | 619 | bool store_config = false; |
578 | oc->enabled = true; | 620 | if (!test_only && ok) { |
579 | if (config_head->state.mode != NULL) { | 621 | struct wlr_output_configuration_head_v1 *config_head; |
580 | struct wlr_output_mode *mode = config_head->state.mode; | 622 | wl_list_for_each(config_head, &config->heads, link) { |
581 | oc->width = mode->width; | 623 | if (config_head->state.output == cfg->output->wlr_output) { |
582 | oc->height = mode->height; | 624 | store_config = true; |
583 | oc->refresh_rate = mode->refresh / 1000.f; | 625 | break; |
584 | } else { | 626 | } |
585 | oc->width = config_head->state.custom_mode.width; | 627 | } |
586 | oc->height = config_head->state.custom_mode.height; | ||
587 | oc->refresh_rate = | ||
588 | config_head->state.custom_mode.refresh / 1000.f; | ||
589 | } | 628 | } |
590 | oc->x = config_head->state.x; | 629 | if (store_config) { |
591 | oc->y = config_head->state.y; | 630 | store_output_config(cfg->config); |
592 | oc->transform = config_head->state.transform; | ||
593 | oc->scale = config_head->state.scale; | ||
594 | oc->adaptive_sync = config_head->state.adaptive_sync_enabled; | ||
595 | |||
596 | if (test_only) { | ||
597 | ok &= test_output_config(oc, output); | ||
598 | } else { | 631 | } else { |
599 | oc = store_output_config(oc); | 632 | free_output_config(cfg->config); |
600 | ok &= apply_output_config(oc, output); | ||
601 | } | 633 | } |
602 | } | 634 | } |
635 | free(configs); | ||
603 | 636 | ||
604 | if (ok) { | 637 | if (ok) { |
605 | wlr_output_configuration_v1_send_succeeded(config); | 638 | wlr_output_configuration_v1_send_succeeded(config); |
@@ -643,6 +676,6 @@ void handle_output_power_manager_set_mode(struct wl_listener *listener, | |||
643 | oc->power = 1; | 676 | oc->power = 1; |
644 | break; | 677 | break; |
645 | } | 678 | } |
646 | oc = store_output_config(oc); | 679 | store_output_config(oc); |
647 | apply_output_config(oc, output); | 680 | apply_all_output_configs(); |
648 | } | 681 | } |
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index acc3e3f9..042141ab 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdbool.h> | 1 | #include <stdbool.h> |
3 | #include <stdlib.h> | 2 | #include <stdlib.h> |
4 | #include <string.h> | 3 | #include <string.h> |
@@ -606,21 +605,15 @@ static void arrange_output(struct sway_output *output, int width, int height) { | |||
606 | } | 605 | } |
607 | } | 606 | } |
608 | 607 | ||
609 | static void arrange_popup(struct wlr_scene_tree *popup) { | 608 | void arrange_popups(struct wlr_scene_tree *popups) { |
610 | struct wlr_scene_node *node; | 609 | struct wlr_scene_node *node; |
611 | wl_list_for_each(node, &popup->children, link) { | 610 | wl_list_for_each(node, &popups->children, link) { |
612 | struct sway_xdg_popup *popup = scene_descriptor_try_get(node, | 611 | struct sway_popup_desc *popup = scene_descriptor_try_get(node, |
613 | SWAY_SCENE_DESC_POPUP); | 612 | SWAY_SCENE_DESC_POPUP); |
614 | 613 | ||
615 | // the popup layer may have popups from layer_shell surfaces, in this | 614 | int lx, ly; |
616 | // case those don't have a scene descriptor, so lets skip those here. | 615 | wlr_scene_node_coords(popup->relative, &lx, &ly); |
617 | if (popup) { | 616 | wlr_scene_node_set_position(node, lx, ly); |
618 | struct wlr_scene_tree *tree = popup->view->content_tree; | ||
619 | |||
620 | int lx, ly; | ||
621 | wlr_scene_node_coords(&tree->node, &lx, &ly); | ||
622 | wlr_scene_node_set_position(&popup->scene_tree->node, lx, ly); | ||
623 | } | ||
624 | } | 617 | } |
625 | } | 618 | } |
626 | 619 | ||
@@ -679,7 +672,7 @@ static void arrange_root(struct sway_root *root) { | |||
679 | } | 672 | } |
680 | } | 673 | } |
681 | 674 | ||
682 | arrange_popup(root->layers.popup); | 675 | arrange_popups(root->layers.popup); |
683 | } | 676 | } |
684 | 677 | ||
685 | /** | 678 | /** |
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 7cdd97c8..7c417891 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 199309L | ||
2 | #include <float.h> | 1 | #include <float.h> |
3 | #include <stdbool.h> | 2 | #include <stdbool.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
@@ -36,6 +35,7 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) { | |||
36 | wl_list_remove(&popup->new_popup.link); | 35 | wl_list_remove(&popup->new_popup.link); |
37 | wl_list_remove(&popup->destroy.link); | 36 | wl_list_remove(&popup->destroy.link); |
38 | wl_list_remove(&popup->surface_commit.link); | 37 | wl_list_remove(&popup->surface_commit.link); |
38 | wl_list_remove(&popup->reposition.link); | ||
39 | wlr_scene_node_destroy(&popup->scene_tree->node); | 39 | wlr_scene_node_destroy(&popup->scene_tree->node); |
40 | free(popup); | 40 | free(popup); |
41 | } | 41 | } |
@@ -71,6 +71,11 @@ static void popup_handle_surface_commit(struct wl_listener *listener, void *data | |||
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
74 | static void popup_handle_reposition(struct wl_listener *listener, void *data) { | ||
75 | struct sway_xdg_popup *popup = wl_container_of(listener, popup, reposition); | ||
76 | popup_unconstrain(popup); | ||
77 | } | ||
78 | |||
74 | static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, | 79 | static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, |
75 | struct sway_view *view, struct wlr_scene_tree *parent) { | 80 | struct sway_view *view, struct wlr_scene_tree *parent) { |
76 | struct wlr_xdg_surface *xdg_surface = wlr_popup->base; | 81 | struct wlr_xdg_surface *xdg_surface = wlr_popup->base; |
@@ -97,8 +102,11 @@ static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, | |||
97 | return NULL; | 102 | return NULL; |
98 | } | 103 | } |
99 | 104 | ||
105 | popup->desc.relative = &view->content_tree->node; | ||
106 | popup->desc.view = view; | ||
107 | |||
100 | if (!scene_descriptor_assign(&popup->scene_tree->node, | 108 | if (!scene_descriptor_assign(&popup->scene_tree->node, |
101 | SWAY_SCENE_DESC_POPUP, popup)) { | 109 | SWAY_SCENE_DESC_POPUP, &popup->desc)) { |
102 | sway_log(SWAY_ERROR, "Failed to allocate a popup scene descriptor"); | 110 | sway_log(SWAY_ERROR, "Failed to allocate a popup scene descriptor"); |
103 | wlr_scene_node_destroy(&popup->scene_tree->node); | 111 | wlr_scene_node_destroy(&popup->scene_tree->node); |
104 | free(popup); | 112 | free(popup); |
@@ -114,6 +122,8 @@ static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, | |||
114 | popup->surface_commit.notify = popup_handle_surface_commit; | 122 | popup->surface_commit.notify = popup_handle_surface_commit; |
115 | wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); | 123 | wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); |
116 | popup->new_popup.notify = popup_handle_new_popup; | 124 | popup->new_popup.notify = popup_handle_new_popup; |
125 | wl_signal_add(&wlr_popup->events.reposition, &popup->reposition); | ||
126 | popup->reposition.notify = popup_handle_reposition; | ||
117 | wl_signal_add(&wlr_popup->events.destroy, &popup->destroy); | 127 | wl_signal_add(&wlr_popup->events.destroy, &popup->destroy); |
118 | popup->destroy.notify = popup_handle_destroy; | 128 | popup->destroy.notify = popup_handle_destroy; |
119 | 129 | ||
@@ -279,6 +289,7 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
279 | } | 289 | } |
280 | // XXX: https://github.com/swaywm/sway/issues/2176 | 290 | // XXX: https://github.com/swaywm/sway/issues/2176 |
281 | wlr_xdg_surface_schedule_configure(xdg_surface); | 291 | wlr_xdg_surface_schedule_configure(xdg_surface); |
292 | // TODO: wlr_xdg_toplevel_set_bounds() | ||
282 | return; | 293 | return; |
283 | } | 294 | } |
284 | 295 | ||
@@ -337,6 +348,7 @@ static void handle_set_app_id(struct wl_listener *listener, void *data) { | |||
337 | struct sway_xdg_shell_view *xdg_shell_view = | 348 | struct sway_xdg_shell_view *xdg_shell_view = |
338 | wl_container_of(listener, xdg_shell_view, set_app_id); | 349 | wl_container_of(listener, xdg_shell_view, set_app_id); |
339 | struct sway_view *view = &xdg_shell_view->view; | 350 | struct sway_view *view = &xdg_shell_view->view; |
351 | view_update_app_id(view); | ||
340 | view_execute_criteria(view); | 352 | view_execute_criteria(view); |
341 | } | 353 | } |
342 | 354 | ||
@@ -563,4 +575,7 @@ void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) { | |||
563 | wlr_scene_xdg_surface_create(xdg_shell_view->view.content_tree, xdg_toplevel->base); | 575 | wlr_scene_xdg_surface_create(xdg_shell_view->view.content_tree, xdg_toplevel->base); |
564 | 576 | ||
565 | xdg_toplevel->base->data = xdg_shell_view; | 577 | xdg_toplevel->base->data = xdg_shell_view; |
578 | |||
579 | wlr_xdg_toplevel_set_wm_capabilities(xdg_toplevel, | ||
580 | XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); | ||
566 | } | 581 | } |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 9f3f4d5f..270cf08f 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 199309L | ||
2 | #include <float.h> | 1 | #include <float.h> |
3 | #include <stdbool.h> | 2 | #include <stdbool.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |