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
137
src/layout.rs
137
src/layout.rs
|
@ -1,8 +1,10 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use itertools::{Either, Itertools};
|
||||
use smithay::{
|
||||
desktop::layer_map_for_output,
|
||||
desktop::{layer_map_for_output, utils::surface_primary_scanout_output},
|
||||
output::Output,
|
||||
reexports::wayland_server::Resource,
|
||||
utils::{IsAlive, Logical, Point, Rectangle, Size},
|
||||
|
@ -57,7 +59,7 @@ impl State {
|
|||
|
||||
pub fn update_windows(&mut self, output: &Output) {
|
||||
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 };
|
||||
|
||||
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()));
|
||||
|
||||
let tiled_windows = windows_on_foc_tags
|
||||
|
@ -122,12 +125,19 @@ impl State {
|
|||
WindowElement::Wayland(win) => {
|
||||
// If the above didn't cause any change to size or other state, simply
|
||||
// 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;
|
||||
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 {
|
||||
tracing::debug!("Pending changes");
|
||||
let serial = win.toplevel().send_configure();
|
||||
state.loc_request_state =
|
||||
LocationRequestState::Requested(serial, loc);
|
||||
|
@ -149,62 +159,39 @@ impl State {
|
|||
});
|
||||
}
|
||||
|
||||
BLOCKER_COUNTER.store(1, std::sync::atomic::Ordering::SeqCst);
|
||||
tracing::debug!(
|
||||
"blocker {}",
|
||||
BLOCKER_COUNTER.load(std::sync::atomic::Ordering::SeqCst)
|
||||
);
|
||||
|
||||
let start_time = self.clock.now();
|
||||
// BLOCKER_COUNTER.store(1, std::sync::atomic::Ordering::SeqCst);
|
||||
// tracing::debug!(
|
||||
// "blocker {}",
|
||||
// BLOCKER_COUNTER.load(std::sync::atomic::Ordering::SeqCst)
|
||||
// );
|
||||
|
||||
// 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
|
||||
// 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.
|
||||
self.pause_rendering = true;
|
||||
|
||||
for (_loc, win) in pending_wins.iter() {
|
||||
if let Some(surf) = win.wl_surface() {
|
||||
tracing::debug!("adding blocker");
|
||||
compositor::add_blocker(&surf, crate::window::WindowBlocker);
|
||||
}
|
||||
}
|
||||
// for (_loc, win) in pending_wins.iter() {
|
||||
// if let Some(surf) = win.wl_surface() {
|
||||
// tracing::debug!("adding blocker");
|
||||
// compositor::add_blocker(&surf, crate::window::WindowBlocker);
|
||||
// }
|
||||
// }
|
||||
|
||||
let pending_wins_clone = pending_wins.clone();
|
||||
|
||||
self.schedule(
|
||||
move |_data| {
|
||||
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(
|
||||
self.schedule(
|
||||
move |_dt| {
|
||||
pending_wins
|
||||
// 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(|(_, win)| win.with_state(|state| state.loc_request_state.is_idle()));
|
||||
|
||||
all_idle
|
||||
},
|
||||
move |dt| {
|
||||
for (loc, win) in non_pending_wins {
|
||||
|
@ -214,16 +201,58 @@ impl State {
|
|||
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
|
||||
//! 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)]
|
||||
|
||||
use clap::Parser;
|
||||
|
|
|
@ -11,7 +11,7 @@ use smithay::{
|
|||
take_presentation_feedback_surface_tree, under_from_surface_tree,
|
||||
with_surfaces_surface_tree, OutputPresentationFeedback,
|
||||
},
|
||||
Space, Window, WindowSurfaceType,
|
||||
Window, WindowSurfaceType,
|
||||
},
|
||||
input::{
|
||||
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
|
||||
|
@ -23,7 +23,7 @@ use smithay::{
|
|||
wayland_protocols::wp::presentation_time::server::wp_presentation_feedback,
|
||||
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::{
|
||||
compositor::{self, Blocker, BlockerState, SurfaceData},
|
||||
dmabuf::DmabufFeedback,
|
||||
|
|
Loading…
Reference in a new issue