mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-19 10:26:36 +01:00
api: Add output powered and enabled props
This commit is contained in:
parent
5fe5152b76
commit
1c55296d8f
15 changed files with 217 additions and 58 deletions
|
@ -118,6 +118,8 @@ local pinnacle_output_v0alpha1_Transform = {
|
|||
---@field transform pinnacle.output.v0alpha1.Transform?
|
||||
---@field serial integer?
|
||||
---@field keyboard_focus_stack_window_ids integer[]?
|
||||
---@field enabled boolean?
|
||||
---@field powered boolean?
|
||||
|
||||
-- Window
|
||||
|
||||
|
|
|
@ -40,8 +40,6 @@ output.handle = output_handle
|
|||
---
|
||||
---@return OutputHandle[]
|
||||
function output.get_all()
|
||||
-- Not going to batch these because I doubt people would have that many monitors
|
||||
|
||||
local response = client.unary_request(output_service.Get, {})
|
||||
|
||||
---@type OutputHandle[]
|
||||
|
@ -54,6 +52,27 @@ function output.get_all()
|
|||
return handles
|
||||
end
|
||||
|
||||
---Get all enabled outputs.
|
||||
---
|
||||
---### Example
|
||||
---```lua
|
||||
---local outputs = Output.get_all_enabled()
|
||||
---```
|
||||
---
|
||||
---@return OutputHandle[]
|
||||
function output.get_all_enabled()
|
||||
local outputs = output.get_all()
|
||||
|
||||
local enabled_handles = {}
|
||||
for _, handle in ipairs(outputs) do
|
||||
if handle:enabled() then
|
||||
table.insert(enabled_handles, handle)
|
||||
end
|
||||
end
|
||||
|
||||
return enabled_handles
|
||||
end
|
||||
|
||||
---Get an output by its name (the connector it's plugged into).
|
||||
---
|
||||
---### Example
|
||||
|
@ -421,7 +440,7 @@ function output.setup_locs(update_locs_on, locs)
|
|||
end
|
||||
|
||||
local function layout_outputs()
|
||||
local outputs = output.get_all()
|
||||
local outputs = output.get_all_enabled()
|
||||
|
||||
---@type OutputHandle[]
|
||||
local placed_outputs = {}
|
||||
|
@ -948,6 +967,8 @@ end
|
|||
---@field transform Transform?
|
||||
---@field serial integer?
|
||||
---@field keyboard_focus_stack WindowHandle[]
|
||||
---@field enabled boolean?
|
||||
---@field powered boolean?
|
||||
|
||||
---Get all properties of this output.
|
||||
---
|
||||
|
@ -1020,6 +1041,8 @@ end
|
|||
|
||||
---Get this output's logical width in pixels.
|
||||
---
|
||||
---If the output is disabled, this returns nil.
|
||||
---
|
||||
---Shorthand for `handle:props().logical_width`.
|
||||
---
|
||||
---@return integer?
|
||||
|
@ -1029,6 +1052,8 @@ end
|
|||
|
||||
---Get this output's logical height in pixels.
|
||||
---
|
||||
---If the output is disabled, this returns nil.
|
||||
---
|
||||
---Shorthand for `handle:props().y`.
|
||||
---
|
||||
---@return integer?
|
||||
|
@ -1142,6 +1167,25 @@ function OutputHandle:keyboard_focus_stack()
|
|||
return self:props().keyboard_focus_stack
|
||||
end
|
||||
|
||||
---Get whether this output is enabled.
|
||||
---
|
||||
---Disabled outputs are not mapped to the global space and cannot be used.
|
||||
---
|
||||
---@return boolean?
|
||||
function OutputHandle:enabled()
|
||||
return self:props().enabled
|
||||
end
|
||||
|
||||
---Get whether this output is powered.
|
||||
---
|
||||
---Unpowered outputs that are enabled will be off, but they will still be
|
||||
---mapped to the global space, meaning you can still interact with them.
|
||||
---
|
||||
---@return boolean?
|
||||
function OutputHandle:powered()
|
||||
return self:props().powered
|
||||
end
|
||||
|
||||
---Get this output's keyboard focus stack.
|
||||
---
|
||||
---This only includes windows on active tags.
|
||||
|
|
|
@ -116,6 +116,8 @@ message GetPropertiesResponse {
|
|||
optional uint32 serial = 16;
|
||||
// Window ids of the keyboard focus stack for this output.
|
||||
repeated uint32 keyboard_focus_stack_window_ids = 17;
|
||||
optional bool enabled = 18;
|
||||
optional bool powered = 19;
|
||||
}
|
||||
|
||||
service OutputService {
|
||||
|
|
|
@ -60,7 +60,7 @@ impl Output {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get a handle to all connected outputs.
|
||||
/// Get handles to all connected outputs.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -82,10 +82,35 @@ impl Output {
|
|||
.into_inner()
|
||||
.output_names
|
||||
.into_iter()
|
||||
.map(move |name| self.new_handle(name))
|
||||
.map(|name| self.new_handle(name))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Get handles to all outputs that are connected and enabled.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let enabled = output.get_all_enabled();
|
||||
/// ```
|
||||
pub fn get_all_enabled(&self) -> Vec<OutputHandle> {
|
||||
block_on_tokio(self.get_all_enabled_async())
|
||||
}
|
||||
|
||||
/// The async version of [`Output::get_all_enabled`].
|
||||
pub async fn get_all_enabled_async(&self) -> Vec<OutputHandle> {
|
||||
let outputs = self.get_all_async().await;
|
||||
|
||||
let mut enabled_outputs = Vec::new();
|
||||
for output in outputs {
|
||||
if output.enabled_async().await.unwrap_or_default() {
|
||||
enabled_outputs.push(output);
|
||||
}
|
||||
}
|
||||
|
||||
enabled_outputs
|
||||
}
|
||||
|
||||
/// Get a handle to the output with the given name.
|
||||
///
|
||||
/// By "name", we mean the name of the connector the output is connected to.
|
||||
|
@ -272,7 +297,7 @@ impl Output {
|
|||
|
||||
let api = self.api.get().unwrap().clone();
|
||||
let layout_outputs = move || {
|
||||
let outputs = api.output.get_all();
|
||||
let outputs = api.output.get_all_enabled();
|
||||
|
||||
let mut rightmost_output_and_x: Option<(OutputHandle, i32)> = None;
|
||||
|
||||
|
@ -1001,6 +1026,8 @@ impl OutputHandle {
|
|||
.into_iter()
|
||||
.map(|id| self.api.window.new_handle(id))
|
||||
.collect(),
|
||||
enabled: response.enabled,
|
||||
powered: response.powered,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1056,6 +1083,8 @@ impl OutputHandle {
|
|||
|
||||
/// Get this output's logical width in pixels.
|
||||
///
|
||||
/// If the output is disabled, this returns None.
|
||||
///
|
||||
/// Shorthand for `self.props().logical_width`.
|
||||
pub fn logical_width(&self) -> Option<u32> {
|
||||
self.props().logical_width
|
||||
|
@ -1068,6 +1097,8 @@ impl OutputHandle {
|
|||
|
||||
/// Get this output's logical height in pixels.
|
||||
///
|
||||
/// If the output is disabled, this returns None.
|
||||
///
|
||||
/// Shorthand for `self.props().logical_height`.
|
||||
pub fn logical_height(&self) -> Option<u32> {
|
||||
self.props().logical_height
|
||||
|
@ -1228,6 +1259,34 @@ impl OutputHandle {
|
|||
.collect()
|
||||
}
|
||||
|
||||
/// Get whether this output is enabled.
|
||||
///
|
||||
/// Disabled outputs act as if you unplugged them.
|
||||
pub fn enabled(&self) -> Option<bool> {
|
||||
self.props().enabled
|
||||
}
|
||||
|
||||
/// The async version of [`OutputHandle::enabled`].
|
||||
pub async fn enabled_async(&self) -> Option<bool> {
|
||||
self.props_async().await.enabled
|
||||
}
|
||||
|
||||
/// Get whether this output is powered.
|
||||
///
|
||||
/// Unpowered outputs will be turned off but you can still interact with them.
|
||||
///
|
||||
/// Outputs can be disabled but still powered; this just means
|
||||
/// they will turn on when powered. Disabled and unpowered outputs
|
||||
/// will not power on when enabled, but will still be interactable.
|
||||
pub fn powered(&self) -> Option<bool> {
|
||||
self.props().powered
|
||||
}
|
||||
|
||||
/// The async version of [`OutputHandle::powered`].
|
||||
pub async fn powered_async(&self) -> Option<bool> {
|
||||
self.props_async().await.powered
|
||||
}
|
||||
|
||||
/// Get this output's unique name (the name of its connector).
|
||||
pub fn name(&self) -> String {
|
||||
self.name.to_string()
|
||||
|
@ -1292,6 +1351,15 @@ pub struct OutputProperties {
|
|||
pub serial: Option<u32>,
|
||||
/// This output's window keyboard focus stack.
|
||||
pub keyboard_focus_stack: Vec<WindowHandle>,
|
||||
/// Whether this output is enabled.
|
||||
///
|
||||
/// Enabled outputs are mapped in the global space and usable.
|
||||
/// Disabled outputs function as if you unplugged them.
|
||||
pub enabled: Option<bool>,
|
||||
/// Whether this output is powered.
|
||||
///
|
||||
/// Unpowered outputs will be off but you can still interact with them.
|
||||
pub powered: Option<bool>,
|
||||
}
|
||||
|
||||
/// A custom modeline.
|
||||
|
|
28
src/api.rs
28
src/api.rs
|
@ -886,7 +886,7 @@ impl tag_service_server::TagService for TagService {
|
|||
.flat_map(|id| id.tag(&state.pinnacle))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for output in state.pinnacle.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
for output in state.pinnacle.outputs.keys().cloned().collect::<Vec<_>>() {
|
||||
// TODO: seriously, convert state.tags into a hashset
|
||||
output.with_state_mut(|state| {
|
||||
for tag_to_remove in tags_to_remove.iter() {
|
||||
|
@ -916,8 +916,8 @@ impl tag_service_server::TagService for TagService {
|
|||
run_unary(&self.sender, move |state| {
|
||||
let tag_ids = state
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.outputs
|
||||
.keys()
|
||||
.flat_map(|op| op.with_state(|state| state.tags.clone()))
|
||||
.map(|tag| tag.id())
|
||||
.map(|id| id.0)
|
||||
|
@ -1272,8 +1272,8 @@ impl output_service_server::OutputService for OutputService {
|
|||
run_unary(&self.sender, move |state| {
|
||||
let output_names = state
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.outputs
|
||||
.keys()
|
||||
.map(|output| output.name())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
@ -1400,6 +1400,18 @@ impl output_service_server::OutputService for OutputService {
|
|||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let enabled = output.as_ref().map(|output| {
|
||||
state
|
||||
.pinnacle
|
||||
.outputs
|
||||
.get(output)
|
||||
.is_some_and(|global| global.is_some())
|
||||
});
|
||||
|
||||
let powered = output
|
||||
.as_ref()
|
||||
.map(|output| output.with_state(|state| state.powered));
|
||||
|
||||
output::v0alpha1::GetPropertiesResponse {
|
||||
make,
|
||||
model,
|
||||
|
@ -1418,6 +1430,8 @@ impl output_service_server::OutputService for OutputService {
|
|||
transform,
|
||||
serial,
|
||||
keyboard_focus_stack_window_ids,
|
||||
enabled,
|
||||
powered,
|
||||
}
|
||||
})
|
||||
.await
|
||||
|
@ -1453,7 +1467,7 @@ impl render_service_server::RenderService for RenderService {
|
|||
|
||||
run_unary_no_response(&self.sender, move |state| {
|
||||
state.backend.set_upscale_filter(filter);
|
||||
for output in state.pinnacle.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
for output in state.pinnacle.outputs.keys().cloned().collect::<Vec<_>>() {
|
||||
state.backend.reset_buffers(&output);
|
||||
state.schedule_render(&output);
|
||||
}
|
||||
|
@ -1478,7 +1492,7 @@ impl render_service_server::RenderService for RenderService {
|
|||
|
||||
run_unary_no_response(&self.sender, move |state| {
|
||||
state.backend.set_downscale_filter(filter);
|
||||
for output in state.pinnacle.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
for output in state.pinnacle.outputs.keys().cloned().collect::<Vec<_>>() {
|
||||
state.backend.reset_buffers(&output);
|
||||
state.schedule_render(&output);
|
||||
}
|
||||
|
|
|
@ -95,10 +95,12 @@ impl Dummy {
|
|||
UninitBackend {
|
||||
seat_name: dummy.seat_name(),
|
||||
init: Box::new(move |pinnacle| {
|
||||
output.create_global::<State>(&display_handle);
|
||||
let global = output.create_global::<State>(&display_handle);
|
||||
|
||||
pinnacle.output_focus_stack.set_focus(output.clone());
|
||||
|
||||
pinnacle.outputs.insert(output.clone(), Some(global));
|
||||
|
||||
pinnacle
|
||||
.shm_state
|
||||
.update_formats(dummy.renderer.shm_formats());
|
||||
|
@ -136,7 +138,9 @@ impl Pinnacle {
|
|||
output.set_preferred(mode);
|
||||
output.with_state_mut(|state| state.modes = vec![mode]);
|
||||
|
||||
output.create_global::<State>(&self.display_handle);
|
||||
let global = output.create_global::<State>(&self.display_handle);
|
||||
|
||||
self.outputs.insert(output.clone(), Some(global));
|
||||
|
||||
self.space.map_output(&output, (0, 0));
|
||||
|
||||
|
|
|
@ -1037,7 +1037,7 @@ impl Udev {
|
|||
|
||||
let (phys_w, phys_h) = connector.size().unwrap_or((0, 0));
|
||||
|
||||
if pinnacle.space.outputs().any(|op| {
|
||||
if pinnacle.outputs.keys().any(|op| {
|
||||
op.user_data()
|
||||
.get::<UdevOutputData>()
|
||||
.is_some_and(|op_id| op_id.crtc == crtc)
|
||||
|
@ -1056,11 +1056,10 @@ impl Udev {
|
|||
);
|
||||
let global = output.create_global::<State>(&self.display_handle);
|
||||
|
||||
pinnacle.outputs.insert(output.clone(), global);
|
||||
pinnacle.outputs.insert(output.clone(), Some(global));
|
||||
|
||||
output.with_state_mut(|state| {
|
||||
state.serial = serial;
|
||||
state.powered = true;
|
||||
});
|
||||
|
||||
output.set_preferred(wl_mode);
|
||||
|
@ -1198,8 +1197,8 @@ impl Udev {
|
|||
device.surfaces.remove(&crtc);
|
||||
|
||||
let output = pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.outputs
|
||||
.keys()
|
||||
.find(|o| {
|
||||
o.user_data()
|
||||
.get::<UdevOutputData>()
|
||||
|
@ -1285,15 +1284,11 @@ impl Udev {
|
|||
return;
|
||||
};
|
||||
|
||||
let output = if let Some(output) = pinnacle
|
||||
.outputs
|
||||
.keys()
|
||||
.chain(pinnacle.unmapped_outputs.iter())
|
||||
.find(|o| {
|
||||
let udev_op_data = o.user_data().get::<UdevOutputData>();
|
||||
udev_op_data
|
||||
.is_some_and(|data| data.device_id == surface.device_id && data.crtc == crtc)
|
||||
}) {
|
||||
let output = if let Some(output) = pinnacle.outputs.keys().find(|o| {
|
||||
let udev_op_data = o.user_data().get::<UdevOutputData>();
|
||||
udev_op_data
|
||||
.is_some_and(|data| data.device_id == surface.device_id && data.crtc == crtc)
|
||||
}) {
|
||||
output.clone()
|
||||
} else {
|
||||
// somehow we got called with an invalid output
|
||||
|
|
|
@ -185,10 +185,12 @@ impl Winit {
|
|||
|
||||
let init = Box::new(move |pinnacle: &mut Pinnacle| {
|
||||
let output = winit.output.clone();
|
||||
output.create_global::<State>(&display_handle);
|
||||
let global = output.create_global::<State>(&display_handle);
|
||||
|
||||
pinnacle.output_focus_stack.set_focus(output.clone());
|
||||
|
||||
pinnacle.outputs.insert(output.clone(), Some(global));
|
||||
|
||||
pinnacle
|
||||
.shm_state
|
||||
.update_formats(winit.backend.renderer().shm_formats());
|
||||
|
|
|
@ -381,7 +381,7 @@ impl Pinnacle {
|
|||
// Clear state
|
||||
|
||||
debug!("Clearing tags");
|
||||
for output in self.space.outputs() {
|
||||
for output in self.outputs.keys() {
|
||||
output.with_state_mut(|state| state.tags.clear());
|
||||
}
|
||||
|
||||
|
|
|
@ -158,11 +158,19 @@ impl LayoutState {
|
|||
}
|
||||
|
||||
impl Pinnacle {
|
||||
pub fn request_layout(&mut self, output: &Output) -> Option<LayoutRequestId> {
|
||||
pub fn request_layout(&mut self, output: &Output) {
|
||||
if self
|
||||
.outputs
|
||||
.get(output)
|
||||
.is_some_and(|global| global.is_none())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let id = self.layout_state.next_id();
|
||||
let Some(sender) = self.layout_state.layout_request_sender.as_ref() else {
|
||||
warn!("Layout requested but no client has connected to the layout service");
|
||||
return None;
|
||||
return;
|
||||
};
|
||||
|
||||
let windows_on_foc_tags = output.with_state(|state| {
|
||||
|
@ -213,8 +221,6 @@ impl Pinnacle {
|
|||
output_width: Some(output_width as u32),
|
||||
output_height: Some(output_height as u32),
|
||||
}));
|
||||
|
||||
Some(id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use std::{cell::RefCell, num::NonZeroU32};
|
||||
use std::{cell::RefCell, collections::hash_map::Entry, num::NonZeroU32};
|
||||
|
||||
use pinnacle_api_defs::pinnacle::signal::v0alpha1::{
|
||||
OutputDisconnectResponse, OutputMoveResponse, OutputResizeResponse,
|
||||
|
@ -35,8 +35,8 @@ impl OutputName {
|
|||
/// Get the output with this name.
|
||||
pub fn output(&self, pinnacle: &Pinnacle) -> Option<Output> {
|
||||
pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.outputs
|
||||
.keys()
|
||||
.find(|output| output.name() == self.0)
|
||||
.cloned()
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ pub enum BlankingState {
|
|||
}
|
||||
|
||||
/// The state of an output
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug)]
|
||||
pub struct OutputState {
|
||||
pub tags: Vec<Tag>,
|
||||
pub focus_stack: WindowKeyboardFocusStack,
|
||||
|
@ -73,6 +73,22 @@ pub struct OutputState {
|
|||
pub powered: bool,
|
||||
}
|
||||
|
||||
impl Default for OutputState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
tags: Default::default(),
|
||||
focus_stack: Default::default(),
|
||||
screencopy: Default::default(),
|
||||
serial: Default::default(),
|
||||
modes: Default::default(),
|
||||
lock_surface: Default::default(),
|
||||
blanking_state: Default::default(),
|
||||
layout_transaction: Default::default(),
|
||||
powered: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WithState for Output {
|
||||
type State = OutputState;
|
||||
|
||||
|
@ -226,21 +242,29 @@ impl Pinnacle {
|
|||
|
||||
pub fn set_output_enabled(&mut self, output: &Output, enabled: bool) {
|
||||
if enabled {
|
||||
self.unmapped_outputs.remove(output);
|
||||
if !self.outputs.contains_key(output) {
|
||||
let global = output.create_global::<State>(&self.display_handle);
|
||||
self.outputs.insert(output.clone(), global);
|
||||
match self.outputs.entry(output.clone()) {
|
||||
Entry::Occupied(entry) => {
|
||||
let global = entry.into_mut();
|
||||
if global.is_none() {
|
||||
*global = Some(output.create_global::<State>(&self.display_handle));
|
||||
}
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
let global = output.create_global::<State>(&self.display_handle);
|
||||
entry.insert(Some(global));
|
||||
}
|
||||
}
|
||||
self.space.map_output(output, output.current_location());
|
||||
|
||||
// TODO: output connect?
|
||||
} else {
|
||||
let global = self.outputs.remove(output);
|
||||
let global = self.outputs.get_mut(output);
|
||||
if let Some(global) = global {
|
||||
self.display_handle.remove_global::<State>(global);
|
||||
if let Some(global) = global.take() {
|
||||
self.display_handle.remove_global::<State>(global);
|
||||
}
|
||||
}
|
||||
self.space.unmap_output(output);
|
||||
self.unmapped_outputs.insert(output.clone());
|
||||
|
||||
// TODO: should this trigger the signal?
|
||||
self.signal_state.output_disconnect.signal(|buffer| {
|
||||
|
@ -267,11 +291,12 @@ impl Pinnacle {
|
|||
}
|
||||
|
||||
pub fn remove_output(&mut self, output: &Output) {
|
||||
let global = self.outputs.remove(output);
|
||||
let global = self.outputs.get_mut(output);
|
||||
if let Some(global) = global {
|
||||
self.display_handle.remove_global::<State>(global);
|
||||
if let Some(global) = global.take() {
|
||||
self.display_handle.remove_global::<State>(global);
|
||||
}
|
||||
}
|
||||
self.unmapped_outputs.remove(output);
|
||||
|
||||
for layer in layer_map_for_output(output).layers() {
|
||||
layer.layer_surface().send_close();
|
||||
|
|
|
@ -3,4 +3,3 @@ pub mod gamma_control;
|
|||
pub mod output_management;
|
||||
pub mod output_power_management;
|
||||
pub mod screencopy;
|
||||
|
||||
|
|
|
@ -153,8 +153,7 @@ pub struct Pinnacle {
|
|||
/// WlSurfaces with an attached idle inhibitor.
|
||||
pub idle_inhibiting_surfaces: HashSet<WlSurface>,
|
||||
|
||||
pub outputs: HashMap<Output, GlobalId>,
|
||||
pub unmapped_outputs: HashSet<Output>,
|
||||
pub outputs: HashMap<Output, Option<GlobalId>>,
|
||||
}
|
||||
|
||||
impl State {
|
||||
|
@ -355,7 +354,6 @@ impl Pinnacle {
|
|||
idle_inhibiting_surfaces: HashSet::new(),
|
||||
|
||||
outputs: HashMap::new(),
|
||||
unmapped_outputs: HashSet::new(),
|
||||
};
|
||||
|
||||
Ok(pinnacle)
|
||||
|
|
|
@ -26,8 +26,8 @@ impl TagId {
|
|||
/// Get the tag associated with this id.
|
||||
pub fn tag(&self, pinnacle: &Pinnacle) -> Option<Tag> {
|
||||
pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.outputs
|
||||
.keys()
|
||||
.flat_map(|op| op.with_state(|state| state.tags.clone()))
|
||||
.find(|tag| &tag.id() == self)
|
||||
}
|
||||
|
@ -118,8 +118,8 @@ impl Tag {
|
|||
/// RefCell Safety: This uses RefCells on every mapped output.
|
||||
pub fn output(&self, pinnacle: &Pinnacle) -> Option<Output> {
|
||||
pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.outputs
|
||||
.keys()
|
||||
.find(|output| output.with_state(|state| state.tags.iter().any(|tg| tg == self)))
|
||||
.cloned()
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ impl Pinnacle {
|
|||
|
||||
self.z_index_stack.retain(|win| win != window);
|
||||
|
||||
for output in self.space.outputs() {
|
||||
for output in self.outputs.keys() {
|
||||
output.with_state_mut(|state| state.focus_stack.stack.retain(|win| win != window));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue