mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-27 21:58:18 +01:00
Prepare for cherry-pick
This commit is contained in:
parent
7dabc4d22c
commit
bef6d92176
3 changed files with 96 additions and 67 deletions
157
src/layout.rs
157
src/layout.rs
|
@ -1,8 +1,10 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use itertools::{Either, Itertools};
|
use itertools::{Either, Itertools};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
desktop::layer_map_for_output,
|
desktop::{layer_map_for_output, utils::surface_primary_scanout_output},
|
||||||
output::Output,
|
output::Output,
|
||||||
reexports::wayland_server::Resource,
|
reexports::wayland_server::Resource,
|
||||||
utils::{IsAlive, Logical, Point, Rectangle, Size},
|
utils::{IsAlive, Logical, Point, Rectangle, Size},
|
||||||
|
@ -57,7 +59,7 @@ impl State {
|
||||||
|
|
||||||
pub fn update_windows(&mut self, output: &Output) {
|
pub fn update_windows(&mut self, output: &Output) {
|
||||||
let Some(layout) = output.with_state(|state| {
|
let Some(layout) = output.with_state(|state| {
|
||||||
state.focused_tags().next().cloned().map(|tag| tag.layout())
|
state.focused_tags().next().map(|tag| tag.layout())
|
||||||
}) else { return };
|
}) else { return };
|
||||||
|
|
||||||
let (windows_on_foc_tags, mut windows_not_on_foc_tags): (Vec<_>, _) =
|
let (windows_on_foc_tags, mut windows_not_on_foc_tags): (Vec<_>, _) =
|
||||||
|
@ -68,6 +70,7 @@ impl State {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Don't unmap windows on other outputs
|
||||||
windows_not_on_foc_tags.retain(|win| win.output(self) == Some(output.clone()));
|
windows_not_on_foc_tags.retain(|win| win.output(self) == Some(output.clone()));
|
||||||
|
|
||||||
let tiled_windows = windows_on_foc_tags
|
let tiled_windows = windows_on_foc_tags
|
||||||
|
@ -122,12 +125,19 @@ impl State {
|
||||||
WindowElement::Wayland(win) => {
|
WindowElement::Wayland(win) => {
|
||||||
// If the above didn't cause any change to size or other state, simply
|
// If the above didn't cause any change to size or other state, simply
|
||||||
// map the window.
|
// map the window.
|
||||||
if !win.toplevel().has_pending_changes() {
|
let current_state = win.toplevel().current_state();
|
||||||
|
let is_pending = win
|
||||||
|
.toplevel()
|
||||||
|
.with_pending_state(|state| state.size != current_state.size);
|
||||||
|
// for whatever reason vscode on wayland likes to have pending state
|
||||||
|
// (like tiled states) but not commit, so we check for just the size
|
||||||
|
// here
|
||||||
|
if !is_pending {
|
||||||
|
tracing::debug!("No pending changes");
|
||||||
state.loc_request_state = LocationRequestState::Idle;
|
state.loc_request_state = LocationRequestState::Idle;
|
||||||
non_pending_wins.push((loc, window.clone()));
|
non_pending_wins.push((loc, window.clone()));
|
||||||
// TODO: wait for windows with pending state to ack and commit
|
|
||||||
// self.space.map_element(window.clone(), loc, false);
|
|
||||||
} else {
|
} else {
|
||||||
|
tracing::debug!("Pending changes");
|
||||||
let serial = win.toplevel().send_configure();
|
let serial = win.toplevel().send_configure();
|
||||||
state.loc_request_state =
|
state.loc_request_state =
|
||||||
LocationRequestState::Requested(serial, loc);
|
LocationRequestState::Requested(serial, loc);
|
||||||
|
@ -149,81 +159,100 @@ impl State {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
BLOCKER_COUNTER.store(1, std::sync::atomic::Ordering::SeqCst);
|
// BLOCKER_COUNTER.store(1, std::sync::atomic::Ordering::SeqCst);
|
||||||
tracing::debug!(
|
// tracing::debug!(
|
||||||
"blocker {}",
|
// "blocker {}",
|
||||||
BLOCKER_COUNTER.load(std::sync::atomic::Ordering::SeqCst)
|
// BLOCKER_COUNTER.load(std::sync::atomic::Ordering::SeqCst)
|
||||||
);
|
// );
|
||||||
|
|
||||||
let start_time = self.clock.now();
|
|
||||||
|
|
||||||
// Pause rendering. Here we'll wait until all windows have ack'ed and committed,
|
// Pause rendering. Here we'll wait until all windows have ack'ed and committed,
|
||||||
// then resume rendering. This prevents flickering because some windows will commit before
|
// then resume rendering. This prevents flickering because some windows will commit before
|
||||||
// others.
|
// others.
|
||||||
//
|
//
|
||||||
// This *will* cause everything to freeze for a few frames, but it should'nt impact
|
// This *will* cause everything to freeze for a few frames, but it shouldn't impact
|
||||||
// anything meaningfully.
|
// anything meaningfully.
|
||||||
self.pause_rendering = true;
|
self.pause_rendering = true;
|
||||||
|
|
||||||
for (_loc, win) in pending_wins.iter() {
|
// for (_loc, win) in pending_wins.iter() {
|
||||||
if let Some(surf) = win.wl_surface() {
|
// if let Some(surf) = win.wl_surface() {
|
||||||
tracing::debug!("adding blocker");
|
// tracing::debug!("adding blocker");
|
||||||
compositor::add_blocker(&surf, crate::window::WindowBlocker);
|
// compositor::add_blocker(&surf, crate::window::WindowBlocker);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
let pending_wins_clone = pending_wins.clone();
|
let pending_wins_clone = pending_wins.clone();
|
||||||
|
|
||||||
|
// schedule on all idle
|
||||||
self.schedule(
|
self.schedule(
|
||||||
move |_data| {
|
move |_dt| {
|
||||||
pending_wins_clone.iter().all(|(_, win)| {
|
// tracing::debug!("Waiting for all to be idle");
|
||||||
win.with_state(|state| state.loc_request_state.is_acknowledged())
|
let all_idle = pending_wins
|
||||||
})
|
|
||||||
},
|
|
||||||
move |data| {
|
|
||||||
// remove and trigger blockers
|
|
||||||
BLOCKER_COUNTER.store(0, std::sync::atomic::Ordering::SeqCst);
|
|
||||||
tracing::debug!(
|
|
||||||
"blocker {}",
|
|
||||||
BLOCKER_COUNTER.load(std::sync::atomic::Ordering::SeqCst)
|
|
||||||
);
|
|
||||||
for client in pending_wins
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(_, win)| win.wl_surface()?.client())
|
.filter(|(_, win)| win.alive())
|
||||||
{
|
.all(|(_, win)| win.with_state(|state| state.loc_request_state.is_idle()));
|
||||||
data.state
|
|
||||||
.client_compositor_state(&client)
|
|
||||||
.blocker_cleared(&mut data.state, &data.display.handle())
|
|
||||||
}
|
|
||||||
|
|
||||||
// schedule on all idle
|
all_idle
|
||||||
data.state.schedule(
|
},
|
||||||
move |_dt| {
|
move |dt| {
|
||||||
pending_wins
|
for (loc, win) in non_pending_wins {
|
||||||
.iter()
|
dt.state.space.map_element(win, loc, false);
|
||||||
.filter(|(_, win)| win.alive())
|
}
|
||||||
.all(|(_, win)| {
|
for win in windows_not_on_foc_tags {
|
||||||
win.with_state(|state| state.loc_request_state.is_idle())
|
dt.state.space.unmap_elem(&win);
|
||||||
})
|
}
|
||||||
},
|
dt.state.pause_rendering = false;
|
||||||
move |dt| {
|
|
||||||
for (loc, win) in non_pending_wins {
|
|
||||||
dt.state.space.map_element(win, loc, false);
|
|
||||||
}
|
|
||||||
for win in windows_not_on_foc_tags {
|
|
||||||
dt.state.space.unmap_elem(&win);
|
|
||||||
}
|
|
||||||
dt.state.pause_rendering = false;
|
|
||||||
let finish_time =
|
|
||||||
smithay::utils::Time::elapsed(&start_time, dt.state.clock.now());
|
|
||||||
tracing::debug!(
|
|
||||||
"spent {} microseconds not rendering",
|
|
||||||
finish_time.as_micros()
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// self.schedule(
|
||||||
|
// move |_data| {
|
||||||
|
// // tracing::debug!("Waiting for all to ack");
|
||||||
|
// pending_wins_clone.iter().all(|(_, win)| {
|
||||||
|
// win.with_state(|state| state.loc_request_state.is_acknowledged())
|
||||||
|
// })
|
||||||
|
// },
|
||||||
|
// move |data| {
|
||||||
|
// // remove and trigger blockers
|
||||||
|
// BLOCKER_COUNTER.store(0, std::sync::atomic::Ordering::SeqCst);
|
||||||
|
// tracing::debug!(
|
||||||
|
// "blocker {}",
|
||||||
|
// BLOCKER_COUNTER.load(std::sync::atomic::Ordering::SeqCst)
|
||||||
|
// );
|
||||||
|
// for client in pending_wins
|
||||||
|
// .iter()
|
||||||
|
// .filter_map(|(_, win)| win.wl_surface()?.client())
|
||||||
|
// {
|
||||||
|
// data.state
|
||||||
|
// .client_compositor_state(&client)
|
||||||
|
// .blocker_cleared(&mut data.state, &data.display.handle())
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // schedule on all idle
|
||||||
|
// data.state.schedule(
|
||||||
|
// move |_dt| {
|
||||||
|
// // tracing::debug!("Waiting for all to be idle");
|
||||||
|
// let all_idle =
|
||||||
|
// pending_wins
|
||||||
|
// .iter()
|
||||||
|
// .filter(|(_, win)| win.alive())
|
||||||
|
// .all(|(_, win)| {
|
||||||
|
// win.with_state(|state| state.loc_request_state.is_idle())
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// all_idle
|
||||||
|
// },
|
||||||
|
// move |dt| {
|
||||||
|
// for (loc, win) in non_pending_wins {
|
||||||
|
// dt.state.space.map_element(win, loc, false);
|
||||||
|
// }
|
||||||
|
// for win in windows_not_on_foc_tags {
|
||||||
|
// dt.state.space.unmap_elem(&win);
|
||||||
|
// }
|
||||||
|
// dt.state.pause_rendering = false;
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
//! While Pinnacle is not a library, this documentation serves to guide those who want to
|
//! While Pinnacle is not a library, this documentation serves to guide those who want to
|
||||||
//! contribute or learn how building something like this works.
|
//! contribute or learn how building something like this works.
|
||||||
|
|
||||||
#![deny(unused_imports)] // gonna force myself to keep stuff clean
|
// #![deny(unused_imports)] // gonna force myself to keep stuff clean
|
||||||
#![warn(clippy::unwrap_used)]
|
#![warn(clippy::unwrap_used)]
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
|
@ -11,7 +11,7 @@ use smithay::{
|
||||||
take_presentation_feedback_surface_tree, under_from_surface_tree,
|
take_presentation_feedback_surface_tree, under_from_surface_tree,
|
||||||
with_surfaces_surface_tree, OutputPresentationFeedback,
|
with_surfaces_surface_tree, OutputPresentationFeedback,
|
||||||
},
|
},
|
||||||
Space, Window, WindowSurfaceType,
|
Window, WindowSurfaceType,
|
||||||
},
|
},
|
||||||
input::{
|
input::{
|
||||||
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
|
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
|
||||||
|
@ -23,7 +23,7 @@ use smithay::{
|
||||||
wayland_protocols::wp::presentation_time::server::wp_presentation_feedback,
|
wayland_protocols::wp::presentation_time::server::wp_presentation_feedback,
|
||||||
wayland_server::protocol::wl_surface::WlSurface,
|
wayland_server::protocol::wl_surface::WlSurface,
|
||||||
},
|
},
|
||||||
utils::{user_data::UserDataMap, IsAlive, Logical, Point, Rectangle, Serial, Size},
|
utils::{user_data::UserDataMap, IsAlive, Logical, Point, Rectangle, Serial},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::{self, Blocker, BlockerState, SurfaceData},
|
compositor::{self, Blocker, BlockerState, SurfaceData},
|
||||||
dmabuf::DmabufFeedback,
|
dmabuf::DmabufFeedback,
|
||||||
|
|
Loading…
Reference in a new issue