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("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("zwlr_layer_shell_v1", 4);
|
||||
|
@ -16,7 +16,7 @@
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zriver_status_manager_v1" version="2">
|
||||
<interface name="zriver_status_manager_v1" version="3">
|
||||
<description summary="manage river status objects">
|
||||
A global factory for objects that receive status information specific
|
||||
to river. It could be used to implement, for example, a status bar.
|
||||
@ -85,7 +85,7 @@
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="zriver_seat_status_v1" version="1">
|
||||
<interface name="zriver_seat_status_v1" version="3">
|
||||
<description summary="track seat focus">
|
||||
This interface allows clients to receive information about the current
|
||||
focus of a seat. Note that (un)focused_output events will only be sent
|
||||
@ -121,5 +121,13 @@
|
||||
</description>
|
||||
<arg name="title" type="string" summary="title of the focused view"/>
|
||||
</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>
|
||||
</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
|
||||
|
||||
/// 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
|
||||
modes: std.ArrayListUnmanaged(Mode),
|
||||
@ -98,7 +99,7 @@ cursor_hide_when_typing: HideCursorWhenTypingMode = .disabled,
|
||||
|
||||
pub fn init() !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),
|
||||
};
|
||||
errdefer self.deinit();
|
||||
@ -106,27 +107,22 @@ pub fn init() !Self {
|
||||
// Start with two empty modes, "normal" and "locked"
|
||||
{
|
||||
// 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);
|
||||
self.modes.appendAssumeCapacity(.{});
|
||||
self.modes.appendAssumeCapacity(.{ .name = owned_slice });
|
||||
}
|
||||
{
|
||||
// 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);
|
||||
self.modes.appendAssumeCapacity(.{});
|
||||
self.modes.appendAssumeCapacity(.{ .name = owned_slice });
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
for (self.modes.items) |*mode| mode.deinit();
|
||||
self.modes.deinit(util.gpa);
|
||||
|
||||
|
@ -188,7 +188,7 @@ fn handleInhibitActivate(
|
||||
|
||||
// Enter locked mode
|
||||
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;
|
||||
@ -215,8 +215,9 @@ fn handleInhibitDeactivate(
|
||||
// have each Seat handle focus and enter their previous mode.
|
||||
var seat_it = self.seats.first;
|
||||
while (seat_it) |seat_node| : (seat_it = seat_node.next) {
|
||||
seat_node.data.focus(null);
|
||||
seat_node.data.mode_id = seat_node.data.prev_mode_id;
|
||||
const seat = &seat_node.data;
|
||||
seat.enterMode(seat.prev_mode_id);
|
||||
seat.focus(null);
|
||||
}
|
||||
|
||||
server.root.startTransaction();
|
||||
|
@ -23,11 +23,13 @@ const Mapping = @import("Mapping.zig");
|
||||
const PointerMapping = @import("PointerMapping.zig");
|
||||
const SwitchMapping = @import("SwitchMapping.zig");
|
||||
|
||||
name: [:0]const u8,
|
||||
mappings: std.ArrayListUnmanaged(Mapping) = .{},
|
||||
pointer_mappings: std.ArrayListUnmanaged(PointerMapping) = .{},
|
||||
switch_mappings: std.ArrayListUnmanaged(SwitchMapping) = .{},
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
util.gpa.free(self.name);
|
||||
for (self.mappings.items) |m| m.deinit();
|
||||
self.mappings.deinit(util.gpa);
|
||||
self.pointer_mappings.deinit(util.gpa);
|
||||
|
@ -63,10 +63,10 @@ keyboards: std.TailQueue(Keyboard) = .{},
|
||||
switches: std.TailQueue(Switch) = .{},
|
||||
|
||||
/// 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
|
||||
prev_mode_id: usize = 0,
|
||||
prev_mode_id: u32 = 0,
|
||||
|
||||
/// Timer for repeating keyboard mappings
|
||||
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);
|
||||
}
|
||||
|
||||
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?
|
||||
pub fn hasMapping(
|
||||
self: *Self,
|
||||
|
@ -21,6 +21,7 @@ const wayland = @import("wayland");
|
||||
const wl = wayland.server.wl;
|
||||
const zriver = wayland.server.zriver;
|
||||
|
||||
const server = &@import("main.zig").server;
|
||||
const util = @import("util.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);
|
||||
|
||||
// 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.sendFocusedView();
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ server_destroy: wl.Listener(*wl.Server) = wl.Listener(*wl.Server).init(handleSer
|
||||
|
||||
pub fn init(self: *Self) !void {
|
||||
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);
|
||||
|
@ -38,9 +38,12 @@ pub fn declareMode(
|
||||
|
||||
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);
|
||||
const owned_name = try util.gpa.dupe(u8, new_mode_name);
|
||||
errdefer util.gpa.free(owned_name);
|
||||
try config.mode_to_id.putNoClobber(owned_name, config.modes.items.len);
|
||||
config.modes.appendAssumeCapacity(.{});
|
||||
|
||||
const owned_name = try util.gpa.dupeZ(u8, new_mode_name);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
seat.mode_id = mode_id;
|
||||
seat.enterMode(mode_id);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user