cargo fmt
This commit is contained in:
parent
43062c1754
commit
39de286d51
40 changed files with 1557 additions and 1080 deletions
|
|
@ -1,32 +1,23 @@
|
|||
use std::{
|
||||
cell::{Ref, RefMut, RefCell},
|
||||
collections::HashMap,
|
||||
sync::Mutex,
|
||||
use crate::{
|
||||
shell::{OutputBoundState, Shell, Workspace, WorkspaceMode},
|
||||
state::Common,
|
||||
utils::prelude::*,
|
||||
wayland::handlers::xdg_shell::PopupGrabData,
|
||||
};
|
||||
use indexmap::IndexSet;
|
||||
use smithay::{
|
||||
desktop::{
|
||||
Window, WindowSurfaceType,
|
||||
PopupUngrabStrategy,
|
||||
},
|
||||
reexports::wayland_server::{
|
||||
DisplayHandle,
|
||||
protocol::wl_surface::WlSurface,
|
||||
},
|
||||
desktop::{PopupUngrabStrategy, Window, WindowSurfaceType},
|
||||
reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle},
|
||||
utils::IsAlive,
|
||||
wayland::{
|
||||
compositor::with_states,
|
||||
seat::Seat,
|
||||
shell::xdg::XdgToplevelSurfaceRoleAttributes,
|
||||
Serial,
|
||||
compositor::with_states, seat::Seat, shell::xdg::XdgToplevelSurfaceRoleAttributes, Serial,
|
||||
SERIAL_COUNTER,
|
||||
},
|
||||
utils::IsAlive,
|
||||
};
|
||||
use crate::{
|
||||
state::Common,
|
||||
shell::{Shell, OutputBoundState, Workspace, WorkspaceMode},
|
||||
wayland::handlers::xdg_shell::PopupGrabData,
|
||||
utils::prelude::*,
|
||||
use std::{
|
||||
cell::{Ref, RefCell, RefMut},
|
||||
collections::HashMap,
|
||||
sync::Mutex,
|
||||
};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||
|
|
@ -130,7 +121,10 @@ impl Shell {
|
|||
// update FocusStack and notify layouts about new focus (if any window)
|
||||
if let Some(surface) = surface {
|
||||
if let Some(workspace) = self.space_for_surface_mut(surface) {
|
||||
if let Some(window) = workspace.space.window_for_surface(surface, WindowSurfaceType::ALL) {
|
||||
if let Some(window) = workspace
|
||||
.space
|
||||
.window_for_surface(surface, WindowSurfaceType::ALL)
|
||||
{
|
||||
let mut focus_stack = workspace.focus_stack_mut(active_seat);
|
||||
if Some(window) != focus_stack.last().as_ref() {
|
||||
slog_scope::debug!("Focusing window: {:?}", window);
|
||||
|
|
@ -226,7 +220,10 @@ impl Common {
|
|||
}
|
||||
|
||||
let workspace = self.shell.active_space(&output);
|
||||
if let Some(window) = workspace.space.window_for_surface(&surface, WindowSurfaceType::ALL) {
|
||||
if let Some(window) = workspace
|
||||
.space
|
||||
.window_for_surface(&surface, WindowSurfaceType::ALL)
|
||||
{
|
||||
let focus_stack = workspace.focus_stack(&seat);
|
||||
if focus_stack.last().map(|w| &w != window).unwrap_or(true) {
|
||||
fixup = true;
|
||||
|
|
|
|||
|
|
@ -1,25 +1,23 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::utils::prelude::*;
|
||||
use smithay::{
|
||||
desktop::{Kind, Window},
|
||||
reexports::{
|
||||
wayland_protocols::xdg::shell::server::xdg_toplevel,
|
||||
wayland_server::DisplayHandle,
|
||||
wayland_protocols::xdg::shell::server::xdg_toplevel, wayland_server::DisplayHandle,
|
||||
},
|
||||
utils::{IsAlive, Logical, Point, Size},
|
||||
wayland::{
|
||||
compositor::with_states,
|
||||
seat::{AxisFrame, PointerGrab, PointerGrabStartData, PointerInnerHandle, MotionEvent, ButtonEvent},
|
||||
seat::{
|
||||
AxisFrame, ButtonEvent, MotionEvent, PointerGrab, PointerGrabStartData,
|
||||
PointerInnerHandle,
|
||||
},
|
||||
shell::xdg::{SurfaceCachedState, ToplevelConfigure, XdgToplevelSurfaceRoleAttributes},
|
||||
Serial,
|
||||
},
|
||||
};
|
||||
use crate::utils::prelude::*;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
convert::TryFrom,
|
||||
sync::Mutex,
|
||||
};
|
||||
use std::{cell::RefCell, convert::TryFrom, sync::Mutex};
|
||||
|
||||
pub struct MoveSurfaceGrab {
|
||||
start_data: PointerGrabStartData,
|
||||
|
|
@ -32,15 +30,19 @@ impl PointerGrab<State> for MoveSurfaceGrab {
|
|||
fn motion(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
_dh: &DisplayHandle,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
event: &MotionEvent
|
||||
_dh: &DisplayHandle,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
event: &MotionEvent,
|
||||
) {
|
||||
// While the grab is active, no client has pointer focus
|
||||
handle.motion(event.location, None, event.serial, event.time);
|
||||
self.delta = event.location - self.start_data.location;
|
||||
|
||||
if let Some(workspace) = data.common.shell.space_for_surface_mut(self.window.toplevel().wl_surface()) {
|
||||
|
||||
if let Some(workspace) = data
|
||||
.common
|
||||
.shell
|
||||
.space_for_surface_mut(self.window.toplevel().wl_surface())
|
||||
{
|
||||
let new_location = (self.initial_window_location.to_f64() + self.delta).to_i32_round();
|
||||
workspace.space.map_window(&self.window, new_location, true);
|
||||
}
|
||||
|
|
@ -197,11 +199,10 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
|
|||
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 data = states.cached_state.current::<SurfaceCachedState>();
|
||||
(data.min_size, data.max_size)
|
||||
});
|
||||
let (min_size, max_size) = with_states(self.window.toplevel().wl_surface(), |states| {
|
||||
let data = states.cached_state.current::<SurfaceCachedState>();
|
||||
(data.min_size, data.max_size)
|
||||
});
|
||||
|
||||
let min_width = min_size.w.max(1);
|
||||
let min_height = min_size.h.max(1);
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use smithay::{
|
||||
desktop::{layer_map_for_output, Kind, Space, Window, space::RenderZindex},
|
||||
desktop::{layer_map_for_output, space::RenderZindex, Kind, Space, Window},
|
||||
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::{
|
||||
ResizeEdge, State as XdgState,
|
||||
},
|
||||
utils::IsAlive,
|
||||
wayland::{
|
||||
output::Output,
|
||||
seat::{PointerGrabStartData, Seat},
|
||||
Serial,
|
||||
},
|
||||
utils::IsAlive,
|
||||
};
|
||||
use std::collections::HashSet;
|
||||
|
||||
|
|
@ -30,12 +30,7 @@ impl FloatingLayout {
|
|||
Default::default()
|
||||
}
|
||||
|
||||
pub fn map_window(
|
||||
&mut self,
|
||||
space: &mut Space,
|
||||
window: Window,
|
||||
seat: &Seat<State>,
|
||||
) {
|
||||
pub fn map_window(&mut self, space: &mut Space, window: Window, seat: &Seat<State>) {
|
||||
if let Some(output) = super::output_from_seat(Some(seat), space) {
|
||||
self.map_window_internal(space, window, &output);
|
||||
} else {
|
||||
|
|
@ -53,12 +48,7 @@ impl FloatingLayout {
|
|||
// TODO make sure all windows are still visible on any output or move them
|
||||
}
|
||||
|
||||
fn map_window_internal(
|
||||
&mut self,
|
||||
space: &mut Space,
|
||||
window: Window,
|
||||
output: &Output
|
||||
) {
|
||||
fn map_window_internal(&mut self, space: &mut Space, window: Window, output: &Output) {
|
||||
let win_geo = window.bbox();
|
||||
let layers = layer_map_for_output(&output);
|
||||
let geometry = layers.non_exclusive_zone();
|
||||
|
|
|
|||
|
|
@ -1,15 +1,10 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::{
|
||||
input::ActiveOutput,
|
||||
state::State,
|
||||
};
|
||||
use crate::{input::ActiveOutput, state::State};
|
||||
use smithay::{
|
||||
desktop::{Space, Window},
|
||||
wayland::{
|
||||
compositor::with_states,
|
||||
output::Output,
|
||||
seat::Seat,
|
||||
compositor::with_states, output::Output, seat::Seat,
|
||||
shell::xdg::XdgToplevelSurfaceRoleAttributes,
|
||||
},
|
||||
};
|
||||
|
|
@ -37,9 +32,7 @@ pub fn should_be_floating(window: &Window) -> bool {
|
|||
// simple heuristic taken from
|
||||
// sway/desktop/xdg_shell.c:188 @ 0ee54a52
|
||||
if attrs.parent.is_some()
|
||||
|| (attrs.min_size.w != 0
|
||||
&& attrs.min_size.h != 0
|
||||
&& attrs.min_size == attrs.max_size)
|
||||
|| (attrs.min_size.w != 0 && attrs.min_size.h != 0 && attrs.min_size == attrs.max_size)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,13 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::{
|
||||
utils::prelude::*,
|
||||
shell::layout::Orientation,
|
||||
};
|
||||
use crate::{shell::layout::Orientation, utils::prelude::*};
|
||||
use atomic_float::AtomicF64;
|
||||
use smithay::{
|
||||
reexports::wayland_server::{
|
||||
DisplayHandle,
|
||||
},
|
||||
reexports::wayland_server::DisplayHandle,
|
||||
utils::{Logical, Size},
|
||||
wayland::seat::{AxisFrame, PointerGrab, PointerGrabStartData, PointerInnerHandle, MotionEvent, ButtonEvent},
|
||||
wayland::seat::{
|
||||
AxisFrame, ButtonEvent, MotionEvent, PointerGrab, PointerGrabStartData, PointerInnerHandle,
|
||||
},
|
||||
};
|
||||
use std::sync::{atomic::Ordering, Arc};
|
||||
|
||||
|
|
@ -26,9 +23,9 @@ impl PointerGrab<State> for ResizeForkGrab {
|
|||
fn motion(
|
||||
&mut self,
|
||||
_data: &mut State,
|
||||
_dh: &DisplayHandle,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
event: &MotionEvent
|
||||
_dh: &DisplayHandle,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
event: &MotionEvent,
|
||||
) {
|
||||
// While the grab is active, no client has pointer focus
|
||||
handle.motion(event.location, None, event.serial, event.time);
|
||||
|
|
@ -58,7 +55,8 @@ impl PointerGrab<State> for ResizeForkGrab {
|
|||
}
|
||||
}
|
||||
|
||||
fn axis(&mut self,
|
||||
fn axis(
|
||||
&mut self,
|
||||
_data: &mut State,
|
||||
_dh: &DisplayHandle,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::{
|
||||
shell::{
|
||||
layout::Orientation,
|
||||
focus::FocusDirection,
|
||||
},
|
||||
shell::{focus::FocusDirection, layout::Orientation},
|
||||
utils::prelude::*,
|
||||
};
|
||||
|
||||
|
|
@ -187,7 +184,12 @@ impl TilingLayout {
|
|||
if let Some(root_id) = tree.root_node_id() {
|
||||
for node in tree.traverse_pre_order(root_id).unwrap() {
|
||||
if let Data::Window(window) = node.data() {
|
||||
self.map_window_internal(space, window, None, Option::<std::iter::Empty<&Window>>::None);
|
||||
self.map_window_internal(
|
||||
space,
|
||||
window,
|
||||
None,
|
||||
Option::<std::iter::Empty<&Window>>::None,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -274,7 +276,7 @@ impl TilingLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn active_tree<'a>(trees: &'a mut Vec<Tree<Data>>, output: usize) -> &'a mut Tree<Data> {
|
||||
while trees.len() <= output {
|
||||
trees.push(Tree::new())
|
||||
|
|
@ -558,11 +560,8 @@ impl TilingLayout {
|
|||
if let Some(geo) = geo {
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
if let Kind::Xdg(xdg) = &window.toplevel() {
|
||||
if xdg
|
||||
.current_state()
|
||||
.states.contains(XdgState::Fullscreen)
|
||||
|| xdg
|
||||
.with_pending_state(|pending| {
|
||||
if xdg.current_state().states.contains(XdgState::Fullscreen)
|
||||
|| xdg.with_pending_state(|pending| {
|
||||
pending.states.contains(XdgState::Fullscreen)
|
||||
})
|
||||
{
|
||||
|
|
|
|||
357
src/shell/mod.rs
357
src/shell/mod.rs
|
|
@ -1,54 +1,41 @@
|
|||
use std::{
|
||||
cell::Cell,
|
||||
mem::MaybeUninit,
|
||||
};
|
||||
use std::{cell::Cell, mem::MaybeUninit};
|
||||
|
||||
use smithay::{
|
||||
desktop::{
|
||||
LayerSurface,
|
||||
PopupManager,
|
||||
Window,
|
||||
WindowSurfaceType,
|
||||
layer_map_for_output,
|
||||
},
|
||||
reexports::wayland_server::{
|
||||
DisplayHandle,
|
||||
protocol::wl_surface::WlSurface,
|
||||
},
|
||||
desktop::{layer_map_for_output, LayerSurface, PopupManager, Window, WindowSurfaceType},
|
||||
reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle},
|
||||
utils::{Logical, Point, Rectangle},
|
||||
wayland::{
|
||||
compositor::with_states,
|
||||
seat::{Seat, MotionEvent},
|
||||
output::Output,
|
||||
seat::{MotionEvent, Seat},
|
||||
shell::{
|
||||
wlr_layer::{WlrLayerShellState, Layer, LayerSurfaceCachedState, KeyboardInteractivity},
|
||||
wlr_layer::{
|
||||
KeyboardInteractivity, Layer, LayerSurfaceCachedState, WlrLayerShellState,
|
||||
},
|
||||
xdg::XdgShellState,
|
||||
},
|
||||
output::Output,
|
||||
SERIAL_COUNTER,
|
||||
},
|
||||
utils::{Point, Rectangle, Logical},
|
||||
};
|
||||
|
||||
use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState;
|
||||
|
||||
use crate::{
|
||||
config::{Config, WorkspaceMode as ConfigMode},
|
||||
utils::prelude::*,
|
||||
wayland::protocols::{
|
||||
toplevel_info::ToplevelInfoState,
|
||||
workspace::{
|
||||
WorkspaceState,
|
||||
WorkspaceGroupHandle,
|
||||
WorkspaceHandle,
|
||||
WorkspaceCapabilities,
|
||||
WorkspaceCapabilities, WorkspaceGroupHandle, WorkspaceHandle, WorkspaceState,
|
||||
WorkspaceUpdateGuard,
|
||||
},
|
||||
},
|
||||
utils::prelude::*,
|
||||
};
|
||||
|
||||
pub const MAX_WORKSPACES: usize = 10;
|
||||
pub mod focus;
|
||||
pub mod layout;
|
||||
mod workspace;
|
||||
pub mod focus;
|
||||
pub use self::workspace::*;
|
||||
|
||||
pub struct Shell {
|
||||
|
|
@ -101,11 +88,20 @@ impl Shell {
|
|||
let mut spaces = unsafe {
|
||||
let mut spaces = [UNINIT_SPACE; MAX_WORKSPACES];
|
||||
for (idx, space) in spaces.iter_mut().enumerate() {
|
||||
*space = MaybeUninit::new(Workspace::new(idx as u8, std::mem::zeroed() /* Will be initialized by init_mode */));
|
||||
*space = MaybeUninit::new(Workspace::new(
|
||||
idx as u8,
|
||||
std::mem::zeroed(), /* Will be initialized by init_mode */
|
||||
));
|
||||
}
|
||||
std::mem::transmute(spaces)
|
||||
};
|
||||
let mode = init_mode(&config.static_conf.workspace_mode, None, &[], &mut workspace_state, &mut spaces);
|
||||
let mode = init_mode(
|
||||
&config.static_conf.workspace_mode,
|
||||
None,
|
||||
&[],
|
||||
&mut workspace_state,
|
||||
&mut spaces,
|
||||
);
|
||||
|
||||
Shell {
|
||||
popups: PopupManager::new(None),
|
||||
|
|
@ -131,14 +127,22 @@ impl Shell {
|
|||
|
||||
match self.workspace_mode {
|
||||
WorkspaceMode::OutputBound => {
|
||||
let idx = self.spaces
|
||||
let idx = self
|
||||
.spaces
|
||||
.iter()
|
||||
.position(|x| x.space.outputs().next().is_none())
|
||||
.expect("More then 10 outputs?");
|
||||
|
||||
remap_output(output, &mut self.spaces, None, idx, Point::from((0, 0)), &mut self.toplevel_info_state);
|
||||
remap_output(
|
||||
output,
|
||||
&mut self.spaces,
|
||||
None,
|
||||
idx,
|
||||
Point::from((0, 0)),
|
||||
&mut self.toplevel_info_state,
|
||||
);
|
||||
let mut workspace = &mut self.spaces[idx];
|
||||
|
||||
|
||||
let group = state.create_workspace_group();
|
||||
state.add_group_output(&group, output);
|
||||
state.remove_workspace(workspace.handle);
|
||||
|
|
@ -156,16 +160,26 @@ impl Shell {
|
|||
}
|
||||
}
|
||||
|
||||
if !output.user_data().insert_if_missing(|| output_state.clone()) {
|
||||
if !output
|
||||
.user_data()
|
||||
.insert_if_missing(|| output_state.clone())
|
||||
{
|
||||
let existing_state = output.user_data().get::<OutputBoundState>().unwrap();
|
||||
existing_state.active.set(output_state.active.get());
|
||||
existing_state.group.set(output_state.group.get());
|
||||
}
|
||||
},
|
||||
}
|
||||
WorkspaceMode::Global { active, group } => {
|
||||
state.add_group_output(&group, output);
|
||||
|
||||
remap_output(output, &mut self.spaces, None, active, output.current_location(), &mut self.toplevel_info_state);
|
||||
|
||||
remap_output(
|
||||
output,
|
||||
&mut self.spaces,
|
||||
None,
|
||||
active,
|
||||
output.current_location(),
|
||||
&mut self.toplevel_info_state,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -173,16 +187,29 @@ impl Shell {
|
|||
pub fn remove_output(&mut self, output: &Output) {
|
||||
let mut state = self.workspace_state.update();
|
||||
self.outputs.retain(|o| o != output);
|
||||
|
||||
|
||||
match self.workspace_mode {
|
||||
WorkspaceMode::OutputBound => {
|
||||
let output_state = output.user_data().get::<OutputBoundState>().unwrap();
|
||||
remap_output(output, &mut self.spaces, output_state.active.get(), None, None, &mut self.toplevel_info_state);
|
||||
remap_output(
|
||||
output,
|
||||
&mut self.spaces,
|
||||
output_state.active.get(),
|
||||
None,
|
||||
None,
|
||||
&mut self.toplevel_info_state,
|
||||
);
|
||||
|
||||
// reassign workspaces to a different output
|
||||
let new_group = self.outputs.iter().next().map(|o| o.user_data().get::<OutputBoundState>().unwrap().group.get());
|
||||
let new_group = self
|
||||
.outputs
|
||||
.iter()
|
||||
.next()
|
||||
.map(|o| o.user_data().get::<OutputBoundState>().unwrap().group.get());
|
||||
for mut workspace in self.spaces.iter_mut() {
|
||||
if state.workspace_belongs_to_group(&output_state.group.get(), &workspace.handle) {
|
||||
if state
|
||||
.workspace_belongs_to_group(&output_state.group.get(), &workspace.handle)
|
||||
{
|
||||
state.remove_workspace(workspace.handle);
|
||||
if let Some(new_group) = new_group {
|
||||
init_workspace_handle(&mut state, &new_group, &mut workspace);
|
||||
|
|
@ -192,12 +219,19 @@ impl Shell {
|
|||
|
||||
// destroy workspace group
|
||||
state.remove_workspace_group(output_state.group.get());
|
||||
},
|
||||
}
|
||||
WorkspaceMode::Global { active, group } => {
|
||||
state.remove_group_output(&group, output);
|
||||
|
||||
remap_output(output, &mut self.spaces, active, None, None, &mut self.toplevel_info_state);
|
||||
},
|
||||
remap_output(
|
||||
output,
|
||||
&mut self.spaces,
|
||||
active,
|
||||
None,
|
||||
None,
|
||||
&mut self.toplevel_info_state,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +239,9 @@ impl Shell {
|
|||
if let WorkspaceMode::Global { active, .. } = self.workspace_mode {
|
||||
let workspace = &mut self.spaces[active];
|
||||
for output in self.outputs.iter() {
|
||||
workspace.space.map_output(output, output.current_location());
|
||||
workspace
|
||||
.space
|
||||
.map_output(output, output.current_location());
|
||||
}
|
||||
} else {
|
||||
for output in self.outputs.iter() {
|
||||
|
|
@ -225,27 +261,68 @@ impl Shell {
|
|||
match (&mut self.workspace_mode, mode) {
|
||||
(WorkspaceMode::OutputBound, ConfigMode::Global) => {
|
||||
let new_active = 0;
|
||||
init_mode(&mode, Some(&WorkspaceMode::OutputBound), &self.outputs, &mut self.workspace_state, &mut self.spaces);
|
||||
init_mode(
|
||||
&mode,
|
||||
Some(&WorkspaceMode::OutputBound),
|
||||
&self.outputs,
|
||||
&mut self.workspace_state,
|
||||
&mut self.spaces,
|
||||
);
|
||||
for output in &self.outputs {
|
||||
let old_active = output.user_data().get::<OutputBoundState>().unwrap().active.get();
|
||||
remap_output(output, &mut self.spaces, old_active, new_active, output.current_location(), &mut self.toplevel_info_state);
|
||||
let old_active = output
|
||||
.user_data()
|
||||
.get::<OutputBoundState>()
|
||||
.unwrap()
|
||||
.active
|
||||
.get();
|
||||
remap_output(
|
||||
output,
|
||||
&mut self.spaces,
|
||||
old_active,
|
||||
new_active,
|
||||
output.current_location(),
|
||||
&mut self.toplevel_info_state,
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
(x @ WorkspaceMode::Global { .. }, ConfigMode::OutputBound) => {
|
||||
// inits OutputBoundState if it not exists
|
||||
init_mode(&mode, Some(x), &self.outputs, &mut self.workspace_state, &mut self.spaces);
|
||||
init_mode(
|
||||
&mode,
|
||||
Some(x),
|
||||
&self.outputs,
|
||||
&mut self.workspace_state,
|
||||
&mut self.spaces,
|
||||
);
|
||||
if let WorkspaceMode::Global { ref active, .. } = x {
|
||||
for output in &self.outputs {
|
||||
let new_active = output.user_data().get::<OutputBoundState>().unwrap().active.get();
|
||||
remap_output(output, &mut self.spaces, *active, new_active, Point::from((0, 0)), &mut self.toplevel_info_state);
|
||||
let new_active = output
|
||||
.user_data()
|
||||
.get::<OutputBoundState>()
|
||||
.unwrap()
|
||||
.active
|
||||
.get();
|
||||
remap_output(
|
||||
output,
|
||||
&mut self.spaces,
|
||||
*active,
|
||||
new_active,
|
||||
Point::from((0, 0)),
|
||||
&mut self.toplevel_info_state,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn activate(&mut self, seat: &Seat<State>, output: &Output, idx: usize) -> Option<MotionEvent> {
|
||||
pub fn activate(
|
||||
&mut self,
|
||||
seat: &Seat<State>,
|
||||
output: &Output,
|
||||
idx: usize,
|
||||
) -> Option<MotionEvent> {
|
||||
if idx > MAX_WORKSPACES {
|
||||
return None;
|
||||
}
|
||||
|
|
@ -254,7 +331,14 @@ impl Shell {
|
|||
WorkspaceMode::OutputBound => {
|
||||
// if the workspace is active on a different output, move the cursor over
|
||||
for output in self.outputs.iter().filter(|o| o != &output) {
|
||||
if output.user_data().get::<OutputBoundState>().unwrap().active.get() == idx {
|
||||
if output
|
||||
.user_data()
|
||||
.get::<OutputBoundState>()
|
||||
.unwrap()
|
||||
.active
|
||||
.get()
|
||||
== idx
|
||||
{
|
||||
let geometry = output.geometry();
|
||||
set_active_output(seat, output);
|
||||
return Some(MotionEvent {
|
||||
|
|
@ -277,25 +361,46 @@ impl Shell {
|
|||
let mut state = self.workspace_state.update();
|
||||
output_state.active.set(idx);
|
||||
|
||||
if !state.workspace_belongs_to_group(&output_state.group.get(), &self.spaces[idx].handle) {
|
||||
if !state.workspace_belongs_to_group(
|
||||
&output_state.group.get(),
|
||||
&self.spaces[idx].handle,
|
||||
) {
|
||||
state.remove_workspace(self.spaces[idx].handle);
|
||||
init_workspace_handle(&mut state, &output_state.group.get(), &mut self.spaces[idx]);
|
||||
init_workspace_handle(
|
||||
&mut state,
|
||||
&output_state.group.get(),
|
||||
&mut self.spaces[idx],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
state.remove_workspace_state(&self.spaces[old_active].handle, WState::Active);
|
||||
state.add_workspace_state(&self.spaces[idx].handle, WState::Active);
|
||||
|
||||
std::mem::drop(state);
|
||||
remap_output(output, &mut self.spaces, old_active, idx, Point::from((0, 0)), &mut self.toplevel_info_state);
|
||||
remap_output(
|
||||
output,
|
||||
&mut self.spaces,
|
||||
old_active,
|
||||
idx,
|
||||
Point::from((0, 0)),
|
||||
&mut self.toplevel_info_state,
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
WorkspaceMode::Global { ref mut active, .. } => {
|
||||
let old = *active;
|
||||
*active = idx;
|
||||
|
||||
let mut state = self.workspace_state.update();
|
||||
for output in &self.outputs {
|
||||
remap_output(output, &mut self.spaces, old, idx, output.current_location(), &mut self.toplevel_info_state);
|
||||
remap_output(
|
||||
output,
|
||||
&mut self.spaces,
|
||||
old,
|
||||
idx,
|
||||
output.current_location(),
|
||||
&mut self.toplevel_info_state,
|
||||
);
|
||||
}
|
||||
state.remove_workspace_state(&self.spaces[old].handle, WState::Active);
|
||||
state.add_workspace_state(&self.spaces[idx].handle, WState::Active);
|
||||
|
|
@ -335,28 +440,38 @@ impl Shell {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn outputs_for_surface(&self, surface: &WlSurface) -> impl Iterator<Item=Output> {
|
||||
pub fn outputs_for_surface(&self, surface: &WlSurface) -> impl Iterator<Item = Output> {
|
||||
self.space_for_surface(surface)
|
||||
.and_then(|w| if let Some(window) = w.space.window_for_surface(surface, WindowSurfaceType::ALL) {
|
||||
Some(w.space.outputs_for_window(&window).into_iter())
|
||||
} else { None })
|
||||
.and_then(|w| {
|
||||
if let Some(window) = w.space.window_for_surface(surface, WindowSurfaceType::ALL) {
|
||||
Some(w.space.outputs_for_window(&window).into_iter())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.into_iter()
|
||||
.flatten()
|
||||
}
|
||||
|
||||
pub fn space_for_surface(&self, surface: &WlSurface) -> Option<&Workspace> {
|
||||
self.spaces.iter().find(|workspace| {
|
||||
workspace.space.window_for_surface(surface, WindowSurfaceType::ALL).is_some()
|
||||
workspace
|
||||
.space
|
||||
.window_for_surface(surface, WindowSurfaceType::ALL)
|
||||
.is_some()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn space_for_surface_mut(&mut self, surface: &WlSurface) -> Option<&mut Workspace> {
|
||||
self.spaces
|
||||
.iter_mut()
|
||||
.find(|workspace| workspace.space.window_for_surface(surface, WindowSurfaceType::ALL).is_some())
|
||||
self.spaces.iter_mut().find(|workspace| {
|
||||
workspace
|
||||
.space
|
||||
.window_for_surface(surface, WindowSurfaceType::ALL)
|
||||
.is_some()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn outputs(&self) -> impl Iterator<Item=&Output> {
|
||||
|
||||
pub fn outputs(&self) -> impl Iterator<Item = &Output> {
|
||||
self.outputs.iter()
|
||||
}
|
||||
|
||||
|
|
@ -411,11 +526,16 @@ impl Shell {
|
|||
map.cleanup();
|
||||
}
|
||||
std::mem::drop(state);
|
||||
self.toplevel_info_state.refresh(Some(&self.workspace_state));
|
||||
self.toplevel_info_state
|
||||
.refresh(Some(&self.workspace_state));
|
||||
}
|
||||
|
||||
|
||||
pub fn map_window(&mut self, window: &Window, output: &Output) {
|
||||
let pos = self.pending_windows.iter().position(|(w, _)| w == window).unwrap();
|
||||
let pos = self
|
||||
.pending_windows
|
||||
.iter()
|
||||
.position(|(w, _)| w == window)
|
||||
.unwrap();
|
||||
let (window, seat) = self.pending_windows.remove(pos);
|
||||
|
||||
let workspace = match &self.workspace_mode {
|
||||
|
|
@ -430,20 +550,34 @@ impl Shell {
|
|||
}
|
||||
WorkspaceMode::Global { active, .. } => &mut self.spaces[*active],
|
||||
};
|
||||
self.workspace_state.update().remove_workspace_state(&workspace.handle, WState::Hidden);
|
||||
self.toplevel_info_state.toplevel_enter_workspace(&window, &workspace.handle);
|
||||
self.workspace_state
|
||||
.update()
|
||||
.remove_workspace_state(&workspace.handle, WState::Hidden);
|
||||
self.toplevel_info_state
|
||||
.toplevel_enter_workspace(&window, &workspace.handle);
|
||||
let focus_stack = workspace.focus_stack(&seat);
|
||||
if layout::should_be_floating(&window) {
|
||||
workspace.floating_layer.map_window(&mut workspace.space, window, &seat);
|
||||
workspace
|
||||
.floating_layer
|
||||
.map_window(&mut workspace.space, window, &seat);
|
||||
} else {
|
||||
workspace.tiling_layer.map_window(&mut workspace.space, window, &seat, focus_stack.iter());
|
||||
workspace.tiling_layer.map_window(
|
||||
&mut workspace.space,
|
||||
window,
|
||||
&seat,
|
||||
focus_stack.iter(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_layer(&mut self, layer_surface: &LayerSurface, dh: &DisplayHandle) {
|
||||
let pos = self.pending_layers.iter().position(|(l, _, _)| l == layer_surface).unwrap();
|
||||
let pos = self
|
||||
.pending_layers
|
||||
.iter()
|
||||
.position(|(l, _, _)| l == layer_surface)
|
||||
.unwrap();
|
||||
let (layer_surface, output, seat) = self.pending_layers.remove(pos);
|
||||
|
||||
|
||||
let surface = layer_surface.wl_surface();
|
||||
let wants_focus = {
|
||||
with_states(surface, |states| {
|
||||
|
|
@ -484,17 +618,30 @@ impl Shell {
|
|||
|
||||
let maybe_window = workspace.focus_stack(seat).last();
|
||||
if let Some(window) = maybe_window {
|
||||
workspace.floating_layer.unmap_window(&mut workspace.space, &window);
|
||||
workspace.tiling_layer.unmap_window(&mut workspace.space, &window);
|
||||
self.toplevel_info_state.toplevel_leave_workspace(&window, &workspace.handle);
|
||||
|
||||
workspace
|
||||
.floating_layer
|
||||
.unmap_window(&mut workspace.space, &window);
|
||||
workspace
|
||||
.tiling_layer
|
||||
.unmap_window(&mut workspace.space, &window);
|
||||
self.toplevel_info_state
|
||||
.toplevel_leave_workspace(&window, &workspace.handle);
|
||||
|
||||
let new_workspace = &mut self.spaces[idx];
|
||||
self.toplevel_info_state.toplevel_enter_workspace(&window, &new_workspace.handle);
|
||||
self.toplevel_info_state
|
||||
.toplevel_enter_workspace(&window, &new_workspace.handle);
|
||||
let focus_stack = new_workspace.focus_stack(&seat);
|
||||
if layout::should_be_floating(&window) {
|
||||
new_workspace.floating_layer.map_window(&mut new_workspace.space, window, &seat);
|
||||
new_workspace
|
||||
.floating_layer
|
||||
.map_window(&mut new_workspace.space, window, &seat);
|
||||
} else {
|
||||
new_workspace.tiling_layer.map_window(&mut new_workspace.space, window, &seat, focus_stack.iter());
|
||||
new_workspace.tiling_layer.map_window(
|
||||
&mut new_workspace.space,
|
||||
window,
|
||||
&seat,
|
||||
focus_stack.iter(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -505,7 +652,7 @@ fn init_mode(
|
|||
old_mode: Option<&WorkspaceMode>,
|
||||
outputs: &[Output],
|
||||
state: &mut WorkspaceState<State>,
|
||||
workspaces: &mut [Workspace; MAX_WORKSPACES]
|
||||
workspaces: &mut [Workspace; MAX_WORKSPACES],
|
||||
) -> WorkspaceMode {
|
||||
let mut state = state.update();
|
||||
|
||||
|
|
@ -513,15 +660,17 @@ fn init_mode(
|
|||
for workspace in workspaces.iter_mut() {
|
||||
state.remove_workspace(workspace.handle);
|
||||
}
|
||||
|
||||
|
||||
match old_mode {
|
||||
Some(WorkspaceMode::Global { group, .. }) => state.remove_workspace_group(group.clone()),
|
||||
Some(WorkspaceMode::OutputBound) => for output in outputs {
|
||||
if let Some(old_state) = output.user_data().get::<OutputBoundState>() {
|
||||
state.remove_workspace_group(old_state.group.get());
|
||||
Some(WorkspaceMode::OutputBound) => {
|
||||
for output in outputs {
|
||||
if let Some(old_state) = output.user_data().get::<OutputBoundState>() {
|
||||
state.remove_workspace_group(old_state.group.get());
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
// set the new state (especially cosmic_workspace state)
|
||||
|
|
@ -536,11 +685,8 @@ fn init_mode(
|
|||
}
|
||||
state.add_workspace_state(&workspaces[0].handle, WState::Active);
|
||||
state.remove_workspace_state(&workspaces[0].handle, WState::Hidden);
|
||||
WorkspaceMode::Global {
|
||||
active: 0,
|
||||
group,
|
||||
}
|
||||
},
|
||||
WorkspaceMode::Global { active: 0, group }
|
||||
}
|
||||
ConfigMode::OutputBound => {
|
||||
for (i, output) in outputs.iter().enumerate() {
|
||||
let group = state.create_workspace_group();
|
||||
|
|
@ -564,7 +710,12 @@ fn init_mode(
|
|||
}
|
||||
if !outputs.is_empty() {
|
||||
for workspace in workspaces.iter_mut().skip(outputs.iter().count()) {
|
||||
let group = outputs[0].user_data().get::<OutputBoundState>().unwrap().group.get();
|
||||
let group = outputs[0]
|
||||
.user_data()
|
||||
.get::<OutputBoundState>()
|
||||
.unwrap()
|
||||
.group
|
||||
.get();
|
||||
init_workspace_handle(&mut state, &group, workspace);
|
||||
}
|
||||
}
|
||||
|
|
@ -573,7 +724,11 @@ fn init_mode(
|
|||
}
|
||||
}
|
||||
|
||||
fn init_workspace_handle<'a>(state: &mut WorkspaceUpdateGuard<'a, State>, group: &WorkspaceGroupHandle, workspace: &mut Workspace) -> WorkspaceHandle {
|
||||
fn init_workspace_handle<'a>(
|
||||
state: &mut WorkspaceUpdateGuard<'a, State>,
|
||||
group: &WorkspaceGroupHandle,
|
||||
workspace: &mut Workspace,
|
||||
) -> WorkspaceHandle {
|
||||
let handle = state.create_workspace(&group).unwrap();
|
||||
state.set_workspace_capabilities(&handle, [WorkspaceCapabilities::Activate].into_iter());
|
||||
state.set_workspace_name(&handle, format!("{}", workspace.idx));
|
||||
|
|
@ -591,7 +746,7 @@ fn remap_output(
|
|||
old: impl Into<Option<usize>>,
|
||||
new: impl Into<Option<usize>>,
|
||||
pos: impl Into<Option<Point<i32, Logical>>>,
|
||||
info_state: &mut ToplevelInfoState<State>
|
||||
info_state: &mut ToplevelInfoState<State>,
|
||||
) {
|
||||
if let Some(old) = old.into() {
|
||||
let old_space = &mut spaces[old].space;
|
||||
|
|
@ -607,4 +762,4 @@ fn remap_output(
|
|||
info_state.toplevel_enter_output(window, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
use crate::{
|
||||
shell::layout::{floating::FloatingLayout, tiling::TilingLayout},
|
||||
state::State,
|
||||
shell::layout::{tiling::TilingLayout, floating::FloatingLayout},
|
||||
wayland::protocols::workspace::WorkspaceHandle,
|
||||
};
|
||||
|
||||
|
|
@ -11,12 +10,12 @@ use smithay::{
|
|||
wayland_protocols::xdg::shell::server::xdg_toplevel::{self, ResizeEdge},
|
||||
wayland_server::DisplayHandle,
|
||||
},
|
||||
utils::IsAlive,
|
||||
wayland::{
|
||||
output::Output,
|
||||
seat::{PointerGrabStartData, Seat},
|
||||
Serial,
|
||||
},
|
||||
utils::IsAlive,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
|
@ -64,7 +63,8 @@ impl Workspace {
|
|||
return;
|
||||
}
|
||||
if self.floating_layer.windows.contains(window) {
|
||||
self.floating_layer.maximize_request(&mut self.space, window, output);
|
||||
self.floating_layer
|
||||
.maximize_request(&mut self.space, window, output);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +79,8 @@ impl Workspace {
|
|||
return;
|
||||
}
|
||||
if self.floating_layer.windows.contains(window) {
|
||||
self.floating_layer.move_request(&mut self.space, window, seat, serial, start_data)
|
||||
self.floating_layer
|
||||
.move_request(&mut self.space, window, seat, serial, start_data)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,10 +96,24 @@ impl Workspace {
|
|||
return;
|
||||
}
|
||||
if self.floating_layer.windows.contains(window) {
|
||||
self.floating_layer.resize_request(&mut self.space, window, seat, serial, start_data.clone(), edges)
|
||||
self.floating_layer.resize_request(
|
||||
&mut self.space,
|
||||
window,
|
||||
seat,
|
||||
serial,
|
||||
start_data.clone(),
|
||||
edges,
|
||||
)
|
||||
}
|
||||
if self.tiling_layer.windows.contains(window) {
|
||||
self.tiling_layer.resize_request(&mut self.space, window, seat, serial, start_data, edges)
|
||||
self.tiling_layer.resize_request(
|
||||
&mut self.space,
|
||||
window,
|
||||
seat,
|
||||
serial,
|
||||
start_data,
|
||||
edges,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -155,8 +170,6 @@ impl Workspace {
|
|||
if !self.space.outputs().any(|o| o == output) {
|
||||
return None;
|
||||
}
|
||||
self.fullscreen
|
||||
.get(&output.name())
|
||||
.filter(|w| w.alive())
|
||||
self.fullscreen.get(&output.name()).filter(|w| w.alive())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue