shell: One workspace per output
This commit is contained in:
parent
42aaafe586
commit
72df9d07e6
21 changed files with 1561 additions and 1987 deletions
|
|
@ -1507,7 +1507,6 @@ impl KmsState {
|
|||
false
|
||||
};
|
||||
|
||||
shell.refresh_outputs();
|
||||
if recreated {
|
||||
let sessions = output.pending_buffers().collect::<Vec<_>>();
|
||||
if let Err(err) = self.schedule_render(
|
||||
|
|
|
|||
|
|
@ -349,7 +349,6 @@ impl State {
|
|||
output.change_current_state(Some(mode), None, None, None);
|
||||
layer_map_for_output(output).arrange();
|
||||
self.common.output_configuration_state.update();
|
||||
self.common.shell.refresh_outputs();
|
||||
render_ping.ping();
|
||||
}
|
||||
WinitEvent::Refresh => render_ping.ping(),
|
||||
|
|
|
|||
|
|
@ -448,7 +448,6 @@ pub fn init_backend(
|
|||
output.set_preferred(mode);
|
||||
layer_map_for_output(output).arrange();
|
||||
state.common.output_configuration_state.update();
|
||||
state.common.shell.refresh_outputs();
|
||||
surface.dirty = true;
|
||||
if !surface.pending {
|
||||
surface.render.ping();
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ impl State {
|
|||
if let Some(old_workspace) = old_w.get_mut(0) {
|
||||
if let Some(new_workspace) = other_w.iter_mut().find(|w| w.handle == new_workspace) {
|
||||
if new_workspace.tiling_layer.windows().next().is_none() {
|
||||
if let Some(focus) = TilingLayout::move_tree(&mut old_workspace.tiling_layer, &mut new_workspace.tiling_layer, ¤t_output, &new_workspace.handle, &seat, new_workspace.focus_stack.get(&seat).iter(), old_descriptor, &mut data.common.shell.toplevel_info_state) {
|
||||
if let Some(focus) = TilingLayout::move_tree(&mut old_workspace.tiling_layer, &mut new_workspace.tiling_layer, &new_workspace.handle, &seat, new_workspace.focus_stack.get(&seat).iter(), old_descriptor, &mut data.common.shell.toplevel_info_state) {
|
||||
let seat = seat.clone();
|
||||
data.common.event_loop_handle.insert_idle(move |state| {
|
||||
Common::set_focus(state, Some(&focus), &seat, None);
|
||||
|
|
@ -1333,16 +1333,15 @@ impl State {
|
|||
}
|
||||
Action::NextOutput => {
|
||||
let current_output = seat.active_output();
|
||||
if let Some(next_output) = self
|
||||
let next_output = self
|
||||
.common
|
||||
.shell
|
||||
.outputs
|
||||
.iter()
|
||||
.outputs()
|
||||
.skip_while(|o| *o != ¤t_output)
|
||||
.skip(1)
|
||||
.next()
|
||||
.cloned()
|
||||
{
|
||||
.cloned();
|
||||
if let Some(next_output) = next_output {
|
||||
let idx = self.common.shell.workspaces.active_num(&next_output).1;
|
||||
match self.common.shell.activate(&next_output, idx) {
|
||||
Ok(Some(new_pos)) => {
|
||||
|
|
@ -1369,17 +1368,16 @@ impl State {
|
|||
}
|
||||
Action::PreviousOutput => {
|
||||
let current_output = seat.active_output();
|
||||
if let Some(prev_output) = self
|
||||
let prev_output = self
|
||||
.common
|
||||
.shell
|
||||
.outputs
|
||||
.iter()
|
||||
.outputs()
|
||||
.rev()
|
||||
.skip_while(|o| *o != ¤t_output)
|
||||
.skip(1)
|
||||
.next()
|
||||
.cloned()
|
||||
{
|
||||
.cloned();
|
||||
if let Some(prev_output) = prev_output {
|
||||
let idx = self.common.shell.workspaces.active_num(&prev_output).1;
|
||||
match self.common.shell.activate(&prev_output, idx) {
|
||||
Ok(Some(new_pos)) => {
|
||||
|
|
@ -1406,16 +1404,15 @@ impl State {
|
|||
}
|
||||
x @ Action::MoveToNextOutput | x @ Action::SendToNextOutput => {
|
||||
let current_output = seat.active_output();
|
||||
if let Some(next_output) = self
|
||||
let next_output = self
|
||||
.common
|
||||
.shell
|
||||
.outputs
|
||||
.iter()
|
||||
.outputs()
|
||||
.skip_while(|o| *o != ¤t_output)
|
||||
.skip(1)
|
||||
.next()
|
||||
.cloned()
|
||||
{
|
||||
.cloned();
|
||||
if let Some(next_output) = next_output {
|
||||
if let Ok(Some(new_pos)) = Shell::move_current_window(
|
||||
self,
|
||||
seat,
|
||||
|
|
@ -1441,17 +1438,16 @@ impl State {
|
|||
}
|
||||
x @ Action::MoveToPreviousOutput | x @ Action::SendToPreviousOutput => {
|
||||
let current_output = seat.active_output();
|
||||
if let Some(prev_output) = self
|
||||
let prev_output = self
|
||||
.common
|
||||
.shell
|
||||
.outputs
|
||||
.iter()
|
||||
.outputs()
|
||||
.rev()
|
||||
.skip_while(|o| *o != ¤t_output)
|
||||
.skip(1)
|
||||
.next()
|
||||
.cloned()
|
||||
{
|
||||
.cloned();
|
||||
if let Some(prev_output) = prev_output {
|
||||
if let Ok(Some(new_pos)) = Shell::move_current_window(
|
||||
self,
|
||||
seat,
|
||||
|
|
|
|||
|
|
@ -492,7 +492,7 @@ impl CosmicMapped {
|
|||
|
||||
pub fn convert_to_stack<'a>(
|
||||
&mut self,
|
||||
outputs: impl Iterator<Item = (&'a Output, Rectangle<i32, Logical>)>,
|
||||
(output, overlap): (&'a Output, Rectangle<i32, Logical>),
|
||||
) {
|
||||
match &self.element {
|
||||
CosmicMappedInternal::Window(window) => {
|
||||
|
|
@ -518,7 +518,7 @@ impl CosmicMapped {
|
|||
pub fn convert_to_surface<'a>(
|
||||
&mut self,
|
||||
surface: CosmicSurface,
|
||||
outputs: impl Iterator<Item = (&'a Output, Rectangle<i32, Logical>)>,
|
||||
(output, overlap): (&'a Output, Rectangle<i32, Logical>),
|
||||
) {
|
||||
let handle = self.loop_handle();
|
||||
surface.try_force_undecorated(false);
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ impl Shell {
|
|||
return None;
|
||||
}
|
||||
|
||||
Some(self.outputs.iter().flat_map(|o| {
|
||||
Some(self.outputs().flat_map(|o| {
|
||||
let space = self.active_space(o);
|
||||
let stack = space.focus_stack.get(seat);
|
||||
stack.last().cloned()
|
||||
|
|
@ -163,8 +163,9 @@ impl Shell {
|
|||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for output in self.outputs.iter() {
|
||||
let workspace = self.workspaces.active_mut(output);
|
||||
for output in self.outputs().cloned().collect::<Vec<_>>().into_iter() {
|
||||
// TODO: Add self.workspaces.active_workspaces()
|
||||
let workspace = self.workspaces.active_mut(&output);
|
||||
for focused in focused_windows.iter() {
|
||||
if let CosmicSurface::X11(window) = focused.active_window() {
|
||||
if let Some(xwm) = xwm.as_mut().and_then(|state| state.xwm.as_mut()) {
|
||||
|
|
@ -223,8 +224,8 @@ impl Common {
|
|||
let seats = state.common.seats().cloned().collect::<Vec<_>>();
|
||||
for seat in seats {
|
||||
let output = seat.active_output();
|
||||
if !state.common.shell.outputs.contains(&output) {
|
||||
seat.set_active_output(&state.common.shell.outputs[0]);
|
||||
if !state.common.shell.outputs().any(|o| o == &output) {
|
||||
seat.set_active_output(&state.common.shell.outputs().next().unwrap());
|
||||
continue;
|
||||
}
|
||||
let last_known_focus = ActiveFocus::get(&seat);
|
||||
|
|
@ -248,11 +249,16 @@ impl Common {
|
|||
continue; // Focus is valid
|
||||
}
|
||||
}
|
||||
KeyboardFocusTarget::Group(WindowGroup {
|
||||
output: weak_output,
|
||||
..
|
||||
}) => {
|
||||
if weak_output == output {
|
||||
KeyboardFocusTarget::Group(WindowGroup { node, .. }) => {
|
||||
if state
|
||||
.common
|
||||
.shell
|
||||
.workspaces
|
||||
.active(&output)
|
||||
.1
|
||||
.tiling_layer
|
||||
.has_node(&node)
|
||||
{
|
||||
continue; // Focus is valid,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,16 +87,13 @@ impl KeyboardFocusTarget {
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct WindowGroup {
|
||||
pub node: NodeId,
|
||||
pub output: WeakOutput,
|
||||
pub alive: Weak<()>,
|
||||
pub focus_stack: Vec<NodeId>,
|
||||
}
|
||||
|
||||
impl PartialEq for WindowGroup {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.node == other.node
|
||||
&& self.output == other.output
|
||||
&& Weak::ptr_eq(&self.alive, &other.alive)
|
||||
self.node == other.node && Weak::ptr_eq(&self.alive, &other.alive)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ impl PointerGrab<State> for MoveGrab {
|
|||
.workspaces
|
||||
.active_mut(&self.cursor_output)
|
||||
.tiling_layer
|
||||
.cleanup_drag(&self.cursor_output);
|
||||
.cleanup_drag();
|
||||
self.cursor_output = current_output.clone();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ use smithay::{
|
|||
utils::{Logical, Point, Rectangle, Size},
|
||||
wayland::seat::WaylandFocus,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::{
|
||||
backend::render::{element::AsGlowRenderer, IndicatorShader, Key, Usage},
|
||||
|
|
@ -28,9 +27,7 @@ use crate::{
|
|||
},
|
||||
state::State,
|
||||
utils::prelude::*,
|
||||
wayland::{
|
||||
handlers::xdg_shell::popup::get_popup_toplevel, protocols::toplevel_info::ToplevelInfoState,
|
||||
},
|
||||
wayland::handlers::xdg_shell::popup::get_popup_toplevel,
|
||||
};
|
||||
|
||||
mod grabs;
|
||||
|
|
@ -42,67 +39,53 @@ pub struct FloatingLayout {
|
|||
}
|
||||
|
||||
impl FloatingLayout {
|
||||
pub fn new() -> FloatingLayout {
|
||||
Default::default()
|
||||
pub fn new(output: &Output) -> FloatingLayout {
|
||||
let mut layout = Self::default();
|
||||
layout.space.map_output(output, (0, 0));
|
||||
layout
|
||||
}
|
||||
|
||||
pub fn map_output(&mut self, output: &Output, location: Point<i32, Logical>) {
|
||||
self.space.map_output(output, location)
|
||||
}
|
||||
pub fn set_output(&mut self, output: &Output) {
|
||||
let old_output = self.space.outputs().next().unwrap().clone();
|
||||
self.space.unmap_output(&old_output);
|
||||
self.space.map_output(output, (0, 0));
|
||||
|
||||
/*
|
||||
TODO: rescale all positions? (evem rescale windows?)
|
||||
*/
|
||||
|
||||
pub fn unmap_output(
|
||||
&mut self,
|
||||
output: &Output,
|
||||
toplevel_info: &mut ToplevelInfoState<State, CosmicSurface>,
|
||||
) {
|
||||
let windows = self
|
||||
.space
|
||||
.elements_for_output(output)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
for window in &windows {
|
||||
for (toplevel, _) in window.windows() {
|
||||
toplevel_info.toplevel_leave_output(&toplevel, output);
|
||||
}
|
||||
}
|
||||
self.space.unmap_output(output);
|
||||
self.refresh();
|
||||
for window in &windows {
|
||||
for output in self.space.outputs_for_element(&window) {
|
||||
for (toplevel, _) in window.windows() {
|
||||
toplevel_info.toplevel_enter_output(&toplevel, &output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map(
|
||||
&mut self,
|
||||
mapped: impl Into<CosmicMapped>,
|
||||
seat: &Seat<State>,
|
||||
position: impl Into<Option<Point<i32, Logical>>>,
|
||||
position: impl Into<Option<Point<i32, Local>>>,
|
||||
) {
|
||||
let mapped = mapped.into();
|
||||
let output = seat.active_output();
|
||||
let position = position.into();
|
||||
|
||||
self.map_internal(mapped, &output, position)
|
||||
self.map_internal(mapped, position, None)
|
||||
}
|
||||
|
||||
pub(in crate::shell) fn map_internal(
|
||||
&mut self,
|
||||
mapped: CosmicMapped,
|
||||
output: &Output,
|
||||
position: Option<Point<i32, Logical>>,
|
||||
position: Option<Point<i32, Local>>,
|
||||
size: Option<Size<i32, Logical>>,
|
||||
) {
|
||||
let mut win_geo = mapped.geometry();
|
||||
let mut win_geo = mapped.geometry().as_local();
|
||||
|
||||
let output = self.space.outputs().next().unwrap().clone();
|
||||
let layers = layer_map_for_output(&output);
|
||||
let geometry = layers.non_exclusive_zone();
|
||||
mapped.set_bounds(geometry.size);
|
||||
let last_geometry = mapped.last_geometry.lock().unwrap().clone();
|
||||
|
||||
if let Some(size) = last_geometry.map(|g| g.size) {
|
||||
if let Some(size) = size
|
||||
.map(SizeExt::as_local)
|
||||
.or(last_geometry.map(|g| g.size))
|
||||
{
|
||||
win_geo.size = size;
|
||||
} else {
|
||||
let (min_size, max_size) = (
|
||||
|
|
@ -150,18 +133,10 @@ impl FloatingLayout {
|
|||
});
|
||||
|
||||
mapped.set_tiled(false);
|
||||
let offset = output.geometry().loc
|
||||
- self
|
||||
.space
|
||||
.output_geometry(output)
|
||||
.map(|g| g.loc)
|
||||
.unwrap_or_default();
|
||||
mapped.set_geometry(Rectangle::from_loc_and_size(
|
||||
position + offset,
|
||||
win_geo.size,
|
||||
));
|
||||
mapped
|
||||
.set_geometry(Rectangle::from_loc_and_size(position, win_geo.size).to_global(&output));
|
||||
mapped.configure();
|
||||
self.space.map_element(mapped, position, false);
|
||||
self.space.map_element(mapped, position.as_logical(), false);
|
||||
}
|
||||
|
||||
pub fn unmap(&mut self, window: &CosmicMapped) -> bool {
|
||||
|
|
@ -170,10 +145,8 @@ impl FloatingLayout {
|
|||
|
||||
if !is_maximized {
|
||||
if let Some(location) = self.space.element_location(window) {
|
||||
*window.last_geometry.lock().unwrap() = Some(Rectangle::from_loc_and_size(
|
||||
location,
|
||||
window.geometry().size,
|
||||
));
|
||||
*window.last_geometry.lock().unwrap() =
|
||||
Some(Rectangle::from_loc_and_size(location, window.geometry().size).as_local());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -182,8 +155,8 @@ impl FloatingLayout {
|
|||
was_unmaped
|
||||
}
|
||||
|
||||
pub fn element_geometry(&self, elem: &CosmicMapped) -> Option<Rectangle<i32, Logical>> {
|
||||
self.space.element_geometry(elem)
|
||||
pub fn element_geometry(&self, elem: &CosmicMapped) -> Option<Rectangle<i32, Local>> {
|
||||
self.space.element_geometry(elem).map(RectExt::as_local)
|
||||
}
|
||||
|
||||
pub fn maximize_request(&mut self, window: &CosmicSurface) {
|
||||
|
|
@ -339,13 +312,10 @@ impl FloatingLayout {
|
|||
}));
|
||||
|
||||
mapped.set_resizing(true);
|
||||
mapped.set_geometry(Rectangle::from_loc_and_size(
|
||||
match mapped.active_window() {
|
||||
CosmicSurface::X11(s) => s.geometry().loc,
|
||||
_ => (0, 0).into(),
|
||||
},
|
||||
geo.size,
|
||||
));
|
||||
mapped.set_geometry(
|
||||
geo.as_local()
|
||||
.to_global(self.space.outputs().next().unwrap()),
|
||||
);
|
||||
mapped.configure();
|
||||
|
||||
true
|
||||
|
|
@ -503,83 +473,26 @@ impl FloatingLayout {
|
|||
{
|
||||
// TODO what about windows leaving to the top with no headerbar to drag? can that happen? (Probably if the user is moving outputs down)
|
||||
*element.last_geometry.lock().unwrap() = None;
|
||||
let output = self.space.outputs().next().unwrap().clone();
|
||||
self.map_internal(element, &output, None);
|
||||
self.map_internal(element, None, None);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn most_overlapped_output_for_element(&self, elem: &CosmicMapped) -> Option<Output> {
|
||||
let elem_geo = self.space.element_geometry(elem)?;
|
||||
|
||||
if self.space.outputs().nth(1).is_none() {
|
||||
return self.space.outputs().next().cloned();
|
||||
}
|
||||
|
||||
Some(
|
||||
self.space
|
||||
.outputs_for_element(elem)
|
||||
.into_iter()
|
||||
.max_by_key(|o| {
|
||||
let output_geo = self.space.output_geometry(o).unwrap();
|
||||
if let Some(intersection) = output_geo.intersection(elem_geo) {
|
||||
intersection.size.w * intersection.size.h
|
||||
} else {
|
||||
0
|
||||
}
|
||||
})
|
||||
.unwrap_or(self.space.outputs().next().unwrap().clone()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn merge(&mut self, other: FloatingLayout) {
|
||||
let mut output_pos_map = HashMap::new();
|
||||
for output in self.space.outputs() {
|
||||
output_pos_map.insert(
|
||||
output.clone(),
|
||||
self.space.output_geometry(output).unwrap().loc
|
||||
- other
|
||||
.space
|
||||
.output_geometry(output)
|
||||
.map(|geo| geo.loc)
|
||||
.unwrap_or_else(|| (0, 0).into()),
|
||||
);
|
||||
}
|
||||
for element in other.space.elements() {
|
||||
let mut elem_geo = other.space.element_geometry(element).unwrap();
|
||||
let output = other
|
||||
let elem_loc = other
|
||||
.space
|
||||
.outputs_for_element(element)
|
||||
.into_iter()
|
||||
.filter(|o| self.space.outputs().any(|o2| o == o2))
|
||||
.max_by_key(|o| {
|
||||
let output_geo = other.space.output_geometry(o).unwrap();
|
||||
let intersection = output_geo.intersection(elem_geo).unwrap();
|
||||
intersection.size.w * intersection.size.h
|
||||
})
|
||||
.unwrap_or(self.space.outputs().next().unwrap().clone());
|
||||
elem_geo.loc += output_pos_map
|
||||
.get(&output)
|
||||
.copied()
|
||||
.unwrap_or_else(|| (0, 0).into());
|
||||
let offset = output.geometry().loc
|
||||
- self
|
||||
.space
|
||||
.output_geometry(&output)
|
||||
.map(|g| g.loc)
|
||||
.unwrap_or_default();
|
||||
element.set_geometry(Rectangle::from_loc_and_size(
|
||||
elem_geo.loc + offset,
|
||||
elem_geo.size,
|
||||
));
|
||||
self.space.map_element(element.clone(), elem_geo.loc, false);
|
||||
.element_geometry(element)
|
||||
.unwrap()
|
||||
.loc
|
||||
.as_local();
|
||||
self.map_internal(element.clone(), Some(elem_loc), None);
|
||||
}
|
||||
self.refresh(); //fixup any out of bounds elements
|
||||
}
|
||||
|
||||
pub fn render_output<R>(
|
||||
pub fn render<R>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
output: &Output,
|
||||
focused: Option<&CosmicMapped>,
|
||||
mut resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
||||
indicator_thickness: u8,
|
||||
|
|
@ -598,68 +511,65 @@ impl FloatingLayout {
|
|||
#[cfg(feature = "debug")]
|
||||
puffin::profile_function!();
|
||||
|
||||
let output = self.space.outputs().next().unwrap();
|
||||
let output_scale = output.current_scale().fractional_scale();
|
||||
let output_geo = self.space.output_geometry(output).unwrap();
|
||||
|
||||
let mut window_elements = Vec::new();
|
||||
let mut popup_elements = Vec::new();
|
||||
|
||||
self.space
|
||||
.elements_for_output(output)
|
||||
.rev()
|
||||
.for_each(|elem| {
|
||||
let render_location = self.space.element_location(elem).unwrap()
|
||||
- output_geo.loc
|
||||
- elem.geometry().loc;
|
||||
let (w_elements, p_elements) = elem.split_render_elements(
|
||||
renderer,
|
||||
render_location.to_physical_precise_round(output_scale),
|
||||
output_scale.into(),
|
||||
alpha,
|
||||
);
|
||||
self.space.elements().rev().for_each(|elem| {
|
||||
let render_location = self.space.element_location(elem).unwrap() - elem.geometry().loc;
|
||||
let (w_elements, p_elements) = elem.split_render_elements(
|
||||
renderer,
|
||||
render_location.to_physical_precise_round(output_scale),
|
||||
output_scale.into(),
|
||||
alpha,
|
||||
);
|
||||
|
||||
if focused == Some(elem) {
|
||||
let mut indicator_geometry = Rectangle::from_loc_and_size(
|
||||
self.space.element_location(elem).unwrap() - output_geo.loc,
|
||||
elem.geometry().size,
|
||||
if focused == Some(elem) {
|
||||
let mut indicator_geometry = Rectangle::from_loc_and_size(
|
||||
self.space.element_location(elem).unwrap(),
|
||||
elem.geometry().size,
|
||||
)
|
||||
.as_local();
|
||||
|
||||
if let Some((mode, resize)) = resize_indicator.as_mut() {
|
||||
indicator_geometry.loc -= (18, 18).into();
|
||||
indicator_geometry.size += (36, 36).into();
|
||||
resize.resize(indicator_geometry.size.as_logical());
|
||||
resize.output_enter(output, Rectangle::default() /* unused */);
|
||||
window_elements.extend(
|
||||
resize
|
||||
.render_elements::<CosmicWindowRenderElement<R>>(
|
||||
renderer,
|
||||
indicator_geometry
|
||||
.loc
|
||||
.as_logical()
|
||||
.to_physical_precise_round(output_scale),
|
||||
output_scale.into(),
|
||||
alpha * mode.alpha().unwrap_or(1.0),
|
||||
)
|
||||
.into_iter()
|
||||
.map(CosmicMappedRenderElement::Window),
|
||||
);
|
||||
|
||||
if let Some((mode, resize)) = resize_indicator.as_mut() {
|
||||
indicator_geometry.loc -= (18, 18).into();
|
||||
indicator_geometry.size += (36, 36).into();
|
||||
resize.resize(indicator_geometry.size);
|
||||
resize.output_enter(output, output_geo);
|
||||
window_elements.extend(
|
||||
resize
|
||||
.render_elements::<CosmicWindowRenderElement<R>>(
|
||||
renderer,
|
||||
indicator_geometry
|
||||
.loc
|
||||
.to_physical_precise_round(output_scale),
|
||||
output_scale.into(),
|
||||
alpha * mode.alpha().unwrap_or(1.0),
|
||||
)
|
||||
.into_iter()
|
||||
.map(CosmicMappedRenderElement::Window),
|
||||
);
|
||||
}
|
||||
|
||||
if indicator_thickness > 0 {
|
||||
let element = IndicatorShader::focus_element(
|
||||
renderer,
|
||||
Key::Window(Usage::FocusIndicator, elem.clone()),
|
||||
indicator_geometry,
|
||||
indicator_thickness,
|
||||
output_scale,
|
||||
alpha,
|
||||
);
|
||||
window_elements.push(element.into());
|
||||
}
|
||||
}
|
||||
|
||||
window_elements.extend(w_elements);
|
||||
popup_elements.extend(p_elements);
|
||||
});
|
||||
if indicator_thickness > 0 {
|
||||
let element = IndicatorShader::focus_element(
|
||||
renderer,
|
||||
Key::Window(Usage::FocusIndicator, elem.clone()),
|
||||
indicator_geometry,
|
||||
indicator_thickness,
|
||||
output_scale,
|
||||
alpha,
|
||||
);
|
||||
window_elements.push(element.into());
|
||||
}
|
||||
}
|
||||
|
||||
window_elements.extend(w_elements);
|
||||
popup_elements.extend(p_elements);
|
||||
});
|
||||
|
||||
(window_elements, popup_elements)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,67 +137,64 @@ impl PointerGrab<State> for ResizeForkGrab {
|
|||
|
||||
if let Some(output) = self.output.upgrade() {
|
||||
let tiling_layer = &mut data.common.shell.active_space_mut(&output).tiling_layer;
|
||||
if let Some(queue) = tiling_layer.queues.get_mut(&output) {
|
||||
let tree = &mut queue.trees.back_mut().unwrap().0;
|
||||
if tree.get(&self.node).is_ok() {
|
||||
let delta = match self.orientation {
|
||||
Orientation::Vertical => delta.x,
|
||||
Orientation::Horizontal => delta.y,
|
||||
}
|
||||
.round() as i32;
|
||||
|
||||
// check that we are still alive
|
||||
let mut iter = tree
|
||||
.children_ids(&self.node)
|
||||
.unwrap()
|
||||
.skip(self.left_up_idx);
|
||||
let first_elem = iter.next();
|
||||
let second_elem = iter.next();
|
||||
if first_elem.is_none() || second_elem.is_none() {
|
||||
return handle.unset_grab(data, event.serial, event.time);
|
||||
};
|
||||
|
||||
match tree.get_mut(&self.node).unwrap().data_mut() {
|
||||
Data::Group {
|
||||
sizes, orientation, ..
|
||||
} => {
|
||||
if sizes[self.left_up_idx] + sizes[self.left_up_idx + 1]
|
||||
< match orientation {
|
||||
Orientation::Vertical => 720,
|
||||
Orientation::Horizontal => 480,
|
||||
}
|
||||
{
|
||||
return;
|
||||
};
|
||||
|
||||
let old_size = sizes[self.left_up_idx];
|
||||
sizes[self.left_up_idx] = (old_size + delta).max(
|
||||
if self.orientation == Orientation::Vertical {
|
||||
360
|
||||
} else {
|
||||
240
|
||||
},
|
||||
);
|
||||
let diff = old_size - sizes[self.left_up_idx];
|
||||
let next_size = sizes[self.left_up_idx + 1] + diff;
|
||||
sizes[self.left_up_idx + 1] =
|
||||
next_size.max(if self.orientation == Orientation::Vertical {
|
||||
360
|
||||
} else {
|
||||
240
|
||||
});
|
||||
let next_diff = next_size - sizes[self.left_up_idx + 1];
|
||||
sizes[self.left_up_idx] += next_diff;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
self.last_loc = event.location;
|
||||
let blocker = TilingLayout::update_positions(&output, tree, tiling_layer.gaps);
|
||||
tiling_layer.pending_blockers.extend(blocker);
|
||||
} else {
|
||||
handle.unset_grab(data, event.serial, event.time);
|
||||
let tree = &mut tiling_layer.queue.trees.back_mut().unwrap().0;
|
||||
if tree.get(&self.node).is_ok() {
|
||||
let delta = match self.orientation {
|
||||
Orientation::Vertical => delta.x,
|
||||
Orientation::Horizontal => delta.y,
|
||||
}
|
||||
.round() as i32;
|
||||
|
||||
// check that we are still alive
|
||||
let mut iter = tree
|
||||
.children_ids(&self.node)
|
||||
.unwrap()
|
||||
.skip(self.left_up_idx);
|
||||
let first_elem = iter.next();
|
||||
let second_elem = iter.next();
|
||||
if first_elem.is_none() || second_elem.is_none() {
|
||||
return handle.unset_grab(data, event.serial, event.time);
|
||||
};
|
||||
|
||||
match tree.get_mut(&self.node).unwrap().data_mut() {
|
||||
Data::Group {
|
||||
sizes, orientation, ..
|
||||
} => {
|
||||
if sizes[self.left_up_idx] + sizes[self.left_up_idx + 1]
|
||||
< match orientation {
|
||||
Orientation::Vertical => 720,
|
||||
Orientation::Horizontal => 480,
|
||||
}
|
||||
{
|
||||
return;
|
||||
};
|
||||
|
||||
let old_size = sizes[self.left_up_idx];
|
||||
sizes[self.left_up_idx] =
|
||||
(old_size + delta).max(if self.orientation == Orientation::Vertical {
|
||||
360
|
||||
} else {
|
||||
240
|
||||
});
|
||||
let diff = old_size - sizes[self.left_up_idx];
|
||||
let next_size = sizes[self.left_up_idx + 1] + diff;
|
||||
sizes[self.left_up_idx + 1] =
|
||||
next_size.max(if self.orientation == Orientation::Vertical {
|
||||
360
|
||||
} else {
|
||||
240
|
||||
});
|
||||
let next_diff = next_size - sizes[self.left_up_idx + 1];
|
||||
sizes[self.left_up_idx] += next_diff;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
self.last_loc = event.location;
|
||||
let blocker = TilingLayout::update_positions(&output, tree, tiling_layer.gaps);
|
||||
tiling_layer.pending_blockers.extend(blocker);
|
||||
} else {
|
||||
handle.unset_grab(data, event.serial, event.time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,7 @@ impl KeyboardGrab<State> for SwapWindowGrab {
|
|||
serial: Serial,
|
||||
time: u32,
|
||||
) {
|
||||
if self.desc.output.upgrade().is_none()
|
||||
|| !matches!(&data.common.shell.overview_mode, OverviewMode::Started(Trigger::KeyboardSwap(_, d), _) if d == &self.desc)
|
||||
if !matches!(&data.common.shell.overview_mode, OverviewMode::Started(Trigger::KeyboardSwap(_, d), _) if d == &self.desc)
|
||||
{
|
||||
handle.unset_grab(data, serial, false);
|
||||
return;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
747
src/shell/mod.rs
747
src/shell/mod.rs
File diff suppressed because it is too large
Load diff
|
|
@ -76,6 +76,7 @@ const FULLSCREEN_ANIMATION_DURATION: Duration = Duration::from_millis(200);
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Workspace {
|
||||
pub output: Output,
|
||||
pub tiling_layer: TilingLayout,
|
||||
pub floating_layer: FloatingLayout,
|
||||
pub tiling_enabled: bool,
|
||||
|
|
@ -84,6 +85,7 @@ pub struct Workspace {
|
|||
pub focus_stack: FocusStacks,
|
||||
pub pending_buffers: Vec<(ScreencopySession, BufferParams)>,
|
||||
pub screencopy_sessions: Vec<DropableSession>,
|
||||
pub output_stack: VecDeque<String>,
|
||||
pub(super) backdrop_id: Id,
|
||||
pub dirty: AtomicBool,
|
||||
}
|
||||
|
|
@ -198,16 +200,26 @@ impl MoveResult {
|
|||
}
|
||||
|
||||
impl Workspace {
|
||||
pub fn new(handle: WorkspaceHandle, tiling_enabled: bool, gaps: (u8, u8)) -> Workspace {
|
||||
pub fn new(
|
||||
handle: WorkspaceHandle,
|
||||
output: Output,
|
||||
tiling_enabled: bool,
|
||||
gaps: (u8, u8),
|
||||
) -> Workspace {
|
||||
let tiling_layer = TilingLayout::new(gaps, &output);
|
||||
let floating_layer = FloatingLayout::new(&output);
|
||||
|
||||
Workspace {
|
||||
tiling_layer: TilingLayout::new(gaps),
|
||||
floating_layer: FloatingLayout::new(),
|
||||
output,
|
||||
tiling_layer,
|
||||
floating_layer,
|
||||
tiling_enabled,
|
||||
fullscreen: HashMap::new(),
|
||||
handle,
|
||||
focus_stack: FocusStacks::default(),
|
||||
pending_buffers: Vec::new(),
|
||||
screencopy_sessions: Vec::new(),
|
||||
output_stack: VecDeque::new(),
|
||||
backdrop_id: Id::new(),
|
||||
dirty: AtomicBool::new(false),
|
||||
}
|
||||
|
|
@ -299,27 +311,29 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn map_output(&mut self, output: &Output, position: Point<i32, Logical>) {
|
||||
self.tiling_layer.map_output(output, position);
|
||||
self.floating_layer.map_output(output, position);
|
||||
pub fn output(&self) -> &Output {
|
||||
&self.output
|
||||
}
|
||||
|
||||
pub fn unmap_output(
|
||||
pub fn set_output(
|
||||
&mut self,
|
||||
output: &Output,
|
||||
toplevel_info: &mut ToplevelInfoState<State, CosmicSurface>,
|
||||
) {
|
||||
if let Some(dead_output_fullscreen) = self.fullscreen.remove(output) {
|
||||
self.unfullscreen_request(&dead_output_fullscreen.window.surface());
|
||||
self.tiling_layer.set_output(output);
|
||||
self.floating_layer.set_output(output);
|
||||
for mapped in self.mapped() {
|
||||
for (surface, _) in mapped.windows() {
|
||||
toplevel_info.toplevel_leave_output(&surface, &self.output);
|
||||
toplevel_info.toplevel_enter_output(&surface, output);
|
||||
}
|
||||
}
|
||||
self.tiling_layer.unmap_output(output, toplevel_info);
|
||||
self.floating_layer.unmap_output(output, toplevel_info);
|
||||
self.refresh();
|
||||
self.output = output.clone();
|
||||
}
|
||||
|
||||
pub fn unmap(&mut self, mapped: &CosmicMapped) -> Option<ManagedState> {
|
||||
let was_floating = self.floating_layer.unmap(&mapped);
|
||||
let was_tiling = self.tiling_layer.unmap(&mapped).is_some();
|
||||
let was_tiling = self.tiling_layer.unmap(&mapped);
|
||||
if was_floating || was_tiling {
|
||||
assert!(was_floating != was_tiling);
|
||||
}
|
||||
|
|
@ -363,67 +377,32 @@ impl Workspace {
|
|||
.find(|e| {
|
||||
e.windows()
|
||||
.any(|(w, _)| w.wl_surface().as_ref() == Some(surface))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn outputs_for_element(&self, elem: &CosmicMapped) -> impl Iterator<Item = Output> {
|
||||
self.floating_layer
|
||||
.space
|
||||
.outputs_for_element(elem)
|
||||
.into_iter()
|
||||
.chain(self.tiling_layer.output_for_element(elem).cloned())
|
||||
}
|
||||
|
||||
pub fn output_under(&self, point: Point<i32, Logical>) -> Option<&Output> {
|
||||
let space = &self.floating_layer.space;
|
||||
space.outputs().find(|o| {
|
||||
let internal_output_geo = space.output_geometry(o).unwrap();
|
||||
let external_output_geo = o.geometry();
|
||||
internal_output_geo.contains(point - external_output_geo.loc + internal_output_geo.loc)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn element_under(
|
||||
&mut self,
|
||||
location: Point<f64, Logical>,
|
||||
location: Point<f64, Global>,
|
||||
overview: OverviewMode,
|
||||
) -> Option<(PointerFocusTarget, Point<i32, Logical>)> {
|
||||
) -> Option<(PointerFocusTarget, Point<i32, Global>)> {
|
||||
let location = location.to_local(&self.output);
|
||||
self.floating_layer
|
||||
.space
|
||||
.element_under(location)
|
||||
.map(|(mapped, p)| (mapped.clone().into(), p))
|
||||
.element_under(location.as_logical())
|
||||
.map(|(mapped, p)| (mapped.clone().into(), p.as_local()))
|
||||
.or_else(|| self.tiling_layer.element_under(location, overview))
|
||||
.map(|(m, p)| (m, p.to_global(&self.output)))
|
||||
}
|
||||
|
||||
pub fn element_geometry(&self, elem: &CosmicMapped) -> Option<Rectangle<i32, Logical>> {
|
||||
let space = &self.floating_layer.space;
|
||||
let outputs = space.outputs().collect::<Vec<_>>();
|
||||
let offset = if outputs.len() == 1
|
||||
&& space.output_geometry(&outputs[0]).unwrap().loc == Point::from((0, 0))
|
||||
{
|
||||
outputs[0].geometry().loc
|
||||
} else {
|
||||
(0, 0).into()
|
||||
};
|
||||
|
||||
pub fn element_geometry(&self, elem: &CosmicMapped) -> Option<Rectangle<i32, Local>> {
|
||||
self.floating_layer
|
||||
.space
|
||||
.element_geometry(elem)
|
||||
.or_else(|| self.tiling_layer.element_geometry(elem))
|
||||
.map(|mut geo| {
|
||||
geo.loc += offset;
|
||||
geo
|
||||
})
|
||||
}
|
||||
|
||||
pub fn recalculate(&mut self, output: &Output) {
|
||||
if let Some(f) = self.fullscreen.get(output) {
|
||||
if !f.exclusive {
|
||||
f.window
|
||||
.set_geometry(layer_map_for_output(output).non_exclusive_zone());
|
||||
}
|
||||
}
|
||||
self.tiling_layer.recalculate(output);
|
||||
pub fn recalculate(&mut self) {
|
||||
self.tiling_layer.recalculate();
|
||||
self.floating_layer.refresh();
|
||||
}
|
||||
|
||||
pub fn maximize_request(
|
||||
|
|
@ -574,7 +553,7 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
|
||||
result
|
||||
Some(f.original_geometry.size.as_logical())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -730,7 +709,7 @@ impl Workspace {
|
|||
}
|
||||
|
||||
let was_floating = self.floating_layer.unmap(&mapped);
|
||||
let was_tiled = self.tiling_layer.unmap_as_placeholder(&mapped);
|
||||
let was_tiled = dbg!(self.tiling_layer.unmap_as_placeholder(&mapped));
|
||||
assert!(was_floating != was_tiled.is_some());
|
||||
|
||||
Some(MoveGrab::new(
|
||||
|
|
@ -754,7 +733,7 @@ impl Workspace {
|
|||
.into_iter()
|
||||
{
|
||||
self.tiling_layer.unmap(&window);
|
||||
self.floating_layer.map(window, seat, None);
|
||||
self.floating_layer.map(window, None);
|
||||
}
|
||||
self.tiling_enabled = false;
|
||||
} else {
|
||||
|
|
@ -767,8 +746,7 @@ impl Workspace {
|
|||
.into_iter()
|
||||
{
|
||||
self.floating_layer.unmap(&window);
|
||||
self.tiling_layer
|
||||
.map(window, seat, focus_stack.iter(), None)
|
||||
self.tiling_layer.map(window, focus_stack.iter(), None)
|
||||
}
|
||||
self.tiling_enabled = true;
|
||||
}
|
||||
|
|
@ -779,12 +757,11 @@ impl Workspace {
|
|||
if let Some(window) = self.focus_stack.get(seat).iter().next().cloned() {
|
||||
if self.tiling_layer.mapped().any(|(_, m, _)| m == &window) {
|
||||
self.tiling_layer.unmap(&window);
|
||||
self.floating_layer.map(window, seat, None);
|
||||
self.floating_layer.map(window, None);
|
||||
} else if self.floating_layer.mapped().any(|w| w == &window) {
|
||||
let focus_stack = self.focus_stack.get(seat);
|
||||
self.floating_layer.unmap(&window);
|
||||
self.tiling_layer
|
||||
.map(window, seat, focus_stack.iter(), None)
|
||||
self.tiling_layer.map(window, focus_stack.iter(), None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -837,8 +814,8 @@ impl Workspace {
|
|||
pub fn node_desc(&self, focus: KeyboardFocusTarget) -> Option<NodeDesc> {
|
||||
match focus {
|
||||
KeyboardFocusTarget::Element(mapped) => {
|
||||
self.tiling_layer.mapped().find_map(|(output, m, _)| {
|
||||
(m == &mapped).then_some(output.clone()).and_then(|output| {
|
||||
self.tiling_layer.mapped().find_map(|(_, m, _)| {
|
||||
if m == &mapped {
|
||||
mapped
|
||||
.tiling_node_id
|
||||
.lock()
|
||||
|
|
@ -846,7 +823,6 @@ impl Workspace {
|
|||
.clone()
|
||||
.map(|node_id| NodeDesc {
|
||||
handle: self.handle.clone(),
|
||||
output: output.downgrade(),
|
||||
node: node_id,
|
||||
stack_window: if mapped
|
||||
.stack_ref()
|
||||
|
|
@ -858,12 +834,13 @@ impl Workspace {
|
|||
None
|
||||
},
|
||||
})
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
KeyboardFocusTarget::Group(WindowGroup { output, node, .. }) => Some(NodeDesc {
|
||||
KeyboardFocusTarget::Group(WindowGroup { node, .. }) => Some(NodeDesc {
|
||||
handle: self.handle.clone(),
|
||||
output,
|
||||
node,
|
||||
stack_window: None,
|
||||
}),
|
||||
|
|
@ -904,10 +881,9 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn render_output<'a, R>(
|
||||
pub fn render<'a, R>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
output: &Output,
|
||||
override_redirect_windows: &[X11Surface],
|
||||
xwm_state: Option<&'a mut XWaylandState>,
|
||||
draw_focus_indicator: Option<&Seat<State>>,
|
||||
|
|
@ -1089,9 +1065,8 @@ impl Workspace {
|
|||
OverviewMode::None => 1.0,
|
||||
};
|
||||
|
||||
let (w_elements, p_elements) = self.floating_layer.render_output::<R>(
|
||||
let (w_elements, p_elements) = self.floating_layer.render::<R>(
|
||||
renderer,
|
||||
output,
|
||||
focused.as_ref(),
|
||||
resize_indicator.clone(),
|
||||
indicator_thickness,
|
||||
|
|
@ -1113,11 +1088,10 @@ impl Workspace {
|
|||
};
|
||||
|
||||
//tiling surfaces
|
||||
let (w_elements, p_elements) = self.tiling_layer.render_output::<R>(
|
||||
let (w_elements, p_elements) = self.tiling_layer.render::<R>(
|
||||
renderer,
|
||||
output,
|
||||
draw_focus_indicator,
|
||||
layer_map.non_exclusive_zone(),
|
||||
zone,
|
||||
overview,
|
||||
resize_indicator,
|
||||
indicator_thickness,
|
||||
|
|
|
|||
76
src/state.rs
76
src/state.rs
|
|
@ -511,50 +511,34 @@ impl Common {
|
|||
|
||||
let active = self.shell.active_space(output);
|
||||
active.mapped().for_each(|mapped| {
|
||||
let outputs_for_element: Vec<_> = active.outputs_for_element(mapped).collect();
|
||||
if outputs_for_element.contains(&output) {
|
||||
let window = mapped.active_window();
|
||||
window.with_surfaces(|surface, states| {
|
||||
let primary_scanout_output = update_surface_primary_scanout_output(
|
||||
surface,
|
||||
output,
|
||||
states,
|
||||
render_element_states,
|
||||
|current_output, current_state, next_output, next_state| {
|
||||
if outputs_for_element.contains(current_output) {
|
||||
default_primary_scanout_output_compare(
|
||||
current_output,
|
||||
current_state,
|
||||
next_output,
|
||||
next_state,
|
||||
)
|
||||
} else {
|
||||
next_output
|
||||
}
|
||||
},
|
||||
);
|
||||
if let Some(output) = primary_scanout_output {
|
||||
with_fractional_scale(states, |fraction_scale| {
|
||||
fraction_scale
|
||||
.set_preferred_scale(output.current_scale().fractional_scale());
|
||||
});
|
||||
}
|
||||
});
|
||||
window.send_frame(output, time, throttle, surface_primary_scanout_output);
|
||||
if let Some(feedback) = window
|
||||
.wl_surface()
|
||||
.and_then(|wl_surface| {
|
||||
source_node_for_surface(&wl_surface, &self.display_handle)
|
||||
})
|
||||
.and_then(|source| dmabuf_feedback(source))
|
||||
{
|
||||
window.send_dmabuf_feedback(
|
||||
output,
|
||||
&feedback,
|
||||
render_element_states,
|
||||
surface_primary_scanout_output,
|
||||
);
|
||||
let window = mapped.active_window();
|
||||
window.with_surfaces(|surface, states| {
|
||||
let primary_scanout_output = update_surface_primary_scanout_output(
|
||||
surface,
|
||||
output,
|
||||
states,
|
||||
render_element_states,
|
||||
|_current_output, _current_state, next_output, _next_state| next_output,
|
||||
);
|
||||
if let Some(output) = primary_scanout_output {
|
||||
with_fractional_scale(states, |fraction_scale| {
|
||||
fraction_scale
|
||||
.set_preferred_scale(output.current_scale().fractional_scale());
|
||||
});
|
||||
}
|
||||
});
|
||||
window.send_frame(output, time, throttle, surface_primary_scanout_output);
|
||||
if let Some(feedback) = window
|
||||
.wl_surface()
|
||||
.and_then(|wl_surface| source_node_for_surface(&wl_surface, &self.display_handle))
|
||||
.and_then(|source| dmabuf_feedback(source))
|
||||
{
|
||||
window.send_dmabuf_feedback(
|
||||
output,
|
||||
&feedback,
|
||||
render_element_states,
|
||||
surface_primary_scanout_output,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -565,10 +549,8 @@ impl Common {
|
|||
.filter(|w| w.handle != active.handle)
|
||||
{
|
||||
space.mapped().for_each(|mapped| {
|
||||
if space.outputs_for_element(mapped).any(|o| &o == output) {
|
||||
let window = mapped.active_window();
|
||||
window.send_frame(output, time, throttle, |_, _| None);
|
||||
}
|
||||
let window = mapped.active_window();
|
||||
window.send_frame(space.output(), time, throttle, |_, _| None);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ impl CompositorHandler for State {
|
|||
let changed = layer_map_for_output(&output).arrange();
|
||||
if changed {
|
||||
for workspace in self.common.shell.workspaces.spaces_mut() {
|
||||
workspace.recalculate(&output);
|
||||
workspace.recalculate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@ impl WlrLayerShellHandler for State {
|
|||
}
|
||||
|
||||
fn new_popup(&mut self, _parent: WlrLayerSurface, popup: PopupSurface) {
|
||||
let positioner = popup.with_pending_state(|state| state.positioner);
|
||||
self.common.shell.unconstrain_popup(&popup, &positioner);
|
||||
self.common.shell.unconstrain_popup(&popup);
|
||||
|
||||
if popup.send_configure().is_ok() {
|
||||
self.common
|
||||
|
|
@ -76,7 +75,7 @@ impl WlrLayerShellHandler for State {
|
|||
}
|
||||
|
||||
for workspace in self.common.shell.workspaces.spaces_mut() {
|
||||
workspace.recalculate(&output);
|
||||
workspace.recalculate();
|
||||
}
|
||||
|
||||
// collect screencopy sessions needing an update
|
||||
|
|
|
|||
|
|
@ -1296,7 +1296,7 @@ pub fn schedule_offscreen_workspace_session(
|
|||
if !session.alive() {
|
||||
return;
|
||||
}
|
||||
if !state.common.shell.outputs.contains(&output) {
|
||||
if !state.common.shell.outputs().any(|o| o == &output) {
|
||||
return;
|
||||
}
|
||||
match render_workspace_to_buffer(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::{
|
||||
shell::WorkspaceMode,
|
||||
state::ClientState,
|
||||
utils::prelude::*,
|
||||
wayland::protocols::workspace::{
|
||||
|
|
@ -30,19 +29,12 @@ impl WorkspaceHandler for State {
|
|||
for request in requests.into_iter() {
|
||||
match request {
|
||||
Request::Activate(handle) => {
|
||||
let maybe = match &self.common.shell.workspaces {
|
||||
WorkspaceMode::Global(set) => set
|
||||
.workspaces
|
||||
let maybe = self.common.shell.workspaces.iter().find_map(|(o, set)| {
|
||||
set.workspaces
|
||||
.iter()
|
||||
.position(|w| w.handle == handle)
|
||||
.map(|i| (self.common.last_active_seat().active_output(), i)),
|
||||
WorkspaceMode::OutputBound(sets, _) => sets.iter().find_map(|(o, set)| {
|
||||
set.workspaces
|
||||
.iter()
|
||||
.position(|w| w.handle == handle)
|
||||
.map(|i| (o.clone(), i))
|
||||
}),
|
||||
};
|
||||
.map(|i| (o.clone(), i))
|
||||
});
|
||||
|
||||
if let Some((output, idx)) = maybe {
|
||||
let _ = self.common.shell.activate(&output, idx); // TODO: move cursor?
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ impl XdgShellHandler for State {
|
|||
|
||||
if surface.get_parent_surface().is_some() {
|
||||
// let other shells deal with their popups
|
||||
self.common.shell.unconstrain_popup(&surface, &positioner);
|
||||
self.common.shell.unconstrain_popup(&surface);
|
||||
|
||||
if surface.send_configure().is_ok() {
|
||||
self.common
|
||||
|
|
@ -123,7 +123,7 @@ impl XdgShellHandler for State {
|
|||
state.positioner = positioner;
|
||||
});
|
||||
|
||||
self.common.shell.unconstrain_popup(&surface, &positioner);
|
||||
self.common.shell.unconstrain_popup(&surface);
|
||||
surface.send_repositioned(token);
|
||||
if let Err(err) = surface.send_configure() {
|
||||
warn!(
|
||||
|
|
@ -150,9 +150,6 @@ impl XdgShellHandler for State {
|
|||
}
|
||||
|
||||
fn maximize_request(&mut self, surface: ToplevelSurface) {
|
||||
let seat = self.common.last_active_seat();
|
||||
let output = seat.active_output();
|
||||
|
||||
if let Some(mapped) = self
|
||||
.common
|
||||
.shell
|
||||
|
|
@ -164,7 +161,7 @@ impl XdgShellHandler for State {
|
|||
.windows()
|
||||
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface()))
|
||||
.unwrap();
|
||||
workspace.maximize_request(&window, &output, self.common.event_loop_handle.clone())
|
||||
workspace.maximize_request(&window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -194,6 +191,7 @@ impl XdgShellHandler for State {
|
|||
let seat = self.common.last_active_seat();
|
||||
seat.active_output()
|
||||
});
|
||||
// TODO: If this is not the output? Do we move it?
|
||||
|
||||
if let Some(mapped) = self
|
||||
.common
|
||||
|
|
@ -206,11 +204,7 @@ impl XdgShellHandler for State {
|
|||
.windows()
|
||||
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface()))
|
||||
.unwrap();
|
||||
workspace.fullscreen_request(
|
||||
&window,
|
||||
&output,
|
||||
self.common.event_loop_handle.clone(),
|
||||
)
|
||||
workspace.fullscreen_request(&window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -363,14 +363,11 @@ impl XwmHandler for State {
|
|||
}
|
||||
|
||||
fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
|
||||
let seat = self.common.last_active_seat();
|
||||
let output = seat.active_output();
|
||||
let surface = CosmicSurface::X11(window);
|
||||
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(&surface).cloned() {
|
||||
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
|
||||
workspace.maximize_request(&window, &output, self.common.event_loop_handle.clone())
|
||||
workspace.maximize_request(&window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -386,18 +383,10 @@ impl XwmHandler for State {
|
|||
}
|
||||
|
||||
fn fullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) {
|
||||
let seat = self.common.last_active_seat();
|
||||
let output = seat.active_output();
|
||||
let surface = CosmicSurface::X11(window);
|
||||
|
||||
if let Some(mapped) = self.common.shell.element_for_surface(&surface).cloned() {
|
||||
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
|
||||
workspace.fullscreen_request(
|
||||
&window,
|
||||
&output,
|
||||
self.common.event_loop_handle.clone(),
|
||||
)
|
||||
workspace.fullscreen_request(&surface)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue