mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-15 15:42:06 +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");
|
tracing::error!("wl_surface had no window");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.set_status(StatusName::Fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
surface.send_configure();
|
surface.send_configure();
|
||||||
|
@ -343,6 +345,33 @@ impl<B: Backend> XdgShellHandler for State<B> {
|
||||||
});
|
});
|
||||||
|
|
||||||
surface.send_pending_configure();
|
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) {
|
// fn minimize_request(&mut self, surface: ToplevelSurface) {
|
||||||
|
|
|
@ -28,7 +28,10 @@ use crate::{
|
||||||
backend::Backend,
|
backend::Backend,
|
||||||
focus::FocusTarget,
|
focus::FocusTarget,
|
||||||
state::{CalloopData, WithState},
|
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> {
|
impl<B: Backend> XwmHandler for CalloopData<B> {
|
||||||
|
@ -331,22 +334,50 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
|
||||||
// TODO: anvil has a TODO here
|
// TODO: anvil has a TODO here
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn maximize_request(&mut self, xwm: XwmId, window: X11Surface) {
|
fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
|
||||||
// // TODO:
|
window
|
||||||
// }
|
.set_maximized(true)
|
||||||
//
|
.expect("failed to set x11 win to maximized");
|
||||||
// fn unmaximize_request(&mut self, xwm: XwmId, window: X11Surface) {
|
let Some(window) = (|| self.state.window_for_surface(&window.wl_surface()?))() else {
|
||||||
// // TODO:
|
return;
|
||||||
// }
|
};
|
||||||
//
|
window.set_status(StatusName::Maximized);
|
||||||
// fn fullscreen_request(&mut self, xwm: XwmId, window: X11Surface) {
|
}
|
||||||
// // TODO:
|
|
||||||
// // window.set_fullscreen(true).unwrap();
|
fn unmaximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
|
||||||
// }
|
window
|
||||||
//
|
.set_maximized(false)
|
||||||
// fn unfullscreen_request(&mut self, xwm: XwmId, window: X11Surface) {
|
.expect("failed to set x11 win to maximized");
|
||||||
// // TODO:
|
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(
|
fn resize_request(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
168
src/window.rs
168
src/window.rs
|
@ -283,57 +283,97 @@ impl WindowElement {
|
||||||
StatusName::Floating => {
|
StatusName::Floating => {
|
||||||
self.with_state(|state| state.status = Status::Floating(geo));
|
self.with_state(|state| state.status = Status::Floating(geo));
|
||||||
|
|
||||||
if let WindowElement::Wayland(window) = self {
|
match self {
|
||||||
window.toplevel().with_pending_state(|state| {
|
WindowElement::Wayland(window) => {
|
||||||
state.states.unset(xdg_toplevel::State::Maximized);
|
window.toplevel().with_pending_state(|state| {
|
||||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
state.states.unset(xdg_toplevel::State::Maximized);
|
||||||
state.states.unset(xdg_toplevel::State::TiledTop);
|
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||||
state.states.unset(xdg_toplevel::State::TiledBottom);
|
state.states.unset(xdg_toplevel::State::TiledTop);
|
||||||
state.states.unset(xdg_toplevel::State::TiledLeft);
|
state.states.unset(xdg_toplevel::State::TiledBottom);
|
||||||
state.states.unset(xdg_toplevel::State::TiledRight);
|
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 => {
|
StatusName::Tiled => {
|
||||||
self.with_state(|state| state.status = Status::Tiled(Some(geo)));
|
self.with_state(|state| state.status = Status::Tiled(Some(geo)));
|
||||||
|
|
||||||
if let WindowElement::Wayland(window) = self {
|
match self {
|
||||||
window.toplevel().with_pending_state(|state| {
|
WindowElement::Wayland(window) => {
|
||||||
state.states.unset(xdg_toplevel::State::Maximized);
|
window.toplevel().with_pending_state(|state| {
|
||||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
state.states.unset(xdg_toplevel::State::Maximized);
|
||||||
state.states.set(xdg_toplevel::State::TiledTop);
|
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||||
state.states.set(xdg_toplevel::State::TiledBottom);
|
state.states.set(xdg_toplevel::State::TiledTop);
|
||||||
state.states.set(xdg_toplevel::State::TiledLeft);
|
state.states.set(xdg_toplevel::State::TiledBottom);
|
||||||
state.states.set(xdg_toplevel::State::TiledRight);
|
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 => {
|
StatusName::Fullscreen => {
|
||||||
self.with_state(|state| state.status = Status::Fullscreen(Some(geo)));
|
self.with_state(|state| state.status = Status::Fullscreen(Some(geo)));
|
||||||
|
|
||||||
if let WindowElement::Wayland(window) = self {
|
match self {
|
||||||
window.toplevel().with_pending_state(|state| {
|
WindowElement::Wayland(window) => {
|
||||||
state.states.unset(xdg_toplevel::State::Maximized);
|
window.toplevel().with_pending_state(|state| {
|
||||||
state.states.set(xdg_toplevel::State::Fullscreen);
|
state.states.unset(xdg_toplevel::State::Maximized);
|
||||||
state.states.set(xdg_toplevel::State::TiledTop);
|
state.states.set(xdg_toplevel::State::Fullscreen);
|
||||||
state.states.set(xdg_toplevel::State::TiledBottom);
|
state.states.set(xdg_toplevel::State::TiledTop);
|
||||||
state.states.set(xdg_toplevel::State::TiledLeft);
|
state.states.set(xdg_toplevel::State::TiledBottom);
|
||||||
state.states.set(xdg_toplevel::State::TiledRight);
|
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 => {
|
StatusName::Maximized => {
|
||||||
self.with_state(|state| state.status = Status::Maximized(Some(geo)));
|
self.with_state(|state| state.status = Status::Maximized(Some(geo)));
|
||||||
|
|
||||||
if let WindowElement::Wayland(window) = self {
|
match self {
|
||||||
window.toplevel().with_pending_state(|state| {
|
WindowElement::Wayland(window) => {
|
||||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
window.toplevel().with_pending_state(|state| {
|
||||||
state.states.set(xdg_toplevel::State::Maximized);
|
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||||
state.states.set(xdg_toplevel::State::TiledTop);
|
state.states.set(xdg_toplevel::State::Maximized);
|
||||||
state.states.set(xdg_toplevel::State::TiledBottom);
|
state.states.set(xdg_toplevel::State::TiledTop);
|
||||||
state.states.set(xdg_toplevel::State::TiledLeft);
|
state.states.set(xdg_toplevel::State::TiledBottom);
|
||||||
state.states.set(xdg_toplevel::State::TiledRight);
|
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 struct WindowBlocker;
|
||||||
pub static BLOCKER_COUNTER: AtomicU32 = AtomicU32::new(0);
|
pub static BLOCKER_COUNTER: AtomicU32 = AtomicU32::new(0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue