idle-inhibit: implement protocol
This commit is contained in:
		
							
								
								
									
										34
									
								
								river/IdleInhibitor.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								river/IdleInhibitor.zig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| const Self = @This(); | ||||
|  | ||||
| const std = @import("std"); | ||||
| const wlr = @import("wlroots"); | ||||
| const wl = @import("wayland").server.wl; | ||||
|  | ||||
| const server = &@import("main.zig").server; | ||||
| const util = @import("util.zig"); | ||||
|  | ||||
| const IdleInhibitorManager = @import("IdleInhibitorManager.zig"); | ||||
|  | ||||
| inhibitor_manager: *IdleInhibitorManager, | ||||
| inhibitor: *wlr.IdleInhibitorV1, | ||||
| destroy: wl.Listener(*wlr.IdleInhibitorV1) = wl.Listener(*wlr.IdleInhibitorV1).init(handleDestroy), | ||||
|  | ||||
| pub fn init(self: *Self, inhibitor: *wlr.IdleInhibitorV1, inhibitor_manager: *IdleInhibitorManager) !void { | ||||
|     self.inhibitor_manager = inhibitor_manager; | ||||
|     self.inhibitor = inhibitor; | ||||
|     self.destroy.setNotify(handleDestroy); | ||||
|     inhibitor.events.destroy.add(&self.destroy); | ||||
|  | ||||
|     inhibitor_manager.idleInhibitCheckActive(); | ||||
| } | ||||
|  | ||||
| fn handleDestroy(listener: *wl.Listener(*wlr.IdleInhibitorV1), _: *wlr.IdleInhibitorV1) void { | ||||
|     const self = @fieldParentPtr(Self, "destroy", listener); | ||||
|     self.destroy.link.remove(); | ||||
|  | ||||
|     const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); | ||||
|     server.idle_inhibitor_manager.inhibitors.remove(node); | ||||
|     util.gpa.destroy(node); | ||||
|  | ||||
|     self.inhibitor_manager.idleInhibitCheckActive(); | ||||
| } | ||||
							
								
								
									
										65
									
								
								river/IdleInhibitorManager.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								river/IdleInhibitorManager.zig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | ||||
| const Self = @This(); | ||||
|  | ||||
| const std = @import("std"); | ||||
| const wlr = @import("wlroots"); | ||||
| const wl = @import("wayland").server.wl; | ||||
|  | ||||
| const server = &@import("main.zig").server; | ||||
| const util = @import("util.zig"); | ||||
|  | ||||
| const View = @import("View.zig"); | ||||
| const IdleInhibitor = @import("IdleInhibitor.zig"); | ||||
|  | ||||
| idle_inhibit_manager: *wlr.IdleInhibitManagerV1, | ||||
| new_idle_inhibitor: wl.Listener(*wlr.IdleInhibitorV1), | ||||
| inhibitors: std.TailQueue(IdleInhibitor) = .{}, | ||||
| idle: *wlr.Idle, | ||||
|  | ||||
| pub fn init(self: *Self, idle: *wlr.Idle) !void { | ||||
|     self.idle_inhibit_manager = try wlr.IdleInhibitManagerV1.create(server.wl_server); | ||||
|     self.idle = idle; | ||||
|     self.new_idle_inhibitor.setNotify(handleNewIdleInhibitor); | ||||
|     self.idle_inhibit_manager.events.new_inhibitor.add(&self.new_idle_inhibitor); | ||||
| } | ||||
|  | ||||
| pub fn deinit(self: *Self) void { | ||||
|     while (self.inhibitors.pop()) |inhibitor| { | ||||
|         inhibitor.data.destroy.link.remove(); | ||||
|         util.gpa.destroy(inhibitor); | ||||
|     } | ||||
|     self.new_idle_inhibitor.link.remove(); | ||||
| } | ||||
|  | ||||
| pub fn idleInhibitCheckActive(self: *Self) void { | ||||
|     var inhibited = false; | ||||
|     var it = self.inhibitors.first; | ||||
|     while (it) |node| : (it = node.next) { | ||||
|         if (View.fromWlrSurface(node.data.inhibitor.surface)) |v| { | ||||
|             // If view is visible, | ||||
|             if (v.current.tags & v.output.current.tags != 0) { | ||||
|                 inhibited = true; | ||||
|                 break; | ||||
|             } | ||||
|         } else { | ||||
|             // If for whatever reason the inhibitor does not have a view, then | ||||
|             // assume it is visible. | ||||
|             inhibited = true; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     self.idle.setEnabled(null, !inhibited); | ||||
| } | ||||
|  | ||||
| fn handleNewIdleInhibitor(listener: *wl.Listener(*wlr.IdleInhibitorV1), inhibitor: *wlr.IdleInhibitorV1) void { | ||||
|     const self = @fieldParentPtr(Self, "new_idle_inhibitor", listener); | ||||
|     const inhibitor_node = util.gpa.create(std.TailQueue(IdleInhibitor).Node) catch return; | ||||
|     inhibitor_node.data.init(inhibitor, self) catch { | ||||
|         util.gpa.destroy(inhibitor_node); | ||||
|         return; | ||||
|     }; | ||||
|  | ||||
|     self.inhibitors.append(inhibitor_node); | ||||
|  | ||||
|     self.idleInhibitCheckActive(); | ||||
| } | ||||
| @ -395,6 +395,7 @@ fn commitTransaction(self: *Self) void { | ||||
|         output.damage.addWhole(); | ||||
|     } | ||||
|     server.input_manager.updateCursorState(); | ||||
|     server.idle_inhibitor_manager.idleInhibitCheckActive(); | ||||
| } | ||||
|  | ||||
| /// Send the new output configuration to all wlr-output-manager clients | ||||
|  | ||||
| @ -36,6 +36,7 @@ const StatusManager = @import("StatusManager.zig"); | ||||
| const View = @import("View.zig"); | ||||
| const ViewStack = @import("view_stack.zig").ViewStack; | ||||
| const XwaylandUnmanaged = @import("XwaylandUnmanaged.zig"); | ||||
| const IdleInhibitorManager = @import("IdleInhibitorManager.zig"); | ||||
|  | ||||
| const log = std.log.scoped(.server); | ||||
|  | ||||
| @ -69,6 +70,7 @@ config: Config, | ||||
| control: Control, | ||||
| status_manager: StatusManager, | ||||
| layout_manager: LayoutManager, | ||||
| idle_inhibitor_manager: IdleInhibitorManager, | ||||
|  | ||||
| pub fn init(self: *Self) !void { | ||||
|     self.wl_server = try wl.Server.create(); | ||||
| @ -123,6 +125,7 @@ pub fn init(self: *Self) !void { | ||||
|     try self.control.init(); | ||||
|     try self.status_manager.init(); | ||||
|     try self.layout_manager.init(); | ||||
|     try self.idle_inhibitor_manager.init(self.input_manager.idle); | ||||
|  | ||||
|     // These all free themselves when the wl_server is destroyed | ||||
|     _ = try wlr.DataDeviceManager.create(self.wl_server); | ||||
| @ -148,6 +151,7 @@ pub fn deinit(self: *Self) void { | ||||
|  | ||||
|     self.root.deinit(); | ||||
|     self.input_manager.deinit(); | ||||
|     self.idle_inhibitor_manager.deinit(); | ||||
|  | ||||
|     self.wl_server.destroy(); | ||||
|  | ||||
|  | ||||
| @ -436,6 +436,13 @@ pub fn fromWlrSurface(surface: *wlr.Surface) ?*Self { | ||||
|             return @intToPtr(*Self, xwayland_surface.data); | ||||
|         } | ||||
|     } | ||||
|     if (surface.isSubsurface()) { | ||||
|         if (wlr.Subsurface.fromWlrSurface(surface)) |ss| { | ||||
|             if (ss.parent) |s| { | ||||
|                 return fromWlrSurface(s); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return null; | ||||
| } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user