#include <wlr/types/wlr_xdg_toplevel_icon_v1.h>
#include "buffer.h"
#include "common/array.h"
+#include "common/box.h"
#include "common/macros.h"
#include "common/mem.h"
#include "config/rcxml.h"
}
}
+static void
+disable_fullscreen_bg(struct view *view)
+{
+ struct xdg_toplevel_view *xdg_view = xdg_toplevel_view_from_view(view);
+ if (xdg_view->fullscreen_bg) {
+ wlr_scene_node_set_enabled(&xdg_view->fullscreen_bg->node, false);
+ }
+}
+
+/*
+ * Centers any fullscreen view smaller than the full output size.
+ * This should be called immediately before view_moved().
+ */
+static void
+center_fullscreen_if_needed(struct view *view)
+{
+ if (!view->fullscreen || !output_is_usable(view->output)) {
+ disable_fullscreen_bg(view);
+ return;
+ }
+
+ struct wlr_box output_box = {0};
+ wlr_output_layout_get_box(view->server->output_layout,
+ view->output->wlr_output, &output_box);
+ box_center(view->current.width, view->current.height, &output_box,
+ &output_box, &view->current.x, &view->current.y);
+
+ /* Reset pending x/y to computed position also */
+ view->pending.x = view->current.x;
+ view->pending.y = view->current.y;
+
+ if (view->current.width >= output_box.width
+ && view->current.width >= output_box.height) {
+ disable_fullscreen_bg(view);
+ return;
+ }
+
+ struct xdg_toplevel_view *xdg_view = xdg_toplevel_view_from_view(view);
+ if (!xdg_view->fullscreen_bg) {
+ const float black[4] = {0, 0, 0, 1};
+ xdg_view->fullscreen_bg =
+ wlr_scene_rect_create(view->scene_tree, 0, 0, black);
+ wlr_scene_node_lower_to_bottom(&xdg_view->fullscreen_bg->node);
+ }
+
+ wlr_scene_node_set_position(&xdg_view->fullscreen_bg->node,
+ output_box.x - view->current.x, output_box.y - view->current.y);
+ wlr_scene_rect_set_size(xdg_view->fullscreen_bg,
+ output_box.width, output_box.height);
+ wlr_scene_node_set_enabled(&xdg_view->fullscreen_bg->node, true);
+}
+
/* TODO: reorder so this forward declaration isn't needed */
static void set_pending_configure_serial(struct view *view, uint32_t serial);
if (update_required) {
view_impl_apply_geometry(view, size.width, size.height);
+ center_fullscreen_if_needed(view);
view_moved(view);
/*
}
view->current.x = view->pending.x;
view->current.y = view->pending.y;
- view_moved(view);
}
+ center_fullscreen_if_needed(view);
+ view_moved(view);
+
/* Re-sync pending view with current state */
snap_constraints_update(view);
view->pending = view->current;
} else if (view->pending_configure_serial == 0) {
view->current.x = geo.x;
view->current.y = geo.y;
+ /*
+ * It's a bit difficult to think of a corner case where
+ * center_fullscreen_if_needed() would actually be needed
+ * here, but including it anyway for completeness.
+ */
+ center_fullscreen_if_needed(view);
view_moved(view);
}
}
if (serial > 0) {
set_pending_configure_serial(view, serial);
}
+ /* Disable background fill immediately on leaving fullscreen */
+ if (!fullscreen) {
+ disable_fullscreen_bg(view);
+ }
}
static void
set_initial_position(view);
}
+ /* Disable background fill at map (paranoid?) */
+ disable_fullscreen_bg(view);
+
/*
* Set initial "current" position directly before
* calling view_moved() to reduce flicker