diff options
Diffstat (limited to 'sway/desktop')
-rw-r--r-- | sway/desktop/launcher.c | 1 | ||||
-rw-r--r-- | sway/desktop/layer_shell.c | 7 | ||||
-rw-r--r-- | sway/desktop/output.c | 132 | ||||
-rw-r--r-- | sway/desktop/transaction.c | 3 |
4 files changed, 90 insertions, 53 deletions
diff --git a/sway/desktop/launcher.c b/sway/desktop/launcher.c index 28043d19..2362e1ba 100644 --- a/sway/desktop/launcher.c +++ b/sway/desktop/launcher.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include "sway/input/seat.h" | 4 | #include "sway/input/seat.h" |
5 | #include "sway/output.h" | 5 | #include "sway/output.h" |
6 | #include "sway/desktop/launcher.h" | 6 | #include "sway/desktop/launcher.h" |
7 | #include "sway/server.h" | ||
7 | #include "sway/tree/node.h" | 8 | #include "sway/tree/node.h" |
8 | #include "sway/tree/container.h" | 9 | #include "sway/tree/container.h" |
9 | #include "sway/tree/workspace.h" | 10 | #include "sway/tree/workspace.h" |
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index 4b2584b6..6221b7b9 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -2,6 +2,7 @@ | |||
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> |
7 | #include <wlr/types/wlr_scene.h> | 8 | #include <wlr/types/wlr_scene.h> |
@@ -432,6 +433,12 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { | |||
432 | 433 | ||
433 | surface->output = output; | 434 | surface->output = output; |
434 | 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 | |||
435 | surface->surface_commit.notify = handle_surface_commit; | 442 | surface->surface_commit.notify = handle_surface_commit; |
436 | wl_signal_add(&layer_surface->surface->events.commit, | 443 | wl_signal_add(&layer_surface->surface->events.commit, |
437 | &surface->surface_commit); | 444 | &surface->surface_commit); |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index b8f2d32d..6bf77d17 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -243,10 +243,14 @@ static int output_repaint_timer_handler(void *data) { | |||
243 | 243 | ||
244 | output_configure_scene(output, &root->root_scene->tree.node, 1.0f); | 244 | output_configure_scene(output, &root->root_scene->tree.node, 1.0f); |
245 | 245 | ||
246 | struct wlr_scene_output_state_options opts = { | ||
247 | .color_transform = output->color_transform, | ||
248 | }; | ||
249 | |||
246 | if (output->gamma_lut_changed) { | 250 | if (output->gamma_lut_changed) { |
247 | struct wlr_output_state pending; | 251 | struct wlr_output_state pending; |
248 | wlr_output_state_init(&pending); | 252 | wlr_output_state_init(&pending); |
249 | if (!wlr_scene_output_build_state(output->scene_output, &pending, NULL)) { | 253 | if (!wlr_scene_output_build_state(output->scene_output, &pending, &opts)) { |
250 | return 0; | 254 | return 0; |
251 | } | 255 | } |
252 | 256 | ||
@@ -269,7 +273,7 @@ static int output_repaint_timer_handler(void *data) { | |||
269 | return 0; | 273 | return 0; |
270 | } | 274 | } |
271 | 275 | ||
272 | wlr_scene_output_commit(output->scene_output, NULL); | 276 | wlr_scene_output_commit(output->scene_output, &opts); |
273 | return 0; | 277 | return 0; |
274 | } | 278 | } |
275 | 279 | ||
@@ -521,9 +525,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
521 | sway_session_lock_add_output(server->session_lock.lock, output); | 525 | sway_session_lock_add_output(server->session_lock.lock, output); |
522 | } | 526 | } |
523 | 527 | ||
524 | struct output_config *oc = find_output_config(output); | 528 | apply_all_output_configs(); |
525 | apply_output_config(oc, output); | ||
526 | free_output_config(oc); | ||
527 | 529 | ||
528 | transaction_commit_dirty(); | 530 | transaction_commit_dirty(); |
529 | 531 | ||
@@ -552,63 +554,89 @@ void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) { | |||
552 | wlr_output_schedule_frame(output->wlr_output); | 554 | wlr_output_schedule_frame(output->wlr_output); |
553 | } | 555 | } |
554 | 556 | ||
557 | static struct output_config *output_config_for_config_head( | ||
558 | struct wlr_output_configuration_head_v1 *config_head, | ||
559 | struct sway_output *output) { | ||
560 | struct output_config *oc = new_output_config(output->wlr_output->name); | ||
561 | oc->enabled = config_head->state.enabled; | ||
562 | if (!oc->enabled) { | ||
563 | return oc; | ||
564 | } | ||
565 | |||
566 | if (config_head->state.mode != NULL) { | ||
567 | struct wlr_output_mode *mode = config_head->state.mode; | ||
568 | oc->width = mode->width; | ||
569 | oc->height = mode->height; | ||
570 | oc->refresh_rate = mode->refresh / 1000.f; | ||
571 | } else { | ||
572 | oc->width = config_head->state.custom_mode.width; | ||
573 | oc->height = config_head->state.custom_mode.height; | ||
574 | oc->refresh_rate = | ||
575 | config_head->state.custom_mode.refresh / 1000.f; | ||
576 | } | ||
577 | oc->x = config_head->state.x; | ||
578 | oc->y = config_head->state.y; | ||
579 | oc->transform = config_head->state.transform; | ||
580 | oc->scale = config_head->state.scale; | ||
581 | oc->adaptive_sync = config_head->state.adaptive_sync_enabled; | ||
582 | return oc; | ||
583 | } | ||
584 | |||
555 | static void output_manager_apply(struct sway_server *server, | 585 | static void output_manager_apply(struct sway_server *server, |
556 | struct wlr_output_configuration_v1 *config, bool test_only) { | 586 | struct wlr_output_configuration_v1 *config, bool test_only) { |
557 | // TODO: perform atomic tests on the whole backend atomically | 587 | size_t configs_len = wl_list_length(&root->all_outputs); |
558 | 588 | struct matched_output_config *configs = calloc(configs_len, sizeof(*configs)); | |
559 | struct wlr_output_configuration_head_v1 *config_head; | 589 | if (!configs) { |
560 | // First disable outputs we need to disable | 590 | return; |
561 | bool ok = true; | 591 | } |
562 | wl_list_for_each(config_head, &config->heads, link) { | 592 | |
563 | struct wlr_output *wlr_output = config_head->state.output; | 593 | int config_idx = 0; |
564 | struct sway_output *output = wlr_output->data; | 594 | struct sway_output *sway_output; |
565 | if (!output->enabled || config_head->state.enabled) { | 595 | wl_list_for_each(sway_output, &root->all_outputs, link) { |
596 | if (sway_output == root->fallback_output) { | ||
597 | configs_len--; | ||
566 | continue; | 598 | continue; |
567 | } | 599 | } |
568 | struct output_config *oc = new_output_config(output->wlr_output->name); | ||
569 | oc->enabled = false; | ||
570 | 600 | ||
571 | if (test_only) { | 601 | struct matched_output_config *cfg = &configs[config_idx++]; |
572 | ok &= test_output_config(oc, output); | 602 | cfg->output = sway_output; |
573 | } else { | 603 | |
574 | oc = store_output_config(oc); | 604 | struct wlr_output_configuration_head_v1 *config_head; |
575 | ok &= apply_output_config(oc, output); | 605 | wl_list_for_each(config_head, &config->heads, link) { |
606 | if (config_head->state.output == sway_output->wlr_output) { | ||
607 | cfg->config = output_config_for_config_head(config_head, sway_output); | ||
608 | break; | ||
609 | } | ||
610 | } | ||
611 | if (!cfg->config) { | ||
612 | cfg->config = find_output_config(sway_output); | ||
576 | } | 613 | } |
577 | } | 614 | } |
578 | 615 | ||
579 | // Then enable outputs that need to | 616 | sort_output_configs_by_priority(configs, configs_len); |
580 | wl_list_for_each(config_head, &config->heads, link) { | 617 | bool ok = apply_output_configs(configs, configs_len, test_only, false); |
581 | struct wlr_output *wlr_output = config_head->state.output; | 618 | for (size_t idx = 0; idx < configs_len; idx++) { |
582 | struct sway_output *output = wlr_output->data; | 619 | struct matched_output_config *cfg = &configs[idx]; |
583 | if (!config_head->state.enabled) { | 620 | |
584 | continue; | 621 | // Only store new configs for successful non-test commits. Old configs, |
585 | } | 622 | // test-only and failed commits just get freed. |
586 | struct output_config *oc = new_output_config(output->wlr_output->name); | 623 | bool store_config = false; |
587 | oc->enabled = true; | 624 | if (!test_only && ok) { |
588 | if (config_head->state.mode != NULL) { | 625 | struct wlr_output_configuration_head_v1 *config_head; |
589 | struct wlr_output_mode *mode = config_head->state.mode; | 626 | wl_list_for_each(config_head, &config->heads, link) { |
590 | oc->width = mode->width; | 627 | if (config_head->state.output == cfg->output->wlr_output) { |
591 | oc->height = mode->height; | 628 | store_config = true; |
592 | oc->refresh_rate = mode->refresh / 1000.f; | 629 | break; |
593 | } else { | 630 | } |
594 | oc->width = config_head->state.custom_mode.width; | 631 | } |
595 | oc->height = config_head->state.custom_mode.height; | ||
596 | oc->refresh_rate = | ||
597 | config_head->state.custom_mode.refresh / 1000.f; | ||
598 | } | 632 | } |
599 | oc->x = config_head->state.x; | 633 | if (store_config) { |
600 | oc->y = config_head->state.y; | 634 | store_output_config(cfg->config); |
601 | oc->transform = config_head->state.transform; | ||
602 | oc->scale = config_head->state.scale; | ||
603 | oc->adaptive_sync = config_head->state.adaptive_sync_enabled; | ||
604 | |||
605 | if (test_only) { | ||
606 | ok &= test_output_config(oc, output); | ||
607 | } else { | 635 | } else { |
608 | oc = store_output_config(oc); | 636 | free_output_config(cfg->config); |
609 | ok &= apply_output_config(oc, output); | ||
610 | } | 637 | } |
611 | } | 638 | } |
639 | free(configs); | ||
612 | 640 | ||
613 | if (ok) { | 641 | if (ok) { |
614 | wlr_output_configuration_v1_send_succeeded(config); | 642 | wlr_output_configuration_v1_send_succeeded(config); |
@@ -652,6 +680,6 @@ void handle_output_power_manager_set_mode(struct wl_listener *listener, | |||
652 | oc->power = 1; | 680 | oc->power = 1; |
653 | break; | 681 | break; |
654 | } | 682 | } |
655 | oc = store_output_config(oc); | 683 | store_output_config(oc); |
656 | apply_output_config(oc, output); | 684 | apply_all_output_configs(); |
657 | } | 685 | } |
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 042141ab..d1898843 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include "sway/input/cursor.h" | 10 | #include "sway/input/cursor.h" |
11 | #include "sway/input/input-manager.h" | 11 | #include "sway/input/input-manager.h" |
12 | #include "sway/output.h" | 12 | #include "sway/output.h" |
13 | #include "sway/server.h" | ||
13 | #include "sway/tree/container.h" | 14 | #include "sway/tree/container.h" |
14 | #include "sway/tree/node.h" | 15 | #include "sway/tree/node.h" |
15 | #include "sway/tree/view.h" | 16 | #include "sway/tree/view.h" |
@@ -761,7 +762,7 @@ static bool should_configure(struct sway_node *node, | |||
761 | } | 762 | } |
762 | struct sway_container_state *cstate = &node->sway_container->current; | 763 | struct sway_container_state *cstate = &node->sway_container->current; |
763 | struct sway_container_state *istate = &instruction->container_state; | 764 | struct sway_container_state *istate = &instruction->container_state; |
764 | #if HAVE_XWAYLAND | 765 | #if WLR_HAS_XWAYLAND |
765 | // Xwayland views are position-aware and need to be reconfigured | 766 | // Xwayland views are position-aware and need to be reconfigured |
766 | // when their position changes. | 767 | // when their position changes. |
767 | if (node->sway_container->view->type == SWAY_VIEW_XWAYLAND) { | 768 | if (node->sway_container->view->type == SWAY_VIEW_XWAYLAND) { |