mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-27 21:58:18 +01:00
Add maximized requests and fullscreen requests for xwayland
This commit is contained in:
parent
e2dea4dd15
commit
947ccdf464
3 changed files with 153 additions and 109 deletions
|
@ -322,6 +322,8 @@ impl<B: Backend> XdgShellHandler for State<B> {
|
|||
tracing::error!("wl_surface had no window");
|
||||
return;
|
||||
};
|
||||
|
||||
window.set_status(StatusName::Fullscreen);
|
||||
}
|
||||
|
||||
surface.send_configure();
|
||||
|
@ -343,6 +345,33 @@ impl<B: Backend> XdgShellHandler for State<B> {
|
|||
});
|
||||
|
||||
surface.send_pending_configure();
|
||||
|
||||
let Some(window) = self.window_for_surface(surface.wl_surface()) else {
|
||||
tracing::error!("wl_surface had no window");
|
||||
return;
|
||||
};
|
||||
|
||||
// TODO: remember the last status instead of tiled
|
||||
window.set_status(StatusName::Tiled);
|
||||
}
|
||||
|
||||
fn maximize_request(&mut self, surface: ToplevelSurface) {
|
||||
let Some(window) = self.window_for_surface(surface.wl_surface()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
window.set_status(StatusName::Maximized);
|
||||
|
||||
// TODO: might need to update_windows here
|
||||
}
|
||||
|
||||
fn unmaximize_request(&mut self, surface: ToplevelSurface) {
|
||||
let Some(window) = self.window_for_surface(surface.wl_surface()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
// TODO: remember last status
|
||||
window.set_status(StatusName::Tiled);
|
||||
}
|
||||
|
||||
// fn minimize_request(&mut self, surface: ToplevelSurface) {
|
||||
|
|
|
@ -28,7 +28,10 @@ use crate::{
|
|||
backend::Backend,
|
||||
focus::FocusTarget,
|
||||
state::{CalloopData, WithState},
|
||||
window::{window_state::Status, WindowBlocker, WindowElement, BLOCKER_COUNTER},
|
||||
window::{
|
||||
window_state::{Status, StatusName},
|
||||
WindowBlocker, WindowElement, BLOCKER_COUNTER,
|
||||
},
|
||||
};
|
||||
|
||||
impl<B: Backend> XwmHandler for CalloopData<B> {
|
||||
|
@ -331,22 +334,50 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
|
|||
// TODO: anvil has a TODO here
|
||||
}
|
||||
|
||||
// fn maximize_request(&mut self, xwm: XwmId, window: X11Surface) {
|
||||
// // TODO:
|
||||
// }
|
||||
//
|
||||
// fn unmaximize_request(&mut self, xwm: XwmId, window: X11Surface) {
|
||||
// // TODO:
|
||||
// }
|
||||
//
|
||||
// fn fullscreen_request(&mut self, xwm: XwmId, window: X11Surface) {
|
||||
// // TODO:
|
||||
// // window.set_fullscreen(true).unwrap();
|
||||
// }
|
||||
//
|
||||
// fn unfullscreen_request(&mut self, xwm: XwmId, window: X11Surface) {
|
||||
// // TODO:
|
||||
// }
|
||||
fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
|
||||
window
|
||||
.set_maximized(true)
|
||||
.expect("failed to set x11 win to maximized");
|
||||
let Some(window) = (|| self.state.window_for_surface(&window.wl_surface()?))() else {
|
||||
return;
|
||||
};
|
||||
window.set_status(StatusName::Maximized);
|
||||
}
|
||||
|
||||
fn unmaximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
|
||||
window
|
||||
.set_maximized(false)
|
||||
.expect("failed to set x11 win to maximized");
|
||||
let Some(window) = (|| self.state.window_for_surface(&window.wl_surface()?))() else {
|
||||
return;
|
||||
};
|
||||
// TODO: remember previous status
|
||||
window.set_status(StatusName::Tiled);
|
||||
}
|
||||
|
||||
fn fullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) {
|
||||
window
|
||||
.set_fullscreen(true)
|
||||
.expect("failed to set x11 win to fullscreen");
|
||||
// TODO: fix this mess
|
||||
let Some(window) = (|| self.state.window_for_surface(&window.wl_surface()?))() else {
|
||||
return;
|
||||
};
|
||||
window.set_status(StatusName::Fullscreen);
|
||||
|
||||
// TODO: do i need to update_windows here?
|
||||
}
|
||||
|
||||
fn unfullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) {
|
||||
window
|
||||
.set_fullscreen(false)
|
||||
.expect("failed to set x11 win to unfullscreen");
|
||||
let Some(window) = (|| self.state.window_for_surface(&window.wl_surface()?))() else {
|
||||
return;
|
||||
};
|
||||
// TODO: remember previous status
|
||||
window.set_status(StatusName::Tiled);
|
||||
}
|
||||
|
||||
fn resize_request(
|
||||
&mut self,
|
||||
|
|
168
src/window.rs
168
src/window.rs
|
@ -283,57 +283,97 @@ impl WindowElement {
|
|||
StatusName::Floating => {
|
||||
self.with_state(|state| state.status = Status::Floating(geo));
|
||||
|
||||
if let WindowElement::Wayland(window) = self {
|
||||
window.toplevel().with_pending_state(|state| {
|
||||
state.states.unset(xdg_toplevel::State::Maximized);
|
||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||
state.states.unset(xdg_toplevel::State::TiledTop);
|
||||
state.states.unset(xdg_toplevel::State::TiledBottom);
|
||||
state.states.unset(xdg_toplevel::State::TiledLeft);
|
||||
state.states.unset(xdg_toplevel::State::TiledRight);
|
||||
});
|
||||
match self {
|
||||
WindowElement::Wayland(window) => {
|
||||
window.toplevel().with_pending_state(|state| {
|
||||
state.states.unset(xdg_toplevel::State::Maximized);
|
||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||
state.states.unset(xdg_toplevel::State::TiledTop);
|
||||
state.states.unset(xdg_toplevel::State::TiledBottom);
|
||||
state.states.unset(xdg_toplevel::State::TiledLeft);
|
||||
state.states.unset(xdg_toplevel::State::TiledRight);
|
||||
});
|
||||
}
|
||||
WindowElement::X11(surface) => {
|
||||
surface
|
||||
.set_fullscreen(false)
|
||||
.expect("failed to set x11 win to not fullscreen");
|
||||
surface
|
||||
.set_maximized(false)
|
||||
.expect("failed to set x11 win to not maximized");
|
||||
}
|
||||
}
|
||||
}
|
||||
StatusName::Tiled => {
|
||||
self.with_state(|state| state.status = Status::Tiled(Some(geo)));
|
||||
|
||||
if let WindowElement::Wayland(window) = self {
|
||||
window.toplevel().with_pending_state(|state| {
|
||||
state.states.unset(xdg_toplevel::State::Maximized);
|
||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||
state.states.set(xdg_toplevel::State::TiledTop);
|
||||
state.states.set(xdg_toplevel::State::TiledBottom);
|
||||
state.states.set(xdg_toplevel::State::TiledLeft);
|
||||
state.states.set(xdg_toplevel::State::TiledRight);
|
||||
});
|
||||
match self {
|
||||
WindowElement::Wayland(window) => {
|
||||
window.toplevel().with_pending_state(|state| {
|
||||
state.states.unset(xdg_toplevel::State::Maximized);
|
||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||
state.states.set(xdg_toplevel::State::TiledTop);
|
||||
state.states.set(xdg_toplevel::State::TiledBottom);
|
||||
state.states.set(xdg_toplevel::State::TiledLeft);
|
||||
state.states.set(xdg_toplevel::State::TiledRight);
|
||||
});
|
||||
}
|
||||
WindowElement::X11(surface) => {
|
||||
surface
|
||||
.set_fullscreen(false)
|
||||
.expect("failed to set x11 win to not fullscreen");
|
||||
surface
|
||||
.set_maximized(false)
|
||||
.expect("failed to set x11 win to not maximized");
|
||||
}
|
||||
}
|
||||
}
|
||||
StatusName::Fullscreen => {
|
||||
self.with_state(|state| state.status = Status::Fullscreen(Some(geo)));
|
||||
|
||||
if let WindowElement::Wayland(window) = self {
|
||||
window.toplevel().with_pending_state(|state| {
|
||||
state.states.unset(xdg_toplevel::State::Maximized);
|
||||
state.states.set(xdg_toplevel::State::Fullscreen);
|
||||
state.states.set(xdg_toplevel::State::TiledTop);
|
||||
state.states.set(xdg_toplevel::State::TiledBottom);
|
||||
state.states.set(xdg_toplevel::State::TiledLeft);
|
||||
state.states.set(xdg_toplevel::State::TiledRight);
|
||||
});
|
||||
match self {
|
||||
WindowElement::Wayland(window) => {
|
||||
window.toplevel().with_pending_state(|state| {
|
||||
state.states.unset(xdg_toplevel::State::Maximized);
|
||||
state.states.set(xdg_toplevel::State::Fullscreen);
|
||||
state.states.set(xdg_toplevel::State::TiledTop);
|
||||
state.states.set(xdg_toplevel::State::TiledBottom);
|
||||
state.states.set(xdg_toplevel::State::TiledLeft);
|
||||
state.states.set(xdg_toplevel::State::TiledRight);
|
||||
});
|
||||
}
|
||||
WindowElement::X11(surface) => {
|
||||
surface
|
||||
.set_fullscreen(true)
|
||||
.expect("failed to set x11 win to fullscreen");
|
||||
surface
|
||||
.set_maximized(false)
|
||||
.expect("failed to set x11 win to not maximzied");
|
||||
}
|
||||
}
|
||||
}
|
||||
StatusName::Maximized => {
|
||||
self.with_state(|state| state.status = Status::Maximized(Some(geo)));
|
||||
|
||||
if let WindowElement::Wayland(window) = self {
|
||||
window.toplevel().with_pending_state(|state| {
|
||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||
state.states.set(xdg_toplevel::State::Maximized);
|
||||
state.states.set(xdg_toplevel::State::TiledTop);
|
||||
state.states.set(xdg_toplevel::State::TiledBottom);
|
||||
state.states.set(xdg_toplevel::State::TiledLeft);
|
||||
state.states.set(xdg_toplevel::State::TiledRight);
|
||||
});
|
||||
match self {
|
||||
WindowElement::Wayland(window) => {
|
||||
window.toplevel().with_pending_state(|state| {
|
||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||
state.states.set(xdg_toplevel::State::Maximized);
|
||||
state.states.set(xdg_toplevel::State::TiledTop);
|
||||
state.states.set(xdg_toplevel::State::TiledBottom);
|
||||
state.states.set(xdg_toplevel::State::TiledLeft);
|
||||
state.states.set(xdg_toplevel::State::TiledRight);
|
||||
});
|
||||
}
|
||||
WindowElement::X11(surface) => {
|
||||
surface
|
||||
.set_fullscreen(false)
|
||||
.expect("failed to set x11 win to not fullscreen");
|
||||
surface
|
||||
.set_maximized(true)
|
||||
.expect("failed to set x11 win to maximized");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -571,62 +611,6 @@ impl<B: Backend> State<B> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Toggle a window's floating status.
|
||||
pub fn toggle_floating<B: Backend>(state: &mut State<B>, window: &WindowElement) {
|
||||
match window.with_state(|state| state.status) {
|
||||
Status::Floating(_) => window.set_status(StatusName::Tiled),
|
||||
Status::Tiled(_) => window.set_status(StatusName::Fullscreen),
|
||||
Status::Fullscreen(_) => window.set_status(StatusName::Maximized),
|
||||
Status::Maximized(_) => window.set_status(StatusName::Floating),
|
||||
}
|
||||
|
||||
// TODO: don't use the focused output, use the one the window is on
|
||||
let output = state
|
||||
.focus_state
|
||||
.focused_output
|
||||
.clone()
|
||||
.expect("no focused output");
|
||||
// state.re_layout(&output);
|
||||
|
||||
state.update_windows(&output);
|
||||
let render = output.with_state(|op_state| {
|
||||
state
|
||||
.windows
|
||||
.iter()
|
||||
.cloned()
|
||||
.filter(|win| {
|
||||
win.with_state(|win_state| {
|
||||
if win_state.status.is_floating() {
|
||||
return true;
|
||||
}
|
||||
for tag in win_state.tags.iter() {
|
||||
if op_state.focused_tags().any(|tg| tg == tag) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
})
|
||||
})
|
||||
.filter(|win| win != window)
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
|
||||
let clone = window.clone();
|
||||
state.loop_handle.insert_idle(move |data| {
|
||||
crate::state::schedule_on_commit(data, render, move |dt| {
|
||||
dt.state.space.raise_element(&clone, true);
|
||||
if let WindowElement::X11(surface) = clone {
|
||||
dt.state
|
||||
.xwm
|
||||
.as_mut()
|
||||
.expect("no xwm")
|
||||
.raise_window(&surface)
|
||||
.expect("failed to raise x11 win");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
pub struct WindowBlocker;
|
||||
pub static BLOCKER_COUNTER: AtomicU32 = AtomicU32::new(0);
|
||||
|
||||
|
|
Loading…
Reference in a new issue