DragIcon: render using the scene graph
This commit is contained in:
parent
0e0b585c44
commit
0b2272ec57
@ -31,6 +31,7 @@ const server = &@import("main.zig").server;
|
|||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
|
|
||||||
const Config = @import("Config.zig");
|
const Config = @import("Config.zig");
|
||||||
|
const DragIcon = @import("DragIcon.zig");
|
||||||
const LayerSurface = @import("LayerSurface.zig");
|
const LayerSurface = @import("LayerSurface.zig");
|
||||||
const LockSurface = @import("LockSurface.zig");
|
const LockSurface = @import("LockSurface.zig");
|
||||||
const Output = @import("Output.zig");
|
const Output = @import("Output.zig");
|
||||||
@ -523,6 +524,8 @@ fn handleTouchMotion(
|
|||||||
log.err("out of memory", .{});
|
log.err("out of memory", .{});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.updateDragIcons();
|
||||||
|
|
||||||
if (server.root.at(lx, ly)) |result| {
|
if (server.root.at(lx, ly)) |result| {
|
||||||
self.seat.wlr_seat.touchNotifyMotion(event.time_msec, event.touch_id, result.sx, result.sy);
|
self.seat.wlr_seat.touchNotifyMotion(event.time_msec, event.touch_id, result.sx, result.sy);
|
||||||
}
|
}
|
||||||
@ -721,6 +724,7 @@ fn processMotion(self: *Self, device: *wlr.InputDevice, time: u32, delta_x: f64,
|
|||||||
unaccel_dx,
|
unaccel_dx,
|
||||||
unaccel_dy,
|
unaccel_dy,
|
||||||
);
|
);
|
||||||
|
|
||||||
var dx: f64 = delta_x;
|
var dx: f64 = delta_x;
|
||||||
var dy: f64 = delta_y;
|
var dy: f64 = delta_y;
|
||||||
switch (self.mode) {
|
switch (self.mode) {
|
||||||
@ -728,6 +732,7 @@ fn processMotion(self: *Self, device: *wlr.InputDevice, time: u32, delta_x: f64,
|
|||||||
self.wlr_cursor.move(device, dx, dy);
|
self.wlr_cursor.move(device, dx, dy);
|
||||||
self.checkFocusFollowsCursor();
|
self.checkFocusFollowsCursor();
|
||||||
self.passthrough(time);
|
self.passthrough(time);
|
||||||
|
self.updateDragIcons();
|
||||||
},
|
},
|
||||||
.down => |down| {
|
.down => |down| {
|
||||||
self.wlr_cursor.move(device, dx, dy);
|
self.wlr_cursor.move(device, dx, dy);
|
||||||
@ -736,6 +741,7 @@ fn processMotion(self: *Self, device: *wlr.InputDevice, time: u32, delta_x: f64,
|
|||||||
down.sx + (self.wlr_cursor.x - down.lx),
|
down.sx + (self.wlr_cursor.x - down.lx),
|
||||||
down.sy + (self.wlr_cursor.y - down.ly),
|
down.sy + (self.wlr_cursor.y - down.ly),
|
||||||
);
|
);
|
||||||
|
self.updateDragIcons();
|
||||||
},
|
},
|
||||||
.move => |*data| {
|
.move => |*data| {
|
||||||
dx += data.delta_x;
|
dx += data.delta_x;
|
||||||
@ -933,3 +939,30 @@ fn warp(self: *Self) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn updateDragIcons(self: *Self) void {
|
||||||
|
var it = server.root.layers.drag_icons.children.iterator(.forward);
|
||||||
|
while (it.next()) |node| {
|
||||||
|
const icon = @intToPtr(*DragIcon, node.data);
|
||||||
|
|
||||||
|
if (icon.wlr_drag_icon.drag.seat != self.seat.wlr_seat) continue;
|
||||||
|
|
||||||
|
switch (icon.wlr_drag_icon.drag.grab_type) {
|
||||||
|
.keyboard => unreachable,
|
||||||
|
.keyboard_pointer => {
|
||||||
|
icon.tree.node.setPosition(
|
||||||
|
@floatToInt(c_int, self.wlr_cursor.x),
|
||||||
|
@floatToInt(c_int, self.wlr_cursor.y),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
.keyboard_touch => {
|
||||||
|
const touch_id = icon.wlr_drag_icon.drag.touch_id;
|
||||||
|
const point = self.touch_points.get(touch_id) orelse continue;
|
||||||
|
icon.tree.node.setPosition(
|
||||||
|
@floatToInt(c_int, point.lx),
|
||||||
|
@floatToInt(c_int, point.ly),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -23,40 +23,70 @@ const wl = @import("wayland").server.wl;
|
|||||||
const server = &@import("main.zig").server;
|
const server = &@import("main.zig").server;
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
|
|
||||||
const Seat = @import("Seat.zig");
|
const SceneNodeData = @import("SceneNodeData.zig");
|
||||||
|
|
||||||
seat: *Seat,
|
|
||||||
wlr_drag_icon: *wlr.Drag.Icon,
|
wlr_drag_icon: *wlr.Drag.Icon,
|
||||||
|
|
||||||
// Accumulated x/y surface offset from the cursor/touch point position.
|
tree: *wlr.SceneTree,
|
||||||
sx: i32 = 0,
|
surface: *wlr.SceneTree,
|
||||||
sy: i32 = 0,
|
|
||||||
|
|
||||||
// Always active
|
|
||||||
destroy: wl.Listener(*wlr.Drag.Icon) = wl.Listener(*wlr.Drag.Icon).init(handleDestroy),
|
destroy: wl.Listener(*wlr.Drag.Icon) = wl.Listener(*wlr.Drag.Icon).init(handleDestroy),
|
||||||
|
map: wl.Listener(*wlr.Drag.Icon) = wl.Listener(*wlr.Drag.Icon).init(handleMap),
|
||||||
|
unmap: wl.Listener(*wlr.Drag.Icon) = wl.Listener(*wlr.Drag.Icon).init(handleUnmap),
|
||||||
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
||||||
|
|
||||||
pub fn init(drag_icon: *DragIcon, seat: *Seat, wlr_drag_icon: *wlr.Drag.Icon) void {
|
pub fn create(wlr_drag_icon: *wlr.Drag.Icon) error{OutOfMemory}!void {
|
||||||
drag_icon.* = .{ .seat = seat, .wlr_drag_icon = wlr_drag_icon };
|
const tree = try server.root.layers.drag_icons.createSceneTree();
|
||||||
|
errdefer tree.node.destroy();
|
||||||
|
|
||||||
|
const drag_icon = try util.gpa.create(DragIcon);
|
||||||
|
errdefer util.gpa.destroy(drag_icon);
|
||||||
|
|
||||||
|
drag_icon.* = .{
|
||||||
|
.wlr_drag_icon = wlr_drag_icon,
|
||||||
|
.tree = tree,
|
||||||
|
.surface = try tree.createSceneSubsurfaceTree(wlr_drag_icon.surface),
|
||||||
|
};
|
||||||
|
tree.node.data = @ptrToInt(drag_icon);
|
||||||
|
|
||||||
|
tree.node.setEnabled(wlr_drag_icon.mapped);
|
||||||
|
|
||||||
wlr_drag_icon.events.destroy.add(&drag_icon.destroy);
|
wlr_drag_icon.events.destroy.add(&drag_icon.destroy);
|
||||||
|
wlr_drag_icon.events.map.add(&drag_icon.map);
|
||||||
|
wlr_drag_icon.events.unmap.add(&drag_icon.unmap);
|
||||||
wlr_drag_icon.surface.events.commit.add(&drag_icon.commit);
|
wlr_drag_icon.surface.events.commit.add(&drag_icon.commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleDestroy(listener: *wl.Listener(*wlr.Drag.Icon), _: *wlr.Drag.Icon) void {
|
fn handleDestroy(listener: *wl.Listener(*wlr.Drag.Icon), _: *wlr.Drag.Icon) void {
|
||||||
const drag_icon = @fieldParentPtr(DragIcon, "destroy", listener);
|
const drag_icon = @fieldParentPtr(DragIcon, "destroy", listener);
|
||||||
|
|
||||||
drag_icon.seat.drag_icon = null;
|
drag_icon.tree.node.destroy();
|
||||||
|
|
||||||
drag_icon.destroy.link.remove();
|
drag_icon.destroy.link.remove();
|
||||||
|
drag_icon.map.link.remove();
|
||||||
|
drag_icon.unmap.link.remove();
|
||||||
drag_icon.commit.link.remove();
|
drag_icon.commit.link.remove();
|
||||||
|
|
||||||
util.gpa.destroy(drag_icon);
|
util.gpa.destroy(drag_icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handleMap(listener: *wl.Listener(*wlr.Drag.Icon), _: *wlr.Drag.Icon) void {
|
||||||
|
const drag_icon = @fieldParentPtr(DragIcon, "map", listener);
|
||||||
|
|
||||||
|
drag_icon.tree.node.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handleUnmap(listener: *wl.Listener(*wlr.Drag.Icon), _: *wlr.Drag.Icon) void {
|
||||||
|
const drag_icon = @fieldParentPtr(DragIcon, "unmap", listener);
|
||||||
|
|
||||||
|
drag_icon.tree.node.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) void {
|
fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) void {
|
||||||
const drag_icon = @fieldParentPtr(DragIcon, "commit", listener);
|
const drag_icon = @fieldParentPtr(DragIcon, "commit", listener);
|
||||||
|
|
||||||
drag_icon.sx += surface.current.dx;
|
drag_icon.surface.node.setPosition(
|
||||||
drag_icon.sy += surface.current.dy;
|
drag_icon.surface.node.x + surface.current.dx,
|
||||||
|
drag_icon.surface.node.y + surface.current.dy,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ tree: *wlr.SceneTree,
|
|||||||
normal_content: *wlr.SceneTree,
|
normal_content: *wlr.SceneTree,
|
||||||
locked_content: *wlr.SceneTree,
|
locked_content: *wlr.SceneTree,
|
||||||
|
|
||||||
|
/// Child nodes of normal_content
|
||||||
layers: struct {
|
layers: struct {
|
||||||
background_color_rect: *wlr.SceneRect,
|
background_color_rect: *wlr.SceneRect,
|
||||||
/// Background layer shell layer
|
/// Background layer shell layer
|
||||||
@ -82,7 +83,7 @@ layers: struct {
|
|||||||
fullscreen: *wlr.SceneTree,
|
fullscreen: *wlr.SceneTree,
|
||||||
/// Overlay layer shell layer
|
/// Overlay layer shell layer
|
||||||
overlay: *wlr.SceneTree,
|
overlay: *wlr.SceneTree,
|
||||||
/// Xdg popups, Xwayland override redirect windows
|
/// xdg-popups of views and layer-shell surfaces
|
||||||
popups: *wlr.SceneTree,
|
popups: *wlr.SceneTree,
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -166,7 +167,7 @@ pub fn create(wlr_output: *wlr.Output) !void {
|
|||||||
var height: c_int = undefined;
|
var height: c_int = undefined;
|
||||||
wlr_output.effectiveResolution(&width, &height);
|
wlr_output.effectiveResolution(&width, &height);
|
||||||
|
|
||||||
const tree = try server.root.scene.tree.createSceneTree();
|
const tree = try server.root.layers.outputs.createSceneTree();
|
||||||
const normal_content = try tree.createSceneTree();
|
const normal_content = try tree.createSceneTree();
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
|
@ -37,6 +37,16 @@ const ViewStack = @import("view_stack.zig").ViewStack;
|
|||||||
const XwaylandOverrideRedirect = @import("XwaylandOverrideRedirect.zig");
|
const XwaylandOverrideRedirect = @import("XwaylandOverrideRedirect.zig");
|
||||||
|
|
||||||
scene: *wlr.Scene,
|
scene: *wlr.Scene,
|
||||||
|
/// All direct children of the root scene node
|
||||||
|
layers: struct {
|
||||||
|
/// Parent tree for output trees which have their position updated when
|
||||||
|
/// outputs are moved in the layout.
|
||||||
|
outputs: *wlr.SceneTree,
|
||||||
|
/// Drag icons which have a position in layout coordinates that is updated
|
||||||
|
/// on cursor/touch point movement.
|
||||||
|
/// This tree is ignored by Root.at()
|
||||||
|
drag_icons: *wlr.SceneTree,
|
||||||
|
},
|
||||||
|
|
||||||
new_output: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleNewOutput),
|
new_output: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleNewOutput),
|
||||||
|
|
||||||
@ -94,12 +104,19 @@ pub fn init(self: *Self) !void {
|
|||||||
const transaction_timer = try event_loop.addTimer(*Self, handleTransactionTimeout, self);
|
const transaction_timer = try event_loop.addTimer(*Self, handleTransactionTimeout, self);
|
||||||
errdefer transaction_timer.remove();
|
errdefer transaction_timer.remove();
|
||||||
|
|
||||||
|
const outputs = try scene.tree.createSceneTree();
|
||||||
|
|
||||||
// TODO get rid of this hack somehow
|
// TODO get rid of this hack somehow
|
||||||
const noop_wlr_output = try server.headless_backend.headlessAddOutput(1920, 1080);
|
const noop_wlr_output = try server.headless_backend.headlessAddOutput(1920, 1080);
|
||||||
const noop_tree = try scene.tree.createSceneTree();
|
const noop_tree = try outputs.createSceneTree();
|
||||||
noop_tree.node.setEnabled(false);
|
noop_tree.node.setEnabled(false);
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.scene = scene,
|
.scene = scene,
|
||||||
|
.layers = .{
|
||||||
|
.outputs = outputs,
|
||||||
|
.drag_icons = try scene.tree.createSceneTree(),
|
||||||
|
},
|
||||||
.output_layout = output_layout,
|
.output_layout = output_layout,
|
||||||
.output_manager = try wlr.OutputManagerV1.create(server.wl_server),
|
.output_manager = try wlr.OutputManagerV1.create(server.wl_server),
|
||||||
.power_manager = try wlr.OutputPowerManagerV1.create(server.wl_server),
|
.power_manager = try wlr.OutputPowerManagerV1.create(server.wl_server),
|
||||||
@ -153,11 +170,12 @@ pub const AtResult = struct {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Return information about what is currently rendered at the given layout coordinates.
|
/// Return information about what is currently rendered in the Root.layers.outputs
|
||||||
|
/// tree at the given layout coordinates.
|
||||||
pub fn at(self: Self, lx: f64, ly: f64) ?AtResult {
|
pub fn at(self: Self, lx: f64, ly: f64) ?AtResult {
|
||||||
var sx: f64 = undefined;
|
var sx: f64 = undefined;
|
||||||
var sy: f64 = undefined;
|
var sy: f64 = undefined;
|
||||||
const node_at = self.scene.tree.node.at(lx, ly, &sx, &sy) orelse return null;
|
const node_at = self.layers.outputs.node.at(lx, ly, &sx, &sy) orelse return null;
|
||||||
|
|
||||||
const surface: ?*wlr.Surface = blk: {
|
const surface: ?*wlr.Surface = blk: {
|
||||||
if (node_at.type == .buffer) {
|
if (node_at.type == .buffer) {
|
||||||
|
@ -92,7 +92,6 @@ drag: enum {
|
|||||||
pointer,
|
pointer,
|
||||||
touch,
|
touch,
|
||||||
} = .none,
|
} = .none,
|
||||||
drag_icon: ?*DragIcon = null,
|
|
||||||
|
|
||||||
request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) =
|
request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) =
|
||||||
wl.Listener(*wlr.Seat.event.RequestSetSelection).init(handleRequestSetSelection),
|
wl.Listener(*wlr.Seat.event.RequestSetSelection).init(handleRequestSetSelection),
|
||||||
@ -573,13 +572,11 @@ fn handleStartDrag(listener: *wl.Listener(*wlr.Drag), wlr_drag: *wlr.Drag) void
|
|||||||
wlr_drag.events.destroy.add(&self.drag_destroy);
|
wlr_drag.events.destroy.add(&self.drag_destroy);
|
||||||
|
|
||||||
if (wlr_drag.icon) |wlr_drag_icon| {
|
if (wlr_drag.icon) |wlr_drag_icon| {
|
||||||
const drag_icon = util.gpa.create(DragIcon) catch {
|
DragIcon.create(wlr_drag_icon) catch {
|
||||||
log.err("out of memory", .{});
|
log.err("out of memory", .{});
|
||||||
wlr_drag.seat_client.client.postNoMemory();
|
wlr_drag.seat_client.client.postNoMemory();
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
drag_icon.init(self, wlr_drag_icon);
|
|
||||||
self.drag_icon = drag_icon;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user