xwm: More fixes
This commit is contained in:
parent
1d28574088
commit
9b1221edc5
14 changed files with 311 additions and 80 deletions
|
|
@ -332,10 +332,10 @@ impl CosmicMapped {
|
|||
window.is_activated()
|
||||
}
|
||||
|
||||
pub fn set_size(&self, size: Size<i32, Logical>) {
|
||||
pub fn set_geometry(&self, geo: Rectangle<i32, Logical>) {
|
||||
match &self.element {
|
||||
CosmicMappedInternal::Stack(s) => s.set_size(size),
|
||||
CosmicMappedInternal::Window(w) => w.set_size(size),
|
||||
CosmicMappedInternal::Stack(s) => s.set_geometry(geo),
|
||||
CosmicMappedInternal::Window(w) => w.set_geometry(geo),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,15 +150,16 @@ impl CosmicStack {
|
|||
Point::from((0, TAB_HEIGHT))
|
||||
}
|
||||
|
||||
pub fn set_size(&self, size: Size<i32, Logical>) {
|
||||
pub fn set_geometry(&self, geo: Rectangle<i32, Logical>) {
|
||||
self.0.with_program(|p| {
|
||||
let surface_size = (size.w, size.h - TAB_HEIGHT).into();
|
||||
let loc = (geo.loc.x, geo.loc.y + TAB_HEIGHT);
|
||||
let size = (geo.size.w, geo.size.h - TAB_HEIGHT);
|
||||
|
||||
for window in p.windows.lock().unwrap().iter() {
|
||||
window.set_size(surface_size);
|
||||
window.set_geometry(Rectangle::from_loc_and_size(loc, size));
|
||||
}
|
||||
});
|
||||
self.0.resize(Size::from((size.w, TAB_HEIGHT)));
|
||||
self.0.resize(Size::from((geo.size.w, TAB_HEIGHT)));
|
||||
}
|
||||
|
||||
fn keyboard_leave_if_previous(
|
||||
|
|
|
|||
|
|
@ -102,14 +102,13 @@ impl CosmicSurface {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_size(&self, size: Size<i32, Logical>) {
|
||||
pub fn set_geometry(&self, geo: Rectangle<i32, Logical>) {
|
||||
match self {
|
||||
CosmicSurface::Wayland(window) => window
|
||||
.toplevel()
|
||||
.with_pending_state(|state| state.size = Some(size)),
|
||||
.with_pending_state(|state| state.size = Some(geo.size)),
|
||||
CosmicSurface::X11(surface) => {
|
||||
let rect = Rectangle::from_loc_and_size(surface.geometry().loc, size);
|
||||
let _ = surface.configure(rect);
|
||||
let _ = surface.configure(geo);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -296,6 +295,13 @@ impl CosmicSurface {
|
|||
CosmicSurface::X11(surface) => surface.min_size(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.map(|size| {
|
||||
if self.is_decorated() {
|
||||
size + (0, SSD_HEIGHT).into()
|
||||
} else {
|
||||
size
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn max_size(&self) -> Option<Size<i32, Logical>> {
|
||||
|
|
@ -315,6 +321,13 @@ impl CosmicSurface {
|
|||
CosmicSurface::X11(surface) => surface.max_size(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.map(|size| {
|
||||
if self.is_decorated() {
|
||||
size + (0, SSD_HEIGHT).into()
|
||||
} else {
|
||||
size
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn send_configure(&self) {
|
||||
|
|
|
|||
|
|
@ -120,12 +120,20 @@ impl CosmicWindow {
|
|||
))
|
||||
}
|
||||
|
||||
pub fn set_size(&self, size: Size<i32, Logical>) {
|
||||
pub fn set_geometry(&self, geo: Rectangle<i32, Logical>) {
|
||||
self.0.with_program(|p| {
|
||||
let surface_size = (size.w, size.h - if p.has_ssd() { SSD_HEIGHT } else { 0 }).into();
|
||||
p.window.set_size(surface_size)
|
||||
let loc = (
|
||||
geo.loc.x,
|
||||
geo.loc.y + if p.has_ssd() { SSD_HEIGHT } else { 0 },
|
||||
);
|
||||
let size = (
|
||||
geo.size.w,
|
||||
geo.size.h - if p.has_ssd() { SSD_HEIGHT } else { 0 },
|
||||
);
|
||||
p.window
|
||||
.set_geometry(Rectangle::from_loc_and_size(loc, size));
|
||||
});
|
||||
self.0.resize(Size::from((size.w, SSD_HEIGHT)));
|
||||
self.0.resize(Size::from((geo.size.w, SSD_HEIGHT)));
|
||||
}
|
||||
|
||||
pub fn surface(&self) -> CosmicSurface {
|
||||
|
|
@ -264,6 +272,7 @@ impl SpaceElement for CosmicWindow {
|
|||
self.0.with_program(|p| {
|
||||
let mut bbox = SpaceElement::bbox(&p.window);
|
||||
if p.has_ssd() {
|
||||
bbox.loc.y -= SSD_HEIGHT;
|
||||
bbox.size.h += SSD_HEIGHT;
|
||||
}
|
||||
bbox
|
||||
|
|
@ -301,6 +310,7 @@ impl SpaceElement for CosmicWindow {
|
|||
self.0.with_program(|p| {
|
||||
let mut geo = SpaceElement::geometry(&p.window);
|
||||
if p.has_ssd() {
|
||||
geo.loc.y -= SSD_HEIGHT;
|
||||
geo.size.h += SSD_HEIGHT;
|
||||
}
|
||||
geo
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use smithay::{
|
|||
Seat,
|
||||
},
|
||||
output::Output,
|
||||
utils::{IsAlive, Logical, Point, Serial},
|
||||
utils::{IsAlive, Logical, Point, Rectangle, Serial},
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
|
||||
|
|
@ -183,6 +183,10 @@ impl MoveSurfaceGrab {
|
|||
.output_geometry(&output)
|
||||
.unwrap()
|
||||
.loc;
|
||||
grab_state.window.set_geometry(Rectangle::from_loc_and_size(
|
||||
window_location + offset,
|
||||
grab_state.window.geometry().size,
|
||||
));
|
||||
state
|
||||
.common
|
||||
.shell
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use smithay::{
|
|||
AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab,
|
||||
PointerInnerHandle,
|
||||
},
|
||||
utils::{IsAlive, Logical, Point, Size},
|
||||
utils::{IsAlive, Logical, Point, Rectangle, Size},
|
||||
};
|
||||
|
||||
/// Information about the resize operation.
|
||||
|
|
@ -97,7 +97,10 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
|
|||
self.last_window_size = (new_window_width, new_window_height).into();
|
||||
|
||||
self.window.set_resizing(true);
|
||||
self.window.set_size(self.last_window_size);
|
||||
self.window.set_geometry(Rectangle::from_loc_and_size(
|
||||
self.window.geometry().loc,
|
||||
self.last_window_size,
|
||||
));
|
||||
self.window.configure();
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +121,10 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
|
|||
}
|
||||
|
||||
self.window.set_resizing(false);
|
||||
self.window.set_size(self.last_window_size);
|
||||
self.window.set_geometry(Rectangle::from_loc_and_size(
|
||||
self.window.geometry().loc,
|
||||
self.last_window_size,
|
||||
));
|
||||
self.window.configure();
|
||||
|
||||
let mut resize_state = self.window.resize_state.lock().unwrap();
|
||||
|
|
@ -220,6 +226,9 @@ impl ResizeSurfaceGrab {
|
|||
);
|
||||
}
|
||||
}
|
||||
let mut geometry = window.geometry();
|
||||
geometry.loc = new_location;
|
||||
let _ = window.set_geometry(geometry);
|
||||
space
|
||||
.floating_layer
|
||||
.space
|
||||
|
|
|
|||
|
|
@ -75,9 +75,7 @@ impl FloatingLayout {
|
|||
let geometry = layers.non_exclusive_zone();
|
||||
let last_geometry = mapped.last_geometry.lock().unwrap().clone();
|
||||
|
||||
let mut geo_updated = false;
|
||||
if let Some(size) = last_geometry.map(|g| g.size) {
|
||||
geo_updated = win_geo.size != size;
|
||||
win_geo.size = size;
|
||||
}
|
||||
{
|
||||
|
|
@ -98,7 +96,6 @@ impl FloatingLayout {
|
|||
}
|
||||
// but no matter the supported sizes, don't be larger than our non-exclusive-zone
|
||||
win_geo.size.w = std::cmp::min(width, geometry.size.w);
|
||||
geo_updated = true;
|
||||
}
|
||||
if win_geo.size.h > geometry.size.h / 3 * 2 {
|
||||
// try a more reasonable size
|
||||
|
|
@ -113,7 +110,6 @@ impl FloatingLayout {
|
|||
}
|
||||
// but no matter the supported sizes, don't be larger than our non-exclusive-zone
|
||||
win_geo.size.h = std::cmp::min(height, geometry.size.h);
|
||||
geo_updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,11 +124,8 @@ impl FloatingLayout {
|
|||
});
|
||||
|
||||
mapped.set_tiled(false);
|
||||
if geo_updated {
|
||||
mapped.set_size(win_geo.size);
|
||||
}
|
||||
mapped.set_geometry(Rectangle::from_loc_and_size(position, win_geo.size));
|
||||
mapped.configure();
|
||||
|
||||
self.space.map_element(mapped, position, false);
|
||||
}
|
||||
|
||||
|
|
@ -183,8 +176,8 @@ impl FloatingLayout {
|
|||
if let Some(mapped) = maybe_mapped {
|
||||
let last_geometry = mapped.last_geometry.lock().unwrap().clone();
|
||||
let last_size = last_geometry.map(|g| g.size).expect("No previous size?");
|
||||
mapped.set_size(last_size);
|
||||
let last_location = last_geometry.map(|g| g.loc).expect("No previous location?");
|
||||
mapped.set_geometry(Rectangle::from_loc_and_size(last_location, last_size));
|
||||
self.space.map_element(mapped, last_location, true);
|
||||
Some(last_size)
|
||||
} else {
|
||||
|
|
@ -293,6 +286,7 @@ impl FloatingLayout {
|
|||
.get(&output)
|
||||
.copied()
|
||||
.unwrap_or_else(|| (0, 0).into());
|
||||
element.set_geometry(elem_geo);
|
||||
self.space.map_element(element.clone(), elem_geo.loc, false);
|
||||
}
|
||||
self.refresh(); //fixup any out of bounds elements
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ lazy_static::lazy_static! {
|
|||
r"update-manager",
|
||||
r"Solaar",
|
||||
r"Steam",
|
||||
r"",
|
||||
r"TelegramDesktop",
|
||||
r"Zotero",
|
||||
r"gjs",
|
||||
|
|
@ -77,6 +78,7 @@ lazy_static::lazy_static! {
|
|||
r"Software Updater",
|
||||
r".*",
|
||||
r"^.*?(Guard|Login).*",
|
||||
r"Steam",
|
||||
r"Media viewer",
|
||||
r"Quick Format Citation",
|
||||
r".*",
|
||||
|
|
|
|||
|
|
@ -1129,14 +1129,17 @@ impl TilingLayout {
|
|||
data.update_geometry(geo);
|
||||
}
|
||||
Data::Mapped { mapped, .. } => {
|
||||
geo.loc += (inner, inner).into();
|
||||
if !(mapped.is_fullscreen() || mapped.is_maximized()) {
|
||||
mapped.set_tiled(true);
|
||||
mapped.set_size(
|
||||
(geo.size.w - inner * 2, geo.size.h - inner * 2).into(),
|
||||
);
|
||||
mapped.configure();
|
||||
let size = (geo.size.w - inner * 2, geo.size.h - inner * 2);
|
||||
let internal_geometry =
|
||||
Rectangle::from_loc_and_size(geo.loc, size);
|
||||
if mapped.geometry() != internal_geometry {
|
||||
mapped.set_geometry(internal_geometry);
|
||||
mapped.configure();
|
||||
}
|
||||
}
|
||||
geo.loc += (inner, inner).into();
|
||||
data.update_geometry(geo);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,16 +3,14 @@ use std::{cell::RefCell, collections::HashMap};
|
|||
|
||||
use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState;
|
||||
use smithay::{
|
||||
backend::renderer::element::Id,
|
||||
desktop::{layer_map_for_output, LayerSurface, PopupManager, WindowSurfaceType},
|
||||
input::{
|
||||
pointer::{Focus, GrabStartData as PointerGrabStartData},
|
||||
Seat,
|
||||
},
|
||||
output::Output,
|
||||
reexports::{
|
||||
wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle},
|
||||
x11rb::protocol::xproto::Window as X11Window,
|
||||
},
|
||||
reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle},
|
||||
utils::{Logical, Point, Rectangle, Serial, SERIAL_COUNTER},
|
||||
wayland::{
|
||||
compositor::with_states,
|
||||
|
|
@ -71,9 +69,17 @@ pub struct Shell {
|
|||
pub workspace_state: WorkspaceState<State>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OverrideRedirectWindow {
|
||||
pub surface: X11Surface,
|
||||
pub above: Option<X11Window>,
|
||||
pub above: Ordering,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Ordering {
|
||||
Above,
|
||||
AboveWindow(Id),
|
||||
Below,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -837,12 +843,25 @@ impl Shell {
|
|||
Some(output) => {
|
||||
Box::new(std::iter::once(output.clone())) as Box<dyn Iterator<Item = Output>>
|
||||
}
|
||||
None => Box::new(self.outputs().map(|o| self.active_space(o)).flat_map(|w| {
|
||||
w.mapped()
|
||||
.find(|e| e.has_surface(surface, WindowSurfaceType::ALL))
|
||||
.into_iter()
|
||||
.flat_map(|e| w.outputs_for_element(e))
|
||||
})),
|
||||
None => Box::new(
|
||||
self.outputs()
|
||||
.filter(|o| {
|
||||
self.override_redirect_windows.iter().any(|or| {
|
||||
if or.surface.wl_surface().as_ref() == Some(surface) {
|
||||
or.surface.geometry().intersection(o.geometry()).is_some()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
})
|
||||
.cloned()
|
||||
.chain(self.outputs().map(|o| self.active_space(o)).flat_map(|w| {
|
||||
w.mapped()
|
||||
.find(|e| e.has_surface(surface, WindowSurfaceType::ALL))
|
||||
.into_iter()
|
||||
.flat_map(|e| w.outputs_for_element(e))
|
||||
})),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -975,6 +994,9 @@ impl Shell {
|
|||
map.cleanup();
|
||||
}
|
||||
|
||||
self.override_redirect_windows
|
||||
.retain(|or| or.surface.alive());
|
||||
|
||||
self.toplevel_info_state
|
||||
.refresh(Some(&self.workspace_state));
|
||||
}
|
||||
|
|
@ -1019,10 +1041,6 @@ impl Shell {
|
|||
}
|
||||
|
||||
if let CosmicSurface::X11(surface) = window {
|
||||
let geometry = workspace.element_geometry(&mapped);
|
||||
if let Err(err) = surface.configure(geometry) {
|
||||
slog_scope::warn!("Failed to configure X11 surface ({:?}): {}", surface, err);
|
||||
};
|
||||
if let Some(xwm) = state
|
||||
.common
|
||||
.xwayland_state
|
||||
|
|
@ -1062,7 +1080,7 @@ impl Shell {
|
|||
.override_redirect_windows
|
||||
.push(OverrideRedirectWindow {
|
||||
surface: window,
|
||||
above: None,
|
||||
above: Ordering::Above,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ use super::{
|
|||
element::CosmicMapped,
|
||||
focus::{FocusStack, FocusStackMut},
|
||||
grabs::{ResizeEdge, ResizeGrab},
|
||||
CosmicMappedRenderElement, CosmicSurface,
|
||||
CosmicMappedRenderElement, CosmicSurface, Ordering,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -232,15 +232,14 @@ impl Workspace {
|
|||
mapped.set_active(window);
|
||||
}
|
||||
|
||||
window.set_size(
|
||||
output
|
||||
.current_mode()
|
||||
.map(|m| m.size)
|
||||
.unwrap_or((0, 0).into())
|
||||
.to_f64()
|
||||
.to_logical(output.current_scale().fractional_scale())
|
||||
.to_i32_round(),
|
||||
);
|
||||
let size = output
|
||||
.current_mode()
|
||||
.map(|m| m.size)
|
||||
.unwrap_or((0, 0).into())
|
||||
.to_f64()
|
||||
.to_logical(output.current_scale().fractional_scale())
|
||||
.to_i32_round();
|
||||
window.set_geometry(Rectangle::from_loc_and_size((0, 0), size));
|
||||
window.send_configure();
|
||||
self.fullscreen.insert(output.clone(), window.clone());
|
||||
}
|
||||
|
|
@ -397,6 +396,7 @@ impl Workspace {
|
|||
&self,
|
||||
renderer: &mut R,
|
||||
output: &Output,
|
||||
override_redirect_windows: &[super::OverrideRedirectWindow],
|
||||
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
|
|
@ -469,8 +469,33 @@ impl Workspace {
|
|||
lower
|
||||
};
|
||||
|
||||
let mut window_elements = Vec::new();
|
||||
|
||||
// OR windows above all
|
||||
window_elements.extend(
|
||||
override_redirect_windows
|
||||
.iter()
|
||||
.filter(|or| {
|
||||
or.above == Ordering::Above
|
||||
&& or
|
||||
.surface
|
||||
.geometry()
|
||||
.intersection(output.geometry())
|
||||
.is_some()
|
||||
})
|
||||
.flat_map(|or| {
|
||||
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
|
||||
&or.surface,
|
||||
renderer,
|
||||
(or.surface.geometry().loc - output.geometry().loc)
|
||||
.to_physical_precise_round(output_scale),
|
||||
Scale::from(output_scale),
|
||||
)
|
||||
}),
|
||||
);
|
||||
|
||||
// floating surfaces
|
||||
render_elements.extend(
|
||||
window_elements.extend(
|
||||
self.floating_layer
|
||||
.render_output::<R>(renderer, output)?
|
||||
.into_iter()
|
||||
|
|
@ -478,13 +503,64 @@ impl Workspace {
|
|||
);
|
||||
|
||||
//tiling surfaces
|
||||
render_elements.extend(
|
||||
window_elements.extend(
|
||||
self.tiling_layer
|
||||
.render_output::<R>(renderer, output)?
|
||||
.into_iter()
|
||||
.map(WorkspaceRenderElement::from),
|
||||
);
|
||||
|
||||
// Sort other OR windows in between
|
||||
for or in override_redirect_windows.iter().filter(|or| {
|
||||
matches!(or.above, Ordering::AboveWindow(_))
|
||||
&& or
|
||||
.surface
|
||||
.geometry()
|
||||
.intersection(output.geometry())
|
||||
.is_some()
|
||||
}) {
|
||||
let pos = window_elements
|
||||
.iter()
|
||||
.position(|w| Ordering::AboveWindow(w.id().clone()) == or.above)
|
||||
.unwrap_or(0);
|
||||
for element in AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
|
||||
&or.surface,
|
||||
renderer,
|
||||
(or.surface.geometry().loc - output.geometry().loc)
|
||||
.to_physical_precise_round(output_scale),
|
||||
Scale::from(output_scale),
|
||||
)
|
||||
.into_iter()
|
||||
.rev()
|
||||
{
|
||||
window_elements.insert(pos, element);
|
||||
}
|
||||
}
|
||||
|
||||
render_elements.extend(window_elements.into_iter());
|
||||
|
||||
// OR windows below all
|
||||
render_elements.extend(
|
||||
override_redirect_windows
|
||||
.iter()
|
||||
.filter(|or| {
|
||||
or.above == Ordering::Below
|
||||
&& or
|
||||
.surface
|
||||
.geometry()
|
||||
.intersection(output.geometry())
|
||||
.is_some()
|
||||
})
|
||||
.flat_map(|or| {
|
||||
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
|
||||
&or.surface,
|
||||
renderer,
|
||||
(or.surface.geometry().loc - output.geometry().loc)
|
||||
.to_physical_precise_round(output_scale),
|
||||
Scale::from(output_scale),
|
||||
)
|
||||
}),
|
||||
);
|
||||
// bottom and background layer surfaces
|
||||
{
|
||||
render_elements.extend(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue