mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-13 08:01:05 +01:00
Take snapshot on foreign toplevel tag change
This commit is contained in:
parent
c0906974a4
commit
fc4dd9d62e
3 changed files with 136 additions and 114 deletions
116
src/handlers.rs
116
src/handlers.rs
|
@ -1,5 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
mod foreign_toplevel;
|
||||
pub mod idle;
|
||||
pub mod session_lock;
|
||||
pub mod window;
|
||||
|
@ -73,13 +74,12 @@ use tracing::{debug, error, trace, warn};
|
|||
|
||||
use crate::{
|
||||
backend::Backend,
|
||||
delegate_foreign_toplevel, delegate_gamma_control, delegate_output_management,
|
||||
delegate_output_power_management, delegate_screencopy,
|
||||
delegate_gamma_control, delegate_output_management, delegate_output_power_management,
|
||||
delegate_screencopy,
|
||||
focus::{keyboard::KeyboardFocusTarget, pointer::PointerFocusTarget},
|
||||
handlers::xdg_shell::snapshot_pre_commit_hook,
|
||||
output::OutputMode,
|
||||
protocol::{
|
||||
foreign_toplevel::{self, ForeignToplevelHandler, ForeignToplevelManagerState},
|
||||
gamma_control::{GammaControlHandler, GammaControlManagerState},
|
||||
output_management::{
|
||||
OutputConfiguration, OutputManagementHandler, OutputManagementManagerState,
|
||||
|
@ -591,7 +591,7 @@ delegate_shm!(State);
|
|||
|
||||
impl OutputHandler for State {
|
||||
fn output_bound(&mut self, output: Output, wl_output: WlOutput) {
|
||||
foreign_toplevel::on_output_bound(self, &output, &wl_output);
|
||||
crate::protocol::foreign_toplevel::on_output_bound(self, &output, &wl_output);
|
||||
}
|
||||
}
|
||||
delegate_output!(State);
|
||||
|
@ -817,114 +817,6 @@ impl PointerConstraintsHandler for State {
|
|||
}
|
||||
delegate_pointer_constraints!(State);
|
||||
|
||||
impl ForeignToplevelHandler for State {
|
||||
fn foreign_toplevel_manager_state(&mut self) -> &mut ForeignToplevelManagerState {
|
||||
&mut self.pinnacle.foreign_toplevel_manager_state
|
||||
}
|
||||
|
||||
fn activate(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
let Some(output) = window.output(&self.pinnacle) else {
|
||||
return;
|
||||
};
|
||||
|
||||
if !window.is_on_active_tag() {
|
||||
let new_active_tag =
|
||||
window.with_state(|state| state.tags.iter().min_by_key(|tag| tag.id().0).cloned());
|
||||
if let Some(tag) = new_active_tag {
|
||||
output.with_state(|state| {
|
||||
if state.tags.contains(&tag) {
|
||||
for op_tag in state.tags.iter() {
|
||||
op_tag.set_active(false, &mut self.pinnacle);
|
||||
}
|
||||
tag.set_active(true, &mut self.pinnacle);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
output.with_state_mut(|state| state.focus_stack.set_focus(window.clone()));
|
||||
self.pinnacle.raise_window(window, true);
|
||||
self.update_keyboard_focus(&output);
|
||||
|
||||
self.pinnacle.request_layout(&output);
|
||||
self.schedule_render(&output);
|
||||
}
|
||||
|
||||
fn close(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
window.close();
|
||||
}
|
||||
|
||||
fn set_fullscreen(&mut self, wl_surface: WlSurface, _wl_output: Option<WlOutput>) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.set_window_fullscreen(&window, true);
|
||||
}
|
||||
|
||||
fn unset_fullscreen(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.set_window_fullscreen(&window, false);
|
||||
}
|
||||
|
||||
fn set_maximized(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.set_window_maximized(&window, true);
|
||||
}
|
||||
|
||||
fn unset_maximized(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.set_window_maximized(&window, false);
|
||||
}
|
||||
|
||||
fn set_minimized(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
window.with_state_mut(|state| state.minimized = true);
|
||||
|
||||
let Some(output) = window.output(&self.pinnacle) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.pinnacle.request_layout(&output);
|
||||
self.schedule_render(&output);
|
||||
}
|
||||
|
||||
fn unset_minimized(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
window.with_state_mut(|state| state.minimized = false);
|
||||
|
||||
let Some(output) = window.output(&self.pinnacle) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.pinnacle.request_layout(&output);
|
||||
self.schedule_render(&output);
|
||||
}
|
||||
}
|
||||
delegate_foreign_toplevel!(State);
|
||||
|
||||
impl XWaylandShellHandler for State {
|
||||
fn xwayland_shell_state(&mut self) -> &mut XWaylandShellState {
|
||||
&mut self.pinnacle.xwayland_shell_state
|
||||
|
|
130
src/handlers/foreign_toplevel.rs
Normal file
130
src/handlers/foreign_toplevel.rs
Normal file
|
@ -0,0 +1,130 @@
|
|||
use smithay::reexports::wayland_server::protocol::{wl_output::WlOutput, wl_surface::WlSurface};
|
||||
|
||||
use crate::{
|
||||
delegate_foreign_toplevel,
|
||||
protocol::foreign_toplevel::{ForeignToplevelHandler, ForeignToplevelManagerState},
|
||||
render::util::snapshot::capture_snapshots_on_output,
|
||||
state::{State, WithState},
|
||||
};
|
||||
|
||||
impl ForeignToplevelHandler for State {
|
||||
fn foreign_toplevel_manager_state(&mut self) -> &mut ForeignToplevelManagerState {
|
||||
&mut self.pinnacle.foreign_toplevel_manager_state
|
||||
}
|
||||
|
||||
fn activate(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
let Some(output) = window.output(&self.pinnacle) else {
|
||||
return;
|
||||
};
|
||||
|
||||
if !window.is_on_active_tag() {
|
||||
let new_active_tag =
|
||||
window.with_state(|state| state.tags.iter().min_by_key(|tag| tag.id().0).cloned());
|
||||
if let Some(tag) = new_active_tag {
|
||||
let snapshots = self.backend.with_renderer(|renderer| {
|
||||
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output, [])
|
||||
});
|
||||
|
||||
output.with_state(|state| {
|
||||
if state.tags.contains(&tag) {
|
||||
for op_tag in state.tags.iter() {
|
||||
op_tag.set_active(false, &mut self.pinnacle);
|
||||
}
|
||||
tag.set_active(true, &mut self.pinnacle);
|
||||
}
|
||||
});
|
||||
|
||||
if let Some((above, below)) = snapshots {
|
||||
output.with_state_mut(|state| {
|
||||
state.new_wait_layout_transaction(
|
||||
self.pinnacle.loop_handle.clone(),
|
||||
above,
|
||||
below,
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output.with_state_mut(|state| state.focus_stack.set_focus(window.clone()));
|
||||
self.pinnacle.raise_window(window, true);
|
||||
self.update_keyboard_focus(&output);
|
||||
|
||||
self.pinnacle.request_layout(&output);
|
||||
self.schedule_render(&output);
|
||||
}
|
||||
|
||||
fn close(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
window.close();
|
||||
}
|
||||
|
||||
fn set_fullscreen(&mut self, wl_surface: WlSurface, _wl_output: Option<WlOutput>) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.set_window_fullscreen(&window, true);
|
||||
}
|
||||
|
||||
fn unset_fullscreen(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.set_window_fullscreen(&window, false);
|
||||
}
|
||||
|
||||
fn set_maximized(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.set_window_maximized(&window, true);
|
||||
}
|
||||
|
||||
fn unset_maximized(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.set_window_maximized(&window, false);
|
||||
}
|
||||
|
||||
fn set_minimized(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
window.with_state_mut(|state| state.minimized = true);
|
||||
|
||||
let Some(output) = window.output(&self.pinnacle) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.pinnacle.request_layout(&output);
|
||||
self.schedule_render(&output);
|
||||
}
|
||||
|
||||
fn unset_minimized(&mut self, wl_surface: WlSurface) {
|
||||
let Some(window) = self.pinnacle.window_for_surface(&wl_surface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
window.with_state_mut(|state| state.minimized = false);
|
||||
|
||||
let Some(output) = window.output(&self.pinnacle) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.pinnacle.request_layout(&output);
|
||||
self.schedule_render(&output);
|
||||
}
|
||||
}
|
||||
delegate_foreign_toplevel!(State);
|
|
@ -17,7 +17,7 @@ use smithay::{
|
|||
},
|
||||
utils::{Physical, Point, Scale, Transform},
|
||||
};
|
||||
use tracing::error;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::layout::transaction::{LayoutSnapshot, SnapshotRenderElement, SnapshotTarget};
|
||||
use crate::render::texture::CommonTextureRenderElement;
|
||||
|
@ -84,7 +84,7 @@ impl<E: RenderElement<GlesRenderer>> RenderSnapshot<E> {
|
|||
) {
|
||||
Ok(tex) => tex,
|
||||
Err(err) => {
|
||||
error!("Failed to render to encompassing texture: {err}");
|
||||
debug!("Failed to render to encompassing texture: {err}");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue