Allow floating views to appear at the mouse
This commit is contained in:
parent
2061ae2c4c
commit
dbe2cb72f8
@ -298,9 +298,11 @@ matches everything while _\*\*_ and the empty string are invalid.
|
|||||||
with make: _HP Inc._, model: _HP 22w_, and serial: _CNC93720WF_, the
|
with make: _HP Inc._, model: _HP 22w_, and serial: _CNC93720WF_, the
|
||||||
identifier would be: _HP Inc. HP 22w CNC93720WF_. If the make, model, or
|
identifier would be: _HP Inc. HP 22w CNC93720WF_. If the make, model, or
|
||||||
serial is unknown, the word "Unknown" is used instead.
|
serial is unknown, the word "Unknown" is used instead.
|
||||||
- *position*: Set the initial position of the view, clamping to the
|
- *position*: Set the initial position of the view, clamping to the bounds
|
||||||
bounds of the output. Requires x and y coordinates of the view as
|
of the output. Requires x and y coordinates of the view as arguments, both
|
||||||
arguments, both of which must be non-negative. Applies only to new views.
|
of which must be non-negative. Optionally, the string "mouse" can appear
|
||||||
|
as the only argument. In this case, the view will appear at the mouse's
|
||||||
|
position. Applies only to new views.
|
||||||
- *dimensions*: Set the initial dimensions of the view, clamping to the
|
- *dimensions*: Set the initial dimensions of the view, clamping to the
|
||||||
constraints of the view. Requires width and height of the view as
|
constraints of the view. Requires width and height of the view as
|
||||||
arguments, both of which must be non-negative. Applies only to new views.
|
arguments, both of which must be non-negative. Applies only to new views.
|
||||||
|
@ -58,11 +58,21 @@ pub const HideCursorWhenTypingMode = enum {
|
|||||||
enabled,
|
enabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const PositionType = enum {
|
||||||
|
absolute,
|
||||||
|
at_mouse,
|
||||||
|
};
|
||||||
|
|
||||||
pub const Position = struct {
|
pub const Position = struct {
|
||||||
x: u31,
|
x: u31,
|
||||||
y: u31,
|
y: u31,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const FloatPosition = union(PositionType) {
|
||||||
|
absolute: Position,
|
||||||
|
at_mouse,
|
||||||
|
};
|
||||||
|
|
||||||
pub const Dimensions = struct {
|
pub const Dimensions = struct {
|
||||||
width: u31,
|
width: u31,
|
||||||
height: u31,
|
height: u31,
|
||||||
@ -98,7 +108,7 @@ rules: struct {
|
|||||||
ssd: RuleList(bool) = .{},
|
ssd: RuleList(bool) = .{},
|
||||||
tags: RuleList(u32) = .{},
|
tags: RuleList(u32) = .{},
|
||||||
output: RuleList([]const u8) = .{},
|
output: RuleList([]const u8) = .{},
|
||||||
position: RuleList(Position) = .{},
|
position: RuleList(FloatPosition) = .{},
|
||||||
dimensions: RuleList(Dimensions) = .{},
|
dimensions: RuleList(Dimensions) = .{},
|
||||||
fullscreen: RuleList(bool) = .{},
|
fullscreen: RuleList(bool) = .{},
|
||||||
tearing: RuleList(bool) = .{},
|
tearing: RuleList(bool) = .{},
|
||||||
|
@ -678,8 +678,17 @@ pub fn map(view: *View) !void {
|
|||||||
server.input_manager.defaultSeat().focused_output;
|
server.input_manager.defaultSeat().focused_output;
|
||||||
|
|
||||||
if (server.config.rules.position.match(view)) |position| {
|
if (server.config.rules.position.match(view)) |position| {
|
||||||
view.pending.box.x = position.x;
|
switch (position) {
|
||||||
view.pending.box.y = position.y;
|
.absolute => |pos| {
|
||||||
|
view.pending.box.x = pos.x;
|
||||||
|
view.pending.box.y = pos.y;
|
||||||
|
},
|
||||||
|
.at_mouse => {
|
||||||
|
const cursor = server.input_manager.defaultSeat().cursor.wlr_cursor;
|
||||||
|
view.pending.box.x = @as(c_int, @intFromFloat(cursor.x));
|
||||||
|
view.pending.box.y = @as(c_int, @intFromFloat(cursor.y));
|
||||||
|
},
|
||||||
|
}
|
||||||
} else if (output) |o| {
|
} else if (output) |o| {
|
||||||
// Center the initial pending box on the output
|
// Center the initial pending box on the output
|
||||||
view.pending.box.x = @divTrunc(@max(0, o.usable_box.width - view.pending.box.width), 2);
|
view.pending.box.x = @divTrunc(@max(0, o.usable_box.width - view.pending.box.width), 2);
|
||||||
|
@ -54,10 +54,17 @@ pub fn ruleAdd(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
|
|||||||
|
|
||||||
const action = std.meta.stringToEnum(Action, result.args[0]) orelse return Error.UnknownOption;
|
const action = std.meta.stringToEnum(Action, result.args[0]) orelse return Error.UnknownOption;
|
||||||
|
|
||||||
|
var pos_is_mouse = false;
|
||||||
const positional_arguments_count: u8 = switch (action) {
|
const positional_arguments_count: u8 = switch (action) {
|
||||||
.float, .@"no-float", .ssd, .csd, .fullscreen, .@"no-fullscreen", .tearing, .@"no-tearing" => 1,
|
.float, .@"no-float", .ssd, .csd, .fullscreen, .@"no-fullscreen", .tearing, .@"no-tearing" => 1,
|
||||||
.tags, .output => 2,
|
.tags, .output => 2,
|
||||||
.position, .dimensions => 3,
|
.dimensions => 3,
|
||||||
|
.position => blk: {
|
||||||
|
if (result.args.len >= 2 and std.mem.eql(u8, result.args[1], "mouse")) {
|
||||||
|
pos_is_mouse = true;
|
||||||
|
break :blk 2;
|
||||||
|
} else break :blk 3;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
if (result.args.len > positional_arguments_count) return Error.TooManyArguments;
|
if (result.args.len > positional_arguments_count) return Error.TooManyArguments;
|
||||||
if (result.args.len < positional_arguments_count) return Error.NotEnoughArguments;
|
if (result.args.len < positional_arguments_count) return Error.NotEnoughArguments;
|
||||||
@ -111,16 +118,24 @@ pub fn ruleAdd(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
.position => {
|
.position => {
|
||||||
|
if (pos_is_mouse) {
|
||||||
|
try server.config.rules.position.add(.{
|
||||||
|
.app_id_glob = app_id_glob,
|
||||||
|
.title_glob = title_glob,
|
||||||
|
.value = .at_mouse,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
const x = try fmt.parseInt(u31, result.args[1], 10);
|
const x = try fmt.parseInt(u31, result.args[1], 10);
|
||||||
const y = try fmt.parseInt(u31, result.args[2], 10);
|
const y = try fmt.parseInt(u31, result.args[2], 10);
|
||||||
try server.config.rules.position.add(.{
|
try server.config.rules.position.add(.{
|
||||||
.app_id_glob = app_id_glob,
|
.app_id_glob = app_id_glob,
|
||||||
.title_glob = title_glob,
|
.title_glob = title_glob,
|
||||||
.value = .{
|
.value = .{ .absolute = .{
|
||||||
.x = x,
|
.x = x,
|
||||||
.y = y,
|
.y = y,
|
||||||
},
|
} },
|
||||||
});
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
.dimensions => {
|
.dimensions => {
|
||||||
const width = try fmt.parseInt(u31, result.args[1], 10);
|
const width = try fmt.parseInt(u31, result.args[1], 10);
|
||||||
@ -277,7 +292,10 @@ pub fn listRules(_: *Seat, args: []const [:0]const u8, out: *?[]const u8) Error!
|
|||||||
for (server.config.rules.position.rules.items) |rule| {
|
for (server.config.rules.position.rules.items) |rule| {
|
||||||
try fmt.formatBuf(rule.title_glob, .{ .width = title_column_max, .alignment = .left }, writer);
|
try fmt.formatBuf(rule.title_glob, .{ .width = title_column_max, .alignment = .left }, writer);
|
||||||
try fmt.formatBuf(rule.app_id_glob, .{ .width = app_id_column_max, .alignment = .left }, writer);
|
try fmt.formatBuf(rule.app_id_glob, .{ .width = app_id_column_max, .alignment = .left }, writer);
|
||||||
try writer.print("{d},{d}\n", .{ rule.value.x, rule.value.y });
|
switch (rule.value) {
|
||||||
|
.absolute => |pos| try writer.print("{d},{d}\n", .{ pos.x, pos.y }),
|
||||||
|
.at_mouse => try writer.print("mouse\n", .{}),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.dimensions => {
|
.dimensions => {
|
||||||
|
Loading…
Reference in New Issue
Block a user