diff options
-rw-r--r-- | sway/desktop/render.c | 95 |
1 files changed, 90 insertions, 5 deletions
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 7d620bd4..5cec5949 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -927,6 +927,72 @@ static void render_seatops(struct sway_output *output, | |||
927 | } | 927 | } |
928 | } | 928 | } |
929 | 929 | ||
930 | static void count_surface_iterator(struct sway_output *output, | ||
931 | struct wlr_surface *surface, struct wlr_box *_box, float rotation, | ||
932 | void *data) { | ||
933 | size_t *n = data; | ||
934 | (*n)++; | ||
935 | } | ||
936 | |||
937 | static bool scan_out_fullscreen_view(struct sway_output *output, | ||
938 | struct sway_view *view) { | ||
939 | struct wlr_output *wlr_output = output->wlr_output; | ||
940 | struct sway_workspace *workspace = output->current.active_workspace; | ||
941 | if (!sway_assert(workspace, "Expected an active workspace")) { | ||
942 | return false; | ||
943 | } | ||
944 | |||
945 | if (view->saved_buffer) { | ||
946 | return false; | ||
947 | } | ||
948 | |||
949 | for (int i = 0; i < workspace->current.floating->length; ++i) { | ||
950 | struct sway_container *floater = | ||
951 | workspace->current.floating->items[i]; | ||
952 | if (container_is_transient_for(floater, view->container)) { | ||
953 | return false; | ||
954 | } | ||
955 | } | ||
956 | |||
957 | #if HAVE_XWAYLAND | ||
958 | if (!wl_list_empty(&root->xwayland_unmanaged)) { | ||
959 | return false; | ||
960 | } | ||
961 | #endif | ||
962 | |||
963 | if (!wl_list_empty(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY])) { | ||
964 | return false; | ||
965 | } | ||
966 | if (!wl_list_empty(&root->drag_icons)) { | ||
967 | return false; | ||
968 | } | ||
969 | |||
970 | struct wlr_surface *surface = view->surface; | ||
971 | if (surface == NULL) { | ||
972 | return false; | ||
973 | } | ||
974 | size_t n_surfaces = 0; | ||
975 | output_view_for_each_surface(output, view, | ||
976 | count_surface_iterator, &n_surfaces); | ||
977 | if (n_surfaces != 1) { | ||
978 | return false; | ||
979 | } | ||
980 | |||
981 | if (surface->buffer == NULL) { | ||
982 | return false; | ||
983 | } | ||
984 | |||
985 | if ((float)surface->current.scale != wlr_output->scale || | ||
986 | surface->current.transform != wlr_output->transform) { | ||
987 | return false; | ||
988 | } | ||
989 | |||
990 | if (!wlr_output_attach_buffer(wlr_output, surface->buffer)) { | ||
991 | return false; | ||
992 | } | ||
993 | return wlr_output_commit(wlr_output); | ||
994 | } | ||
995 | |||
930 | void output_render(struct sway_output *output, struct timespec *when, | 996 | void output_render(struct sway_output *output, struct timespec *when, |
931 | pixman_region32_t *damage) { | 997 | pixman_region32_t *damage) { |
932 | struct wlr_output *wlr_output = output->wlr_output; | 998 | struct wlr_output *wlr_output = output->wlr_output; |
@@ -943,6 +1009,30 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
943 | return; | 1009 | return; |
944 | } | 1010 | } |
945 | 1011 | ||
1012 | struct sway_container *fullscreen_con = root->fullscreen_global; | ||
1013 | if (!fullscreen_con) { | ||
1014 | fullscreen_con = workspace->current.fullscreen; | ||
1015 | } | ||
1016 | |||
1017 | if (fullscreen_con && fullscreen_con->view) { | ||
1018 | // Try to scan-out the fullscreen view | ||
1019 | static bool last_scanned_out = false; | ||
1020 | bool scanned_out = | ||
1021 | scan_out_fullscreen_view(output, fullscreen_con->view); | ||
1022 | |||
1023 | if (scanned_out && !last_scanned_out) { | ||
1024 | sway_log(SWAY_DEBUG, "Scanning out fullscreen view"); | ||
1025 | } | ||
1026 | if (last_scanned_out && !scanned_out) { | ||
1027 | sway_log(SWAY_DEBUG, "Stopping fullscreen view scan out"); | ||
1028 | } | ||
1029 | last_scanned_out = scanned_out; | ||
1030 | |||
1031 | if (scanned_out) { | ||
1032 | return; | ||
1033 | } | ||
1034 | } | ||
1035 | |||
946 | wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); | 1036 | wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); |
947 | 1037 | ||
948 | if (!pixman_region32_not_empty(damage)) { | 1038 | if (!pixman_region32_not_empty(damage)) { |
@@ -962,11 +1052,6 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
962 | goto render_overlay; | 1052 | goto render_overlay; |
963 | } | 1053 | } |
964 | 1054 | ||
965 | struct sway_container *fullscreen_con = root->fullscreen_global; | ||
966 | if (!fullscreen_con) { | ||
967 | fullscreen_con = workspace->current.fullscreen; | ||
968 | } | ||
969 | |||
970 | if (fullscreen_con) { | 1055 | if (fullscreen_con) { |
971 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; | 1056 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; |
972 | 1057 | ||