mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-25 09:59:21 +01:00
Get xwayland snapshots partially working
This commit is contained in:
parent
e6b18fcec2
commit
ff2b78f828
8 changed files with 121 additions and 27 deletions
24
src/api.rs
24
src/api.rs
|
@ -738,6 +738,14 @@ impl tag_service_server::TagService for TagService {
|
|||
return;
|
||||
};
|
||||
|
||||
let Some(output) = tag.output(&state.pinnacle) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let snapshots = state.backend.with_renderer(|renderer| {
|
||||
capture_snapshots_on_output(&mut state.pinnacle, renderer, &output)
|
||||
});
|
||||
|
||||
match set_or_toggle {
|
||||
SetOrToggle::Set => tag.set_active(true, state),
|
||||
SetOrToggle::Unset => tag.set_active(false, state),
|
||||
|
@ -745,12 +753,12 @@ impl tag_service_server::TagService for TagService {
|
|||
SetOrToggle::Unspecified => unreachable!(),
|
||||
}
|
||||
|
||||
let Some(output) = tag.output(&state.pinnacle) else {
|
||||
return;
|
||||
};
|
||||
|
||||
state.pinnacle.fixup_xwayland_window_layering();
|
||||
|
||||
output.with_state_mut(|op_state| {
|
||||
op_state.new_wait_layout_transaction(state.pinnacle.loop_handle.clone(), snapshots)
|
||||
});
|
||||
|
||||
state.pinnacle.request_layout(&output);
|
||||
state.update_keyboard_focus(&output);
|
||||
state.schedule_render(&output);
|
||||
|
@ -773,6 +781,10 @@ impl tag_service_server::TagService for TagService {
|
|||
return;
|
||||
};
|
||||
|
||||
let snapshots = state.backend.with_renderer(|renderer| {
|
||||
capture_snapshots_on_output(&mut state.pinnacle, renderer, &output)
|
||||
});
|
||||
|
||||
output.with_state(|op_state| {
|
||||
for op_tag in op_state.tags.iter() {
|
||||
op_tag.set_active(false, state);
|
||||
|
@ -782,6 +794,10 @@ impl tag_service_server::TagService for TagService {
|
|||
|
||||
state.pinnacle.fixup_xwayland_window_layering();
|
||||
|
||||
output.with_state_mut(|op_state| {
|
||||
op_state.new_wait_layout_transaction(state.pinnacle.loop_handle.clone(), snapshots)
|
||||
});
|
||||
|
||||
state.pinnacle.request_layout(&output);
|
||||
state.update_keyboard_focus(&output);
|
||||
state.schedule_render(&output);
|
||||
|
|
|
@ -21,7 +21,10 @@ use smithay::{
|
|||
use tonic::{Request, Response, Status};
|
||||
use tracing::warn;
|
||||
|
||||
use crate::{output::OutputName, state::WithState, tag::TagId, window::window_state::WindowId};
|
||||
use crate::{
|
||||
output::OutputName, render::util::snapshot::capture_snapshots_on_output, state::WithState,
|
||||
tag::TagId, window::window_state::WindowId,
|
||||
};
|
||||
|
||||
use super::{run_unary, run_unary_no_response, StateFnSender};
|
||||
|
||||
|
@ -136,6 +139,12 @@ impl window_service_server::WindowService for WindowService {
|
|||
return;
|
||||
};
|
||||
|
||||
let snapshots = window.output(pinnacle).map(|output| {
|
||||
state.backend.with_renderer(|renderer| {
|
||||
capture_snapshots_on_output(pinnacle, renderer, &output)
|
||||
})
|
||||
});
|
||||
|
||||
match set_or_toggle {
|
||||
SetOrToggle::Set => {
|
||||
if !window.with_state(|state| state.fullscreen_or_maximized.is_fullscreen()) {
|
||||
|
@ -155,6 +164,12 @@ impl window_service_server::WindowService for WindowService {
|
|||
return;
|
||||
};
|
||||
|
||||
if let Some(snapshots) = snapshots {
|
||||
output.with_state_mut(|op_state| {
|
||||
op_state.new_wait_layout_transaction(pinnacle.loop_handle.clone(), snapshots)
|
||||
});
|
||||
}
|
||||
|
||||
pinnacle.request_layout(&output);
|
||||
state.schedule_render(&output);
|
||||
})
|
||||
|
@ -185,6 +200,12 @@ impl window_service_server::WindowService for WindowService {
|
|||
return;
|
||||
};
|
||||
|
||||
let snapshots = window.output(pinnacle).map(|output| {
|
||||
state.backend.with_renderer(|renderer| {
|
||||
capture_snapshots_on_output(pinnacle, renderer, &output)
|
||||
})
|
||||
});
|
||||
|
||||
match set_or_toggle {
|
||||
SetOrToggle::Set => {
|
||||
if !window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) {
|
||||
|
@ -204,6 +225,12 @@ impl window_service_server::WindowService for WindowService {
|
|||
return;
|
||||
};
|
||||
|
||||
if let Some(snapshots) = snapshots {
|
||||
output.with_state_mut(|op_state| {
|
||||
op_state.new_wait_layout_transaction(pinnacle.loop_handle.clone(), snapshots)
|
||||
});
|
||||
}
|
||||
|
||||
pinnacle.request_layout(&output);
|
||||
state.schedule_render(&output);
|
||||
})
|
||||
|
@ -234,6 +261,12 @@ impl window_service_server::WindowService for WindowService {
|
|||
return;
|
||||
};
|
||||
|
||||
let snapshots = window.output(pinnacle).map(|output| {
|
||||
state.backend.with_renderer(|renderer| {
|
||||
capture_snapshots_on_output(pinnacle, renderer, &output)
|
||||
})
|
||||
});
|
||||
|
||||
match set_or_toggle {
|
||||
SetOrToggle::Set => {
|
||||
if !window.with_state(|state| state.floating_or_tiled.is_floating()) {
|
||||
|
@ -253,6 +286,12 @@ impl window_service_server::WindowService for WindowService {
|
|||
return;
|
||||
};
|
||||
|
||||
if let Some(snapshots) = snapshots {
|
||||
output.with_state_mut(|op_state| {
|
||||
op_state.new_wait_layout_transaction(pinnacle.loop_handle.clone(), snapshots)
|
||||
});
|
||||
}
|
||||
|
||||
pinnacle.request_layout(&output);
|
||||
state.schedule_render(&output);
|
||||
})
|
||||
|
@ -363,12 +402,24 @@ impl window_service_server::WindowService for WindowService {
|
|||
|
||||
let Some(tag) = tag_id.tag(pinnacle) else { return };
|
||||
|
||||
let snapshots = window.output(pinnacle).map(|output| {
|
||||
state.backend.with_renderer(|renderer| {
|
||||
capture_snapshots_on_output(pinnacle, renderer, &output)
|
||||
})
|
||||
});
|
||||
|
||||
window.with_state_mut(|state| {
|
||||
state.tags = vec![tag.clone()];
|
||||
});
|
||||
|
||||
let Some(output) = tag.output(pinnacle) else { return };
|
||||
|
||||
if let Some(snapshots) = snapshots {
|
||||
output.with_state_mut(|op_state| {
|
||||
op_state.new_wait_layout_transaction(pinnacle.loop_handle.clone(), snapshots)
|
||||
});
|
||||
}
|
||||
|
||||
pinnacle.request_layout(&output);
|
||||
state.schedule_render(&output);
|
||||
|
||||
|
@ -405,6 +456,12 @@ impl window_service_server::WindowService for WindowService {
|
|||
};
|
||||
let Some(tag) = tag_id.tag(pinnacle) else { return };
|
||||
|
||||
let snapshots = window.output(pinnacle).map(|output| {
|
||||
state.backend.with_renderer(|renderer| {
|
||||
capture_snapshots_on_output(pinnacle, renderer, &output)
|
||||
})
|
||||
});
|
||||
|
||||
// TODO: turn state.tags into a hashset
|
||||
match set_or_toggle {
|
||||
SetOrToggle::Set => window.with_state_mut(|state| {
|
||||
|
@ -425,6 +482,13 @@ impl window_service_server::WindowService for WindowService {
|
|||
}
|
||||
|
||||
let Some(output) = tag.output(pinnacle) else { return };
|
||||
|
||||
if let Some(snapshots) = snapshots {
|
||||
output.with_state_mut(|op_state| {
|
||||
op_state.new_wait_layout_transaction(pinnacle.loop_handle.clone(), snapshots)
|
||||
});
|
||||
}
|
||||
|
||||
pinnacle.request_layout(&output);
|
||||
state.schedule_render(&output);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use smithay::{desktop::space::SpaceElement, output::Output, utils::SERIAL_COUNTER};
|
||||
use tracing::warn;
|
||||
|
||||
use crate::{
|
||||
state::{Pinnacle, State, WithState},
|
||||
|
@ -77,14 +76,7 @@ impl Pinnacle {
|
|||
}
|
||||
|
||||
/// Raise a window to the top of the z-index stack.
|
||||
///
|
||||
/// This does nothing if the window is unmapped.
|
||||
pub fn raise_window(&mut self, window: WindowElement, activate: bool) {
|
||||
if self.space.elements().all(|win| win != window) {
|
||||
warn!("Tried to raise an unmapped window");
|
||||
return;
|
||||
}
|
||||
|
||||
self.space.raise_element(&window, activate);
|
||||
|
||||
self.z_index_stack.retain(|win| win != window);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
pub mod session_lock;
|
||||
pub mod window;
|
||||
mod xdg_shell;
|
||||
mod xwayland;
|
||||
|
||||
|
@ -32,7 +33,7 @@ use smithay::{
|
|||
Client, Resource,
|
||||
},
|
||||
},
|
||||
utils::{Logical, Point, Rectangle, SERIAL_COUNTER},
|
||||
utils::{Logical, Point, Rectangle},
|
||||
wayland::{
|
||||
buffer::BufferHandler,
|
||||
compositor::{
|
||||
|
@ -202,6 +203,8 @@ impl CompositorHandler for State {
|
|||
.retain(|win| win != unmapped_window);
|
||||
self.pinnacle.windows.push(unmapped_window.clone());
|
||||
|
||||
self.pinnacle.raise_window(unmapped_window.clone(), true);
|
||||
|
||||
self.pinnacle.apply_window_rules(&unmapped_window);
|
||||
|
||||
if let Some(focused_output) = self.pinnacle.focused_output().cloned() {
|
||||
|
|
1
src/handlers/window.rs
Normal file
1
src/handlers/window.rs
Normal file
|
@ -0,0 +1 @@
|
|||
|
|
@ -26,6 +26,7 @@ use tracing::{debug, error, trace, warn};
|
|||
use crate::{
|
||||
cursor::Cursor,
|
||||
focus::keyboard::KeyboardFocusTarget,
|
||||
render::util::snapshot::capture_snapshots_on_output,
|
||||
state::{Pinnacle, State, WithState},
|
||||
window::{window_state::FloatingOrTiled, WindowElement},
|
||||
};
|
||||
|
@ -104,7 +105,8 @@ impl XwmHandler for State {
|
|||
});
|
||||
}
|
||||
|
||||
// TODO: will an unmap -> map duplicate the window
|
||||
// TODO: do snapshot and transaction here BUT ONLY IF TILED AND ON ACTIVE TAG
|
||||
|
||||
self.pinnacle.windows.push(window.clone());
|
||||
self.pinnacle.raise_window(window.clone(), true);
|
||||
|
||||
|
@ -432,13 +434,27 @@ impl State {
|
|||
.iter()
|
||||
.find(|elem| elem.x11_surface() == Some(&surface))
|
||||
.cloned();
|
||||
|
||||
if let Some(win) = win {
|
||||
debug!("removing x11 window from windows");
|
||||
|
||||
let snapshots = win.output(&self.pinnacle).map(|output| {
|
||||
self.backend.with_renderer(|renderer| {
|
||||
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output)
|
||||
})
|
||||
});
|
||||
|
||||
self.pinnacle.remove_window(&win, false);
|
||||
|
||||
if let Some(output) = win.output(&self.pinnacle) {
|
||||
if let Some(snapshots) = snapshots {
|
||||
output.with_state_mut(|state| {
|
||||
state.new_wait_layout_transaction(
|
||||
self.pinnacle.loop_handle.clone(),
|
||||
snapshots,
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
self.pinnacle.request_layout(&output);
|
||||
self.update_keyboard_focus(&output);
|
||||
self.schedule_render(&output);
|
||||
|
|
|
@ -32,6 +32,9 @@ use crate::{
|
|||
window::WindowElement,
|
||||
};
|
||||
|
||||
/// The timeout before transactions stop applying.
|
||||
const TIMEOUT: Duration = Duration::from_millis(1000);
|
||||
|
||||
/// Type for window snapshots.
|
||||
pub type LayoutSnapshot = RenderSnapshot<WaylandSurfaceRenderElement<GlesRenderer>>;
|
||||
|
||||
|
@ -56,10 +59,10 @@ pub struct LayoutTransaction {
|
|||
}
|
||||
|
||||
impl LayoutTransaction {
|
||||
/// Schedule an event after the timeout to check for stuff.
|
||||
/// Schedule an event after the timeout to check for readiness.
|
||||
fn register_wakeup(loop_handle: &LoopHandle<'static, State>) {
|
||||
let _ = loop_handle.insert_source(
|
||||
Timer::from_duration(Duration::from_millis(150)),
|
||||
Timer::from_duration(TIMEOUT + Duration::from_millis(10)),
|
||||
|_, _, _| TimeoutAction::Drop,
|
||||
);
|
||||
}
|
||||
|
@ -117,12 +120,12 @@ impl LayoutTransaction {
|
|||
/// Returns whether all pending windows have committed their serials or the timeout has been
|
||||
/// reached.
|
||||
pub fn ready(&self) -> bool {
|
||||
Instant::now().duration_since(self.start_time) >= Duration::from_millis(150)
|
||||
|| (!self.wait
|
||||
&& self
|
||||
.pending_windows
|
||||
.iter()
|
||||
.all(|(win, serial)| win.is_serial_committed(*serial)))
|
||||
Instant::now().duration_since(self.start_time) >= TIMEOUT
|
||||
// || (!self.wait
|
||||
// && self
|
||||
// .pending_windows
|
||||
// .iter()
|
||||
// .all(|(win, serial)| win.is_serial_committed(*serial)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ impl WindowElement {
|
|||
alpha: f32,
|
||||
) {
|
||||
self.with_state_mut(|state| {
|
||||
if state.snapshot.is_none() {
|
||||
if state.snapshot.is_none() || self.is_x11() {
|
||||
let elements = self.render_elements(renderer, location, scale, alpha);
|
||||
state.snapshot = Some(RenderSnapshot::new(elements, scale));
|
||||
}
|
||||
|
@ -117,10 +117,9 @@ pub fn capture_snapshots_on_output(
|
|||
let windows_on_foc_tags = output.with_state(|state| {
|
||||
let focused_tags = state.focused_tags().collect::<Vec<_>>();
|
||||
pinnacle
|
||||
.windows
|
||||
.z_index_stack
|
||||
.iter()
|
||||
.rev()
|
||||
.filter(|win| !win.is_x11_override_redirect())
|
||||
.filter(|win| {
|
||||
win.with_state(|state| state.tags.iter().any(|tg| focused_tags.contains(&tg)))
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue