shell: Have Move-shortcut for floating layer and fullscreen windows
This commit is contained in:
parent
3d10ca6105
commit
4709a1d684
11 changed files with 207 additions and 69 deletions
|
|
@ -1,8 +1,6 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use crate::shell::{
|
use crate::shell::{focus::FocusDirection, grabs::ResizeEdge, Direction, ResizeDirection};
|
||||||
focus::FocusDirection, grabs::ResizeEdge, layout::tiling::Direction, ResizeDirection,
|
|
||||||
};
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::input::KeyState,
|
backend::input::KeyState,
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,9 @@ use crate::{
|
||||||
shell::{
|
shell::{
|
||||||
focus::{target::PointerFocusTarget, FocusDirection},
|
focus::{target::PointerFocusTarget, FocusDirection},
|
||||||
grabs::{ResizeEdge, SeatMoveGrabState},
|
grabs::{ResizeEdge, SeatMoveGrabState},
|
||||||
layout::tiling::{Direction, MoveResult, SwapWindowGrab, TilingLayout},
|
layout::tiling::{SwapWindowGrab, TilingLayout},
|
||||||
FocusResult, OverviewMode, ResizeDirection, ResizeMode, Trigger, Workspace,
|
Direction, FocusResult, MoveResult, OverviewMode, ResizeDirection, ResizeMode, Trigger,
|
||||||
|
Workspace,
|
||||||
},
|
},
|
||||||
state::Common,
|
state::Common,
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
|
|
@ -1373,7 +1374,7 @@ impl State {
|
||||||
return; // TODO, is this what we want? How do we indicate the switch?
|
return; // TODO, is this what we want? How do we indicate the switch?
|
||||||
}
|
}
|
||||||
|
|
||||||
match workspace.tiling_layer.move_current_node(direction, seat) {
|
match workspace.move_current_element(direction, seat) {
|
||||||
MoveResult::MoveFurther(_move_further) => {
|
MoveResult::MoveFurther(_move_further) => {
|
||||||
match (direction, self.common.config.static_conf.workspace_layout) {
|
match (direction, self.common.config.static_conf.workspace_layout) {
|
||||||
(Direction::Left, WorkspaceLayout::Horizontal)
|
(Direction::Left, WorkspaceLayout::Horizontal)
|
||||||
|
|
@ -1417,7 +1418,7 @@ impl State {
|
||||||
MoveResult::ShiftFocus(shift) => {
|
MoveResult::ShiftFocus(shift) => {
|
||||||
Common::set_focus(self, Some(&shift), seat, None);
|
Common::set_focus(self, Some(&shift), seat, None);
|
||||||
}
|
}
|
||||||
MoveResult::Done => {
|
_ => {
|
||||||
if let Some(focused_window) = workspace.focus_stack.get(seat).last() {
|
if let Some(focused_window) = workspace.focus_stack.get(seat).last() {
|
||||||
if workspace.is_tiled(focused_window) {
|
if workspace.is_tiled(focused_window) {
|
||||||
self.common.shell.set_overview_mode(
|
self.common.shell.set_overview_mode(
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,8 @@ use tracing::debug;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
focus::FocusDirection,
|
focus::FocusDirection,
|
||||||
layout::{
|
layout::{floating::ResizeState, tiling::NodeDesc},
|
||||||
floating::ResizeState,
|
Direction,
|
||||||
tiling::{Direction, NodeDesc},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
space_elements! {
|
space_elements! {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
use super::{CosmicMapped, CosmicSurface, CosmicWindow};
|
use super::{CosmicMapped, CosmicSurface, CosmicWindow};
|
||||||
use crate::{
|
use crate::{
|
||||||
shell::{
|
shell::{
|
||||||
focus::FocusDirection,
|
focus::FocusDirection, grabs::MoveGrab, layout::tiling::NodeDesc, Direction, Shell, Trigger,
|
||||||
grabs::MoveGrab,
|
|
||||||
layout::tiling::{Direction, NodeDesc},
|
|
||||||
Shell, Trigger,
|
|
||||||
},
|
},
|
||||||
state::State,
|
state::State,
|
||||||
utils::iced::{IcedElement, Program},
|
utils::iced::{IcedElement, Program},
|
||||||
|
|
|
||||||
|
|
@ -97,12 +97,22 @@ impl Shell {
|
||||||
serial: Option<Serial>,
|
serial: Option<Serial>,
|
||||||
) {
|
) {
|
||||||
// update FocusStack and notify layouts about new focus (if any window)
|
// update FocusStack and notify layouts about new focus (if any window)
|
||||||
if let Some(KeyboardFocusTarget::Element(mapped)) = target {
|
let element = match target {
|
||||||
if let Some(workspace) = state.common.shell.space_for_mut(mapped) {
|
Some(KeyboardFocusTarget::Element(mapped)) => Some(mapped.clone()),
|
||||||
|
Some(KeyboardFocusTarget::Fullscreen(window)) => state
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.element_for_surface(&window.surface())
|
||||||
|
.cloned(),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(mapped) = element {
|
||||||
|
if let Some(workspace) = state.common.shell.space_for_mut(&mapped) {
|
||||||
let mut focus_stack = workspace.focus_stack.get_mut(active_seat);
|
let mut focus_stack = workspace.focus_stack.get_mut(active_seat);
|
||||||
if Some(mapped) != focus_stack.last() {
|
if Some(&mapped) != focus_stack.last() {
|
||||||
trace!(?mapped, "Focusing window.");
|
trace!(?mapped, "Focusing window.");
|
||||||
focus_stack.append(mapped);
|
focus_stack.append(&mapped);
|
||||||
// also remove popup grabs, if we are switching focus
|
// also remove popup grabs, if we are switching focus
|
||||||
if let Some(mut popup_grab) = active_seat
|
if let Some(mut popup_grab) = active_seat
|
||||||
.user_data()
|
.user_data()
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,18 @@ use smithay::{
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::shell::focus::FocusDirection;
|
|
||||||
use crate::shell::FocusResult;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{element::AsGlowRenderer, IndicatorShader, Key, Usage},
|
backend::render::{element::AsGlowRenderer, IndicatorShader, Key, Usage},
|
||||||
shell::{
|
shell::{
|
||||||
element::{
|
element::{
|
||||||
resize_indicator::ResizeIndicator, stack::CosmicStackRenderElement,
|
resize_indicator::ResizeIndicator,
|
||||||
window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement,
|
stack::{CosmicStackRenderElement, MoveResult as StackMoveResult},
|
||||||
|
window::CosmicWindowRenderElement,
|
||||||
|
CosmicMapped, CosmicMappedRenderElement, CosmicWindow,
|
||||||
},
|
},
|
||||||
focus::target::KeyboardFocusTarget,
|
focus::{target::KeyboardFocusTarget, FocusDirection},
|
||||||
grabs::ResizeEdge,
|
grabs::ResizeEdge,
|
||||||
CosmicSurface, ResizeDirection, ResizeMode,
|
CosmicSurface, Direction, FocusResult, MoveResult, ResizeDirection, ResizeMode,
|
||||||
},
|
},
|
||||||
state::State,
|
state::State,
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
|
|
@ -423,6 +423,62 @@ impl FloatingLayout {
|
||||||
.unwrap_or(FocusResult::None)
|
.unwrap_or(FocusResult::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn move_current_element<'a>(
|
||||||
|
&mut self,
|
||||||
|
direction: Direction,
|
||||||
|
seat: &Seat<State>,
|
||||||
|
) -> MoveResult {
|
||||||
|
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
||||||
|
return MoveResult::None
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(focused) = (match target {
|
||||||
|
KeyboardFocusTarget::Popup(popup) => {
|
||||||
|
let Some(toplevel_surface) = (match popup {
|
||||||
|
PopupKind::Xdg(xdg) => get_popup_toplevel(&xdg),
|
||||||
|
}) else {
|
||||||
|
return MoveResult::None
|
||||||
|
};
|
||||||
|
self.space.elements().find(|elem| elem.wl_surface().as_ref() == Some(&toplevel_surface))
|
||||||
|
},
|
||||||
|
KeyboardFocusTarget::Element(elem) => self.space.elements().find(|e| *e == &elem),
|
||||||
|
_ => None,
|
||||||
|
}) else {
|
||||||
|
return MoveResult::None
|
||||||
|
};
|
||||||
|
|
||||||
|
match focused.handle_move(direction) {
|
||||||
|
StackMoveResult::Handled => return MoveResult::Done,
|
||||||
|
StackMoveResult::MoveOut(surface, loop_handle) => {
|
||||||
|
let mapped: CosmicMapped = CosmicWindow::new(surface, loop_handle).into();
|
||||||
|
let output = seat.active_output();
|
||||||
|
let pos = self.space.element_geometry(focused).unwrap().loc
|
||||||
|
+ match direction {
|
||||||
|
Direction::Up => Point::from((5, -10)),
|
||||||
|
Direction::Down => Point::from((5, 10)),
|
||||||
|
Direction::Left => Point::from((-10, 5)),
|
||||||
|
Direction::Right => Point::from((10, 5)),
|
||||||
|
};
|
||||||
|
let position = self
|
||||||
|
.space
|
||||||
|
.output_geometry(&output)
|
||||||
|
.unwrap()
|
||||||
|
.overlaps({
|
||||||
|
let mut geo = mapped.geometry();
|
||||||
|
geo.loc += pos;
|
||||||
|
geo
|
||||||
|
})
|
||||||
|
.then_some(pos);
|
||||||
|
|
||||||
|
self.map_internal(mapped.clone(), &output, position);
|
||||||
|
return MoveResult::ShiftFocus(KeyboardFocusTarget::Element(mapped));
|
||||||
|
}
|
||||||
|
StackMoveResult::Default => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
MoveResult::MoveFurther(KeyboardFocusTarget::Element(focused.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mapped(&self) -> impl Iterator<Item = &CosmicMapped> {
|
pub fn mapped(&self) -> impl Iterator<Item = &CosmicMapped> {
|
||||||
self.space.elements().rev()
|
self.space.elements().rev()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ use crate::{
|
||||||
},
|
},
|
||||||
grabs::ResizeEdge,
|
grabs::ResizeEdge,
|
||||||
layout::Orientation,
|
layout::Orientation,
|
||||||
CosmicSurface, FocusResult, OutputNotMapped, OverviewMode, ResizeDirection, ResizeMode,
|
CosmicSurface, Direction, FocusResult, MoveResult, OutputNotMapped, OverviewMode,
|
||||||
Trigger,
|
ResizeDirection, ResizeMode, Trigger,
|
||||||
},
|
},
|
||||||
utils::{prelude::*, tween::EaseRectangle},
|
utils::{prelude::*, tween::EaseRectangle},
|
||||||
wayland::{
|
wayland::{
|
||||||
|
|
@ -112,33 +112,6 @@ pub struct NodeDesc {
|
||||||
pub stack_window: Option<CosmicSurface>,
|
pub stack_window: Option<CosmicSurface>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, Clone, Copy, PartialEq, Eq)]
|
|
||||||
pub enum Direction {
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
Up,
|
|
||||||
Down,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::ops::Not for Direction {
|
|
||||||
type Output = Self;
|
|
||||||
fn not(self) -> Self::Output {
|
|
||||||
match self {
|
|
||||||
Direction::Left => Direction::Right,
|
|
||||||
Direction::Right => Direction::Left,
|
|
||||||
Direction::Up => Direction::Down,
|
|
||||||
Direction::Down => Direction::Up,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
pub enum MoveResult {
|
|
||||||
Done,
|
|
||||||
MoveFurther(KeyboardFocusTarget),
|
|
||||||
ShiftFocus(KeyboardFocusTarget),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
enum TargetZone {
|
enum TargetZone {
|
||||||
Initial,
|
Initial,
|
||||||
|
|
@ -1454,12 +1427,12 @@ impl TilingLayout {
|
||||||
let mut tree = queue.trees.back().unwrap().0.copy_clone();
|
let mut tree = queue.trees.back().unwrap().0.copy_clone();
|
||||||
|
|
||||||
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
||||||
return MoveResult::Done;
|
return MoveResult::None;
|
||||||
};
|
};
|
||||||
let Some((node_id, data)) =
|
let Some((node_id, data)) =
|
||||||
TilingLayout::currently_focused_node(&mut tree, &seat.active_output(), target)
|
TilingLayout::currently_focused_node(&mut tree, &seat.active_output(), target)
|
||||||
else {
|
else {
|
||||||
return MoveResult::Done;
|
return MoveResult::None;
|
||||||
};
|
};
|
||||||
|
|
||||||
// stacks may handle movement internally
|
// stacks may handle movement internally
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ use self::{
|
||||||
grabs::ResizeEdge,
|
grabs::ResizeEdge,
|
||||||
layout::{
|
layout::{
|
||||||
floating::{FloatingLayout, ResizeState},
|
floating::{FloatingLayout, ResizeState},
|
||||||
tiling::{Direction, NodeDesc, TilingLayout},
|
tiling::{NodeDesc, TilingLayout},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1500,13 +1500,47 @@ impl Shell {
|
||||||
.get_mut(to_idx, to_output)
|
.get_mut(to_idx, to_output)
|
||||||
.unwrap(); // checked above
|
.unwrap(); // checked above
|
||||||
let focus_stack = to_workspace.focus_stack.get(&seat);
|
let focus_stack = to_workspace.focus_stack.get(&seat);
|
||||||
if window_state == ManagedState::Floating {
|
if window_state.layer == ManagedLayer::Floating {
|
||||||
to_workspace.floating_layer.map(mapped.clone(), &seat, None);
|
to_workspace.floating_layer.map(mapped.clone(), &seat, None);
|
||||||
} else {
|
} else {
|
||||||
to_workspace
|
to_workspace
|
||||||
.tiling_layer
|
.tiling_layer
|
||||||
.map(mapped.clone(), &seat, focus_stack.iter(), direction);
|
.map(mapped.clone(), &seat, focus_stack.iter(), direction);
|
||||||
}
|
}
|
||||||
|
let focus_target = match window_state.was_fullscreen {
|
||||||
|
Some(true) => {
|
||||||
|
to_workspace.fullscreen_request(
|
||||||
|
&mapped.active_window(),
|
||||||
|
&to_output,
|
||||||
|
state.common.event_loop_handle.clone(),
|
||||||
|
);
|
||||||
|
KeyboardFocusTarget::from(
|
||||||
|
to_workspace
|
||||||
|
.fullscreen
|
||||||
|
.get(to_output)
|
||||||
|
.unwrap()
|
||||||
|
.window
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Some(false) => {
|
||||||
|
to_workspace.maximize_request(
|
||||||
|
&mapped.active_window(),
|
||||||
|
&to_output,
|
||||||
|
state.common.event_loop_handle.clone(),
|
||||||
|
);
|
||||||
|
KeyboardFocusTarget::from(
|
||||||
|
to_workspace
|
||||||
|
.fullscreen
|
||||||
|
.get(to_output)
|
||||||
|
.unwrap()
|
||||||
|
.window
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
None => KeyboardFocusTarget::from(mapped.clone()),
|
||||||
|
};
|
||||||
|
|
||||||
for (toplevel, _) in mapped.windows() {
|
for (toplevel, _) in mapped.windows() {
|
||||||
if from_output != to_output {
|
if from_output != to_output {
|
||||||
state
|
state
|
||||||
|
|
@ -1531,7 +1565,7 @@ impl Shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
if follow {
|
if follow {
|
||||||
Common::set_focus(state, Some(&KeyboardFocusTarget::from(mapped)), &seat, None);
|
Common::set_focus(state, Some(&focus_target), &seat, None);
|
||||||
}
|
}
|
||||||
Ok(new_pos)
|
Ok(new_pos)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,11 +128,36 @@ impl IsAlive for FullscreenSurface {
|
||||||
pub struct FocusStacks(HashMap<Seat<State>, IndexSet<CosmicMapped>>);
|
pub struct FocusStacks(HashMap<Seat<State>, IndexSet<CosmicMapped>>);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum ManagedState {
|
pub struct ManagedState {
|
||||||
|
pub layer: ManagedLayer,
|
||||||
|
pub was_fullscreen: Option<bool>,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum ManagedLayer {
|
||||||
Tiling,
|
Tiling,
|
||||||
Floating,
|
Floating,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum Direction {
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Not for Direction {
|
||||||
|
type Output = Self;
|
||||||
|
fn not(self) -> Self::Output {
|
||||||
|
match self {
|
||||||
|
Direction::Left => Direction::Right,
|
||||||
|
Direction::Right => Direction::Left,
|
||||||
|
Direction::Up => Direction::Down,
|
||||||
|
Direction::Down => Direction::Up,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum FocusResult {
|
pub enum FocusResult {
|
||||||
None,
|
None,
|
||||||
|
|
@ -152,6 +177,26 @@ impl FocusResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum MoveResult {
|
||||||
|
None,
|
||||||
|
Done,
|
||||||
|
MoveFurther(KeyboardFocusTarget),
|
||||||
|
ShiftFocus(KeyboardFocusTarget),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MoveResult {
|
||||||
|
pub fn or_else<F>(self, f: F) -> MoveResult
|
||||||
|
where
|
||||||
|
F: FnOnce() -> MoveResult,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
MoveResult::None => f(),
|
||||||
|
x => x,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Workspace {
|
impl Workspace {
|
||||||
pub fn new(handle: WorkspaceHandle, tiling_enabled: bool, gaps: (u8, u8)) -> Workspace {
|
pub fn new(handle: WorkspaceHandle, tiling_enabled: bool, gaps: (u8, u8)) -> Workspace {
|
||||||
Workspace {
|
Workspace {
|
||||||
|
|
@ -279,7 +324,9 @@ impl Workspace {
|
||||||
assert!(was_floating != was_tiling);
|
assert!(was_floating != was_tiling);
|
||||||
}
|
}
|
||||||
|
|
||||||
if mapped.is_maximized(true) || mapped.is_fullscreen(true) {
|
let was_maximized = mapped.is_maximized(true);
|
||||||
|
let was_fullscreen = mapped.is_fullscreen(true);
|
||||||
|
if was_maximized || was_fullscreen {
|
||||||
self.unmaximize_request(&mapped.active_window());
|
self.unmaximize_request(&mapped.active_window());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -288,9 +335,15 @@ impl Workspace {
|
||||||
.values_mut()
|
.values_mut()
|
||||||
.for_each(|set| set.retain(|m| m != mapped));
|
.for_each(|set| set.retain(|m| m != mapped));
|
||||||
if was_floating {
|
if was_floating {
|
||||||
Some(ManagedState::Floating)
|
Some(ManagedState {
|
||||||
|
layer: ManagedLayer::Floating,
|
||||||
|
was_fullscreen: (was_fullscreen || was_maximized).then_some(was_fullscreen),
|
||||||
|
})
|
||||||
} else if was_tiling {
|
} else if was_tiling {
|
||||||
Some(ManagedState::Tiling)
|
Some(ManagedState {
|
||||||
|
layer: ManagedLayer::Tiling,
|
||||||
|
was_fullscreen: (was_fullscreen || was_maximized).then_some(was_fullscreen),
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -389,14 +442,14 @@ impl Workspace {
|
||||||
window.set_maximized(true);
|
window.set_maximized(true);
|
||||||
self.set_fullscreen(window, output, false, evlh)
|
self.set_fullscreen(window, output, false, evlh)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unmaximize_request(&mut self, window: &CosmicSurface) -> Option<Size<i32, Logical>> {
|
pub fn unmaximize_request(&mut self, window: &CosmicSurface) -> Option<Size<i32, Logical>> {
|
||||||
if self
|
if self
|
||||||
.fullscreen
|
.fullscreen
|
||||||
.values()
|
.values()
|
||||||
.any(|f| &f.window.surface() == window)
|
.any(|f| &f.window.surface() == window)
|
||||||
{
|
{
|
||||||
self.unfullscreen_request(window);
|
self.unfullscreen_request(window)
|
||||||
self.floating_layer.unmaximize_request(window)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -476,7 +529,7 @@ impl Workspace {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unfullscreen_request(&mut self, window: &CosmicSurface) {
|
pub fn unfullscreen_request(&mut self, window: &CosmicSurface) -> Option<Size<i32, Logical>> {
|
||||||
if let Some((output, f)) = self
|
if let Some((output, f)) = self
|
||||||
.fullscreen
|
.fullscreen
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
|
@ -485,7 +538,7 @@ impl Workspace {
|
||||||
f.window.output_leave(output);
|
f.window.output_leave(output);
|
||||||
window.set_maximized(false);
|
window.set_maximized(false);
|
||||||
window.set_fullscreen(false);
|
window.set_fullscreen(false);
|
||||||
self.floating_layer.unmaximize_request(window);
|
let result = self.floating_layer.unmaximize_request(window);
|
||||||
self.floating_layer.refresh();
|
self.floating_layer.refresh();
|
||||||
self.tiling_layer.recalculate(output);
|
self.tiling_layer.recalculate(output);
|
||||||
self.tiling_layer.refresh();
|
self.tiling_layer.refresh();
|
||||||
|
|
@ -520,6 +573,10 @@ impl Workspace {
|
||||||
old_signal.store(true, Ordering::SeqCst);
|
old_signal.store(true, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -833,6 +890,20 @@ impl Workspace {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn move_current_element<'a>(
|
||||||
|
&mut self,
|
||||||
|
direction: Direction,
|
||||||
|
seat: &Seat<State>,
|
||||||
|
) -> MoveResult {
|
||||||
|
if let Some(f) = self.fullscreen.get(&seat.active_output()) {
|
||||||
|
MoveResult::MoveFurther(KeyboardFocusTarget::Fullscreen(f.window.clone()))
|
||||||
|
} else {
|
||||||
|
self.floating_layer
|
||||||
|
.move_current_element(direction, seat)
|
||||||
|
.or_else(|| self.tiling_layer.move_current_node(direction, seat))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render_output<'a, R>(
|
pub fn render_output<'a, R>(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ impl XdgShellHandler for State {
|
||||||
.windows()
|
.windows()
|
||||||
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface()))
|
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
workspace.unfullscreen_request(&window)
|
workspace.unfullscreen_request(&window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -460,7 +460,7 @@ impl XwmHandler for Data {
|
||||||
{
|
{
|
||||||
if let Some(workspace) = self.state.common.shell.space_for_mut(&mapped) {
|
if let Some(workspace) = self.state.common.shell.space_for_mut(&mapped) {
|
||||||
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
|
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
|
||||||
workspace.unfullscreen_request(&window)
|
workspace.unfullscreen_request(&window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue