shell/floating: Reintroduce resizing
This commit is contained in:
parent
bb07ab4155
commit
7d068ab6bc
6 changed files with 154 additions and 210 deletions
|
|
@ -34,7 +34,7 @@ pub use self::stack::CosmicStack;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
pub use self::window::CosmicWindow;
|
pub use self::window::CosmicWindow;
|
||||||
|
|
||||||
use super::focus::FocusDirection;
|
use super::{focus::FocusDirection, layout::floating::ResizeState};
|
||||||
|
|
||||||
space_elements! {
|
space_elements! {
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
|
@ -53,6 +53,7 @@ pub struct CosmicMapped {
|
||||||
pub(super) tiling_node_id: Arc<Mutex<Option<NodeId>>>,
|
pub(super) tiling_node_id: Arc<Mutex<Option<NodeId>>>,
|
||||||
//floating
|
//floating
|
||||||
pub(super) last_geometry: Arc<Mutex<Option<Rectangle<i32, Logical>>>>,
|
pub(super) last_geometry: Arc<Mutex<Option<Rectangle<i32, Logical>>>>,
|
||||||
|
pub(super) resize_state: Arc<Mutex<Option<ResizeState>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for CosmicMapped {
|
impl PartialEq for CosmicMapped {
|
||||||
|
|
@ -165,6 +166,40 @@ impl CosmicMapped {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_resizing(&self, resizing: bool) {
|
||||||
|
for window in match &self.element {
|
||||||
|
CosmicMappedInternal::Stack(s) => {
|
||||||
|
Box::new(s.windows()) as Box<dyn Iterator<Item = Window>>
|
||||||
|
}
|
||||||
|
CosmicMappedInternal::Window(w) => Box::new(std::iter::once(w.window.clone())),
|
||||||
|
_ => unreachable!(),
|
||||||
|
} {
|
||||||
|
match window.toplevel() {
|
||||||
|
Kind::Xdg(xdg) => xdg.with_pending_state(|state| {
|
||||||
|
if resizing {
|
||||||
|
state.states.set(XdgState::Resizing);
|
||||||
|
} else {
|
||||||
|
state.states.unset(XdgState::Resizing);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
// Kind::X11?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_resizing(&self) -> bool {
|
||||||
|
let window = match &self.element {
|
||||||
|
CosmicMappedInternal::Stack(s) => s.active(),
|
||||||
|
CosmicMappedInternal::Window(w) => w.window.clone(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
match window.toplevel() {
|
||||||
|
Kind::Xdg(xdg) => xdg.current_state().states.contains(XdgState::Resizing),
|
||||||
|
// Kind::X11?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_tiled(&self, tiled: bool) {
|
pub fn set_tiled(&self, tiled: bool) {
|
||||||
for toplevel in match &self.element {
|
for toplevel in match &self.element {
|
||||||
// we use the tiled state of stack windows anyway to get rid of decorations
|
// we use the tiled state of stack windows anyway to get rid of decorations
|
||||||
|
|
@ -590,6 +625,7 @@ impl From<CosmicWindow> for CosmicMapped {
|
||||||
element: CosmicMappedInternal::Window(w),
|
element: CosmicMappedInternal::Window(w),
|
||||||
tiling_node_id: Arc::new(Mutex::new(None)),
|
tiling_node_id: Arc::new(Mutex::new(None)),
|
||||||
last_geometry: Arc::new(Mutex::new(None)),
|
last_geometry: Arc::new(Mutex::new(None)),
|
||||||
|
resize_state: Arc::new(Mutex::new(None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -600,6 +636,7 @@ impl From<CosmicStack> for CosmicMapped {
|
||||||
element: CosmicMappedInternal::Stack(s),
|
element: CosmicMappedInternal::Stack(s),
|
||||||
tiling_node_id: Arc::new(Mutex::new(None)),
|
tiling_node_id: Arc::new(Mutex::new(None)),
|
||||||
last_geometry: Arc::new(Mutex::new(None)),
|
last_geometry: Arc::new(Mutex::new(None)),
|
||||||
|
resize_state: Arc::new(Mutex::new(None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,32 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use crate::{shell::focus::target::PointerFocusTarget, utils::prelude::*};
|
use crate::{
|
||||||
|
shell::{element::CosmicMapped, focus::target::PointerFocusTarget},
|
||||||
|
utils::prelude::*,
|
||||||
|
};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
desktop::{Kind, Window},
|
desktop::space::SpaceElement,
|
||||||
input::pointer::{
|
input::pointer::{
|
||||||
AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab,
|
AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab,
|
||||||
PointerInnerHandle,
|
PointerInnerHandle,
|
||||||
},
|
},
|
||||||
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel,
|
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel,
|
||||||
utils::{IsAlive, Logical, Point, Serial, Size},
|
utils::{IsAlive, Logical, Point, Size},
|
||||||
wayland::{
|
|
||||||
compositor::with_states,
|
|
||||||
shell::xdg::{SurfaceCachedState, ToplevelConfigure, XdgToplevelSurfaceRoleAttributes},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use std::{cell::RefCell, convert::TryFrom, sync::Mutex};
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
bitflags::bitflags! {
|
bitflags::bitflags! {
|
||||||
struct ResizeEdge: u32 {
|
pub struct ResizeEdge: u32 {
|
||||||
const NONE = 0;
|
const TOP = 0b0001;
|
||||||
const TOP = 1;
|
const BOTTOM = 0b0010;
|
||||||
const BOTTOM = 2;
|
const LEFT = 0b0100;
|
||||||
const LEFT = 4;
|
const RIGHT = 0b1000;
|
||||||
const TOP_LEFT = 5;
|
|
||||||
const BOTTOM_LEFT = 6;
|
const TOP_LEFT = Self::TOP.bits | Self::LEFT.bits;
|
||||||
const RIGHT = 8;
|
const BOTTOM_LEFT = Self::BOTTOM.bits | Self::LEFT.bits;
|
||||||
const TOP_RIGHT = 9;
|
|
||||||
const BOTTOM_RIGHT = 10;
|
const TOP_RIGHT = Self::TOP.bits | Self::RIGHT.bits;
|
||||||
|
const BOTTOM_RIGHT = Self::BOTTOM.bits | Self::RIGHT.bits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,7 +46,7 @@ impl From<ResizeEdge> for xdg_toplevel::ResizeEdge {
|
||||||
|
|
||||||
/// Information about the resize operation.
|
/// Information about the resize operation.
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
struct ResizeData {
|
pub struct ResizeData {
|
||||||
/// The edges the surface is being resized with.
|
/// The edges the surface is being resized with.
|
||||||
edges: ResizeEdge,
|
edges: ResizeEdge,
|
||||||
/// The initial window location.
|
/// The initial window location.
|
||||||
|
|
@ -57,26 +57,16 @@ struct ResizeData {
|
||||||
|
|
||||||
/// State of the resize operation.
|
/// State of the resize operation.
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
enum ResizeState {
|
pub enum ResizeState {
|
||||||
/// The surface is not being resized.
|
|
||||||
NotResizing,
|
|
||||||
/// The surface is currently being resized.
|
/// The surface is currently being resized.
|
||||||
Resizing(ResizeData),
|
Resizing(ResizeData),
|
||||||
/// The resize has finished, and the surface needs to ack the final configure.
|
|
||||||
WaitingForFinalAck(ResizeData, Serial),
|
|
||||||
/// The resize has finished, and the surface needs to commit its final state.
|
/// The resize has finished, and the surface needs to commit its final state.
|
||||||
WaitingForCommit(ResizeData),
|
WaitingForCommit(ResizeData),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ResizeState {
|
|
||||||
fn default() -> Self {
|
|
||||||
ResizeState::NotResizing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ResizeSurfaceGrab {
|
pub struct ResizeSurfaceGrab {
|
||||||
start_data: PointerGrabStartData<State>,
|
start_data: PointerGrabStartData<State>,
|
||||||
window: Window,
|
window: CosmicMapped,
|
||||||
edges: ResizeEdge,
|
edges: ResizeEdge,
|
||||||
initial_window_size: Size<i32, Logical>,
|
initial_window_size: Size<i32, Logical>,
|
||||||
last_window_size: Size<i32, Logical>,
|
last_window_size: Size<i32, Logical>,
|
||||||
|
|
@ -123,10 +113,7 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
|
||||||
new_window_height = (self.initial_window_size.h as f64 + dy) as i32;
|
new_window_height = (self.initial_window_size.h as f64 + dy) as i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (min_size, max_size) = with_states(self.window.toplevel().wl_surface(), |states| {
|
let (min_size, max_size) = (self.window.min_size(), self.window.max_size());
|
||||||
let data = states.cached_state.current::<SurfaceCachedState>();
|
|
||||||
(data.min_size, data.max_size)
|
|
||||||
});
|
|
||||||
|
|
||||||
let min_width = min_size.w.max(1);
|
let min_width = min_size.w.max(1);
|
||||||
let min_height = min_size.h.max(1);
|
let min_height = min_size.h.max(1);
|
||||||
|
|
@ -146,15 +133,9 @@ 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();
|
||||||
|
|
||||||
match &self.window.toplevel() {
|
self.window.set_resizing(true);
|
||||||
Kind::Xdg(xdg) => {
|
self.window.set_size(self.last_window_size);
|
||||||
xdg.with_pending_state(|state| {
|
self.window.configure();
|
||||||
state.states.set(xdg_toplevel::State::Resizing);
|
|
||||||
state.size = Some(self.last_window_size);
|
|
||||||
});
|
|
||||||
xdg.send_configure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn button(
|
fn button(
|
||||||
|
|
@ -173,23 +154,13 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
self.window.set_resizing(false);
|
||||||
if let Kind::Xdg(xdg) = &self.window.toplevel() {
|
self.window.set_size(self.last_window_size);
|
||||||
xdg.with_pending_state(|state| {
|
self.window.configure();
|
||||||
state.states.unset(xdg_toplevel::State::Resizing);
|
|
||||||
state.size = Some(self.last_window_size);
|
|
||||||
});
|
|
||||||
xdg.send_configure();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut resize_state = self
|
let mut resize_state = self.window.resize_state.lock().unwrap();
|
||||||
.window
|
if let Some(ResizeState::Resizing(resize_data)) = *resize_state {
|
||||||
.user_data()
|
*resize_state = Some(ResizeState::WaitingForCommit(resize_data));
|
||||||
.get::<RefCell<ResizeState>>()
|
|
||||||
.unwrap()
|
|
||||||
.borrow_mut();
|
|
||||||
if let ResizeState::Resizing(resize_data) = *resize_state {
|
|
||||||
*resize_state = ResizeState::WaitingForFinalAck(resize_data, event.serial);
|
|
||||||
} else {
|
} else {
|
||||||
panic!("invalid resize state: {:?}", resize_state);
|
panic!("invalid resize state: {:?}", resize_state);
|
||||||
}
|
}
|
||||||
|
|
@ -213,7 +184,7 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
|
||||||
impl ResizeSurfaceGrab {
|
impl ResizeSurfaceGrab {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
start_data: PointerGrabStartData<State>,
|
start_data: PointerGrabStartData<State>,
|
||||||
window: Window,
|
mapped: CosmicMapped,
|
||||||
edges: xdg_toplevel::ResizeEdge,
|
edges: xdg_toplevel::ResizeEdge,
|
||||||
initial_window_location: Point<i32, Logical>,
|
initial_window_location: Point<i32, Logical>,
|
||||||
initial_window_size: Size<i32, Logical>,
|
initial_window_size: Size<i32, Logical>,
|
||||||
|
|
@ -224,92 +195,27 @@ impl ResizeSurfaceGrab {
|
||||||
initial_window_size,
|
initial_window_size,
|
||||||
});
|
});
|
||||||
|
|
||||||
window
|
*mapped.resize_state.lock().unwrap() = Some(resize_state);
|
||||||
.user_data()
|
|
||||||
.insert_if_missing(|| RefCell::new(ResizeState::default()));
|
|
||||||
*window
|
|
||||||
.user_data()
|
|
||||||
.get::<RefCell<ResizeState>>()
|
|
||||||
.unwrap()
|
|
||||||
.borrow_mut() = resize_state;
|
|
||||||
|
|
||||||
ResizeSurfaceGrab {
|
ResizeSurfaceGrab {
|
||||||
start_data,
|
start_data,
|
||||||
window,
|
window: mapped,
|
||||||
edges: edges.into(),
|
edges: edges.into(),
|
||||||
initial_window_size,
|
initial_window_size,
|
||||||
last_window_size: initial_window_size,
|
last_window_size: initial_window_size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ack_configure(window: &Window, configure: ToplevelConfigure) {
|
pub fn apply_resize_to_location(window: CosmicMapped, space: &mut Workspace) {
|
||||||
let surface = window.toplevel().wl_surface();
|
if let Some(mut location) = space.floating_layer.space.element_location(&window) {
|
||||||
|
let mut new_location = None;
|
||||||
let waiting_for_serial =
|
|
||||||
if let Some(data) = window.user_data().get::<RefCell<ResizeState>>() {
|
|
||||||
if let ResizeState::WaitingForFinalAck(_, serial) = *data.borrow() {
|
|
||||||
Some(serial)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(serial) = waiting_for_serial {
|
|
||||||
// When the resize grab is released the surface
|
|
||||||
// resize state will be set to WaitingForFinalAck
|
|
||||||
// and the client will receive a configure request
|
|
||||||
// without the resize state to inform the client
|
|
||||||
// resizing has finished. Here we will wait for
|
|
||||||
// the client to acknowledge the end of the
|
|
||||||
// resizing. To check if the surface was resizing
|
|
||||||
// before sending the configure we need to use
|
|
||||||
// the current state as the received acknowledge
|
|
||||||
// will no longer have the resize state set
|
|
||||||
let is_resizing = with_states(&surface, |states| {
|
|
||||||
states
|
|
||||||
.data_map
|
|
||||||
.get::<Mutex<XdgToplevelSurfaceRoleAttributes>>()
|
|
||||||
.unwrap()
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.current
|
|
||||||
.states
|
|
||||||
.contains(xdg_toplevel::State::Resizing)
|
|
||||||
});
|
|
||||||
|
|
||||||
if configure.serial >= serial && is_resizing {
|
|
||||||
let mut resize_state = window
|
|
||||||
.user_data()
|
|
||||||
.get::<RefCell<ResizeState>>()
|
|
||||||
.unwrap()
|
|
||||||
.borrow_mut();
|
|
||||||
if let ResizeState::WaitingForFinalAck(resize_data, _) = *resize_state {
|
|
||||||
*resize_state = ResizeState::WaitingForCommit(resize_data);
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn apply_resize_state(
|
|
||||||
window: &Window,
|
|
||||||
mut location: Point<i32, Logical>,
|
|
||||||
size: Size<i32, Logical>,
|
|
||||||
) -> Option<Point<i32, Logical>> {
|
|
||||||
let mut new_location = None;
|
|
||||||
|
|
||||||
if let Some(resize_state) = window.user_data().get::<RefCell<ResizeState>>() {
|
|
||||||
let mut resize_state = resize_state.borrow_mut();
|
|
||||||
|
|
||||||
|
let mut resize_state = window.resize_state.lock().unwrap();
|
||||||
// If the window is being resized by top or left, its location must be adjusted
|
// If the window is being resized by top or left, its location must be adjusted
|
||||||
// accordingly.
|
// accordingly.
|
||||||
match *resize_state {
|
match *resize_state {
|
||||||
ResizeState::Resizing(resize_data)
|
Some(ResizeState::Resizing(resize_data))
|
||||||
| ResizeState::WaitingForFinalAck(resize_data, _)
|
| Some(ResizeState::WaitingForCommit(resize_data)) => {
|
||||||
| ResizeState::WaitingForCommit(resize_data) => {
|
|
||||||
let ResizeData {
|
let ResizeData {
|
||||||
edges,
|
edges,
|
||||||
initial_window_location,
|
initial_window_location,
|
||||||
|
|
@ -317,6 +223,7 @@ impl ResizeSurfaceGrab {
|
||||||
} = resize_data;
|
} = resize_data;
|
||||||
|
|
||||||
if edges.intersects(ResizeEdge::TOP_LEFT) {
|
if edges.intersects(ResizeEdge::TOP_LEFT) {
|
||||||
|
let size = window.geometry().size;
|
||||||
if edges.intersects(ResizeEdge::LEFT) {
|
if edges.intersects(ResizeEdge::LEFT) {
|
||||||
location.x =
|
location.x =
|
||||||
initial_window_location.x + (initial_window_size.w - size.w);
|
initial_window_location.x + (initial_window_size.w - size.w);
|
||||||
|
|
@ -329,15 +236,30 @@ impl ResizeSurfaceGrab {
|
||||||
new_location = Some(location);
|
new_location = Some(location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResizeState::NotResizing => (),
|
_ => {}
|
||||||
}
|
};
|
||||||
|
|
||||||
// Finish resizing.
|
// Finish resizing.
|
||||||
if let ResizeState::WaitingForCommit(_) = *resize_state {
|
if let Some(ResizeState::WaitingForCommit(_)) = *resize_state {
|
||||||
*resize_state = ResizeState::NotResizing;
|
if !window.is_resizing() {
|
||||||
|
*resize_state = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::mem::drop(resize_state);
|
||||||
|
|
||||||
|
if let Some(new_location) = new_location {
|
||||||
|
for (window, offset) in window.windows() {
|
||||||
|
update_reactive_popups(
|
||||||
|
&window,
|
||||||
|
new_location + offset,
|
||||||
|
space.floating_layer.space.outputs(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
space
|
||||||
|
.floating_layer
|
||||||
|
.space
|
||||||
|
.map_element(window, new_location, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new_location
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::renderer::{ImportAll, Renderer},
|
backend::renderer::{ImportAll, Renderer},
|
||||||
desktop::{layer_map_for_output, space::SpaceElement, Space, Window},
|
desktop::{layer_map_for_output, space::SpaceElement, Space, Window},
|
||||||
input::Seat,
|
input::{pointer::GrabStartData as PointerGrabStartData, Seat},
|
||||||
output::Output,
|
output::Output,
|
||||||
|
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::ResizeEdge,
|
||||||
render_elements,
|
render_elements,
|
||||||
utils::{Logical, Point, Rectangle},
|
utils::{Logical, Point, Rectangle, Serial},
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
|
@ -185,33 +186,31 @@ impl FloatingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub fn resize_request(
|
pub fn resize_request(
|
||||||
window: &CosmicWindow,
|
&mut self,
|
||||||
|
mapped: &CosmicMapped,
|
||||||
seat: &Seat<State>,
|
seat: &Seat<State>,
|
||||||
serial: Serial,
|
serial: Serial,
|
||||||
start_data: PointerGrabStartData<State>,
|
start_data: PointerGrabStartData<State>,
|
||||||
edges: ResizeEdge,
|
edges: ResizeEdge,
|
||||||
) {
|
) -> Option<ResizeSurfaceGrab> {
|
||||||
// it is so stupid, that we have to do this here. TODO: Refactor grabs
|
|
||||||
let workspace = state
|
|
||||||
.common
|
|
||||||
.shell
|
|
||||||
.space_for_window_mut(window.toplevel().wl_surface())
|
|
||||||
.unwrap();
|
|
||||||
let space = &mut workspace.space;
|
|
||||||
|
|
||||||
if let Some(pointer) = seat.get_pointer() {
|
if let Some(pointer) = seat.get_pointer() {
|
||||||
let location = space.window_location(&window).unwrap();
|
let location = self.space.element_location(&mapped).unwrap();
|
||||||
let size = window.geometry().size;
|
let size = mapped.geometry().size;
|
||||||
|
|
||||||
let grab =
|
Some(grabs::ResizeSurfaceGrab::new(
|
||||||
grabs::ResizeSurfaceGrab::new(start_data, window.clone(), edges, location, size);
|
start_data,
|
||||||
|
mapped.clone(),
|
||||||
|
edges,
|
||||||
|
location,
|
||||||
|
size,
|
||||||
|
))
|
||||||
|
|
||||||
pointer.set_grab(state, grab, serial, Focus::Clear);
|
//pointer.set_grab(state, grab, serial, Focus::Clear);
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
pub fn mapped(&self) -> impl Iterator<Item = &CosmicMapped> {
|
pub fn mapped(&self) -> impl Iterator<Item = &CosmicMapped> {
|
||||||
self.space.elements()
|
self.space.elements()
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,10 @@ use std::{collections::HashMap, time::Duration};
|
||||||
use super::{
|
use super::{
|
||||||
element::CosmicMapped,
|
element::CosmicMapped,
|
||||||
focus::{FocusStack, FocusStackMut},
|
focus::{FocusStack, FocusStackMut},
|
||||||
layout::{floating::FloatingRenderElement, tiling::TilingRenderElement},
|
layout::{
|
||||||
|
floating::{FloatingRenderElement, ResizeSurfaceGrab},
|
||||||
|
tiling::TilingRenderElement,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -253,32 +256,27 @@ impl Workspace {
|
||||||
self.fullscreen.get(output).filter(|w| w.alive())
|
self.fullscreen.get(output).filter(|w| w.alive())
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub fn resize_request(
|
pub fn resize_request(
|
||||||
state: &mut State,
|
&mut self,
|
||||||
surface: &WlSurface,
|
mapped: &CosmicMapped,
|
||||||
seat: &Seat<State>,
|
seat: &Seat<State>,
|
||||||
serial: Serial,
|
serial: Serial,
|
||||||
start_data: PointerGrabStartData<State>,
|
start_data: PointerGrabStartData<State>,
|
||||||
edges: ResizeEdge,
|
edges: ResizeEdge,
|
||||||
) {
|
) -> Option<ResizeSurfaceGrab> {
|
||||||
let workspace = state.common.shell.space_for_window_mut(surface).unwrap();
|
if mapped.is_fullscreen() || mapped.is_maximized() {
|
||||||
let window = workspace
|
return None;
|
||||||
.space
|
|
||||||
.window_for_surface(surface, WindowSurfaceType::TOPLEVEL)
|
|
||||||
.unwrap()
|
|
||||||
.clone();
|
|
||||||
|
|
||||||
if workspace.fullscreen.values().any(|w| w == &window) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if workspace.floating_layer.windows.contains(&window) {
|
if self.floating_layer.mapped().any(|m| m == mapped) {
|
||||||
FloatingLayout::resize_request(state, &window, seat, serial, start_data.clone(), edges)
|
self.floating_layer
|
||||||
} else if workspace.tiling_layer.windows.contains(&window) {
|
.resize_request(mapped, seat, serial, start_data.clone(), edges)
|
||||||
TilingLayout::resize_request(state, &window, seat, serial, start_data, edges)
|
} else if self.tiling_layer.mapped().any(|(_, m, _)| m == mapped) {
|
||||||
|
//self.tiling_layer.resize_request(mapped, seat, serial, start_data, edges)
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
pub fn toggle_tiling(&mut self, seat: &Seat<State>) {
|
pub fn toggle_tiling(&mut self, seat: &Seat<State>) {
|
||||||
if self.tiling_enabled {
|
if self.tiling_enabled {
|
||||||
|
|
|
||||||
|
|
@ -147,43 +147,18 @@ impl CompositorHandler for State {
|
||||||
self.xdg_popup_ensure_initial_configure(&popup);
|
self.xdg_popup_ensure_initial_configure(&popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// at last handle some special cases, like grabs and changing layer surfaces
|
// at last handle some special cases, like grabs and changing layer surfaces
|
||||||
|
|
||||||
// If we would re-position the window inside the grab we would get a weird jittery animation.
|
// If we would re-position the window inside the grab we would get a weird jittery animation.
|
||||||
// We only want to resize once the client has acknoledged & commited the new size,
|
// We only want to resize once the client has acknoledged & commited the new size,
|
||||||
// so we need to carefully track the state through different handlers.
|
// so we need to carefully track the state through different handlers.
|
||||||
if let Some((space, window)) =
|
if let Some(element) = self.common.shell.element_for_surface(surface).cloned() {
|
||||||
self.common
|
if let Some(workspace) = self.common.shell.space_for_mut(&element) {
|
||||||
.shell
|
crate::shell::layout::floating::ResizeSurfaceGrab::apply_resize_to_location(
|
||||||
.space_for_window_mut(surface)
|
element, workspace,
|
||||||
.and_then(|workspace| {
|
|
||||||
workspace
|
|
||||||
.space
|
|
||||||
.window_for_surface(surface, WindowSurfaceType::TOPLEVEL)
|
|
||||||
.cloned()
|
|
||||||
.map(|window| (&mut workspace.space, window))
|
|
||||||
})
|
|
||||||
{
|
|
||||||
let new_location =
|
|
||||||
crate::shell::layout::floating::ResizeSurfaceGrab::apply_resize_state(
|
|
||||||
&window,
|
|
||||||
space.window_location(&window).unwrap(),
|
|
||||||
window.geometry().size,
|
|
||||||
);
|
);
|
||||||
if let Some(location) = new_location {
|
|
||||||
space.map_window(
|
|
||||||
&window,
|
|
||||||
location,
|
|
||||||
crate::shell::layout::floating::FLOATING_INDEX,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
for window in space.windows() {
|
|
||||||
update_reactive_popups(space, window);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// We need to know every potential output for importing to the right gpu and scheduling a render,
|
// We need to know every potential output for importing to the right gpu and scheduling a render,
|
||||||
// so call this only after every potential surface map operation has been done.
|
// so call this only after every potential surface map operation has been done.
|
||||||
|
|
|
||||||
|
|
@ -169,8 +169,21 @@ impl XdgShellHandler for State {
|
||||||
) {
|
) {
|
||||||
let seat = Seat::from_resource(&seat).unwrap();
|
let seat = Seat::from_resource(&seat).unwrap();
|
||||||
if let Some(start_data) = check_grab_preconditions(&seat, surface.wl_surface(), serial) {
|
if let Some(start_data) = check_grab_preconditions(&seat, surface.wl_surface(), serial) {
|
||||||
if let Some(mapped) = self.common.shell.element_for_surface(surface.wl_surface()) {
|
if let Some(mapped) = self
|
||||||
// Shell::resize_request(self, mapped, &seat, serial, start_data, edges);
|
.common
|
||||||
|
.shell
|
||||||
|
.element_for_surface(surface.wl_surface())
|
||||||
|
.cloned()
|
||||||
|
{
|
||||||
|
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||||
|
if let Some(grab) =
|
||||||
|
workspace.resize_request(&mapped, &seat, serial, start_data, edges)
|
||||||
|
{
|
||||||
|
seat.get_pointer()
|
||||||
|
.unwrap()
|
||||||
|
.set_grab(self, grab, serial, Focus::Clear);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue