cursor: handle popup subsurfaces properly

I added the required functions in wlroots 0.13.0, so use them.
This commit is contained in:
Isaac Freund 2021-04-27 18:56:06 +02:00
parent ec2c50b33f
commit 0c8e718d95
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11

View File

@ -426,7 +426,6 @@ fn handleRequestSetCursor(
/// returns the surface if found and sets the sx/sy parametes to the /// returns the surface if found and sets the sx/sy parametes to the
/// surface coordinates. /// surface coordinates.
fn surfaceAt(self: Self, lx: f64, ly: f64, sx: *f64, sy: *f64) ?*wlr.Surface { fn surfaceAt(self: Self, lx: f64, ly: f64, sx: *f64, sy: *f64) ?*wlr.Surface {
// Find the output to check
const root = self.seat.input_manager.server.root; const root = self.seat.input_manager.server.root;
const wlr_output = root.output_layout.outputAt(lx, ly) orelse return null; const wlr_output = root.output_layout.outputAt(lx, ly) orelse return null;
const output = @intToPtr(*Output, wlr_output.data); const output = @intToPtr(*Output, wlr_output.data);
@ -436,37 +435,46 @@ fn surfaceAt(self: Self, lx: f64, ly: f64, sx: *f64, sy: *f64) ?*wlr.Surface {
var oy = ly; var oy = ly;
root.output_layout.outputCoords(wlr_output, &ox, &oy); root.output_layout.outputCoords(wlr_output, &ox, &oy);
// Check overlay layer incl. popups // Check surfaces in the reverse order they are rendered in:
if (layerSurfaceAt(output.*, output.getLayer(.overlay).*, ox, oy, sx, sy, false)) |s| return s; // 1. overlay layer (+ popups)
// 2. top, bottom, background popups
// 3. top layer
// 4. views
// 5. bottom, background layers
if (layerSurfaceAt(output.getLayer(.overlay).*, ox, oy, sx, sy)) |s| return s;
// Check top-background popups only for ([_]zwlr.LayerShellV1.Layer{ .top, .bottom, .background }) |layer| {
for ([_]zwlr.LayerShellV1.Layer{ .top, .bottom, .background }) |layer| if (layerPopupSurfaceAt(output.getLayer(layer).*, ox, oy, sx, sy)) |s| return s;
if (layerSurfaceAt(output.*, output.getLayer(layer).*, ox, oy, sx, sy, true)) |s| return s; }
// Check top layer if (layerSurfaceAt(output.getLayer(.top).*, ox, oy, sx, sy)) |s| return s;
if (layerSurfaceAt(output.*, output.getLayer(.top).*, ox, oy, sx, sy, false)) |s| return s;
// Check views
if (viewSurfaceAt(output.*, ox, oy, sx, sy)) |s| return s; if (viewSurfaceAt(output.*, ox, oy, sx, sy)) |s| return s;
// Check the bottom-background layers for ([_]zwlr.LayerShellV1.Layer{ .bottom, .background }) |layer| {
for ([_]zwlr.LayerShellV1.Layer{ .bottom, .background }) |layer| if (layerSurfaceAt(output.getLayer(layer).*, ox, oy, sx, sy)) |s| return s;
if (layerSurfaceAt(output.*, output.getLayer(layer).*, ox, oy, sx, sy, false)) |s| return s; }
return null; return null;
} }
/// Find the topmost surface on the given layer at ox,oy. Will only check /// Find the topmost popup surface on the given layer at ox,oy.
/// popups if popups_only is true. fn layerPopupSurfaceAt(layer: std.TailQueue(LayerSurface), ox: f64, oy: f64, sx: *f64, sy: *f64) ?*wlr.Surface {
fn layerSurfaceAt( var it = layer.first;
output: Output, while (it) |node| : (it = node.next) {
layer: std.TailQueue(LayerSurface), const layer_surface = &node.data;
ox: f64, if (layer_surface.wlr_layer_surface.popupSurfaceAt(
oy: f64, ox - @intToFloat(f64, layer_surface.box.x),
sx: *f64, oy - @intToFloat(f64, layer_surface.box.y),
sy: *f64, sx,
popups_only: bool, sy,
) ?*wlr.Surface { )) |found| return found;
}
return null;
}
/// Find the topmost surface (or popup surface) on the given layer at ox,oy.
fn layerSurfaceAt(layer: std.TailQueue(LayerSurface), ox: f64, oy: f64, sx: *f64, sy: *f64) ?*wlr.Surface {
var it = layer.first; var it = layer.first;
while (it) |node| : (it = node.next) { while (it) |node| : (it = node.next) {
const layer_surface = &node.data; const layer_surface = &node.data;
@ -475,13 +483,7 @@ fn layerSurfaceAt(
oy - @intToFloat(f64, layer_surface.box.y), oy - @intToFloat(f64, layer_surface.box.y),
sx, sx,
sy, sy,
)) |found| { )) |found| return found;
if (!popups_only) {
return found;
} else if (found.isXdgSurface() and wlr.XdgSurface.fromWlrSurface(found).role == .popup) {
return found;
}
}
} }
return null; return null;
} }