Allow floating views to appear at the mouse
This commit is contained in:
parent
0c095f0c93
commit
dc1d5c8418
@ -1,6 +1,6 @@
|
|||||||
function __riverctl_completion ()
|
function __riverctl_completion ()
|
||||||
{
|
{
|
||||||
local rule_actions="float no-float ssd csd tags output position dimensions fullscreen no-fullscreen"
|
local rule_actions="float no-float ssd csd tags output position relative-position dimensions fullscreen no-fullscreen"
|
||||||
if [ "${COMP_CWORD}" -eq 1 ]
|
if [ "${COMP_CWORD}" -eq 1 ]
|
||||||
then
|
then
|
||||||
OPTS=" \
|
OPTS=" \
|
||||||
|
@ -89,7 +89,7 @@ complete -c riverctl -n '__fish_seen_subcommand_from set-cursor-warp'
|
|||||||
complete -c riverctl -n '__fish_seen_subcommand_from list-rules' -n '__fish_riverctl_complete_arg 2' -a 'float ssd tags output position dimensions fullscreen'
|
complete -c riverctl -n '__fish_seen_subcommand_from list-rules' -n '__fish_riverctl_complete_arg 2' -a 'float ssd tags output position dimensions fullscreen'
|
||||||
|
|
||||||
# Options and subcommands for 'rule-add' and 'rule-del'
|
# Options and subcommands for 'rule-add' and 'rule-del'
|
||||||
set -l rule_actions float no-float ssd csd tags output position dimensions fullscreen no-fullscreen
|
set -l rule_actions float no-float ssd csd tags output position relative-position dimensions fullscreen no-fullscreen
|
||||||
complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'not __fish_seen_argument -o app-id' -o 'app-id' -r
|
complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'not __fish_seen_argument -o app-id' -o 'app-id' -r
|
||||||
complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'not __fish_seen_argument -o title' -o 'title' -r
|
complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'not __fish_seen_argument -o title' -o 'title' -r
|
||||||
complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'test (math (count (commandline -opc)) % 2) -eq 0' -a "$rule_actions"
|
complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'test (math (count (commandline -opc)) % 2) -eq 0' -a "$rule_actions"
|
||||||
|
@ -202,7 +202,7 @@ _riverctl()
|
|||||||
# In case of a new rule added in river, we just need
|
# In case of a new rule added in river, we just need
|
||||||
# to add it to the third option between '()',
|
# to add it to the third option between '()',
|
||||||
# i.e (float no-float <new-option>)
|
# i.e (float no-float <new-option>)
|
||||||
_arguments '1: :(-app-id -title)' '2: : ' ':: :(float no-float ssd csd tags output position dimensions fullscreen no-fullscreen)'
|
_arguments '1: :(-app-id -title)' '2: : ' ':: :(float no-float ssd csd tags output position relative-position dimensions fullscreen no-fullscreen)'
|
||||||
;;
|
;;
|
||||||
list-rules) _alternative 'arguments:args:(float ssd tags output position dimensions fullscreen)' ;;
|
list-rules) _alternative 'arguments:args:(float ssd tags output position dimensions fullscreen)' ;;
|
||||||
*) return 0 ;;
|
*) return 0 ;;
|
||||||
|
@ -298,9 +298,13 @@ 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. Applies only to new views.
|
||||||
|
- *relative-position*: Set the position of the view relative to
|
||||||
|
something. Requires the anchor and the x and y coordinates of the
|
||||||
|
view. The coordinates are either positive or negative numbers that are
|
||||||
|
relative to the anchor. 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,9 +58,15 @@ pub const HideCursorWhenTypingMode = enum {
|
|||||||
enabled,
|
enabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const Anchor = enum {
|
||||||
|
absolute,
|
||||||
|
mouse,
|
||||||
|
};
|
||||||
|
|
||||||
pub const Position = struct {
|
pub const Position = struct {
|
||||||
x: u31,
|
anchor: Anchor,
|
||||||
y: u31,
|
x: i31,
|
||||||
|
y: i31,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Dimensions = struct {
|
pub const Dimensions = struct {
|
||||||
|
@ -681,8 +681,18 @@ 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;
|
var base_x: i31 = 0;
|
||||||
view.pending.box.y = position.y;
|
var base_y: i31 = 0;
|
||||||
|
switch (position.anchor) {
|
||||||
|
.absolute => {},
|
||||||
|
.mouse => {
|
||||||
|
const cursor = server.input_manager.defaultSeat().wlr_seat.pointer_state;
|
||||||
|
base_x = @intCast(@as(i31, @intFromFloat(cursor.sx)));
|
||||||
|
base_y = @intCast(@as(i31, @intFromFloat(cursor.sy)));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
view.pending.box.x = base_x + position.x;
|
||||||
|
view.pending.box.y = base_y + position.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);
|
||||||
|
@ -26,6 +26,7 @@ const util = @import("../util.zig");
|
|||||||
const Error = @import("../command.zig").Error;
|
const Error = @import("../command.zig").Error;
|
||||||
const Seat = @import("../Seat.zig");
|
const Seat = @import("../Seat.zig");
|
||||||
const View = @import("../View.zig");
|
const View = @import("../View.zig");
|
||||||
|
const Anchor = @import("../Config.zig").Anchor;
|
||||||
const RuleGlobs = @import("../rule_list.zig").RuleGlobs;
|
const RuleGlobs = @import("../rule_list.zig").RuleGlobs;
|
||||||
|
|
||||||
const Action = enum {
|
const Action = enum {
|
||||||
@ -36,6 +37,7 @@ const Action = enum {
|
|||||||
tags,
|
tags,
|
||||||
output,
|
output,
|
||||||
position,
|
position,
|
||||||
|
@"relative-position",
|
||||||
dimensions,
|
dimensions,
|
||||||
fullscreen,
|
fullscreen,
|
||||||
@"no-fullscreen",
|
@"no-fullscreen",
|
||||||
@ -59,6 +61,7 @@ pub fn ruleAdd(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
|
|||||||
.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,
|
.position, .dimensions => 3,
|
||||||
|
.@"relative-position" => 4,
|
||||||
};
|
};
|
||||||
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;
|
||||||
@ -112,14 +115,32 @@ pub fn ruleAdd(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
.position => {
|
.position => {
|
||||||
const x = try fmt.parseInt(u31, result.args[1], 10);
|
const x = try fmt.parseInt(i31, result.args[1], 10);
|
||||||
const y = try fmt.parseInt(u31, result.args[2], 10);
|
const y = try fmt.parseInt(i31, result.args[2], 10);
|
||||||
|
if (x < 0 or y < 0) return Error.OutOfBounds;
|
||||||
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 = .{
|
||||||
.x = x,
|
.anchor = .absolute,
|
||||||
.y = y,
|
.x = @intCast(x),
|
||||||
|
.y = @intCast(y),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.@"relative-position" => {
|
||||||
|
const anchor = std.meta.stringToEnum(Anchor, result.args[1]) orelse return Error.UnknownOption;
|
||||||
|
// force the use of the normal position command for absolute positions
|
||||||
|
if (anchor == .absolute) return Error.UnknownOption;
|
||||||
|
const x_off = try fmt.parseInt(i31, result.args[2], 10);
|
||||||
|
const y_off = try fmt.parseInt(i31, result.args[3], 10);
|
||||||
|
try server.config.rules.position.add(.{
|
||||||
|
.app_id_glob = app_id_glob,
|
||||||
|
.title_glob = title_glob,
|
||||||
|
.value = .{
|
||||||
|
.anchor = anchor,
|
||||||
|
.x = x_off,
|
||||||
|
.y = y_off,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -179,7 +200,7 @@ pub fn ruleDel(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
|
|||||||
util.gpa.free(output_rule);
|
util.gpa.free(output_rule);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.position => {
|
.position, .@"relative-position" => {
|
||||||
_ = server.config.rules.position.del(rule);
|
_ = server.config.rules.position.del(rule);
|
||||||
},
|
},
|
||||||
.dimensions => {
|
.dimensions => {
|
||||||
@ -278,7 +299,7 @@ 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 });
|
try writer.print("{s},{d},{d}", .{ @tagName(rule.value.anchor), rule.value.x, rule.value.y });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.dimensions => {
|
.dimensions => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user