xwm: More fixes
This commit is contained in:
parent
1d28574088
commit
9b1221edc5
14 changed files with 311 additions and 80 deletions
|
|
@ -157,7 +157,7 @@ where
|
||||||
Source: Clone,
|
Source: Clone,
|
||||||
{
|
{
|
||||||
let handle = state.shell.workspaces.active(output).handle;
|
let handle = state.shell.workspaces.active(output).handle;
|
||||||
render_workspace(
|
let result = render_workspace(
|
||||||
gpu,
|
gpu,
|
||||||
renderer,
|
renderer,
|
||||||
target,
|
target,
|
||||||
|
|
@ -169,7 +169,27 @@ where
|
||||||
cursor_mode,
|
cursor_mode,
|
||||||
screencopy,
|
screencopy,
|
||||||
fps,
|
fps,
|
||||||
)
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if let Ok((_, states)) = result.as_ref() {
|
||||||
|
for xwm in state
|
||||||
|
.xwayland_state
|
||||||
|
.values_mut()
|
||||||
|
.flat_map(|state| state.xwm.as_mut())
|
||||||
|
{
|
||||||
|
if let Err(err) = xwm.update_stacking_order_upwards(states.states.keys()) {
|
||||||
|
slog_scope::warn!(
|
||||||
|
"Failed to update Xwm ({:?}) stacking order: {}",
|
||||||
|
xwm.id(),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_workspace<'frame, R, Target, OffTarget, Source>(
|
pub fn render_workspace<'frame, R, Target, OffTarget, Source>(
|
||||||
|
|
@ -258,7 +278,7 @@ where
|
||||||
|
|
||||||
elements.extend(
|
elements.extend(
|
||||||
workspace
|
workspace
|
||||||
.render_output::<R>(renderer, output)
|
.render_output::<R>(renderer, output, &state.shell.override_redirect_windows)
|
||||||
.map_err(|_| OutputNoMode)?
|
.map_err(|_| OutputNoMode)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Into::into),
|
.map(Into::into),
|
||||||
|
|
|
||||||
|
|
@ -332,10 +332,10 @@ impl CosmicMapped {
|
||||||
window.is_activated()
|
window.is_activated()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_size(&self, size: Size<i32, Logical>) {
|
pub fn set_geometry(&self, geo: Rectangle<i32, Logical>) {
|
||||||
match &self.element {
|
match &self.element {
|
||||||
CosmicMappedInternal::Stack(s) => s.set_size(size),
|
CosmicMappedInternal::Stack(s) => s.set_geometry(geo),
|
||||||
CosmicMappedInternal::Window(w) => w.set_size(size),
|
CosmicMappedInternal::Window(w) => w.set_geometry(geo),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,15 +150,16 @@ impl CosmicStack {
|
||||||
Point::from((0, TAB_HEIGHT))
|
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| {
|
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() {
|
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(
|
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 {
|
match self {
|
||||||
CosmicSurface::Wayland(window) => window
|
CosmicSurface::Wayland(window) => window
|
||||||
.toplevel()
|
.toplevel()
|
||||||
.with_pending_state(|state| state.size = Some(size)),
|
.with_pending_state(|state| state.size = Some(geo.size)),
|
||||||
CosmicSurface::X11(surface) => {
|
CosmicSurface::X11(surface) => {
|
||||||
let rect = Rectangle::from_loc_and_size(surface.geometry().loc, size);
|
let _ = surface.configure(geo);
|
||||||
let _ = surface.configure(rect);
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -296,6 +295,13 @@ impl CosmicSurface {
|
||||||
CosmicSurface::X11(surface) => surface.min_size(),
|
CosmicSurface::X11(surface) => surface.min_size(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
.map(|size| {
|
||||||
|
if self.is_decorated() {
|
||||||
|
size + (0, SSD_HEIGHT).into()
|
||||||
|
} else {
|
||||||
|
size
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn max_size(&self) -> Option<Size<i32, Logical>> {
|
pub fn max_size(&self) -> Option<Size<i32, Logical>> {
|
||||||
|
|
@ -315,6 +321,13 @@ impl CosmicSurface {
|
||||||
CosmicSurface::X11(surface) => surface.max_size(),
|
CosmicSurface::X11(surface) => surface.max_size(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
.map(|size| {
|
||||||
|
if self.is_decorated() {
|
||||||
|
size + (0, SSD_HEIGHT).into()
|
||||||
|
} else {
|
||||||
|
size
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_configure(&self) {
|
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| {
|
self.0.with_program(|p| {
|
||||||
let surface_size = (size.w, size.h - if p.has_ssd() { SSD_HEIGHT } else { 0 }).into();
|
let loc = (
|
||||||
p.window.set_size(surface_size)
|
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 {
|
pub fn surface(&self) -> CosmicSurface {
|
||||||
|
|
@ -264,6 +272,7 @@ impl SpaceElement for CosmicWindow {
|
||||||
self.0.with_program(|p| {
|
self.0.with_program(|p| {
|
||||||
let mut bbox = SpaceElement::bbox(&p.window);
|
let mut bbox = SpaceElement::bbox(&p.window);
|
||||||
if p.has_ssd() {
|
if p.has_ssd() {
|
||||||
|
bbox.loc.y -= SSD_HEIGHT;
|
||||||
bbox.size.h += SSD_HEIGHT;
|
bbox.size.h += SSD_HEIGHT;
|
||||||
}
|
}
|
||||||
bbox
|
bbox
|
||||||
|
|
@ -301,6 +310,7 @@ impl SpaceElement for CosmicWindow {
|
||||||
self.0.with_program(|p| {
|
self.0.with_program(|p| {
|
||||||
let mut geo = SpaceElement::geometry(&p.window);
|
let mut geo = SpaceElement::geometry(&p.window);
|
||||||
if p.has_ssd() {
|
if p.has_ssd() {
|
||||||
|
geo.loc.y -= SSD_HEIGHT;
|
||||||
geo.size.h += SSD_HEIGHT;
|
geo.size.h += SSD_HEIGHT;
|
||||||
}
|
}
|
||||||
geo
|
geo
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ use smithay::{
|
||||||
Seat,
|
Seat,
|
||||||
},
|
},
|
||||||
output::Output,
|
output::Output,
|
||||||
utils::{IsAlive, Logical, Point, Serial},
|
utils::{IsAlive, Logical, Point, Rectangle, Serial},
|
||||||
};
|
};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
|
@ -183,6 +183,10 @@ impl MoveSurfaceGrab {
|
||||||
.output_geometry(&output)
|
.output_geometry(&output)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.loc;
|
.loc;
|
||||||
|
grab_state.window.set_geometry(Rectangle::from_loc_and_size(
|
||||||
|
window_location + offset,
|
||||||
|
grab_state.window.geometry().size,
|
||||||
|
));
|
||||||
state
|
state
|
||||||
.common
|
.common
|
||||||
.shell
|
.shell
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use smithay::{
|
||||||
AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab,
|
AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab,
|
||||||
PointerInnerHandle,
|
PointerInnerHandle,
|
||||||
},
|
},
|
||||||
utils::{IsAlive, Logical, Point, Size},
|
utils::{IsAlive, Logical, Point, Rectangle, Size},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Information about the resize operation.
|
/// 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.last_window_size = (new_window_width, new_window_height).into();
|
||||||
|
|
||||||
self.window.set_resizing(true);
|
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();
|
self.window.configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,7 +121,10 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.window.set_resizing(false);
|
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();
|
self.window.configure();
|
||||||
|
|
||||||
let mut resize_state = self.window.resize_state.lock().unwrap();
|
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
|
space
|
||||||
.floating_layer
|
.floating_layer
|
||||||
.space
|
.space
|
||||||
|
|
|
||||||
|
|
@ -75,9 +75,7 @@ impl FloatingLayout {
|
||||||
let geometry = layers.non_exclusive_zone();
|
let geometry = layers.non_exclusive_zone();
|
||||||
let last_geometry = mapped.last_geometry.lock().unwrap().clone();
|
let last_geometry = mapped.last_geometry.lock().unwrap().clone();
|
||||||
|
|
||||||
let mut geo_updated = false;
|
|
||||||
if let Some(size) = last_geometry.map(|g| g.size) {
|
if let Some(size) = last_geometry.map(|g| g.size) {
|
||||||
geo_updated = win_geo.size != size;
|
|
||||||
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
|
// 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);
|
win_geo.size.w = std::cmp::min(width, geometry.size.w);
|
||||||
geo_updated = true;
|
|
||||||
}
|
}
|
||||||
if win_geo.size.h > geometry.size.h / 3 * 2 {
|
if win_geo.size.h > geometry.size.h / 3 * 2 {
|
||||||
// try a more reasonable size
|
// 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
|
// 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);
|
win_geo.size.h = std::cmp::min(height, geometry.size.h);
|
||||||
geo_updated = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,11 +124,8 @@ impl FloatingLayout {
|
||||||
});
|
});
|
||||||
|
|
||||||
mapped.set_tiled(false);
|
mapped.set_tiled(false);
|
||||||
if geo_updated {
|
mapped.set_geometry(Rectangle::from_loc_and_size(position, win_geo.size));
|
||||||
mapped.set_size(win_geo.size);
|
|
||||||
}
|
|
||||||
mapped.configure();
|
mapped.configure();
|
||||||
|
|
||||||
self.space.map_element(mapped, position, false);
|
self.space.map_element(mapped, position, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,8 +176,8 @@ impl FloatingLayout {
|
||||||
if let Some(mapped) = maybe_mapped {
|
if let Some(mapped) = maybe_mapped {
|
||||||
let last_geometry = mapped.last_geometry.lock().unwrap().clone();
|
let last_geometry = mapped.last_geometry.lock().unwrap().clone();
|
||||||
let last_size = last_geometry.map(|g| g.size).expect("No previous size?");
|
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?");
|
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);
|
self.space.map_element(mapped, last_location, true);
|
||||||
Some(last_size)
|
Some(last_size)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -293,6 +286,7 @@ impl FloatingLayout {
|
||||||
.get(&output)
|
.get(&output)
|
||||||
.copied()
|
.copied()
|
||||||
.unwrap_or_else(|| (0, 0).into());
|
.unwrap_or_else(|| (0, 0).into());
|
||||||
|
element.set_geometry(elem_geo);
|
||||||
self.space.map_element(element.clone(), elem_geo.loc, false);
|
self.space.map_element(element.clone(), elem_geo.loc, false);
|
||||||
}
|
}
|
||||||
self.refresh(); //fixup any out of bounds elements
|
self.refresh(); //fixup any out of bounds elements
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ lazy_static::lazy_static! {
|
||||||
r"update-manager",
|
r"update-manager",
|
||||||
r"Solaar",
|
r"Solaar",
|
||||||
r"Steam",
|
r"Steam",
|
||||||
|
r"",
|
||||||
r"TelegramDesktop",
|
r"TelegramDesktop",
|
||||||
r"Zotero",
|
r"Zotero",
|
||||||
r"gjs",
|
r"gjs",
|
||||||
|
|
@ -77,6 +78,7 @@ lazy_static::lazy_static! {
|
||||||
r"Software Updater",
|
r"Software Updater",
|
||||||
r".*",
|
r".*",
|
||||||
r"^.*?(Guard|Login).*",
|
r"^.*?(Guard|Login).*",
|
||||||
|
r"Steam",
|
||||||
r"Media viewer",
|
r"Media viewer",
|
||||||
r"Quick Format Citation",
|
r"Quick Format Citation",
|
||||||
r".*",
|
r".*",
|
||||||
|
|
|
||||||
|
|
@ -1129,14 +1129,17 @@ impl TilingLayout {
|
||||||
data.update_geometry(geo);
|
data.update_geometry(geo);
|
||||||
}
|
}
|
||||||
Data::Mapped { mapped, .. } => {
|
Data::Mapped { mapped, .. } => {
|
||||||
|
geo.loc += (inner, inner).into();
|
||||||
if !(mapped.is_fullscreen() || mapped.is_maximized()) {
|
if !(mapped.is_fullscreen() || mapped.is_maximized()) {
|
||||||
mapped.set_tiled(true);
|
mapped.set_tiled(true);
|
||||||
mapped.set_size(
|
let size = (geo.size.w - inner * 2, geo.size.h - inner * 2);
|
||||||
(geo.size.w - inner * 2, geo.size.h - inner * 2).into(),
|
let internal_geometry =
|
||||||
);
|
Rectangle::from_loc_and_size(geo.loc, size);
|
||||||
mapped.configure();
|
if mapped.geometry() != internal_geometry {
|
||||||
|
mapped.set_geometry(internal_geometry);
|
||||||
|
mapped.configure();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
geo.loc += (inner, inner).into();
|
|
||||||
data.update_geometry(geo);
|
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 cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
|
backend::renderer::element::Id,
|
||||||
desktop::{layer_map_for_output, LayerSurface, PopupManager, WindowSurfaceType},
|
desktop::{layer_map_for_output, LayerSurface, PopupManager, WindowSurfaceType},
|
||||||
input::{
|
input::{
|
||||||
pointer::{Focus, GrabStartData as PointerGrabStartData},
|
pointer::{Focus, GrabStartData as PointerGrabStartData},
|
||||||
Seat,
|
Seat,
|
||||||
},
|
},
|
||||||
output::Output,
|
output::Output,
|
||||||
reexports::{
|
reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle},
|
||||||
wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle},
|
|
||||||
x11rb::protocol::xproto::Window as X11Window,
|
|
||||||
},
|
|
||||||
utils::{Logical, Point, Rectangle, Serial, SERIAL_COUNTER},
|
utils::{Logical, Point, Rectangle, Serial, SERIAL_COUNTER},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::with_states,
|
compositor::with_states,
|
||||||
|
|
@ -71,9 +69,17 @@ pub struct Shell {
|
||||||
pub workspace_state: WorkspaceState<State>,
|
pub workspace_state: WorkspaceState<State>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct OverrideRedirectWindow {
|
pub struct OverrideRedirectWindow {
|
||||||
pub surface: X11Surface,
|
pub surface: X11Surface,
|
||||||
pub above: Option<X11Window>,
|
pub above: Ordering,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum Ordering {
|
||||||
|
Above,
|
||||||
|
AboveWindow(Id),
|
||||||
|
Below,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -837,12 +843,25 @@ impl Shell {
|
||||||
Some(output) => {
|
Some(output) => {
|
||||||
Box::new(std::iter::once(output.clone())) as Box<dyn Iterator<Item = 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| {
|
None => Box::new(
|
||||||
w.mapped()
|
self.outputs()
|
||||||
.find(|e| e.has_surface(surface, WindowSurfaceType::ALL))
|
.filter(|o| {
|
||||||
.into_iter()
|
self.override_redirect_windows.iter().any(|or| {
|
||||||
.flat_map(|e| w.outputs_for_element(e))
|
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();
|
map.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.override_redirect_windows
|
||||||
|
.retain(|or| or.surface.alive());
|
||||||
|
|
||||||
self.toplevel_info_state
|
self.toplevel_info_state
|
||||||
.refresh(Some(&self.workspace_state));
|
.refresh(Some(&self.workspace_state));
|
||||||
}
|
}
|
||||||
|
|
@ -1019,10 +1041,6 @@ impl Shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let CosmicSurface::X11(surface) = window {
|
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
|
if let Some(xwm) = state
|
||||||
.common
|
.common
|
||||||
.xwayland_state
|
.xwayland_state
|
||||||
|
|
@ -1062,7 +1080,7 @@ impl Shell {
|
||||||
.override_redirect_windows
|
.override_redirect_windows
|
||||||
.push(OverrideRedirectWindow {
|
.push(OverrideRedirectWindow {
|
||||||
surface: window,
|
surface: window,
|
||||||
above: None,
|
above: Ordering::Above,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ use super::{
|
||||||
element::CosmicMapped,
|
element::CosmicMapped,
|
||||||
focus::{FocusStack, FocusStackMut},
|
focus::{FocusStack, FocusStackMut},
|
||||||
grabs::{ResizeEdge, ResizeGrab},
|
grabs::{ResizeEdge, ResizeGrab},
|
||||||
CosmicMappedRenderElement, CosmicSurface,
|
CosmicMappedRenderElement, CosmicSurface, Ordering,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -232,15 +232,14 @@ impl Workspace {
|
||||||
mapped.set_active(window);
|
mapped.set_active(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.set_size(
|
let size = output
|
||||||
output
|
.current_mode()
|
||||||
.current_mode()
|
.map(|m| m.size)
|
||||||
.map(|m| m.size)
|
.unwrap_or((0, 0).into())
|
||||||
.unwrap_or((0, 0).into())
|
.to_f64()
|
||||||
.to_f64()
|
.to_logical(output.current_scale().fractional_scale())
|
||||||
.to_logical(output.current_scale().fractional_scale())
|
.to_i32_round();
|
||||||
.to_i32_round(),
|
window.set_geometry(Rectangle::from_loc_and_size((0, 0), size));
|
||||||
);
|
|
||||||
window.send_configure();
|
window.send_configure();
|
||||||
self.fullscreen.insert(output.clone(), window.clone());
|
self.fullscreen.insert(output.clone(), window.clone());
|
||||||
}
|
}
|
||||||
|
|
@ -397,6 +396,7 @@ impl Workspace {
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
|
override_redirect_windows: &[super::OverrideRedirectWindow],
|
||||||
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped>
|
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
|
|
@ -469,8 +469,33 @@ impl Workspace {
|
||||||
lower
|
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
|
// floating surfaces
|
||||||
render_elements.extend(
|
window_elements.extend(
|
||||||
self.floating_layer
|
self.floating_layer
|
||||||
.render_output::<R>(renderer, output)?
|
.render_output::<R>(renderer, output)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -478,13 +503,64 @@ impl Workspace {
|
||||||
);
|
);
|
||||||
|
|
||||||
//tiling surfaces
|
//tiling surfaces
|
||||||
render_elements.extend(
|
window_elements.extend(
|
||||||
self.tiling_layer
|
self.tiling_layer
|
||||||
.render_output::<R>(renderer, output)?
|
.render_output::<R>(renderer, output)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(WorkspaceRenderElement::from),
|
.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
|
// bottom and background layer surfaces
|
||||||
{
|
{
|
||||||
render_elements.extend(
|
render_elements.extend(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
shell::CosmicSurface, state::BackendData, utils::prelude::*,
|
shell::CosmicSurface,
|
||||||
|
state::{BackendData, Data},
|
||||||
|
utils::prelude::*,
|
||||||
wayland::protocols::screencopy::SessionType,
|
wayland::protocols::screencopy::SessionType,
|
||||||
};
|
};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
|
|
@ -109,7 +111,7 @@ impl CompositorHandler for State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn commit(&mut self, surface: &WlSurface) {
|
fn commit(&mut self, surface: &WlSurface) {
|
||||||
X11Wm::commit_hook(surface);
|
X11Wm::commit_hook::<Data>(surface);
|
||||||
// first load the buffer for various smithay helper functions
|
// first load the buffer for various smithay helper functions
|
||||||
on_commit_buffer_handler(surface);
|
on_commit_buffer_handler(surface);
|
||||||
|
|
||||||
|
|
|
||||||
107
src/xwayland.rs
107
src/xwayland.rs
|
|
@ -1,12 +1,12 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::cursor::Cursor,
|
backend::render::cursor::Cursor,
|
||||||
shell::{CosmicSurface, Shell},
|
shell::{CosmicSurface, Ordering, Shell},
|
||||||
state::{Data, State},
|
state::{Data, State},
|
||||||
utils::prelude::SeatExt,
|
utils::prelude::SeatExt,
|
||||||
wayland::{handlers::screencopy::PendingScreencopyBuffers, protocols::screencopy::SessionType},
|
wayland::{handlers::screencopy::PendingScreencopyBuffers, protocols::screencopy::SessionType},
|
||||||
};
|
};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::drm::DrmNode,
|
backend::{drm::DrmNode, renderer::element::Id},
|
||||||
reexports::x11rb::protocol::xproto::Window as X11Window,
|
reexports::x11rb::protocol::xproto::Window as X11Window,
|
||||||
utils::{Logical, Point, Rectangle, Size},
|
utils::{Logical, Point, Rectangle, Size},
|
||||||
xwayland::{
|
xwayland::{
|
||||||
|
|
@ -131,6 +131,16 @@ impl XwmHandler for Data {
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if self
|
||||||
|
.state
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.element_for_surface(&CosmicSurface::X11(window.clone()))
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let window = CosmicSurface::X11(window);
|
let window = CosmicSurface::X11(window);
|
||||||
self.state
|
self.state
|
||||||
.common
|
.common
|
||||||
|
|
@ -149,11 +159,27 @@ impl XwmHandler for Data {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mapped_override_redirect_window(&mut self, _xwm: XwmId, window: X11Surface) {
|
fn mapped_override_redirect_window(&mut self, _xwm: XwmId, window: X11Surface) {
|
||||||
|
if self
|
||||||
|
.state
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.override_redirect_windows
|
||||||
|
.iter()
|
||||||
|
.any(|or| or.surface == window)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
Shell::map_override_redirect(&mut self.state, window)
|
Shell::map_override_redirect(&mut self.state, window)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unmapped_window(&mut self, _xwm: XwmId, window: X11Surface) {
|
fn unmapped_window(&mut self, _xwm: XwmId, window: X11Surface) {
|
||||||
if let Some((element, space)) = self
|
if window.is_override_redirect() {
|
||||||
|
self.state
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.override_redirect_windows
|
||||||
|
.retain(|or| or.surface != window);
|
||||||
|
} else if let Some((element, space)) = self
|
||||||
.state
|
.state
|
||||||
.common
|
.common
|
||||||
.shell
|
.shell
|
||||||
|
|
@ -225,30 +251,45 @@ impl XwmHandler for Data {
|
||||||
&mut self,
|
&mut self,
|
||||||
_xwm: XwmId,
|
_xwm: XwmId,
|
||||||
window: X11Surface,
|
window: X11Surface,
|
||||||
_x: Option<i32>,
|
x: Option<i32>,
|
||||||
_y: Option<i32>,
|
y: Option<i32>,
|
||||||
w: Option<u32>,
|
w: Option<u32>,
|
||||||
h: Option<u32>,
|
h: Option<u32>,
|
||||||
_reorder: Option<Reorder>,
|
_reorder: Option<Reorder>,
|
||||||
) {
|
) {
|
||||||
// We only allow floating X11 windows to resize themselves. Nothing else
|
// We only allow floating X11 windows to resize themselves. Nothing else
|
||||||
let current_size = window.geometry().size;
|
let mut current_geo = window.geometry();
|
||||||
if let Some(mapped) = self
|
if let Some(mapped) = self
|
||||||
.state
|
.state
|
||||||
.common
|
.common
|
||||||
.shell
|
.shell
|
||||||
.element_for_surface(&CosmicSurface::X11(window))
|
.element_for_surface(&CosmicSurface::X11(window.clone()))
|
||||||
{
|
{
|
||||||
let space = self.state.common.shell.space_for(mapped).unwrap();
|
let space = self.state.common.shell.space_for(mapped).unwrap();
|
||||||
if space.is_floating(mapped) {
|
if space.is_floating(mapped) {
|
||||||
mapped.set_size(
|
mapped.set_geometry(Rectangle::from_loc_and_size(
|
||||||
|
current_geo.loc,
|
||||||
(
|
(
|
||||||
w.map(|w| w as i32).unwrap_or(current_size.w),
|
w.map(|w| w as i32).unwrap_or(current_geo.size.w),
|
||||||
h.map(|h| h as i32).unwrap_or(current_size.h),
|
h.map(|h| h as i32).unwrap_or(current_geo.size.h),
|
||||||
)
|
),
|
||||||
.into(),
|
))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if let Some(x) = x {
|
||||||
|
current_geo.loc.x = x;
|
||||||
|
}
|
||||||
|
if let Some(y) = y {
|
||||||
|
current_geo.loc.y = y;
|
||||||
|
}
|
||||||
|
if let Some(w) = w {
|
||||||
|
current_geo.size.w = w as i32;
|
||||||
|
}
|
||||||
|
if let Some(h) = h {
|
||||||
|
current_geo.size.h = h as i32;
|
||||||
|
}
|
||||||
|
// the window is not yet mapped. Lets give it what it wants
|
||||||
|
let _ = window.configure(current_geo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -260,6 +301,44 @@ impl XwmHandler for Data {
|
||||||
above: Option<X11Window>,
|
above: Option<X11Window>,
|
||||||
) {
|
) {
|
||||||
if window.is_override_redirect() {
|
if window.is_override_redirect() {
|
||||||
|
let ordering = match above {
|
||||||
|
None => Ordering::Below,
|
||||||
|
Some(id) => self
|
||||||
|
.state
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.override_redirect_windows
|
||||||
|
.iter()
|
||||||
|
.find_map(|or| {
|
||||||
|
if or.surface.window_id() == id {
|
||||||
|
or.surface
|
||||||
|
.wl_surface()
|
||||||
|
.map(|s| Id::from_wayland_resource(&s))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.state
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.workspaces
|
||||||
|
.spaces()
|
||||||
|
.flat_map(|s| s.windows())
|
||||||
|
.find_map(|w| {
|
||||||
|
if let CosmicSurface::X11(w) = w {
|
||||||
|
if w.window_id() == id || w.mapped_window_id() == Some(id) {
|
||||||
|
return w
|
||||||
|
.wl_surface()
|
||||||
|
.map(|s| Id::from_wayland_resource(&s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.map(Ordering::AboveWindow)
|
||||||
|
.unwrap_or(Ordering::Above),
|
||||||
|
};
|
||||||
if let Some(or) = self
|
if let Some(or) = self
|
||||||
.state
|
.state
|
||||||
.common
|
.common
|
||||||
|
|
@ -268,7 +347,7 @@ impl XwmHandler for Data {
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|or| or.surface == window)
|
.find(|or| or.surface == window)
|
||||||
{
|
{
|
||||||
or.above = above;
|
or.above = ordering;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue