render: sync with Cursor.surfaceAt(), draw all view popups
This was slightly out of sync with Cursor.surfaceAt() which did not fullscreen or xwayland unmanaged views properly. Also simplify things and improve correctness by always rendering all xdg popups. A view losing focus does not always mean that all popups will be destroyed.
This commit is contained in:
@ -80,7 +80,6 @@ pub fn renderOutput(output: *Output) void {
|
||||
renderer.clear(&[_]f32{ 0, 0, 0, 1 });
|
||||
renderView(output, view, &now);
|
||||
if (build_options.xwayland) renderXwaylandUnmanaged(output, &now);
|
||||
if (!view.destroying) renderViewPopups(output, view, &now);
|
||||
} else {
|
||||
// No fullscreen view, so render normal layers/views
|
||||
renderer.clear(&server.config.background_color);
|
||||
@ -126,13 +125,6 @@ pub fn renderOutput(output: *Output) void {
|
||||
|
||||
renderLayer(output, output.getLayer(.top).*, &now, .toplevels);
|
||||
|
||||
// Render popups of focused views
|
||||
it = ViewStack(View).iter(output.views.last, .reverse, output.current.tags, renderFilter);
|
||||
while (it.next()) |view| {
|
||||
if (view.current.focus == 0 or view.destroying) continue;
|
||||
renderViewPopups(output, view, &now);
|
||||
}
|
||||
|
||||
renderLayer(output, output.getLayer(.background).*, &now, .popups);
|
||||
renderLayer(output, output.getLayer(.bottom).*, &now, .popups);
|
||||
renderLayer(output, output.getLayer(.top).*, &now, .popups);
|
||||
@ -200,6 +192,7 @@ fn renderLayer(
|
||||
}
|
||||
}
|
||||
|
||||
/// Render all surfaces in the view's surface tree, including subsurfaces and popups
|
||||
fn renderView(output: *const Output, view: *View, now: *os.timespec) void {
|
||||
// If we have saved buffers, we are in the middle of a transaction
|
||||
// and need to render those buffers until the transaction is complete.
|
||||
@ -217,29 +210,19 @@ fn renderView(output: *const Output, view: *View, now: *os.timespec) void {
|
||||
saved_buffer.transform,
|
||||
);
|
||||
} else {
|
||||
// Since there is no stashed buffer, we are not in the middle of
|
||||
// a transaction and may simply render each toplevel surface.
|
||||
// Since there are no stashed buffers, we are not in the middle of
|
||||
// a transaction and may simply render the most recent buffers provided
|
||||
// by the client.
|
||||
var rdata = SurfaceRenderData{
|
||||
.output = output,
|
||||
.output_x = view.current.box.x - view.surface_box.x,
|
||||
.output_y = view.current.box.y - view.surface_box.y,
|
||||
.when = now,
|
||||
};
|
||||
|
||||
view.surface.?.forEachSurface(*SurfaceRenderData, renderSurfaceIterator, &rdata);
|
||||
view.forEachSurface(*SurfaceRenderData, renderSurfaceIterator, &rdata);
|
||||
}
|
||||
}
|
||||
|
||||
fn renderViewPopups(output: *const Output, view: *View, now: *os.timespec) void {
|
||||
var rdata = SurfaceRenderData{
|
||||
.output = output,
|
||||
.output_x = view.current.box.x - view.surface_box.x,
|
||||
.output_y = view.current.box.y - view.surface_box.y,
|
||||
.when = now,
|
||||
};
|
||||
view.forEachPopupSurface(*SurfaceRenderData, renderSurfaceIterator, &rdata);
|
||||
}
|
||||
|
||||
fn renderDragIcons(output: *const Output, now: *os.timespec) void {
|
||||
const output_box = server.root.output_layout.getBox(output.wlr_output).?;
|
||||
|
||||
@ -263,8 +246,8 @@ fn renderDragIcons(output: *const Output, now: *os.timespec) void {
|
||||
fn renderXwaylandUnmanaged(output: *const Output, now: *os.timespec) void {
|
||||
const output_box = server.root.output_layout.getBox(output.wlr_output).?;
|
||||
|
||||
var it = server.root.xwayland_unmanaged_views.first;
|
||||
while (it) |node| : (it = node.next) {
|
||||
var it = server.root.xwayland_unmanaged_views.last;
|
||||
while (it) |node| : (it = node.prev) {
|
||||
const xwayland_surface = node.data.xwayland_surface;
|
||||
|
||||
var rdata = SurfaceRenderData{
|
||||
|
Reference in New Issue
Block a user