mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-14 08:01:14 +01:00
Simplify snapshots at call-site
This commit is contained in:
parent
fe182fdfcb
commit
05b8196319
10 changed files with 147 additions and 280 deletions
49
src/api.rs
49
src/api.rs
|
@ -58,7 +58,6 @@ use crate::{
|
||||||
config::ConnectorSavedState,
|
config::ConnectorSavedState,
|
||||||
input::{KeybindData, ModifierMask},
|
input::{KeybindData, ModifierMask},
|
||||||
output::{OutputMode, OutputName},
|
output::{OutputMode, OutputName},
|
||||||
render::util::snapshot::capture_snapshots_on_output,
|
|
||||||
state::{State, WithState},
|
state::{State, WithState},
|
||||||
tag::{Tag, TagId},
|
tag::{Tag, TagId},
|
||||||
util::restore_nofile_rlimit,
|
util::restore_nofile_rlimit,
|
||||||
|
@ -803,9 +802,7 @@ impl tag_service_server::TagService for TagService {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let snapshots = state.backend.with_renderer(|renderer| {
|
state.capture_snapshots_on_output(&output, []);
|
||||||
capture_snapshots_on_output(&mut state.pinnacle, renderer, &output, [])
|
|
||||||
});
|
|
||||||
|
|
||||||
match set_or_toggle {
|
match set_or_toggle {
|
||||||
SetOrToggle::Set => tag.set_active(true, &mut state.pinnacle),
|
SetOrToggle::Set => tag.set_active(true, &mut state.pinnacle),
|
||||||
|
@ -816,17 +813,9 @@ impl tag_service_server::TagService for TagService {
|
||||||
|
|
||||||
state.pinnacle.fixup_xwayland_window_layering();
|
state.pinnacle.fixup_xwayland_window_layering();
|
||||||
|
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots {
|
state.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|op_state| {
|
|
||||||
op_state.new_wait_layout_transaction(
|
|
||||||
state.pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
state.pinnacle.request_layout(&output);
|
state.pinnacle.request_layout(&output);
|
||||||
|
|
||||||
state.update_keyboard_focus(&output);
|
state.update_keyboard_focus(&output);
|
||||||
state.schedule_render(&output);
|
state.schedule_render(&output);
|
||||||
})
|
})
|
||||||
|
@ -848,9 +837,7 @@ impl tag_service_server::TagService for TagService {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let snapshots = state.backend.with_renderer(|renderer| {
|
state.capture_snapshots_on_output(&output, []);
|
||||||
capture_snapshots_on_output(&mut state.pinnacle, renderer, &output, [])
|
|
||||||
});
|
|
||||||
|
|
||||||
output.with_state(|op_state| {
|
output.with_state(|op_state| {
|
||||||
for op_tag in op_state.tags.iter() {
|
for op_tag in op_state.tags.iter() {
|
||||||
|
@ -861,17 +848,9 @@ impl tag_service_server::TagService for TagService {
|
||||||
|
|
||||||
state.pinnacle.fixup_xwayland_window_layering();
|
state.pinnacle.fixup_xwayland_window_layering();
|
||||||
|
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots {
|
state.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|op_state| {
|
|
||||||
op_state.new_wait_layout_transaction(
|
|
||||||
state.pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
state.pinnacle.request_layout(&output);
|
state.pinnacle.request_layout(&output);
|
||||||
|
|
||||||
state.update_keyboard_focus(&output);
|
state.update_keyboard_focus(&output);
|
||||||
state.schedule_render(&output);
|
state.schedule_render(&output);
|
||||||
})
|
})
|
||||||
|
@ -1218,9 +1197,7 @@ impl output_service_server::OutputService for OutputService {
|
||||||
|
|
||||||
current_scale = f64::max(current_scale, 0.25);
|
current_scale = f64::max(current_scale, 0.25);
|
||||||
|
|
||||||
let snapshots = state.backend.with_renderer(|renderer| {
|
state.capture_snapshots_on_output(&output, []);
|
||||||
capture_snapshots_on_output(&mut state.pinnacle, renderer, &output, [])
|
|
||||||
});
|
|
||||||
|
|
||||||
state.pinnacle.change_output_state(
|
state.pinnacle.change_output_state(
|
||||||
&mut state.backend,
|
&mut state.backend,
|
||||||
|
@ -1231,17 +1208,9 @@ impl output_service_server::OutputService for OutputService {
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots {
|
state.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|op_state| {
|
|
||||||
op_state.new_wait_layout_transaction(
|
|
||||||
state.pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
state.pinnacle.request_layout(&output);
|
state.pinnacle.request_layout(&output);
|
||||||
|
|
||||||
state.schedule_render(&output);
|
state.schedule_render(&output);
|
||||||
state
|
state
|
||||||
.pinnacle
|
.pinnacle
|
||||||
|
|
|
@ -21,10 +21,7 @@ use smithay::{
|
||||||
use tonic::{Request, Response, Status};
|
use tonic::{Request, Response, Status};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
use crate::{
|
use crate::{output::OutputName, state::WithState, tag::TagId, window::window_state::WindowId};
|
||||||
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};
|
use super::{run_unary, run_unary_no_response, StateFnSender};
|
||||||
|
|
||||||
|
@ -220,16 +217,15 @@ impl window_service_server::WindowService for WindowService {
|
||||||
}
|
}
|
||||||
|
|
||||||
run_unary_no_response(&self.sender, move |state| {
|
run_unary_no_response(&self.sender, move |state| {
|
||||||
let pinnacle = &mut state.pinnacle;
|
let Some(window) = window_id.window(&state.pinnacle) else {
|
||||||
let Some(window) = window_id.window(pinnacle) else {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let snapshots = window.output(pinnacle).map(|output| {
|
let output = window.output(&state.pinnacle);
|
||||||
state.backend.with_renderer(|renderer| {
|
|
||||||
capture_snapshots_on_output(pinnacle, renderer, &output, [window.clone()])
|
if let Some(output) = output.as_ref() {
|
||||||
})
|
state.capture_snapshots_on_output(output, [window.clone()]);
|
||||||
});
|
}
|
||||||
|
|
||||||
match set_or_toggle {
|
match set_or_toggle {
|
||||||
SetOrToggle::Set => {
|
SetOrToggle::Set => {
|
||||||
|
@ -246,21 +242,13 @@ impl window_service_server::WindowService for WindowService {
|
||||||
SetOrToggle::Unspecified => unreachable!(),
|
SetOrToggle::Unspecified => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(output) = window.output(pinnacle) else {
|
let Some(output) = output else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots.flatten() {
|
state.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|op_state| {
|
state.pinnacle.request_layout(&output);
|
||||||
op_state.new_wait_layout_transaction(
|
|
||||||
pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pinnacle.request_layout(&output);
|
|
||||||
state.schedule_render(&output);
|
state.schedule_render(&output);
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
@ -362,37 +350,29 @@ impl window_service_server::WindowService for WindowService {
|
||||||
);
|
);
|
||||||
|
|
||||||
run_unary_no_response(&self.sender, move |state| {
|
run_unary_no_response(&self.sender, move |state| {
|
||||||
let pinnacle = &mut state.pinnacle;
|
let Some(window) = window_id.window(&state.pinnacle) else {
|
||||||
|
|
||||||
let Some(window) = window_id.window(pinnacle) else {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(tag) = tag_id.tag(pinnacle) else { return };
|
let Some(tag) = tag_id.tag(&state.pinnacle) else { return };
|
||||||
|
|
||||||
let snapshots = window.output(pinnacle).map(|output| {
|
let output = window.output(&state.pinnacle);
|
||||||
state.backend.with_renderer(|renderer| {
|
|
||||||
capture_snapshots_on_output(pinnacle, renderer, &output, [window.clone()])
|
if let Some(output) = output.as_ref() {
|
||||||
})
|
state.capture_snapshots_on_output(output, [window.clone()]);
|
||||||
});
|
}
|
||||||
|
|
||||||
window.with_state_mut(|state| {
|
window.with_state_mut(|state| {
|
||||||
state.tags = vec![tag.clone()];
|
state.tags = vec![tag.clone()];
|
||||||
});
|
});
|
||||||
|
|
||||||
let Some(output) = tag.output(pinnacle) else { return };
|
let Some(output) = tag.output(&state.pinnacle) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots.flatten() {
|
state.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|op_state| {
|
state.pinnacle.request_layout(&output);
|
||||||
op_state.new_wait_layout_transaction(
|
|
||||||
pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pinnacle.request_layout(&output);
|
|
||||||
state.schedule_render(&output);
|
state.schedule_render(&output);
|
||||||
|
|
||||||
state.pinnacle.fixup_xwayland_window_layering();
|
state.pinnacle.fixup_xwayland_window_layering();
|
||||||
|
@ -422,17 +402,16 @@ impl window_service_server::WindowService for WindowService {
|
||||||
}
|
}
|
||||||
|
|
||||||
run_unary_no_response(&self.sender, move |state| {
|
run_unary_no_response(&self.sender, move |state| {
|
||||||
let pinnacle = &mut state.pinnacle;
|
let Some(window) = window_id.window(&state.pinnacle) else {
|
||||||
let Some(window) = window_id.window(pinnacle) else {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(tag) = tag_id.tag(pinnacle) else { return };
|
let Some(tag) = tag_id.tag(&state.pinnacle) else { return };
|
||||||
|
|
||||||
let snapshots = window.output(pinnacle).map(|output| {
|
let output = window.output(&state.pinnacle);
|
||||||
state.backend.with_renderer(|renderer| {
|
|
||||||
capture_snapshots_on_output(pinnacle, renderer, &output, [window.clone()])
|
if let Some(output) = output.as_ref() {
|
||||||
})
|
state.capture_snapshots_on_output(output, [window.clone()]);
|
||||||
});
|
}
|
||||||
|
|
||||||
// TODO: turn state.tags into a hashset
|
// TODO: turn state.tags into a hashset
|
||||||
match set_or_toggle {
|
match set_or_toggle {
|
||||||
|
@ -453,19 +432,13 @@ impl window_service_server::WindowService for WindowService {
|
||||||
SetOrToggle::Unspecified => unreachable!(),
|
SetOrToggle::Unspecified => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(output) = tag.output(pinnacle) else { return };
|
let Some(output) = tag.output(&state.pinnacle) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots.flatten() {
|
state.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|op_state| {
|
state.pinnacle.request_layout(&output);
|
||||||
op_state.new_wait_layout_transaction(
|
|
||||||
pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pinnacle.request_layout(&output);
|
|
||||||
state.schedule_render(&output);
|
state.schedule_render(&output);
|
||||||
|
|
||||||
state.pinnacle.fixup_xwayland_window_layering();
|
state.pinnacle.fixup_xwayland_window_layering();
|
||||||
|
|
|
@ -87,7 +87,6 @@ use crate::{
|
||||||
output_power_management::{OutputPowerManagementHandler, OutputPowerManagementState},
|
output_power_management::{OutputPowerManagementHandler, OutputPowerManagementState},
|
||||||
screencopy::{Screencopy, ScreencopyHandler},
|
screencopy::{Screencopy, ScreencopyHandler},
|
||||||
},
|
},
|
||||||
render::util::snapshot::capture_snapshots_on_output,
|
|
||||||
state::{ClientState, Pinnacle, State, WithState},
|
state::{ClientState, Pinnacle, State, WithState},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -188,20 +187,18 @@ impl CompositorHandler for State {
|
||||||
.with_state_mut(|state| state.snapshot_hook_id = Some(hook_id));
|
.with_state_mut(|state| state.snapshot_hook_id = Some(hook_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
let snapshots = if let Some(output) = self.pinnacle.focused_output().cloned() {
|
let output = self.pinnacle.focused_output().cloned();
|
||||||
|
|
||||||
|
if let Some(output) = output.as_ref() {
|
||||||
tracing::debug!("Placing toplevel");
|
tracing::debug!("Placing toplevel");
|
||||||
unmapped_window.place_on_output(&output);
|
unmapped_window.place_on_output(output);
|
||||||
|
|
||||||
output.with_state_mut(|state| {
|
output.with_state_mut(|state| {
|
||||||
state.focus_stack.set_focus(unmapped_window.clone())
|
state.focus_stack.set_focus(unmapped_window.clone())
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(self.backend.with_renderer(|renderer| {
|
self.capture_snapshots_on_output(output, []);
|
||||||
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output, [])
|
}
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
self.pinnacle
|
self.pinnacle
|
||||||
.unmapped_windows
|
.unmapped_windows
|
||||||
|
@ -212,21 +209,12 @@ impl CompositorHandler for State {
|
||||||
|
|
||||||
self.pinnacle.apply_window_rules(&unmapped_window);
|
self.pinnacle.apply_window_rules(&unmapped_window);
|
||||||
|
|
||||||
if let Some(focused_output) = self.pinnacle.focused_output().cloned() {
|
if let Some(focused_output) = output {
|
||||||
if unmapped_window.is_on_active_tag() {
|
if unmapped_window.is_on_active_tag() {
|
||||||
self.update_keyboard_focus(&focused_output);
|
self.update_keyboard_focus(&focused_output);
|
||||||
|
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) =
|
self.pinnacle.begin_layout_transaction(&focused_output);
|
||||||
snapshots.flatten()
|
self.pinnacle.request_layout(&focused_output);
|
||||||
{
|
|
||||||
focused_output.with_state_mut(|state| {
|
|
||||||
state.new_wait_layout_transaction(
|
|
||||||
self.pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// It seems wlcs needs immediate frame sends for client tests to work
|
// It seems wlcs needs immediate frame sends for client tests to work
|
||||||
#[cfg(feature = "testing")]
|
#[cfg(feature = "testing")]
|
||||||
|
@ -236,8 +224,6 @@ impl CompositorHandler for State {
|
||||||
Some(std::time::Duration::ZERO),
|
Some(std::time::Duration::ZERO),
|
||||||
|_, _| None,
|
|_, _| None,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.pinnacle.request_layout(&focused_output);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -269,30 +255,16 @@ impl CompositorHandler for State {
|
||||||
compositor::remove_pre_commit_hook(surface, hook_id);
|
compositor::remove_pre_commit_hook(surface, hook_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(output) = window.output(&self.pinnacle) {
|
let output = window.output(&self.pinnacle);
|
||||||
let snapshots = self.backend.with_renderer(|renderer| {
|
|
||||||
capture_snapshots_on_output(
|
|
||||||
&mut self.pinnacle,
|
|
||||||
renderer,
|
|
||||||
&output,
|
|
||||||
[],
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots {
|
if let Some(output) = output.as_ref() {
|
||||||
output.with_state_mut(|op_state| {
|
self.capture_snapshots_on_output(output, []);
|
||||||
op_state.new_wait_layout_transaction(
|
self.pinnacle.begin_layout_transaction(output);
|
||||||
self.pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pinnacle.remove_window(&window, true);
|
self.pinnacle.remove_window(&window, true);
|
||||||
|
|
||||||
if let Some(output) = window.output(&self.pinnacle) {
|
if let Some(output) = output {
|
||||||
self.update_keyboard_focus(&output);
|
self.update_keyboard_focus(&output);
|
||||||
self.pinnacle.request_layout(&output);
|
self.pinnacle.request_layout(&output);
|
||||||
}
|
}
|
||||||
|
@ -848,11 +820,7 @@ impl OutputManagementHandler for State {
|
||||||
// TODO: split
|
// TODO: split
|
||||||
self.backend.set_output_powered(&output, true);
|
self.backend.set_output_powered(&output, true);
|
||||||
|
|
||||||
self.schedule_render(&output);
|
self.capture_snapshots_on_output(&output, []);
|
||||||
|
|
||||||
let snapshots = self.backend.with_renderer(|renderer| {
|
|
||||||
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output, [])
|
|
||||||
});
|
|
||||||
|
|
||||||
let mode = mode.map(|(size, refresh)| {
|
let mode = mode.map(|(size, refresh)| {
|
||||||
if let Some(refresh) = refresh {
|
if let Some(refresh) = refresh {
|
||||||
|
@ -886,17 +854,10 @@ impl OutputManagementHandler for State {
|
||||||
position,
|
position,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some((a, b)) = snapshots {
|
self.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|state| {
|
|
||||||
state.new_wait_layout_transaction(
|
|
||||||
self.pinnacle.loop_handle.clone(),
|
|
||||||
a,
|
|
||||||
b,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.pinnacle.request_layout(&output);
|
self.pinnacle.request_layout(&output);
|
||||||
|
|
||||||
|
self.schedule_render(&output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ use smithay::reexports::wayland_server::protocol::{wl_output::WlOutput, wl_surfa
|
||||||
use crate::{
|
use crate::{
|
||||||
delegate_foreign_toplevel,
|
delegate_foreign_toplevel,
|
||||||
protocol::foreign_toplevel::{ForeignToplevelHandler, ForeignToplevelManagerState},
|
protocol::foreign_toplevel::{ForeignToplevelHandler, ForeignToplevelManagerState},
|
||||||
render::util::snapshot::capture_snapshots_on_output,
|
|
||||||
state::{State, WithState},
|
state::{State, WithState},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,10 +22,9 @@ impl ForeignToplevelHandler for State {
|
||||||
if !window.is_on_active_tag() {
|
if !window.is_on_active_tag() {
|
||||||
let new_active_tag =
|
let new_active_tag =
|
||||||
window.with_state(|state| state.tags.iter().min_by_key(|tag| tag.id().0).cloned());
|
window.with_state(|state| state.tags.iter().min_by_key(|tag| tag.id().0).cloned());
|
||||||
|
|
||||||
if let Some(tag) = new_active_tag {
|
if let Some(tag) = new_active_tag {
|
||||||
let snapshots = self.backend.with_renderer(|renderer| {
|
self.capture_snapshots_on_output(&output, []);
|
||||||
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output, [])
|
|
||||||
});
|
|
||||||
|
|
||||||
output.with_state(|state| {
|
output.with_state(|state| {
|
||||||
if state.tags.contains(&tag) {
|
if state.tags.contains(&tag) {
|
||||||
|
@ -37,15 +35,8 @@ impl ForeignToplevelHandler for State {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some((above, below)) = snapshots {
|
self.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|state| {
|
self.pinnacle.request_layout(&output);
|
||||||
state.new_wait_layout_transaction(
|
|
||||||
self.pinnacle.loop_handle.clone(),
|
|
||||||
above,
|
|
||||||
below,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +44,6 @@ impl ForeignToplevelHandler for State {
|
||||||
self.pinnacle.raise_window(window, true);
|
self.pinnacle.raise_window(window, true);
|
||||||
self.update_keyboard_focus(&output);
|
self.update_keyboard_focus(&output);
|
||||||
|
|
||||||
self.pinnacle.request_layout(&output);
|
|
||||||
self.schedule_render(&output);
|
self.schedule_render(&output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
render::util::snapshot::capture_snapshots_on_output,
|
|
||||||
state::{State, WithState},
|
state::{State, WithState},
|
||||||
window::WindowElement,
|
window::WindowElement,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub fn set_window_maximized(&mut self, window: &WindowElement, maximized: bool) {
|
pub fn set_window_maximized(&mut self, window: &WindowElement, maximized: bool) {
|
||||||
let snapshots = window.output(&self.pinnacle).map(|output| {
|
let output = window.output(&self.pinnacle);
|
||||||
self.backend.with_renderer(|renderer| {
|
if let Some(output) = output.as_ref() {
|
||||||
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output, [window.clone()])
|
self.capture_snapshots_on_output(output, [window.clone()]);
|
||||||
})
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if maximized {
|
if maximized {
|
||||||
if !window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) {
|
if !window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) {
|
||||||
|
@ -20,28 +18,19 @@ impl State {
|
||||||
window.toggle_maximized();
|
window.toggle_maximized();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(output) = window.output(&self.pinnacle) {
|
if let Some(output) = output {
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots.flatten() {
|
self.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|op_state| {
|
|
||||||
op_state.new_wait_layout_transaction(
|
|
||||||
self.pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.pinnacle.request_layout(&output);
|
self.pinnacle.request_layout(&output);
|
||||||
|
|
||||||
self.schedule_render(&output);
|
self.schedule_render(&output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_window_fullscreen(&mut self, window: &WindowElement, fullscreen: bool) {
|
pub fn set_window_fullscreen(&mut self, window: &WindowElement, fullscreen: bool) {
|
||||||
let snapshots = window.output(&self.pinnacle).map(|output| {
|
let output = window.output(&self.pinnacle);
|
||||||
self.backend.with_renderer(|renderer| {
|
if let Some(output) = output.as_ref() {
|
||||||
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output, [window.clone()])
|
self.capture_snapshots_on_output(output, [window.clone()]);
|
||||||
})
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if fullscreen {
|
if fullscreen {
|
||||||
if !window.with_state(|state| state.fullscreen_or_maximized.is_fullscreen()) {
|
if !window.with_state(|state| state.fullscreen_or_maximized.is_fullscreen()) {
|
||||||
|
@ -52,17 +41,9 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(output) = window.output(&self.pinnacle) {
|
if let Some(output) = window.output(&self.pinnacle) {
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots.flatten() {
|
self.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|op_state| {
|
|
||||||
op_state.new_wait_layout_transaction(
|
|
||||||
self.pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.pinnacle.request_layout(&output);
|
self.pinnacle.request_layout(&output);
|
||||||
|
|
||||||
self.schedule_render(&output);
|
self.schedule_render(&output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ use tracing::trace;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
focus::keyboard::KeyboardFocusTarget,
|
focus::keyboard::KeyboardFocusTarget,
|
||||||
render::util::snapshot::capture_snapshots_on_output,
|
|
||||||
state::{State, WithState},
|
state::{State, WithState},
|
||||||
window::WindowElement,
|
window::WindowElement,
|
||||||
};
|
};
|
||||||
|
@ -55,36 +54,19 @@ impl XdgShellHandler for State {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let snapshots = if let Some(output) = window.output(&self.pinnacle) {
|
let output = window.output(&self.pinnacle);
|
||||||
self.backend.with_renderer(|renderer| {
|
|
||||||
Some(capture_snapshots_on_output(
|
if let Some(output) = output.as_ref() {
|
||||||
&mut self.pinnacle,
|
self.capture_snapshots_on_output(output, []);
|
||||||
renderer,
|
}
|
||||||
&output,
|
|
||||||
[],
|
|
||||||
))
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
self.pinnacle.remove_window(&window, false);
|
self.pinnacle.remove_window(&window, false);
|
||||||
|
|
||||||
if let Some(output) = window.output(&self.pinnacle) {
|
if let Some(output) = output {
|
||||||
|
self.pinnacle.begin_layout_transaction(&output);
|
||||||
self.pinnacle.request_layout(&output);
|
self.pinnacle.request_layout(&output);
|
||||||
|
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots.flatten() {
|
|
||||||
output.with_state_mut(|state| {
|
|
||||||
state.new_wait_layout_transaction(
|
|
||||||
self.pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.update_keyboard_focus(&output);
|
self.update_keyboard_focus(&output);
|
||||||
|
|
||||||
self.schedule_render(&output);
|
self.schedule_render(&output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ use tracing::{debug, error, trace, warn};
|
||||||
use crate::{
|
use crate::{
|
||||||
cursor::Cursor,
|
cursor::Cursor,
|
||||||
focus::keyboard::KeyboardFocusTarget,
|
focus::keyboard::KeyboardFocusTarget,
|
||||||
render::util::snapshot::capture_snapshots_on_output,
|
|
||||||
state::{Pinnacle, State, WithState},
|
state::{Pinnacle, State, WithState},
|
||||||
window::{window_state::FloatingOrTiled, WindowElement},
|
window::{window_state::FloatingOrTiled, WindowElement},
|
||||||
};
|
};
|
||||||
|
@ -102,13 +101,11 @@ impl XwmHandler for State {
|
||||||
|
|
||||||
// TODO: do snapshot and transaction here BUT ONLY IF TILED AND ON ACTIVE TAG
|
// TODO: do snapshot and transaction here BUT ONLY IF TILED AND ON ACTIVE TAG
|
||||||
|
|
||||||
let snapshots = if let Some(output) = window.output(&self.pinnacle) {
|
let output = window.output(&self.pinnacle);
|
||||||
Some(self.backend.with_renderer(|renderer| {
|
|
||||||
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output, [])
|
if let Some(output) = output.as_ref() {
|
||||||
}))
|
self.capture_snapshots_on_output(output, []);
|
||||||
} else {
|
}
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
self.pinnacle.windows.push(window.clone());
|
self.pinnacle.windows.push(window.clone());
|
||||||
self.pinnacle.raise_window(window.clone(), true);
|
self.pinnacle.raise_window(window.clone(), true);
|
||||||
|
@ -116,20 +113,11 @@ impl XwmHandler for State {
|
||||||
self.pinnacle.apply_window_rules(&window);
|
self.pinnacle.apply_window_rules(&window);
|
||||||
|
|
||||||
if window.is_on_active_tag() {
|
if window.is_on_active_tag() {
|
||||||
if let Some(output) = window.output(&self.pinnacle) {
|
if let Some(output) = output {
|
||||||
output.with_state_mut(|state| state.focus_stack.set_focus(window.clone()));
|
output.with_state_mut(|state| state.focus_stack.set_focus(window.clone()));
|
||||||
self.update_keyboard_focus(&output);
|
self.update_keyboard_focus(&output);
|
||||||
|
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots.flatten() {
|
self.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|state| {
|
|
||||||
state.new_wait_layout_transaction(
|
|
||||||
self.pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.pinnacle.request_layout(&output);
|
self.pinnacle.request_layout(&output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,27 +409,20 @@ impl State {
|
||||||
if let Some(win) = win {
|
if let Some(win) = win {
|
||||||
debug!("removing x11 window from windows");
|
debug!("removing x11 window from windows");
|
||||||
|
|
||||||
let snapshots = win.output(&self.pinnacle).map(|output| {
|
let output = win.output(&self.pinnacle);
|
||||||
self.backend.with_renderer(|renderer| {
|
|
||||||
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output, [])
|
if let Some(output) = output.as_ref() {
|
||||||
})
|
self.capture_snapshots_on_output(output, []);
|
||||||
});
|
}
|
||||||
|
|
||||||
self.pinnacle.remove_window(&win, false);
|
self.pinnacle.remove_window(&win, false);
|
||||||
|
|
||||||
if let Some(output) = win.output(&self.pinnacle) {
|
if let Some(output) = win.output(&self.pinnacle) {
|
||||||
if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots.flatten() {
|
self.pinnacle.begin_layout_transaction(&output);
|
||||||
output.with_state_mut(|state| {
|
|
||||||
state.new_wait_layout_transaction(
|
|
||||||
self.pinnacle.loop_handle.clone(),
|
|
||||||
fs_and_up_snapshots,
|
|
||||||
under_fs_snapshots,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.pinnacle.request_layout(&output);
|
self.pinnacle.request_layout(&output);
|
||||||
|
|
||||||
self.update_keyboard_focus(&output);
|
self.update_keyboard_focus(&output);
|
||||||
|
// FIXME: schedule renders on all the outputs this window intersected
|
||||||
self.schedule_render(&output);
|
self.schedule_render(&output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ use tracing::warn;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
output::OutputName,
|
output::OutputName,
|
||||||
render::util::snapshot::capture_snapshots_on_output,
|
|
||||||
state::{Pinnacle, State, WithState},
|
state::{Pinnacle, State, WithState},
|
||||||
window::{
|
window::{
|
||||||
window_state::{FloatingOrTiled, FullscreenOrMaximized},
|
window_state::{FloatingOrTiled, FullscreenOrMaximized},
|
||||||
|
@ -278,9 +277,7 @@ impl State {
|
||||||
.fulfilled_requests
|
.fulfilled_requests
|
||||||
.insert(output.clone(), current_pending);
|
.insert(output.clone(), current_pending);
|
||||||
|
|
||||||
let snapshots = self.backend.with_renderer(|renderer| {
|
self.capture_snapshots_on_output(&output, []);
|
||||||
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output, [])
|
|
||||||
});
|
|
||||||
|
|
||||||
let pending_windows = self
|
let pending_windows = self
|
||||||
.pinnacle
|
.pinnacle
|
||||||
|
@ -289,11 +286,11 @@ impl State {
|
||||||
output.with_state_mut(|state| {
|
output.with_state_mut(|state| {
|
||||||
if let Some(ts) = state.layout_transaction.as_mut() {
|
if let Some(ts) = state.layout_transaction.as_mut() {
|
||||||
ts.update_pending(pending_windows);
|
ts.update_pending(pending_windows);
|
||||||
} else if let Some((fs_and_up_snapshots, under_fs_snapshots)) = snapshots {
|
} else {
|
||||||
state.layout_transaction = Some(LayoutTransaction::new(
|
state.layout_transaction = Some(LayoutTransaction::new(
|
||||||
self.pinnacle.loop_handle.clone(),
|
self.pinnacle.loop_handle.clone(),
|
||||||
fs_and_up_snapshots,
|
std::mem::take(&mut state.snapshots.fullscreen_and_above),
|
||||||
under_fs_snapshots,
|
std::mem::take(&mut state.snapshots.under_fullscreen),
|
||||||
pending_windows,
|
pending_windows,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ use crate::{
|
||||||
focus::WindowKeyboardFocusStack,
|
focus::WindowKeyboardFocusStack,
|
||||||
layout::transaction::{LayoutTransaction, SnapshotTarget},
|
layout::transaction::{LayoutTransaction, SnapshotTarget},
|
||||||
protocol::screencopy::Screencopy,
|
protocol::screencopy::Screencopy,
|
||||||
|
render::util::snapshot::OutputSnapshots,
|
||||||
state::{Pinnacle, State, WithState},
|
state::{Pinnacle, State, WithState},
|
||||||
tag::Tag,
|
tag::Tag,
|
||||||
window::window_state::FloatingOrTiled,
|
window::window_state::FloatingOrTiled,
|
||||||
|
@ -71,6 +72,7 @@ pub struct OutputState {
|
||||||
/// Unpowered monitors aren't drawn to but their tags and windows
|
/// Unpowered monitors aren't drawn to but their tags and windows
|
||||||
/// still exist and can be interacted with.
|
/// still exist and can be interacted with.
|
||||||
pub powered: bool,
|
pub powered: bool,
|
||||||
|
pub snapshots: OutputSnapshots,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for OutputState {
|
impl Default for OutputState {
|
||||||
|
@ -85,6 +87,7 @@ impl Default for OutputState {
|
||||||
blanking_state: Default::default(),
|
blanking_state: Default::default(),
|
||||||
layout_transaction: Default::default(),
|
layout_transaction: Default::default(),
|
||||||
powered: true,
|
powered: true,
|
||||||
|
snapshots: OutputSnapshots::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +123,7 @@ impl OutputState {
|
||||||
self.tags.iter().filter(|tag| tag.active())
|
self.tags.iter().filter(|tag| tag.active())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_wait_layout_transaction(
|
fn new_wait_layout_transaction(
|
||||||
&mut self,
|
&mut self,
|
||||||
loop_handle: LoopHandle<'static, State>,
|
loop_handle: LoopHandle<'static, State>,
|
||||||
fullscreen_and_up_snapshots: impl IntoIterator<Item = SnapshotTarget>,
|
fullscreen_and_up_snapshots: impl IntoIterator<Item = SnapshotTarget>,
|
||||||
|
@ -138,6 +141,18 @@ impl OutputState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Pinnacle {
|
||||||
|
pub fn begin_layout_transaction(&self, output: &Output) {
|
||||||
|
output.with_state_mut(|state| {
|
||||||
|
let (fullscreen_and_up, under) = (
|
||||||
|
std::mem::take(&mut state.snapshots.under_fullscreen),
|
||||||
|
std::mem::take(&mut state.snapshots.fullscreen_and_above),
|
||||||
|
);
|
||||||
|
state.new_wait_layout_transaction(self.loop_handle.clone(), fullscreen_and_up, under);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum OutputMode {
|
pub enum OutputMode {
|
||||||
Smithay(Mode),
|
Smithay(Mode),
|
||||||
|
|
|
@ -22,7 +22,7 @@ use tracing::debug;
|
||||||
use crate::layout::transaction::{LayoutSnapshot, SnapshotRenderElement, SnapshotTarget};
|
use crate::layout::transaction::{LayoutSnapshot, SnapshotRenderElement, SnapshotTarget};
|
||||||
use crate::render::texture::CommonTextureRenderElement;
|
use crate::render::texture::CommonTextureRenderElement;
|
||||||
use crate::render::{AsGlesRenderer, PRenderer};
|
use crate::render::{AsGlesRenderer, PRenderer};
|
||||||
use crate::state::{Pinnacle, WithState};
|
use crate::state::{Pinnacle, State, WithState};
|
||||||
use crate::window::WindowElement;
|
use crate::window::WindowElement;
|
||||||
|
|
||||||
use super::{render_to_encompassing_texture, EncompassingTexture};
|
use super::{render_to_encompassing_texture, EncompassingTexture};
|
||||||
|
@ -149,18 +149,33 @@ impl WindowElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
/// Capture snapshots for all tiled windows on this output.
|
/// Capture snapshots for all tiled windows on this output.
|
||||||
///
|
///
|
||||||
/// Any windows in `also_include` are also included in the capture.
|
/// Any windows in `also_include` are also included in the capture.
|
||||||
///
|
pub fn capture_snapshots_on_output(
|
||||||
/// ret.1 = fullscreen and up,
|
&mut self,
|
||||||
/// ret.2 = under fullscreen
|
output: &Output,
|
||||||
|
also_include: impl IntoIterator<Item = WindowElement>,
|
||||||
|
) {
|
||||||
|
self.backend.with_renderer(|renderer| {
|
||||||
|
capture_snapshots_on_output(&mut self.pinnacle, renderer, output, also_include);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct OutputSnapshots {
|
||||||
|
pub fullscreen_and_above: Vec<SnapshotTarget>,
|
||||||
|
pub under_fullscreen: Vec<SnapshotTarget>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn capture_snapshots_on_output(
|
pub fn capture_snapshots_on_output(
|
||||||
pinnacle: &mut Pinnacle,
|
pinnacle: &mut Pinnacle,
|
||||||
renderer: &mut GlesRenderer,
|
renderer: &mut GlesRenderer,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
also_include: impl IntoIterator<Item = WindowElement>,
|
also_include: impl IntoIterator<Item = WindowElement>,
|
||||||
) -> (Vec<SnapshotTarget>, Vec<SnapshotTarget>) {
|
) {
|
||||||
let split_index = pinnacle
|
let split_index = pinnacle
|
||||||
.space
|
.space
|
||||||
.elements()
|
.elements()
|
||||||
|
@ -216,5 +231,8 @@ pub fn capture_snapshots_on_output(
|
||||||
.flat_map(&mut flat_map)
|
.flat_map(&mut flat_map)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
(fullscreen_and_up_snapshots, under_fullscreen_snapshots)
|
output.with_state_mut(|state| {
|
||||||
|
state.snapshots.fullscreen_and_above = fullscreen_and_up_snapshots;
|
||||||
|
state.snapshots.under_fullscreen = under_fullscreen_snapshots;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue