Get most things on the transaction system

This commit is contained in:
Ottatop 2024-05-24 19:55:34 -05:00 committed by Ottatop
parent ff2b78f828
commit 4f3d6513ca
5 changed files with 128 additions and 163 deletions

View file

@ -194,45 +194,26 @@ impl window_service_server::WindowService for WindowService {
return Err(Status::invalid_argument("unspecified set or toggle")); return Err(Status::invalid_argument("unspecified set or toggle"));
} }
let maximized = match set_or_toggle {
SetOrToggle::Set => Some(true),
SetOrToggle::Unset => Some(false),
SetOrToggle::Toggle => None,
SetOrToggle::Unspecified => unreachable!(),
};
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| { match maximized {
state.backend.with_renderer(|renderer| { Some(maximized) => state.set_window_maximized(&window, maximized),
capture_snapshots_on_output(pinnacle, renderer, &output) None => {
}) let is_maximized = window
}); .with_state(|win_state| win_state.fullscreen_or_maximized.is_maximized());
state.set_window_maximized(&window, !is_maximized);
match set_or_toggle {
SetOrToggle::Set => {
if !window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) {
window.toggle_maximized();
}
} }
SetOrToggle::Unset => {
if window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) {
window.toggle_maximized();
}
}
SetOrToggle::Toggle => window.toggle_maximized(),
SetOrToggle::Unspecified => unreachable!(),
} }
let Some(output) = window.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);
}) })
.await .await
} }
@ -255,45 +236,26 @@ impl window_service_server::WindowService for WindowService {
return Err(Status::invalid_argument("unspecified set or toggle")); return Err(Status::invalid_argument("unspecified set or toggle"));
} }
let fullscreen = match set_or_toggle {
SetOrToggle::Set => Some(true),
SetOrToggle::Unset => Some(false),
SetOrToggle::Toggle => None,
SetOrToggle::Unspecified => unreachable!(),
};
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| { match fullscreen {
state.backend.with_renderer(|renderer| { Some(fullscreen) => state.set_window_fullscreen(&window, fullscreen),
capture_snapshots_on_output(pinnacle, renderer, &output) None => {
}) let is_fullscreen = window
}); .with_state(|win_state| win_state.fullscreen_or_maximized.is_fullscreen());
state.set_window_fullscreen(&window, !is_fullscreen);
match set_or_toggle {
SetOrToggle::Set => {
if !window.with_state(|state| state.floating_or_tiled.is_floating()) {
window.toggle_floating();
}
} }
SetOrToggle::Unset => {
if window.with_state(|state| state.floating_or_tiled.is_floating()) {
window.toggle_floating();
}
}
SetOrToggle::Toggle => window.toggle_floating(),
SetOrToggle::Unspecified => unreachable!(),
} }
let Some(output) = window.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);
}) })
.await .await
} }

View file

@ -1 +1,63 @@
use crate::{
render::util::snapshot::capture_snapshots_on_output,
state::{State, WithState},
window::WindowElement,
};
impl State {
pub fn set_window_maximized(&mut self, window: &WindowElement, maximized: bool) {
let snapshots = window.output(&self.pinnacle).map(|output| {
self.backend.with_renderer(|renderer| {
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output)
})
});
if maximized {
if !window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) {
window.toggle_maximized();
}
} else if window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) {
window.toggle_maximized();
}
if let Some(output) = window.output(&self.pinnacle) {
if let Some(snapshots) = snapshots {
output.with_state_mut(|op_state| {
op_state
.new_wait_layout_transaction(self.pinnacle.loop_handle.clone(), snapshots)
});
}
self.pinnacle.request_layout(&output);
self.schedule_render(&output);
}
}
pub fn set_window_fullscreen(&mut self, window: &WindowElement, fullscreen: bool) {
let snapshots = window.output(&self.pinnacle).map(|output| {
self.backend.with_renderer(|renderer| {
capture_snapshots_on_output(&mut self.pinnacle, renderer, &output)
})
});
if fullscreen {
if !window.with_state(|state| state.fullscreen_or_maximized.is_fullscreen()) {
window.toggle_fullscreen();
}
} else if window.with_state(|state| state.fullscreen_or_maximized.is_fullscreen()) {
window.toggle_fullscreen();
}
if let Some(output) = window.output(&self.pinnacle) {
if let Some(snapshots) = snapshots {
output.with_state_mut(|op_state| {
op_state
.new_wait_layout_transaction(self.pinnacle.loop_handle.clone(), snapshots)
});
}
self.pinnacle.request_layout(&output);
self.schedule_render(&output);
}
}
}

View file

@ -235,53 +235,30 @@ impl XdgShellHandler for State {
} }
surface.with_pending_state(|state| { surface.with_pending_state(|state| {
state.states.set(xdg_toplevel::State::Fullscreen);
state.size = Some(geometry.size); state.size = Some(geometry.size);
state.fullscreen_output = wl_output; state.fullscreen_output = wl_output;
}); });
let Some(window) = self.pinnacle.window_for_surface(wl_surface) else { let Some(window) = self.pinnacle.window_for_surface(wl_surface) else {
tracing::error!("wl_surface had no window");
return; return;
}; };
if !window.with_state(|state| state.fullscreen_or_maximized.is_fullscreen()) { self.set_window_fullscreen(&window, true);
window.toggle_fullscreen();
self.pinnacle.request_layout(&output);
}
} }
surface.send_configure(); surface.send_configure();
} }
fn unfullscreen_request(&mut self, surface: ToplevelSurface) { fn unfullscreen_request(&mut self, surface: ToplevelSurface) {
if !surface
.current_state()
.states
.contains(xdg_toplevel::State::Fullscreen)
{
return;
}
surface.with_pending_state(|state| { surface.with_pending_state(|state| {
state.states.unset(xdg_toplevel::State::Fullscreen);
state.size = None;
state.fullscreen_output.take(); state.fullscreen_output.take();
}); });
surface.send_pending_configure();
let Some(window) = self.pinnacle.window_for_surface(surface.wl_surface()) else { let Some(window) = self.pinnacle.window_for_surface(surface.wl_surface()) else {
tracing::error!("wl_surface had no window");
return; return;
}; };
if window.with_state(|state| state.fullscreen_or_maximized.is_fullscreen()) { self.set_window_fullscreen(&window, false);
window.toggle_fullscreen();
if let Some(output) = window.output(&self.pinnacle) {
self.pinnacle.request_layout(&output);
}
}
} }
fn maximize_request(&mut self, surface: ToplevelSurface) { fn maximize_request(&mut self, surface: ToplevelSurface) {
@ -289,14 +266,7 @@ impl XdgShellHandler for State {
return; return;
}; };
if !window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) { self.set_window_maximized(&window, true);
window.toggle_maximized();
}
let Some(output) = window.output(&self.pinnacle) else {
return;
};
self.pinnacle.request_layout(&output);
} }
fn unmaximize_request(&mut self, surface: ToplevelSurface) { fn unmaximize_request(&mut self, surface: ToplevelSurface) {
@ -304,14 +274,7 @@ impl XdgShellHandler for State {
return; return;
}; };
if window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) { self.set_window_maximized(&window, false);
window.toggle_maximized();
}
let Some(output) = window.output(&self.pinnacle) else {
return;
};
self.pinnacle.request_layout(&output);
} }
fn minimize_request(&mut self, _surface: ToplevelSurface) { fn minimize_request(&mut self, _surface: ToplevelSurface) {

View file

@ -49,14 +49,7 @@ impl XwmHandler for State {
} }
let window = WindowElement::new(Window::new_x11_window(surface)); let window = WindowElement::new(Window::new_x11_window(surface));
self.pinnacle let bbox = window.bbox();
.space
.map_element(window.clone(), (0, 0), true);
let bbox = self
.pinnacle
.space
.element_bbox(&window)
.expect("called element_bbox on an unmapped window");
let output_size = self let output_size = self
.pinnacle .pinnacle
@ -84,16 +77,13 @@ impl XwmHandler for State {
unreachable!() unreachable!()
}; };
self.pinnacle.space.map_element(window.clone(), loc, true);
surface.set_mapped(true).expect("failed to map x11 window"); surface.set_mapped(true).expect("failed to map x11 window");
let bbox = Rectangle::from_loc_and_size(loc, bbox.size); let bbox = Rectangle::from_loc_and_size(loc, bbox.size);
debug!("map_window_request, configuring with bbox {bbox:?}");
surface surface
.configure(bbox) .configure(bbox)
.expect("failed to configure x11 window"); .expect("failed to configure x11 window");
// TODO: ssd
if let Some(output) = self.pinnacle.focused_output() { if let Some(output) = self.pinnacle.focused_output() {
window.place_on_output(output); window.place_on_output(output);
@ -103,22 +93,40 @@ impl XwmHandler for State {
window.with_state_mut(|state| { window.with_state_mut(|state| {
state.floating_or_tiled = FloatingOrTiled::Floating(bbox); state.floating_or_tiled = FloatingOrTiled::Floating(bbox);
}); });
self.pinnacle.space.map_element(window.clone(), loc, true);
} }
// 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) {
Some(self.backend.with_renderer(|renderer| {
capture_snapshots_on_output(&mut self.pinnacle, renderer, &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);
self.pinnacle.apply_window_rules(&window); self.pinnacle.apply_window_rules(&window);
if let Some(output) = window.output(&self.pinnacle) { if window.is_on_active_tag() {
output.with_state_mut(|state| state.focus_stack.set_focus(window.clone())); if let Some(output) = window.output(&self.pinnacle) {
self.pinnacle.request_layout(&output); output.with_state_mut(|state| state.focus_stack.set_focus(window.clone()));
self.update_keyboard_focus(&output);
self.pinnacle.loop_handle.insert_idle(move |state| { if let Some(snapshots) = snapshots {
state.update_keyboard_focus(&output); output.with_state_mut(|state| {
}); state.new_wait_layout_transaction(
self.pinnacle.loop_handle.clone(),
snapshots,
)
});
}
self.pinnacle.request_layout(&output);
}
} }
} }
@ -240,10 +248,6 @@ impl XwmHandler for State {
} }
fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) { fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
window
.set_maximized(true)
.expect("failed to set x11 win to maximized");
let Some(window) = window let Some(window) = window
.wl_surface() .wl_surface()
.and_then(|surf| self.pinnacle.window_for_surface(&surf)) .and_then(|surf| self.pinnacle.window_for_surface(&surf))
@ -251,16 +255,10 @@ impl XwmHandler for State {
return; return;
}; };
if !window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) { self.set_window_maximized(&window, true);
window.toggle_maximized();
}
} }
fn unmaximize_request(&mut self, _xwm: XwmId, window: X11Surface) { fn unmaximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
window
.set_maximized(false)
.expect("failed to set x11 win to maximized");
let Some(window) = window let Some(window) = window
.wl_surface() .wl_surface()
.and_then(|surf| self.pinnacle.window_for_surface(&surf)) .and_then(|surf| self.pinnacle.window_for_surface(&surf))
@ -268,16 +266,10 @@ impl XwmHandler for State {
return; return;
}; };
if window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) { self.set_window_maximized(&window, false);
window.toggle_maximized();
}
} }
fn fullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) { fn fullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) {
window
.set_fullscreen(true)
.expect("failed to set x11 win to fullscreen");
let Some(window) = window let Some(window) = window
.wl_surface() .wl_surface()
.and_then(|surf| self.pinnacle.window_for_surface(&surf)) .and_then(|surf| self.pinnacle.window_for_surface(&surf))
@ -285,19 +277,10 @@ impl XwmHandler for State {
return; return;
}; };
if !window.with_state(|state| state.fullscreen_or_maximized.is_fullscreen()) { self.set_window_fullscreen(&window, true);
window.toggle_fullscreen();
if let Some(output) = window.output(&self.pinnacle) {
self.pinnacle.request_layout(&output);
}
}
} }
fn unfullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) { fn unfullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) {
window
.set_fullscreen(false)
.expect("failed to set x11 win to unfullscreen");
let Some(window) = window let Some(window) = window
.wl_surface() .wl_surface()
.and_then(|surf| self.pinnacle.window_for_surface(&surf)) .and_then(|surf| self.pinnacle.window_for_surface(&surf))
@ -305,12 +288,7 @@ impl XwmHandler for State {
return; return;
}; };
if window.with_state(|state| state.fullscreen_or_maximized.is_fullscreen()) { self.set_window_fullscreen(&window, true);
window.toggle_fullscreen();
if let Some(output) = window.output(&self.pinnacle) {
self.pinnacle.request_layout(&output);
}
}
} }
fn resize_request( fn resize_request(

View file

@ -121,11 +121,11 @@ impl LayoutTransaction {
/// reached. /// reached.
pub fn ready(&self) -> bool { pub fn ready(&self) -> bool {
Instant::now().duration_since(self.start_time) >= TIMEOUT Instant::now().duration_since(self.start_time) >= TIMEOUT
// || (!self.wait || (!self.wait
// && self && self
// .pending_windows .pending_windows
// .iter() .iter()
// .all(|(win, serial)| win.is_serial_committed(*serial))) .all(|(win, serial)| win.is_serial_committed(*serial)))
} }
} }