Merge pull request #588 from mahkoh/jorth/effective-geometry
xdg-toplevel: center fullscreen surfaces with geometry smaller than o…
This commit is contained in:
commit
fbef86e928
6 changed files with 81 additions and 26 deletions
|
|
@ -301,6 +301,7 @@ pub struct WlSurface {
|
|||
pub extents: Cell<Rect>,
|
||||
pub buffer_abs_pos: Cell<Rect>,
|
||||
pub need_extents_update: Cell<bool>,
|
||||
need_extents_propagation: Cell<bool>,
|
||||
pub buffer: CloneCell<Option<Rc<SurfaceBuffer>>>,
|
||||
pub shm_staging: CloneCell<Option<Rc<dyn GfxStagingBuffer>>>,
|
||||
pub shm_textures: DoubleBuffered<SurfaceShmTexture>,
|
||||
|
|
@ -650,6 +651,7 @@ impl WlSurface {
|
|||
extents: Default::default(),
|
||||
buffer_abs_pos: Cell::new(Default::default()),
|
||||
need_extents_update: Default::default(),
|
||||
need_extents_propagation: Default::default(),
|
||||
buffer: Default::default(),
|
||||
shm_staging: Default::default(),
|
||||
shm_textures: DoubleBuffered::new(DamageQueue::new().map(|damage| SurfaceShmTexture {
|
||||
|
|
@ -904,7 +906,7 @@ impl WlSurface {
|
|||
self.ext.set(self.client.state.none_surface_ext.clone());
|
||||
}
|
||||
|
||||
fn calculate_extents(&self) {
|
||||
fn calculate_extents(&self, propagate: bool) {
|
||||
let old_extents = self.extents.get();
|
||||
let mut extents = self.buffer_abs_pos.get().at_point(0, 0);
|
||||
let children = self.children.borrow();
|
||||
|
|
@ -925,7 +927,11 @@ impl WlSurface {
|
|||
self.extents.set(extents);
|
||||
self.need_extents_update.set(false);
|
||||
if old_extents != extents {
|
||||
self.ext.get().extents_changed()
|
||||
if propagate {
|
||||
self.ext.get().extents_changed()
|
||||
} else {
|
||||
self.need_extents_propagation.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1398,7 +1404,7 @@ impl WlSurface {
|
|||
.push(XWaylandEvent::SurfaceSerialAssigned(self.id));
|
||||
}
|
||||
if self.need_extents_update.get() {
|
||||
self.calculate_extents();
|
||||
self.calculate_extents(false);
|
||||
}
|
||||
if buffer_changed || transform_changed || alpha_changed {
|
||||
for (_, cursor) in &self.cursors {
|
||||
|
|
@ -1461,6 +1467,9 @@ impl WlSurface {
|
|||
{
|
||||
self.output.get().update_presentation_type();
|
||||
}
|
||||
if self.need_extents_propagation.take() {
|
||||
self.ext.get().extents_changed();
|
||||
}
|
||||
self.commit_version.fetch_add(1);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ impl WlSubsurfaceRequestHandler for WlSubsurface {
|
|||
if !parent.need_extents_update.get() {
|
||||
break;
|
||||
}
|
||||
parent.calculate_extents();
|
||||
parent.calculate_extents(true);
|
||||
parent_opt = parent.ext.get().subsurface_parent();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ use {
|
|||
WorkspaceNode,
|
||||
},
|
||||
utils::{
|
||||
cell_ext::CellExt,
|
||||
clonecell::CloneCell,
|
||||
copyhashmap::CopyHashMap,
|
||||
hash_map_ext::HashMapExt,
|
||||
|
|
@ -90,6 +91,7 @@ pub struct XdgSurface {
|
|||
acked_serial: Cell<Option<u32>>,
|
||||
geometry: Cell<Option<Rect>>,
|
||||
extents: Cell<Rect>,
|
||||
effective_geometry: Cell<Rect>,
|
||||
pub absolute_desired_extents: Cell<Rect>,
|
||||
ext: CloneCell<Option<Rc<dyn XdgSurfaceExt>>>,
|
||||
popup_display_stack: CloneCell<Rc<LinkedList<Rc<dyn StackedNode>>>>,
|
||||
|
|
@ -231,6 +233,10 @@ pub trait XdgSurfaceExt: Debug {
|
|||
None
|
||||
}
|
||||
|
||||
fn effective_geometry(&self, geometry: Rect) -> Rect {
|
||||
geometry
|
||||
}
|
||||
|
||||
fn make_visible(self: Rc<Self>);
|
||||
|
||||
fn node_layer(&self) -> NodeLayerLink;
|
||||
|
|
@ -247,6 +253,7 @@ impl XdgSurface {
|
|||
acked_serial: Cell::new(None),
|
||||
geometry: Cell::new(None),
|
||||
extents: Cell::new(surface.extents.get()),
|
||||
effective_geometry: Default::default(),
|
||||
absolute_desired_extents: Cell::new(Default::default()),
|
||||
ext: Default::default(),
|
||||
popup_display_stack: CloneCell::new(surface.client.state.root.stacked.clone()),
|
||||
|
|
@ -262,10 +269,9 @@ impl XdgSurface {
|
|||
|
||||
fn update_surface_position(&self) {
|
||||
let (mut x1, mut y1) = self.absolute_desired_extents.get().position();
|
||||
if let Some(geo) = self.geometry.get() {
|
||||
x1 -= geo.x1();
|
||||
y1 -= geo.y1();
|
||||
}
|
||||
let geo = self.effective_geometry.get();
|
||||
x1 -= geo.x1();
|
||||
y1 -= geo.y1();
|
||||
self.surface.set_absolute_position(x1, y1);
|
||||
self.update_popup_positions();
|
||||
}
|
||||
|
|
@ -336,8 +342,8 @@ impl XdgSurface {
|
|||
self.surface.client.state.damage(extents.move_(x, y));
|
||||
}
|
||||
|
||||
pub fn geometry(&self) -> Option<Rect> {
|
||||
self.geometry.get()
|
||||
pub fn geometry(&self) -> Rect {
|
||||
self.effective_geometry.get()
|
||||
}
|
||||
|
||||
pub fn schedule_configure(self: &Rc<Self>) {
|
||||
|
|
@ -512,6 +518,24 @@ impl XdgSurfaceRequestHandler for XdgSurface {
|
|||
}
|
||||
|
||||
impl XdgSurface {
|
||||
fn update_effective_geometry(&self) {
|
||||
let geometry = self
|
||||
.geometry
|
||||
.get()
|
||||
.unwrap_or_else(|| self.surface.extents.get());
|
||||
let mut effective_geometry = geometry;
|
||||
let ext = self.ext.get();
|
||||
if let Some(ext) = &ext {
|
||||
effective_geometry = ext.effective_geometry(geometry);
|
||||
}
|
||||
if self.effective_geometry.replace(effective_geometry) != effective_geometry {
|
||||
self.update_surface_position();
|
||||
if let Some(ext) = &ext {
|
||||
ext.geometry_changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_extents(&self) {
|
||||
let old_extents = self.extents.get();
|
||||
let mut new_extents = self.surface.extents.get();
|
||||
|
|
@ -519,19 +543,19 @@ impl XdgSurface {
|
|||
new_extents = new_extents.intersect(geometry);
|
||||
}
|
||||
self.extents.set(new_extents);
|
||||
if old_extents != new_extents
|
||||
&& let Some(ext) = self.ext.get()
|
||||
{
|
||||
ext.extents_changed();
|
||||
if old_extents != new_extents {
|
||||
if self.geometry.is_none() {
|
||||
self.update_effective_geometry();
|
||||
}
|
||||
if let Some(ext) = self.ext.get() {
|
||||
ext.extents_changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_tree_at(&self, mut x: i32, mut y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||
if let Some(geo) = self.geometry.get() {
|
||||
let (xt, yt) = geo.translate_inv(x, y);
|
||||
x = xt;
|
||||
y = yt;
|
||||
}
|
||||
let geo = self.effective_geometry.get();
|
||||
(x, y) = geo.translate_inv(x, y);
|
||||
self.surface.find_tree_at_(x, y, tree)
|
||||
}
|
||||
|
||||
|
|
@ -604,11 +628,8 @@ impl SurfaceExt for XdgSurface {
|
|||
{
|
||||
let prev = self.geometry.replace(Some(geometry));
|
||||
if prev != Some(geometry) {
|
||||
self.update_effective_geometry();
|
||||
self.update_extents();
|
||||
self.update_surface_position();
|
||||
if let Some(ext) = self.ext.get() {
|
||||
ext.geometry_changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -746,6 +746,10 @@ impl ToplevelNodeBase for XdgToplevel {
|
|||
) -> Option<TileDragDestination> {
|
||||
default_tile_drag_destination(self, source, split, abs_bounds, x, y)
|
||||
}
|
||||
|
||||
fn tl_mark_fullscreen_ext(&self) {
|
||||
self.xdg.update_effective_geometry();
|
||||
}
|
||||
}
|
||||
|
||||
impl XdgSurfaceExt for XdgToplevel {
|
||||
|
|
@ -776,6 +780,23 @@ impl XdgSurfaceExt for XdgToplevel {
|
|||
.damage(self.node_absolute_position());
|
||||
}
|
||||
|
||||
fn effective_geometry(&self, geometry: Rect) -> Rect {
|
||||
if !self.toplevel_data.is_fullscreen.get() {
|
||||
return geometry;
|
||||
}
|
||||
let output = self
|
||||
.toplevel_data
|
||||
.output()
|
||||
.node_absolute_position()
|
||||
.at_point(0, 0);
|
||||
let x_overflow = output.width() - geometry.width();
|
||||
let y_overflow = output.height() - geometry.height();
|
||||
output.at_point(
|
||||
geometry.x1() - x_overflow / 2,
|
||||
geometry.y1() - y_overflow / 2,
|
||||
)
|
||||
}
|
||||
|
||||
fn make_visible(self: Rc<Self>) {
|
||||
self.node_make_visible();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -338,9 +338,8 @@ impl Renderer<'_> {
|
|||
bounds: Option<&Rect>,
|
||||
) {
|
||||
let surface = &xdg.surface;
|
||||
if let Some(geo) = xdg.geometry() {
|
||||
(x, y) = geo.translate(x, y);
|
||||
}
|
||||
let geo = xdg.geometry();
|
||||
(x, y) = geo.translate(x, y);
|
||||
self.render_surface(surface, x, y, bounds);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -247,6 +247,7 @@ impl<T: ToplevelNodeBase> ToplevelNode for T {
|
|||
fn tl_mark_fullscreen(&self, fullscreen: bool) {
|
||||
self.tl_data().is_fullscreen.set(fullscreen);
|
||||
self.tl_mark_ancestor_fullscreen(fullscreen);
|
||||
self.tl_mark_fullscreen_ext();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -315,6 +316,10 @@ pub trait ToplevelNodeBase: Node {
|
|||
fn tl_mark_ancestor_fullscreen_ext(&self, fullscreen: bool) {
|
||||
let _ = fullscreen;
|
||||
}
|
||||
|
||||
fn tl_mark_fullscreen_ext(&self) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FullscreenedData {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue