river-status: add mode event to seat status
This allows clients such as a status bar to display the currently active mode.
This commit is contained in:
parent
03e8da669c
commit
d657dc791b
@ -112,7 +112,7 @@ pub fn build(b: *zbs.Builder) !void {
|
|||||||
scanner.generate("zwp_pointer_constraints_v1", 1);
|
scanner.generate("zwp_pointer_constraints_v1", 1);
|
||||||
|
|
||||||
scanner.generate("zriver_control_v1", 1);
|
scanner.generate("zriver_control_v1", 1);
|
||||||
scanner.generate("zriver_status_manager_v1", 2);
|
scanner.generate("zriver_status_manager_v1", 3);
|
||||||
scanner.generate("river_layout_manager_v3", 1);
|
scanner.generate("river_layout_manager_v3", 1);
|
||||||
|
|
||||||
scanner.generate("zwlr_layer_shell_v1", 4);
|
scanner.generate("zwlr_layer_shell_v1", 4);
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
<interface name="zriver_status_manager_v1" version="2">
|
<interface name="zriver_status_manager_v1" version="3">
|
||||||
<description summary="manage river status objects">
|
<description summary="manage river status objects">
|
||||||
A global factory for objects that receive status information specific
|
A global factory for objects that receive status information specific
|
||||||
to river. It could be used to implement, for example, a status bar.
|
to river. It could be used to implement, for example, a status bar.
|
||||||
@ -85,7 +85,7 @@
|
|||||||
</event>
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="zriver_seat_status_v1" version="1">
|
<interface name="zriver_seat_status_v1" version="3">
|
||||||
<description summary="track seat focus">
|
<description summary="track seat focus">
|
||||||
This interface allows clients to receive information about the current
|
This interface allows clients to receive information about the current
|
||||||
focus of a seat. Note that (un)focused_output events will only be sent
|
focus of a seat. Note that (un)focused_output events will only be sent
|
||||||
@ -121,5 +121,13 @@
|
|||||||
</description>
|
</description>
|
||||||
<arg name="title" type="string" summary="title of the focused view"/>
|
<arg name="title" type="string" summary="title of the focused view"/>
|
||||||
</event>
|
</event>
|
||||||
|
|
||||||
|
<event name="mode" since="3">
|
||||||
|
<description summary="the active mode changed">
|
||||||
|
Sent once on binding the interface and again whenever a new mode
|
||||||
|
is entered (e.g. with riverctl enter-mode foobar).
|
||||||
|
</description>
|
||||||
|
<arg name="name" type="string" summary="name of the mode"/>
|
||||||
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
</protocol>
|
</protocol>
|
||||||
|
@ -57,7 +57,8 @@ border_color_unfocused: [4]f32 = [_]f32{ 0.34509804, 0.43137255, 0.45882353, 1.0
|
|||||||
border_color_urgent: [4]f32 = [_]f32{ 0.86274510, 0.19607843, 0.18431373, 1.0 }, // Solarized red
|
border_color_urgent: [4]f32 = [_]f32{ 0.86274510, 0.19607843, 0.18431373, 1.0 }, // Solarized red
|
||||||
|
|
||||||
/// Map of keymap mode name to mode id
|
/// Map of keymap mode name to mode id
|
||||||
mode_to_id: std.StringHashMap(usize),
|
/// Does not own the string keys. They are owned by the corresponding Mode struct.
|
||||||
|
mode_to_id: std.StringHashMap(u32),
|
||||||
|
|
||||||
/// All user-defined keymap modes, indexed by mode id
|
/// All user-defined keymap modes, indexed by mode id
|
||||||
modes: std.ArrayListUnmanaged(Mode),
|
modes: std.ArrayListUnmanaged(Mode),
|
||||||
@ -98,7 +99,7 @@ cursor_hide_when_typing: HideCursorWhenTypingMode = .disabled,
|
|||||||
|
|
||||||
pub fn init() !Self {
|
pub fn init() !Self {
|
||||||
var self = Self{
|
var self = Self{
|
||||||
.mode_to_id = std.StringHashMap(usize).init(util.gpa),
|
.mode_to_id = std.StringHashMap(u32).init(util.gpa),
|
||||||
.modes = try std.ArrayListUnmanaged(Mode).initCapacity(util.gpa, 2),
|
.modes = try std.ArrayListUnmanaged(Mode).initCapacity(util.gpa, 2),
|
||||||
};
|
};
|
||||||
errdefer self.deinit();
|
errdefer self.deinit();
|
||||||
@ -106,27 +107,22 @@ pub fn init() !Self {
|
|||||||
// Start with two empty modes, "normal" and "locked"
|
// Start with two empty modes, "normal" and "locked"
|
||||||
{
|
{
|
||||||
// Normal mode, id 0
|
// Normal mode, id 0
|
||||||
const owned_slice = try util.gpa.dupe(u8, "normal");
|
const owned_slice = try util.gpa.dupeZ(u8, "normal");
|
||||||
try self.mode_to_id.putNoClobber(owned_slice, 0);
|
try self.mode_to_id.putNoClobber(owned_slice, 0);
|
||||||
self.modes.appendAssumeCapacity(.{});
|
self.modes.appendAssumeCapacity(.{ .name = owned_slice });
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Locked mode, id 1
|
// Locked mode, id 1
|
||||||
const owned_slice = try util.gpa.dupe(u8, "locked");
|
const owned_slice = try util.gpa.dupeZ(u8, "locked");
|
||||||
try self.mode_to_id.putNoClobber(owned_slice, 1);
|
try self.mode_to_id.putNoClobber(owned_slice, 1);
|
||||||
self.modes.appendAssumeCapacity(.{});
|
self.modes.appendAssumeCapacity(.{ .name = owned_slice });
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
{
|
|
||||||
var it = self.mode_to_id.keyIterator();
|
|
||||||
while (it.next()) |key| util.gpa.free(key.*);
|
|
||||||
self.mode_to_id.deinit();
|
self.mode_to_id.deinit();
|
||||||
}
|
|
||||||
|
|
||||||
for (self.modes.items) |*mode| mode.deinit();
|
for (self.modes.items) |*mode| mode.deinit();
|
||||||
self.modes.deinit(util.gpa);
|
self.modes.deinit(util.gpa);
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ fn handleInhibitActivate(
|
|||||||
|
|
||||||
// Enter locked mode
|
// Enter locked mode
|
||||||
seat_node.data.prev_mode_id = seat_node.data.mode_id;
|
seat_node.data.prev_mode_id = seat_node.data.mode_id;
|
||||||
seat_node.data.mode_id = 1;
|
seat_node.data.enterMode(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.exclusive_client = self.input_inhibit_manager.active_client;
|
self.exclusive_client = self.input_inhibit_manager.active_client;
|
||||||
@ -215,8 +215,9 @@ fn handleInhibitDeactivate(
|
|||||||
// have each Seat handle focus and enter their previous mode.
|
// have each Seat handle focus and enter their previous mode.
|
||||||
var seat_it = self.seats.first;
|
var seat_it = self.seats.first;
|
||||||
while (seat_it) |seat_node| : (seat_it = seat_node.next) {
|
while (seat_it) |seat_node| : (seat_it = seat_node.next) {
|
||||||
seat_node.data.focus(null);
|
const seat = &seat_node.data;
|
||||||
seat_node.data.mode_id = seat_node.data.prev_mode_id;
|
seat.enterMode(seat.prev_mode_id);
|
||||||
|
seat.focus(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
server.root.startTransaction();
|
server.root.startTransaction();
|
||||||
|
@ -23,11 +23,13 @@ const Mapping = @import("Mapping.zig");
|
|||||||
const PointerMapping = @import("PointerMapping.zig");
|
const PointerMapping = @import("PointerMapping.zig");
|
||||||
const SwitchMapping = @import("SwitchMapping.zig");
|
const SwitchMapping = @import("SwitchMapping.zig");
|
||||||
|
|
||||||
|
name: [:0]const u8,
|
||||||
mappings: std.ArrayListUnmanaged(Mapping) = .{},
|
mappings: std.ArrayListUnmanaged(Mapping) = .{},
|
||||||
pointer_mappings: std.ArrayListUnmanaged(PointerMapping) = .{},
|
pointer_mappings: std.ArrayListUnmanaged(PointerMapping) = .{},
|
||||||
switch_mappings: std.ArrayListUnmanaged(SwitchMapping) = .{},
|
switch_mappings: std.ArrayListUnmanaged(SwitchMapping) = .{},
|
||||||
|
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
|
util.gpa.free(self.name);
|
||||||
for (self.mappings.items) |m| m.deinit();
|
for (self.mappings.items) |m| m.deinit();
|
||||||
self.mappings.deinit(util.gpa);
|
self.mappings.deinit(util.gpa);
|
||||||
self.pointer_mappings.deinit(util.gpa);
|
self.pointer_mappings.deinit(util.gpa);
|
||||||
|
@ -63,10 +63,10 @@ keyboards: std.TailQueue(Keyboard) = .{},
|
|||||||
switches: std.TailQueue(Switch) = .{},
|
switches: std.TailQueue(Switch) = .{},
|
||||||
|
|
||||||
/// ID of the current keymap mode
|
/// ID of the current keymap mode
|
||||||
mode_id: usize = 0,
|
mode_id: u32 = 0,
|
||||||
|
|
||||||
/// ID of previous keymap mode, used when returning from "locked" mode
|
/// ID of previous keymap mode, used when returning from "locked" mode
|
||||||
prev_mode_id: usize = 0,
|
prev_mode_id: u32 = 0,
|
||||||
|
|
||||||
/// Timer for repeating keyboard mappings
|
/// Timer for repeating keyboard mappings
|
||||||
mapping_repeat_timer: *wl.EventSource,
|
mapping_repeat_timer: *wl.EventSource,
|
||||||
@ -358,6 +358,16 @@ pub fn handleViewUnmap(self: *Self, view: *View) void {
|
|||||||
if (self.focused == .view and self.focused.view == view) self.focus(null);
|
if (self.focused == .view and self.focused.view == view) self.focus(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn enterMode(self: *Self, mode_id: u32) void {
|
||||||
|
self.mode_id = mode_id;
|
||||||
|
|
||||||
|
var it = self.status_trackers.first;
|
||||||
|
while (it) |node| : (it = node.next) {
|
||||||
|
const seat_status = node.data.seat_status;
|
||||||
|
seat_status.sendMode(server.config.modes.items[mode_id].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Is there a user-defined mapping for passed keycode, modifiers and keyboard state?
|
/// Is there a user-defined mapping for passed keycode, modifiers and keyboard state?
|
||||||
pub fn hasMapping(
|
pub fn hasMapping(
|
||||||
self: *Self,
|
self: *Self,
|
||||||
|
@ -21,6 +21,7 @@ const wayland = @import("wayland");
|
|||||||
const wl = wayland.server.wl;
|
const wl = wayland.server.wl;
|
||||||
const zriver = wayland.server.zriver;
|
const zriver = wayland.server.zriver;
|
||||||
|
|
||||||
|
const server = &@import("main.zig").server;
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
|
|
||||||
const Seat = @import("Seat.zig");
|
const Seat = @import("Seat.zig");
|
||||||
@ -35,7 +36,8 @@ pub fn init(self: *Self, seat: *Seat, seat_status: *zriver.SeatStatusV1) void {
|
|||||||
|
|
||||||
seat_status.setHandler(*Self, handleRequest, handleDestroy, self);
|
seat_status.setHandler(*Self, handleRequest, handleDestroy, self);
|
||||||
|
|
||||||
// Send focused output/view once on bind
|
// Send all info once on bind
|
||||||
|
seat_status.sendMode(server.config.modes.items[seat.mode_id].name);
|
||||||
self.sendOutput(.focused);
|
self.sendOutput(.focused);
|
||||||
self.sendFocusedView();
|
self.sendFocusedView();
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ server_destroy: wl.Listener(*wl.Server) = wl.Listener(*wl.Server).init(handleSer
|
|||||||
|
|
||||||
pub fn init(self: *Self) !void {
|
pub fn init(self: *Self) !void {
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.global = try wl.Global.create(server.wl_server, zriver.StatusManagerV1, 2, ?*anyopaque, null, bind),
|
.global = try wl.Global.create(server.wl_server, zriver.StatusManagerV1, 3, ?*anyopaque, null, bind),
|
||||||
};
|
};
|
||||||
|
|
||||||
server.wl_server.addDestroyListener(&self.server_destroy);
|
server.wl_server.addDestroyListener(&self.server_destroy);
|
||||||
|
@ -38,9 +38,12 @@ pub fn declareMode(
|
|||||||
|
|
||||||
if (config.mode_to_id.get(new_mode_name) != null) return;
|
if (config.mode_to_id.get(new_mode_name) != null) return;
|
||||||
|
|
||||||
|
try config.mode_to_id.ensureUnusedCapacity(1);
|
||||||
try config.modes.ensureUnusedCapacity(util.gpa, 1);
|
try config.modes.ensureUnusedCapacity(util.gpa, 1);
|
||||||
const owned_name = try util.gpa.dupe(u8, new_mode_name);
|
|
||||||
errdefer util.gpa.free(owned_name);
|
const owned_name = try util.gpa.dupeZ(u8, new_mode_name);
|
||||||
try config.mode_to_id.putNoClobber(owned_name, config.modes.items.len);
|
|
||||||
config.modes.appendAssumeCapacity(.{});
|
const id = @intCast(u32, config.modes.items.len);
|
||||||
|
config.mode_to_id.putAssumeCapacityNoClobber(owned_name, id);
|
||||||
|
config.modes.appendAssumeCapacity(.{ .name = owned_name });
|
||||||
}
|
}
|
||||||
|
@ -59,5 +59,5 @@ pub fn enterMode(
|
|||||||
return Error.Other;
|
return Error.Other;
|
||||||
}
|
}
|
||||||
|
|
||||||
seat.mode_id = mode_id;
|
seat.enterMode(mode_id);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user