Skip to content

Commit

Permalink
Take snapshot on foreign toplevel tag change
Browse files Browse the repository at this point in the history
  • Loading branch information
Ottatop committed Jun 18, 2024
1 parent c090697 commit fc4dd9d
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 114 deletions.
116 changes: 4 additions & 112 deletions src/handlers.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
130 changes: 130 additions & 0 deletions src/handlers/foreign_toplevel.rs
Original file line number Diff line number Diff line change
@@ -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);
4 changes: 2 additions & 2 deletions src/render/util/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
};
Expand Down

0 comments on commit fc4dd9d

Please sign in to comment.