Remove space_elements!

so uh when you impl SpaceElement you gotta actually remember to impl the geometry fn, which is why Alacritty was 44 pixels off in the other attempt at this
This commit is contained in:
Ottatop 2024-02-29 20:10:23 -06:00
parent 16fff3f7e3
commit 48cd3d0df9
12 changed files with 379 additions and 733 deletions

View file

@ -34,11 +34,11 @@ use pinnacle_api_defs::pinnacle::{
},
};
use smithay::{
desktop::space::SpaceElement,
desktop::{space::SpaceElement, WindowSurface},
input::keyboard::XkbConfig,
reexports::{calloop, input as libinput, wayland_protocols::xdg::shell::server},
utils::{Point, Rectangle, SERIAL_COUNTER},
wayland::{compositor, shell::xdg::XdgToplevelSurfaceData},
wayland::seat::WaylandFocus,
};
use sysinfo::ProcessRefreshKind;
use tokio::{
@ -48,6 +48,7 @@ use tokio::{
};
use tokio_stream::{Stream, StreamExt};
use tonic::{Request, Response, Status, Streaming};
use tracing::{error, warn};
use crate::{
config::ConnectorSavedState,
@ -56,7 +57,7 @@ use crate::{
output::OutputName,
state::{State, WithState},
tag::{Tag, TagId},
window::{window_state::WindowId, WindowElement},
window::window_state::WindowId,
};
type ResponseStream<T> = Pin<Box<dyn Stream<Item = Result<T, Status>> + Send>>;
@ -316,7 +317,7 @@ impl input_service_server::InputService for InputService {
};
if let Some(kb) = state.seat.get_keyboard() {
if let Err(err) = kb.set_xkb_config(state, new_config) {
tracing::error!("Failed to set xkbconfig: {err}");
error!("Failed to set xkbconfig: {err}");
}
}
})
@ -557,7 +558,7 @@ impl process_service_server::ProcessService for ProcessService {
.args(command)
.spawn()
else {
tracing::warn!("Tried to run {arg0}, but it doesn't exist",);
warn!("Tried to run {arg0}, but it doesn't exist",);
return;
};
@ -584,7 +585,7 @@ impl process_service_server::ProcessService for ProcessService {
match sender.send(response) {
Ok(_) => (),
Err(err) => {
tracing::error!(err = ?err);
error!(err = ?err);
break;
}
}
@ -608,7 +609,7 @@ impl process_service_server::ProcessService for ProcessService {
match sender.send(response) {
Ok(_) => (),
Err(err) => {
tracing::error!(err = ?err);
error!(err = ?err);
break;
}
}
@ -627,7 +628,7 @@ impl process_service_server::ProcessService for ProcessService {
// TODO: handle error
let _ = sender.send(response);
}
Err(err) => tracing::warn!("child wait() err: {err}"),
Err(err) => warn!("child wait() err: {err}"),
}
});
})
@ -1122,15 +1123,17 @@ impl window_service_server::WindowService for WindowService {
run_unary_no_response(&self.sender, move |state| {
let Some(window) = window_id.window(state) else { return };
match window {
WindowElement::Wayland(window) => {
window.toplevel().expect("in wayland enum").send_close()
match window.underlying_surface() {
WindowSurface::Wayland(toplevel) => toplevel.send_close(),
WindowSurface::X11(surface) => {
if !surface.is_override_redirect() {
if let Err(err) = surface.close() {
error!("failed to close x11 window: {err}");
}
} else {
warn!("tried to close OR window");
}
}
WindowElement::X11(surface) => surface.close().expect("failed to close x11 win"),
WindowElement::X11OverrideRedirect(_) => {
tracing::warn!("tried to close override redirect window");
}
_ => unreachable!(),
}
})
.await
@ -1356,32 +1359,14 @@ impl window_service_server::WindowService for WindowService {
return;
};
if window.is_x11_override_redirect() {
return;
}
let Some(output) = window.output(state) else {
return;
};
// if !matches!(
// &focus,
// FocusTarget::Window(WindowElement::X11OverrideRedirect(_))
// ) {
// keyboard.set_focus(self, Some(focus.clone()), serial);
// }
//
// self.space.elements().for_each(|window| {
// if let WindowElement::Wayland(window) = window {
// window.toplevel().send_configure();
// }
// });
// } else {
// self.space.elements().for_each(|window| {
// window.set_activate(false);
// if let WindowElement::Wayland(window) = window {
// window.toplevel().send_configure();
// }
// });
// keyboard.set_focus(self, None, serial);
// }
for win in state.space.elements() {
win.set_activate(false);
}
@ -1432,8 +1417,8 @@ impl window_service_server::WindowService for WindowService {
}
for window in state.space.elements() {
if let WindowElement::Wayland(window) = window {
window.toplevel().expect("in wayland enum").send_configure();
if let Some(toplevel) = window.toplevel() {
toplevel.send_configure();
}
}
@ -1677,27 +1662,8 @@ impl window_service_server::WindowService for WindowService {
})
};
let (class, title) = window.as_ref().map_or((None, None), |win| match &win {
WindowElement::Wayland(_) => {
if let Some(wl_surf) = win.wl_surface() {
compositor::with_states(&wl_surf, |states| {
let lock = states
.data_map
.get::<XdgToplevelSurfaceData>()
.expect("XdgToplevelSurfaceData wasn't in surface's data map")
.lock()
.expect("failed to acquire lock");
(lock.app_id.clone(), lock.title.clone())
})
} else {
(None, None)
}
}
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
(Some(surface.class()), Some(surface.title()))
}
_ => unreachable!(),
});
let class = window.as_ref().and_then(|win| win.class());
let title = window.as_ref().and_then(|win| win.title());
let focused = window.as_ref().and_then(|win| {
state

View file

@ -56,8 +56,8 @@ impl State {
if let Some(win) = &current_focus {
assert!(!win.is_x11_override_redirect());
if let WindowElement::Wayland(w) = win {
w.toplevel().expect("in wayland enum").send_configure();
if let Some(toplevel) = win.toplevel() {
toplevel.send_configure();
}
}
@ -437,13 +437,9 @@ impl WaylandFocus for FocusTarget {
object_id: &smithay::reexports::wayland_server::backend::ObjectId,
) -> bool {
match self {
FocusTarget::Window(WindowElement::Wayland(window)) => window.same_client_as(object_id),
FocusTarget::Window(
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface),
) => surface.same_client_as(object_id),
FocusTarget::Window(window) => window.same_client_as(object_id),
FocusTarget::Popup(popup) => popup.wl_surface().id().same_client_as(object_id),
FocusTarget::LayerSurface(surf) => surf.wl_surface().id().same_client_as(object_id),
_ => unreachable!(),
}
}
}

View file

@ -51,13 +51,16 @@ impl PointerGrab<State> for MoveSurfaceGrab {
}
state.space.raise_element(&self.window, false);
if let WindowElement::X11(surface) = &self.window {
state
.xwm
.as_mut()
.expect("no xwm")
.raise_window(surface)
.expect("failed to raise x11 win");
if let Some(surface) = self.window.x11_surface() {
// INFO: can you raise OR windows or no idk
if !surface.is_override_redirect() {
state
.xwm
.as_mut()
.expect("no xwm")
.raise_window(surface)
.expect("failed to raise x11 win");
}
}
let is_tiled = self
@ -136,12 +139,14 @@ impl PointerGrab<State> for MoveSurfaceGrab {
}
});
if let WindowElement::X11(surface) = &self.window {
let geo = surface.geometry();
let new_geo = Rectangle::from_loc_and_size(new_loc, geo.size);
surface
.configure(new_geo)
.expect("failed to configure x11 win");
if let Some(surface) = self.window.x11_surface() {
if !surface.is_override_redirect() {
let geo = surface.geometry();
let new_geo = Rectangle::from_loc_and_size(new_loc, geo.size);
surface
.configure(new_geo)
.expect("failed to configure x11 win");
}
}
let outputs = state.space.outputs_for_element(&self.window);

View file

@ -1,17 +1,17 @@
// SPDX-License-Identifier: GPL-3.0-or-later
use smithay::{
desktop::space::SpaceElement,
desktop::{space::SpaceElement, utils::bbox_from_surface_tree, WindowSurface},
input::{
pointer::{AxisFrame, ButtonEvent, Focus, GrabStartData, PointerGrab, PointerInnerHandle},
Seat, SeatHandler,
},
reexports::{
wayland_protocols::xdg::shell::server::xdg_toplevel::{self},
wayland_protocols::xdg::shell::server::xdg_toplevel,
wayland_server::protocol::wl_surface::WlSurface,
},
utils::{IsAlive, Logical, Point, Rectangle, Size},
wayland::{compositor, shell::xdg::SurfaceCachedState},
wayland::{compositor, seat::WaylandFocus, shell::xdg::SurfaceCachedState},
xwayland,
};
@ -158,28 +158,26 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
new_window_height.clamp(min_height, max_height),
));
match &self.window {
WindowElement::Wayland(window) => {
let toplevel_surface = window.toplevel().expect("in wayland enum");
toplevel_surface.with_pending_state(|state| {
match self.window.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
toplevel.with_pending_state(|state| {
state.states.set(xdg_toplevel::State::Resizing);
state.size = Some(self.last_window_size);
});
toplevel_surface.send_pending_configure();
toplevel.send_pending_configure();
}
WindowElement::X11(surface) => {
let loc = data
.space
.element_location(&self.window)
.expect("failed to get x11 win loc");
surface
.configure(Rectangle::from_loc_and_size(loc, self.last_window_size))
.expect("failed to configure x11 win");
WindowSurface::X11(surface) => {
if !surface.is_override_redirect() {
let loc = data
.space
.element_location(&self.window)
.expect("failed to get x11 win loc");
surface
.configure(Rectangle::from_loc_and_size(loc, self.last_window_size))
.expect("failed to configure x11 win");
}
}
WindowElement::X11OverrideRedirect(_) => (),
_ => unreachable!(),
}
}
@ -208,17 +206,16 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
return;
}
match &self.window {
WindowElement::Wayland(window) => {
let toplevel_surface = window.toplevel().expect("in wayland enum");
toplevel_surface.with_pending_state(|state| {
match self.window.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
toplevel.with_pending_state(|state| {
state.states.unset(xdg_toplevel::State::Resizing);
state.size = Some(self.last_window_size);
});
toplevel_surface.send_pending_configure();
toplevel.send_pending_configure();
toplevel_surface.wl_surface().with_state(|state| {
toplevel.wl_surface().with_state(|state| {
// TODO: validate resize state
state.resize_state = ResizeSurfaceState::WaitingForLastCommit {
edges: self.edges,
@ -226,7 +223,10 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
};
});
}
WindowElement::X11(surface) => {
WindowSurface::X11(surface) => {
if surface.is_override_redirect() {
return;
}
let Some(surface) = surface.wl_surface() else { return };
surface.with_state(|state| {
state.resize_state = ResizeSurfaceState::WaitingForLastCommit {
@ -235,8 +235,6 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
};
});
}
WindowElement::X11OverrideRedirect(_) => (),
_ => unreachable!(),
}
}
}
@ -418,12 +416,14 @@ pub fn handle_commit(state: &mut State, surface: &WlSurface) -> Option<()> {
if new_loc.x.is_some() || new_loc.y.is_some() {
state.space.map_element(window.clone(), window_loc, false);
if let WindowElement::X11(surface) = window {
let geo = surface.geometry();
let new_geo = Rectangle::from_loc_and_size(window_loc, geo.size);
surface
.configure(new_geo)
.expect("failed to configure x11 win");
if let Some(surface) = window.x11_surface() {
if !surface.is_override_redirect() {
let geo = surface.geometry();
let new_geo = Rectangle::from_loc_and_size(window_loc, geo.size);
surface
.configure(new_geo)
.expect("failed to configure x11 win");
}
}
}
@ -458,18 +458,14 @@ pub fn resize_request_client(
.expect("resize request called on unmapped window");
let initial_window_size = window.geometry().size;
if let Some(WindowElement::Wayland(window)) = state.window_for_surface(surface) {
window
.toplevel()
.expect("in wayland enum")
.with_pending_state(|state| {
if let Some(window) = state.window_for_surface(surface) {
if let Some(toplevel) = window.toplevel() {
toplevel.with_pending_state(|state| {
state.states.set(xdg_toplevel::State::Resizing);
});
window
.toplevel()
.expect("in wayland enum")
.send_pending_configure();
toplevel.send_pending_configure();
}
}
let grab = ResizeSurfaceGrab::start(
@ -512,18 +508,14 @@ pub fn resize_request_server(
.expect("resize request called on unmapped window");
let initial_window_size = window.geometry().size;
if let Some(WindowElement::Wayland(window)) = state.window_for_surface(surface) {
window
.toplevel()
.expect("in wayland enum")
.with_pending_state(|state| {
if let Some(window) = state.window_for_surface(surface) {
if let Some(toplevel) = window.toplevel() {
toplevel.with_pending_state(|state| {
state.states.set(xdg_toplevel::State::Resizing);
});
window
.toplevel()
.expect("in wayland enum")
.send_pending_configure();
toplevel.send_pending_configure();
}
}
let start_data = smithay::input::pointer::GrabStartData {

View file

@ -60,7 +60,6 @@ use smithay::{
use crate::{
focus::FocusTarget,
state::{ClientState, State, WithState},
window::WindowElement,
};
impl BufferHandler for State {
@ -107,9 +106,10 @@ impl CompositorHandler for State {
fn commit(&mut self, surface: &WlSurface) {
tracing::trace!("commit on surface {surface:?}");
utils::on_commit_buffer_handler::<State>(surface);
X11Wm::commit_hook::<State>(surface);
utils::on_commit_buffer_handler::<State>(surface);
self.backend.early_import(surface);
let mut root = surface.clone();
@ -118,10 +118,10 @@ impl CompositorHandler for State {
}
if !compositor::is_sync_subsurface(surface) {
if let Some(win @ WindowElement::Wayland(window)) = &self.window_for_surface(&root) {
if let Some(window) = self.window_for_surface(&root) {
window.on_commit();
if let Some(loc) = win.with_state(|state| state.target_loc.take()) {
self.space.map_element(win.clone(), loc, false);
if let Some(loc) = window.with_state(|state| state.target_loc.take()) {
self.space.map_element(window.clone(), loc, false);
}
}
};
@ -149,7 +149,7 @@ impl CompositorHandler for State {
self.output_focus_stack.current_focus(),
self.space.outputs().next(),
) {
tracing::debug!("PLACING TOPLEVEL");
tracing::debug!("Placing toplevel");
new_window.place_on_output(output);
output.with_state(|state| state.focus_stack.set_focus(new_window.clone()));
}
@ -180,22 +180,9 @@ impl CompositorHandler for State {
SERIAL_COUNTER.next_serial(),
);
});
} else if let WindowElement::Wayland(window) = &new_window {
window.on_commit();
let initial_configure_sent = compositor::with_states(surface, |states| {
states
.data_map
.get::<XdgToplevelSurfaceData>()
.expect("XdgToplevelSurfaceData wasn't in surface's data map")
.lock()
.expect("Failed to lock Mutex<XdgToplevelSurfaceData>")
.initial_configure_sent
});
if !initial_configure_sent {
tracing::debug!("Initial configure");
window.toplevel().expect("in wayland enum").send_configure();
}
} else if new_window.toplevel().is_some() {
new_window.on_commit();
ensure_initial_configure(surface, self);
}
return;
@ -266,8 +253,11 @@ impl CompositorHandler for State {
delegate_compositor!(State);
fn ensure_initial_configure(surface: &WlSurface, state: &mut State) {
if let Some(window) = state.window_for_surface(surface) {
if let WindowElement::Wayland(window) = &window {
if let (Some(window), _) | (None, Some(window)) = (
state.window_for_surface(surface),
state.new_window_for_surface(surface),
) {
if let Some(toplevel) = window.toplevel() {
let initial_configure_sent = compositor::with_states(surface, |states| {
states
.data_map
@ -280,7 +270,7 @@ fn ensure_initial_configure(surface: &WlSurface, state: &mut State) {
if !initial_configure_sent {
tracing::debug!("Initial configure");
window.toplevel().expect("in wayland enum").send_configure();
toplevel.send_configure();
}
}
return;

View file

@ -17,8 +17,11 @@ use smithay::{
},
},
utils::{Logical, Point, Rectangle, Serial, SERIAL_COUNTER},
wayland::shell::xdg::{
PopupSurface, PositionerState, ToplevelSurface, XdgShellHandler, XdgShellState,
wayland::{
seat::WaylandFocus,
shell::xdg::{
PopupSurface, PositionerState, ToplevelSurface, XdgShellHandler, XdgShellState,
},
},
};
@ -41,65 +44,8 @@ impl XdgShellHandler for State {
state.states.set(xdg_toplevel::State::TiledRight);
});
let window = WindowElement::Wayland(Window::new_wayland_window(surface.clone()));
let window = WindowElement::new(Window::new_wayland_window(surface.clone()));
self.new_windows.push(window);
// if let (Some(output), _) | (None, Some(output)) = (
// &self.focus_state.focused_output,
// self.space.outputs().next(),
// ) {
// tracing::debug!("PLACING TOPLEVEL");
// window.place_on_output(output);
// }
//
// // note to self: don't reorder this
// // TODO: fix it so that reordering this doesn't break stuff
// self.windows.push(window.clone());
//
// self.space.map_element(window.clone(), (0, 0), true);
//
// let win_clone = window.clone();
//
// // Let the initial configure happen before updating the windows
// self.schedule(
// move |_data| {
// if let WindowElement::Wayland(window) = &win_clone {
// let initial_configure_sent =
// compositor::with_states(window.toplevel().wl_surface(), |states| {
// states
// .data_map
// .get::<smithay::wayland::shell::xdg::XdgToplevelSurfaceData>()
// .expect("XdgToplevelSurfaceData wasn't in surface's data map")
// .lock()
// .expect("Failed to lock Mutex<XdgToplevelSurfaceData>")
// .initial_configure_sent
// });
//
// initial_configure_sent
// } else {
// true
// }
// },
// |data| {
// data.state.apply_window_rules(&window);
//
// if let Some(focused_output) = data.state.focus_state.focused_output.clone() {
// data.state.update_windows(&focused_output);
// }
//
// data.state.loop_handle.insert_idle(move |data| {
// data.state
// .seat
// .get_keyboard()
// .expect("Seat had no keyboard") // FIXME: actually handle error
// .set_focus(
// &mut data.state,
// Some(FocusTarget::Window(window)),
// SERIAL_COUNTER.next_serial(),
// );
// });
// },
// );
}
fn toplevel_destroyed(&mut self, surface: ToplevelSurface) {
@ -138,8 +84,8 @@ impl XdgShellHandler for State {
// TODO:
self.space.raise_element(win, true);
self.z_index_stack.set_focus(win.clone());
if let WindowElement::Wayland(win) = &win {
win.toplevel().expect("in wayland enum").send_configure();
if let Some(toplevel) = win.toplevel() {
toplevel.send_configure();
}
}
self.seat
@ -733,27 +679,6 @@ impl XdgShellHandler for State {
}
}
// fn ack_configure(&mut self, surface: WlSurface, configure: Configure) {
// if let Some(window) = self.window_for_surface(&surface) {
// if let LocationRequestState::Requested(serial, new_loc) =
// window.with_state(|state| state.loc_request_state.clone())
// {
// match &configure {
// Configure::Toplevel(configure) => {
// if configure.serial >= serial {
// tracing::debug!("acked configure, new loc is {:?}", new_loc);
// window.with_state(|state| {
// state.loc_request_state =
// LocationRequestState::Acknowledged(new_loc);
// });
// }
// }
// Configure::Popup(_) => todo!(),
// }
// }
// }
// }
fn fullscreen_request(&mut self, surface: ToplevelSurface, mut wl_output: Option<WlOutput>) {
if !surface
.current_state()

View file

@ -1,13 +1,15 @@
// SPDX-License-Identifier: GPL-3.0-or-later
use smithay::{
desktop::Window,
utils::{Logical, Point, Rectangle, SERIAL_COUNTER},
wayland::{
selection::data_device::{
clear_data_device_selection, current_data_device_selection_userdata,
request_data_device_client_selection, set_data_device_selection,
},
seat::WaylandFocus,
selection::{
data_device::{
clear_data_device_selection, current_data_device_selection_userdata,
request_data_device_client_selection, set_data_device_selection,
},
primary_selection::{
clear_primary_selection, current_primary_selection_userdata,
request_primary_client_selection, set_primary_selection,
@ -36,12 +38,12 @@ impl XwmHandler for State {
fn new_override_redirect_window(&mut self, _xwm: XwmId, _window: X11Surface) {}
fn map_window_request(&mut self, _xwm: XwmId, window: X11Surface) {
fn map_window_request(&mut self, _xwm: XwmId, surface: X11Surface) {
tracing::trace!("map_window_request");
assert!(!window.is_override_redirect());
assert!(!surface.is_override_redirect());
let window = WindowElement::X11(window);
let window = WindowElement::new(Window::new_x11_window(surface));
self.space.map_element(window.clone(), (0, 0), true);
let bbox = self
.space
@ -70,7 +72,7 @@ impl XwmHandler for State {
)
.into();
let WindowElement::X11(surface) = &window else {
let Some(surface) = window.x11_surface() else {
unreachable!()
};
@ -122,14 +124,14 @@ impl XwmHandler for State {
});
}
fn mapped_override_redirect_window(&mut self, _xwm: XwmId, window: X11Surface) {
fn mapped_override_redirect_window(&mut self, _xwm: XwmId, surface: X11Surface) {
tracing::trace!("mapped_override_redirect_window");
assert!(window.is_override_redirect());
assert!(surface.is_override_redirect());
let loc = window.geometry().loc;
let loc = surface.geometry().loc;
let window = WindowElement::X11OverrideRedirect(window);
let window = WindowElement::new(Window::new_x11_window(surface));
self.windows.push(window.clone());
self.z_index_stack.set_focus(window.clone());
@ -139,18 +141,20 @@ impl XwmHandler for State {
self.space.outputs().next(),
) {
window.place_on_output(output);
// FIXME: setting focus here may possibly muck things up
// | or maybe they won't idk
output.with_state(|state| state.focus_stack.set_focus(window.clone()))
}
self.space.map_element(window, loc, true);
}
fn unmapped_window(&mut self, _xwm: XwmId, window: X11Surface) {
fn unmapped_window(&mut self, _xwm: XwmId, surface: X11Surface) {
for output in self.space.outputs() {
output.with_state(|state| {
state.focus_stack.stack.retain(|win| {
win.wl_surface()
.is_some_and(|surf| Some(surf) != window.wl_surface())
.is_some_and(|surf| Some(surf) != surface.wl_surface())
})
});
}
@ -158,7 +162,7 @@ impl XwmHandler for State {
let win = self
.space
.elements()
.find(|elem| matches!(elem, WindowElement::X11(surface) if surface == &window))
.find(|elem| matches!(elem.x11_surface(), Some(surf) if surf == &surface))
.cloned();
if let Some(win) = win {
@ -178,8 +182,8 @@ impl XwmHandler for State {
if let Some(FocusTarget::Window(win)) = &focus {
self.space.raise_element(win, true);
self.z_index_stack.set_focus(win.clone());
if let WindowElement::Wayland(win) = &win {
win.toplevel().expect("in wayland enum").send_configure();
if let Some(toplevel) = win.toplevel() {
toplevel.send_configure();
}
}
@ -192,18 +196,18 @@ impl XwmHandler for State {
}
}
if !window.is_override_redirect() {
if !surface.is_override_redirect() {
tracing::debug!("set mapped to false");
window.set_mapped(false).expect("failed to unmap x11 win");
surface.set_mapped(false).expect("failed to unmap x11 win");
}
}
fn destroyed_window(&mut self, _xwm: XwmId, window: X11Surface) {
fn destroyed_window(&mut self, _xwm: XwmId, surface: X11Surface) {
for output in self.space.outputs() {
output.with_state(|state| {
state.focus_stack.stack.retain(|win| {
win.wl_surface()
.is_some_and(|surf| Some(surf) != window.wl_surface())
.is_some_and(|surf| Some(surf) != surface.wl_surface())
})
});
}
@ -213,10 +217,8 @@ impl XwmHandler for State {
.iter()
.find(|elem| {
matches!(
elem,
WindowElement::X11(surface)
| WindowElement::X11OverrideRedirect(surface)
if surface.wl_surface() == window.wl_surface()
elem.x11_surface(),
Some(surf) if surf.wl_surface() == surface.wl_surface()
)
})
.cloned();
@ -241,8 +243,8 @@ impl XwmHandler for State {
if let Some(FocusTarget::Window(win)) = &focus {
self.space.raise_element(win, true);
self.z_index_stack.set_focus(win.clone());
if let WindowElement::Wayland(win) = &win {
win.toplevel().expect("in wayland enum").send_configure();
if let Some(toplevel) = win.toplevel() {
toplevel.send_configure();
}
}
@ -283,14 +285,14 @@ impl XwmHandler for State {
fn configure_notify(
&mut self,
_xwm: XwmId,
window: X11Surface,
surface: X11Surface,
geometry: Rectangle<i32, Logical>,
_above: Option<smithay::reexports::x11rb::protocol::xproto::Window>,
) {
let Some(win) = self
.space
.elements()
.find(|elem| matches!(elem, WindowElement::X11(surface) if surface == &window))
.find(|elem| matches!(elem.x11_surface(), Some(surf) if surf == &surface))
.cloned()
else {
return;
@ -409,11 +411,12 @@ impl XwmHandler for State {
.get_keyboard()
.and_then(|kb| kb.current_focus())
.is_some_and(|focus| {
if let FocusTarget::Window(WindowElement::X11(surface)) = focus {
surface.xwm_id().expect("x11surface had no xwm id") == xwm
} else {
false
if let FocusTarget::Window(window) = focus {
if let Some(surface) = window.x11_surface() {
return surface.xwm_id().expect("x11surface had no xwm id") == xwm;
}
}
false
})
}

View file

@ -4,7 +4,7 @@ pub mod libinput;
use std::{collections::HashMap, mem::Discriminant};
use crate::{focus::FocusTarget, state::WithState, window::WindowElement};
use crate::{focus::FocusTarget, state::WithState};
use pinnacle_api_defs::pinnacle::input::v0alpha1::{
set_libinput_setting_request::Setting, set_mousebind_request, SetKeybindResponse,
SetMousebindResponse,
@ -351,14 +351,14 @@ impl State {
if !matches!(
&focus,
FocusTarget::Window(WindowElement::X11OverrideRedirect(_))
FocusTarget::Window(window) if window.is_x11_override_redirect()
) {
keyboard.set_focus(self, Some(focus.clone()), serial);
}
for window in self.space.elements() {
if let WindowElement::Wayland(window) = window {
window.toplevel().expect("in wayland enum").send_configure();
if let Some(toplevel) = window.toplevel() {
toplevel.send_configure();
}
}
} else {
@ -367,8 +367,8 @@ impl State {
state.focus_stack.unset_focus();
for window in state.focus_stack.stack.iter() {
window.set_activate(false);
if let WindowElement::Wayland(window) = window {
window.toplevel().expect("in wayland enum").send_configure();
if let Some(toplevel) = window.toplevel() {
toplevel.send_configure();
}
}
});

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later
use smithay::{
desktop::layer_map_for_output,
desktop::{layer_map_for_output, WindowSurface},
output::Output,
utils::{Logical, Point, Rectangle, Serial, Size},
wayland::{compositor, shell::xdg::XdgToplevelSurfaceData},
@ -115,26 +115,20 @@ impl State {
for win in windows_on_foc_tags.iter() {
if win.with_state(|state| state.target_loc.is_some()) {
match win {
WindowElement::Wayland(wl_win) => {
let pending = compositor::with_states(
wl_win.toplevel().expect("in wayland enum").wl_surface(),
|states| {
states
.data_map
.get::<XdgToplevelSurfaceData>()
.expect("XdgToplevelSurfaceData wasn't in surface's data map")
.lock()
.expect("Failed to lock Mutex<XdgToplevelSurfaceData>")
.has_pending_changes()
},
);
match win.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
let pending = compositor::with_states(toplevel.wl_surface(), |states| {
states
.data_map
.get::<XdgToplevelSurfaceData>()
.expect("XdgToplevelSurfaceData wasn't in surface's data map")
.lock()
.expect("Failed to lock Mutex<XdgToplevelSurfaceData>")
.has_pending_changes()
});
if pending {
pending_wins.push((
win.clone(),
wl_win.toplevel().expect("in wayland enum").send_configure(),
))
pending_wins.push((win.clone(), toplevel.send_configure()))
} else {
let loc = win.with_state(|state| state.target_loc.take());
if let Some(loc) = loc {
@ -142,14 +136,12 @@ impl State {
}
}
}
WindowElement::X11(_) => {
WindowSurface::X11(_) => {
let loc = win.with_state(|state| state.target_loc.take());
if let Some(loc) = loc {
self.space.map_element(win.clone(), loc, false);
}
}
WindowElement::X11OverrideRedirect(_) => (),
_ => unreachable!(),
}
}
}

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
use std::sync::Mutex;
use std::{ops::Deref, sync::Mutex};
use smithay::{
backend::renderer::{
@ -71,18 +71,8 @@ where
scale: Scale<f64>,
alpha: f32,
) -> Vec<C> {
match self {
WindowElement::Wayland(window) => {
window.render_elements(renderer, location, scale, alpha)
}
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
surface.render_elements(renderer, location, scale, alpha)
}
_ => unreachable!(),
}
.into_iter()
.map(C::from)
.collect()
self.deref()
.render_elements(renderer, location, scale, alpha)
}
}
@ -307,10 +297,8 @@ where
let top_fullscreen_window = windows.iter().rev().find(|win| {
let is_wayland_actually_fullscreen = {
if let WindowElement::Wayland(window) = win {
window
.toplevel()
.expect("in wayland enum")
if let Some(toplevel) = win.toplevel() {
toplevel
.current_state()
.states
.contains(xdg_toplevel::State::Fullscreen)

View file

@ -2,40 +2,23 @@
pub mod rules;
use std::{cell::RefCell, time::Duration};
use std::{cell::RefCell, ops::Deref};
use pinnacle_api_defs::pinnacle::signal::v0alpha1::{
WindowPointerEnterResponse, WindowPointerLeaveResponse,
};
use smithay::{
backend::input::KeyState,
desktop::{
utils::{
send_dmabuf_feedback_surface_tree, send_frames_surface_tree,
take_presentation_feedback_surface_tree, with_surfaces_surface_tree,
OutputPresentationFeedback,
},
Window,
},
desktop::{space::SpaceElement, Window, WindowSurface},
input::{
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
pointer::{AxisFrame, MotionEvent, PointerTarget},
Seat,
},
output::Output,
reexports::{
wayland_protocols::wp::presentation_time::server::wp_presentation_feedback,
wayland_server::protocol::wl_surface::WlSurface,
},
space_elements,
utils::{user_data::UserDataMap, Logical, Rectangle, Serial},
wayland::{
compositor::{self, SurfaceData},
dmabuf::DmabufFeedback,
seat::WaylandFocus,
shell::xdg::XdgToplevelSurfaceData,
},
xwayland::X11Surface,
reexports::wayland_server::protocol::wl_surface::WlSurface,
utils::{IsAlive, Logical, Point, Rectangle, Serial},
wayland::{compositor, seat::WaylandFocus, shell::xdg::XdgToplevelSurfaceData},
};
use crate::state::{State, WithState};
@ -44,143 +27,20 @@ use self::window_state::WindowElementState;
pub mod window_state;
space_elements! {
/// The different types of windows.
#[derive(Debug, Clone, PartialEq)]
pub WindowElement;
/// This is a native Wayland window.
Wayland = Window,
/// This is an Xwayland window.
X11 = X11Surface,
/// This is an Xwayland override redirect window, which should not be messed with.
X11OverrideRedirect = X11Surface,
#[derive(Debug, Clone, PartialEq)]
pub struct WindowElement(Window);
impl Deref for WindowElement {
type Target = Window;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl WindowElement {
pub fn with_surfaces<F>(&self, processor: F)
where
F: FnMut(&WlSurface, &SurfaceData) + Copy,
{
match self {
WindowElement::Wayland(window) => window.with_surfaces(processor),
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
if let Some(surface) = surface.wl_surface() {
with_surfaces_surface_tree(&surface, processor);
}
}
_ => unreachable!(),
}
}
pub fn send_frame<T, F>(
&self,
output: &Output,
time: T,
throttle: Option<Duration>,
primary_scan_out_output: F,
) where
T: Into<Duration>,
F: FnMut(&WlSurface, &SurfaceData) -> Option<Output> + Copy,
{
match self {
WindowElement::Wayland(window) => {
window.send_frame(output, time, throttle, primary_scan_out_output)
}
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
if let Some(surface) = surface.wl_surface() {
send_frames_surface_tree(
&surface,
output,
time,
throttle,
primary_scan_out_output,
);
}
}
_ => unreachable!(),
}
}
pub fn send_dmabuf_feedback<'a, P, F>(
&self,
output: &Output,
primary_scan_out_output: P,
select_dmabuf_feedback: F,
) where
P: FnMut(&WlSurface, &SurfaceData) -> Option<Output> + Copy,
F: Fn(&WlSurface, &SurfaceData) -> &'a DmabufFeedback + Copy,
{
match self {
WindowElement::Wayland(window) => {
window.send_dmabuf_feedback(
output,
primary_scan_out_output,
select_dmabuf_feedback,
);
}
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
if let Some(surface) = surface.wl_surface() {
send_dmabuf_feedback_surface_tree(
&surface,
output,
primary_scan_out_output,
select_dmabuf_feedback,
);
}
}
_ => unreachable!(),
}
}
pub fn take_presentation_feedback<F1, F2>(
&self,
output_feedback: &mut OutputPresentationFeedback,
primary_scan_out_output: F1,
presentation_feedback_flags: F2,
) where
F1: FnMut(&WlSurface, &SurfaceData) -> Option<Output> + Copy,
F2: FnMut(&WlSurface, &SurfaceData) -> wp_presentation_feedback::Kind + Copy,
{
match self {
WindowElement::Wayland(window) => {
window.take_presentation_feedback(
output_feedback,
primary_scan_out_output,
presentation_feedback_flags,
);
}
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
if let Some(surface) = surface.wl_surface() {
take_presentation_feedback_surface_tree(
&surface,
output_feedback,
primary_scan_out_output,
presentation_feedback_flags,
);
}
}
_ => unreachable!(),
}
}
pub fn wl_surface(&self) -> Option<WlSurface> {
match self {
WindowElement::Wayland(window) => window.wl_surface(),
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
surface.wl_surface()
}
_ => unreachable!(),
}
}
pub fn user_data(&self) -> &UserDataMap {
match self {
WindowElement::Wayland(window) => window.user_data(),
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
surface.user_data()
}
_ => unreachable!(),
}
pub fn new(window: Window) -> Self {
Self(window)
}
/// Send a geometry change without mapping windows or sending
@ -191,16 +51,13 @@ impl WindowElement {
/// RefCell Safety: This method uses a [`RefCell`] on this window.
// TODO: ^ does that make things flicker?
pub fn change_geometry(&self, new_geo: Rectangle<i32, Logical>) {
match self {
WindowElement::Wayland(window) => {
window
.toplevel()
.expect("in wayland enum")
.with_pending_state(|state| {
state.size = Some(new_geo.size);
});
match self.0.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
toplevel.with_pending_state(|state| {
state.size = Some(new_geo.size);
});
}
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
WindowSurface::X11(surface) => {
// TODO: maybe move this check elsewhere idk
if !surface.is_override_redirect() {
surface
@ -208,21 +65,16 @@ impl WindowElement {
.expect("failed to configure x11 win");
}
}
_ => unreachable!(),
}
self.with_state(|state| {
state.target_loc = Some(new_geo.loc);
});
// self.with_state(|state| {
// state.loc_request_state = LocationRequestState::Sent(new_geo.loc);
// });
}
pub fn class(&self) -> Option<String> {
match self {
WindowElement::Wayland(window) => compositor::with_states(
window.toplevel().expect("in wayland enum").wl_surface(),
|states| {
match self.0.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
compositor::with_states(toplevel.wl_surface(), |states| {
states
.data_map
.get::<XdgToplevelSurfaceData>()
@ -231,20 +83,16 @@ impl WindowElement {
.expect("Failed to lock Mutex<XdgToplevelSurfaceData>")
.app_id
.clone()
},
),
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
Some(surface.class())
})
}
_ => unreachable!(),
WindowSurface::X11(surface) => Some(surface.class()),
}
}
pub fn title(&self) -> Option<String> {
match self {
WindowElement::Wayland(window) => compositor::with_states(
window.toplevel().expect("in wayland enum").wl_surface(),
|states| {
match self.0.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
compositor::with_states(toplevel.wl_surface(), |states| {
states
.data_map
.get::<XdgToplevelSurfaceData>()
@ -253,12 +101,9 @@ impl WindowElement {
.expect("Failed to lock Mutex<XdgToplevelSurfaceData>")
.title
.clone()
},
),
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
Some(surface.title())
})
}
_ => unreachable!(),
WindowSurface::X11(surface) => Some(surface.title()),
}
}
@ -312,58 +157,67 @@ impl WindowElement {
});
}
/// Returns `true` if the window element is [`Wayland`].
///
/// [`Wayland`]: WindowElement::Wayland
#[must_use]
pub fn is_wayland(&self) -> bool {
matches!(self, Self::Wayland(..))
}
/// Returns `true` if the window element is [`X11`].
///
/// [`X11`]: WindowElement::X11
#[must_use]
pub fn is_x11(&self) -> bool {
matches!(self, Self::X11(..))
}
/// Returns `true` if the window element is [`X11OverrideRedirect`].
///
/// [`X11OverrideRedirect`]: WindowElement::X11OverrideRedirect
#[must_use]
pub fn is_x11_override_redirect(&self) -> bool {
matches!(self, Self::X11OverrideRedirect(..))
matches!(self.x11_surface(), Some(surface) if surface.is_override_redirect())
}
}
impl SpaceElement for WindowElement {
fn bbox(&self) -> Rectangle<i32, Logical> {
self.0.bbox()
}
fn is_in_input_region(&self, point: &Point<f64, Logical>) -> bool {
self.0.is_in_input_region(point)
}
fn set_activate(&self, activated: bool) {
self.0.set_activate(activated)
}
fn output_enter(&self, output: &Output, overlap: Rectangle<i32, Logical>) {
self.0.output_enter(output, overlap)
}
fn output_leave(&self, output: &Output) {
self.0.output_leave(output)
}
fn geometry(&self) -> Rectangle<i32, Logical> {
self.0.geometry()
}
fn z_index(&self) -> u8 {
self.0.z_index()
}
fn refresh(&self) {
self.0.refresh();
}
}
impl IsAlive for WindowElement {
fn alive(&self) -> bool {
self.0.alive()
}
}
impl PointerTarget<State> for WindowElement {
fn frame(&self, seat: &Seat<State>, state: &mut State) {
match self {
WindowElement::Wayland(window) => window
.wl_surface()
.expect("in wayland enum")
.frame(seat, state),
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
surface.frame(seat, state)
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
PointerTarget::frame(toplevel.wl_surface(), seat, state);
}
_ => unreachable!(),
WindowSurface::X11(surface) => PointerTarget::frame(surface, seat, state),
}
}
fn enter(&self, seat: &Seat<State>, state: &mut State, event: &MotionEvent) {
// TODO: ssd
match self {
WindowElement::Wayland(window) => PointerTarget::enter(
&window.wl_surface().expect("in wayland enum"),
seat,
state,
event,
),
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
PointerTarget::enter(surface, seat, state, event)
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
PointerTarget::enter(toplevel.wl_surface(), seat, state, event);
}
_ => unreachable!(),
WindowSurface::X11(surface) => PointerTarget::enter(surface, seat, state, event),
}
let window_id = Some(self.with_state(|state| state.id.0));
@ -375,18 +229,11 @@ impl PointerTarget<State> for WindowElement {
}
fn motion(&self, seat: &Seat<State>, state: &mut State, event: &MotionEvent) {
// TODO: ssd
match self {
WindowElement::Wayland(window) => PointerTarget::motion(
&window.wl_surface().expect("in wayland enum"),
seat,
state,
event,
),
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
PointerTarget::motion(surface, seat, state, event)
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
PointerTarget::motion(toplevel.wl_surface(), seat, state, event);
}
_ => unreachable!(),
WindowSurface::X11(surface) => PointerTarget::motion(surface, seat, state, event),
}
}
@ -396,20 +243,13 @@ impl PointerTarget<State> for WindowElement {
state: &mut State,
event: &smithay::input::pointer::RelativeMotionEvent,
) {
// TODO: ssd
match self {
WindowElement::Wayland(window) => {
PointerTarget::relative_motion(
&window.wl_surface().expect("in wayland enum"),
seat,
state,
event,
);
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
PointerTarget::relative_motion(toplevel.wl_surface(), seat, state, event);
}
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
WindowSurface::X11(surface) => {
PointerTarget::relative_motion(surface, seat, state, event);
}
_ => unreachable!(),
}
}
@ -419,53 +259,29 @@ impl PointerTarget<State> for WindowElement {
state: &mut State,
event: &smithay::input::pointer::ButtonEvent,
) {
// TODO: ssd
match self {
WindowElement::Wayland(window) => PointerTarget::button(
&window.wl_surface().expect("in wayland enum"),
seat,
state,
event,
),
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
PointerTarget::button(surface, seat, state, event)
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
PointerTarget::button(toplevel.wl_surface(), seat, state, event);
}
_ => unreachable!(),
WindowSurface::X11(surface) => PointerTarget::button(surface, seat, state, event),
}
}
fn axis(&self, seat: &Seat<State>, state: &mut State, frame: AxisFrame) {
// TODO: ssd
match self {
WindowElement::Wayland(window) => PointerTarget::axis(
&window.wl_surface().expect("in wayland enum"),
seat,
state,
frame,
),
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
PointerTarget::axis(surface, seat, state, frame)
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
PointerTarget::axis(toplevel.wl_surface(), seat, state, frame);
}
_ => unreachable!(),
WindowSurface::X11(surface) => PointerTarget::axis(surface, seat, state, frame),
}
}
fn leave(&self, seat: &Seat<State>, state: &mut State, serial: Serial, time: u32) {
// TODO: ssd
match self {
WindowElement::Wayland(window) => {
PointerTarget::leave(
&window.wl_surface().expect("in wayland enum"),
seat,
state,
serial,
time,
);
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
PointerTarget::leave(toplevel.wl_surface(), seat, state, serial, time);
}
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
PointerTarget::leave(surface, seat, state, serial, time)
}
_ => unreachable!(),
WindowSurface::X11(surface) => PointerTarget::leave(surface, seat, state, serial, time),
}
let window_id = Some(self.with_state(|state| state.id.0));
@ -557,35 +373,22 @@ impl KeyboardTarget<State> for WindowElement {
keys: Vec<KeysymHandle<'_>>,
serial: Serial,
) {
match self {
WindowElement::Wayland(window) => {
KeyboardTarget::enter(
&window.wl_surface().expect("in wayland enum"),
seat,
state,
keys,
serial,
);
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
KeyboardTarget::enter(toplevel.wl_surface(), seat, state, keys, serial);
}
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
KeyboardTarget::enter(surface, seat, state, keys, serial)
WindowSurface::X11(surface) => {
KeyboardTarget::enter(surface, seat, state, keys, serial);
}
_ => unreachable!(),
}
}
fn leave(&self, seat: &Seat<State>, state: &mut State, serial: Serial) {
match self {
WindowElement::Wayland(window) => KeyboardTarget::leave(
&window.wl_surface().expect("in wayland enum"),
seat,
state,
serial,
),
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
KeyboardTarget::leave(surface, seat, state, serial)
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
KeyboardTarget::leave(toplevel.wl_surface(), seat, state, serial);
}
_ => unreachable!(),
WindowSurface::X11(surface) => KeyboardTarget::leave(surface, seat, state, serial),
}
}
@ -598,10 +401,10 @@ impl KeyboardTarget<State> for WindowElement {
serial: Serial,
time: u32,
) {
match self {
WindowElement::Wayland(window) => {
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
KeyboardTarget::key(
&window.wl_surface().expect("in wayland enum"),
toplevel.wl_surface(),
seat,
state,
key,
@ -610,10 +413,9 @@ impl KeyboardTarget<State> for WindowElement {
time,
);
}
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
WindowSurface::X11(surface) => {
KeyboardTarget::key(surface, seat, state, key, key_state, serial, time);
}
_ => unreachable!(),
}
}
@ -624,20 +426,13 @@ impl KeyboardTarget<State> for WindowElement {
modifiers: ModifiersState,
serial: Serial,
) {
match self {
WindowElement::Wayland(window) => {
KeyboardTarget::modifiers(
&window.wl_surface().expect("in wayland enum"),
seat,
state,
modifiers,
serial,
);
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
KeyboardTarget::modifiers(toplevel.wl_surface(), seat, state, modifiers, serial);
}
WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => {
WindowSurface::X11(surface) => {
KeyboardTarget::modifiers(surface, seat, state, modifiers, serial);
}
_ => unreachable!(),
}
}
}
@ -663,12 +458,18 @@ impl State {
self.space
.elements()
.find(|window| window.wl_surface().map(|s| s == *surface).unwrap_or(false))
.cloned()
.or_else(|| {
self.windows
.iter()
.find(|&win| win.wl_surface().is_some_and(|surf| &surf == surface))
.cloned()
})
.cloned()
}
pub fn new_window_for_surface(&self, surface: &WlSurface) -> Option<WindowElement> {
self.new_windows
.iter()
.find(|&win| win.wl_surface().is_some_and(|surf| &surf == surface))
.cloned()
}
}

View file

@ -3,7 +3,7 @@
use std::sync::atomic::{AtomicU32, Ordering};
use smithay::{
desktop::space::SpaceElement,
desktop::{space::SpaceElement, WindowSurface},
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel,
utils::{Logical, Point, Rectangle},
};
@ -81,30 +81,27 @@ impl WindowElement {
state.fullscreen_or_maximized = FullscreenOrMaximized::Fullscreen;
});
match self {
WindowElement::Wayland(window) => {
window
.toplevel()
.expect("in wayland enum")
.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::TiledLeft);
state.states.set(xdg_toplevel::State::TiledBottom);
state.states.set(xdg_toplevel::State::TiledRight);
});
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
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::TiledLeft);
state.states.set(xdg_toplevel::State::TiledBottom);
state.states.set(xdg_toplevel::State::TiledRight);
});
}
WindowElement::X11(surface) => {
surface
.set_maximized(false)
.expect("failed to set x11 win to maximized");
surface
.set_fullscreen(true)
.expect("failed to set x11 win to not fullscreen");
WindowSurface::X11(surface) => {
if !surface.is_override_redirect() {
surface
.set_maximized(false)
.expect("failed to set x11 win to maximized");
surface
.set_fullscreen(true)
.expect("failed to set x11 win to not fullscreen");
}
}
WindowElement::X11OverrideRedirect(_) => (),
_ => unreachable!(),
}
}
FullscreenOrMaximized::Fullscreen => {
@ -131,30 +128,27 @@ impl WindowElement {
state.fullscreen_or_maximized = FullscreenOrMaximized::Maximized;
});
match self {
WindowElement::Wayland(window) => {
window
.toplevel()
.expect("in wayland enum")
.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::TiledLeft);
state.states.set(xdg_toplevel::State::TiledBottom);
state.states.set(xdg_toplevel::State::TiledRight);
});
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
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::TiledLeft);
state.states.set(xdg_toplevel::State::TiledBottom);
state.states.set(xdg_toplevel::State::TiledRight);
});
}
WindowElement::X11(surface) => {
surface
.set_maximized(true)
.expect("failed to set x11 win to maximized");
surface
.set_fullscreen(false)
.expect("failed to set x11 win to not fullscreen");
WindowSurface::X11(surface) => {
if !surface.is_override_redirect() {
surface
.set_maximized(true)
.expect("failed to set x11 win to maximized");
surface
.set_fullscreen(false)
.expect("failed to set x11 win to not fullscreen");
}
}
WindowElement::X11OverrideRedirect(_) => (),
_ => unreachable!(),
}
}
FullscreenOrMaximized::Maximized => {
@ -176,60 +170,54 @@ impl WindowElement {
/// Unsets maximized and fullscreen states for both wayland and xwayland windows
/// and unsets tiled states for wayland windows.
fn set_floating_states(&self) {
match self {
WindowElement::Wayland(window) => {
window
.toplevel()
.expect("in wayland enum")
.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::TiledLeft);
state.states.unset(xdg_toplevel::State::TiledBottom);
state.states.unset(xdg_toplevel::State::TiledRight);
});
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
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::TiledLeft);
state.states.unset(xdg_toplevel::State::TiledBottom);
state.states.unset(xdg_toplevel::State::TiledRight);
});
}
WindowElement::X11(surface) => {
surface
.set_maximized(false)
.expect("failed to set x11 win to maximized");
surface
.set_fullscreen(false)
.expect("failed to set x11 win to not fullscreen");
WindowSurface::X11(surface) => {
if !surface.is_override_redirect() {
surface
.set_maximized(false)
.expect("failed to set x11 win to maximized");
surface
.set_fullscreen(false)
.expect("failed to set x11 win to not fullscreen");
}
}
WindowElement::X11OverrideRedirect(_) => (),
_ => unreachable!(),
}
}
/// Unsets maximized and fullscreen states for both wayland and xwayland windows
/// and sets tiled states for wayland windows.
fn set_tiled_states(&self) {
match self {
WindowElement::Wayland(window) => {
window
.toplevel()
.expect("in wayland enum")
.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::TiledLeft);
state.states.set(xdg_toplevel::State::TiledBottom);
state.states.set(xdg_toplevel::State::TiledRight);
});
match self.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
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::TiledLeft);
state.states.set(xdg_toplevel::State::TiledBottom);
state.states.set(xdg_toplevel::State::TiledRight);
});
}
WindowElement::X11(surface) => {
surface
.set_maximized(false)
.expect("failed to set x11 win to maximized");
surface
.set_fullscreen(false)
.expect("failed to set x11 win to not fullscreen");
WindowSurface::X11(surface) => {
if !surface.is_override_redirect() {
surface
.set_maximized(false)
.expect("failed to set x11 win to maximized");
surface
.set_fullscreen(false)
.expect("failed to set x11 win to not fullscreen");
}
}
WindowElement::X11OverrideRedirect(_) => (),
_ => unreachable!(),
}
}
}