aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop')
-rw-r--r--sway/desktop/launcher.c1
-rw-r--r--sway/desktop/layer_shell.c7
-rw-r--r--sway/desktop/output.c132
-rw-r--r--sway/desktop/transaction.c3
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
557static 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
555static void output_manager_apply(struct sway_server *server, 585static 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) {