diff --git a/src/backend/kms/surface/mod.rs b/src/backend/kms/surface/mod.rs index 1607cff6..a335bbc1 100644 --- a/src/backend/kms/surface/mod.rs +++ b/src/backend/kms/surface/mod.rs @@ -943,7 +943,11 @@ impl SurfaceThreadState { let has_active_fullscreen = { let shell = self.shell.read().unwrap(); let output = self.mirroring.as_ref().unwrap_or(&self.output); - shell.workspaces.active(output).1.get_fullscreen().is_some() + if let Some((_, workspace)) = shell.workspaces.active(output) { + workspace.get_fullscreen().is_some() + } else { + false + } }; if self.vrr_mode == AdaptiveSync::Enabled { @@ -1457,7 +1461,9 @@ fn render_node_for_output( return *target_node; } - let workspace = shell.active_space(output); + let Some(workspace) = shell.active_space(output) else { + return *target_node; + }; let nodes = workspace .get_fullscreen() .map(|w| vec![w.clone()]) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 8c0a6354..5d4bf3b9 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -516,8 +516,42 @@ where WorkspaceRenderElement: RenderElement, { let shell_guard = shell.read().unwrap(); + #[cfg(feature = "debug")] + let mut debug_elements = { + let output_geo = output.geometry(); + let seats = shell_guard.seats.iter().cloned().collect::>(); + let scale = output.current_scale().fractional_scale(); + + if let Some((state, timings)) = _fps { + let debug_active = shell_guard.debug_active; + vec![fps_ui( + _gpu, + debug_active, + &seats, + renderer.glow_renderer_mut(), + state, + timings, + Rectangle::from_loc_and_size( + (0, 0), + (output_geo.size.w.min(400), output_geo.size.h.min(800)), + ), + scale, + ) + .map_err(FromGlesError::from_gles_error) + .map_err(RenderError::Rendering)? + .into()] + } else { + Vec::new() + } + }; + + let Some((previous_workspace, workspace)) = shell_guard.workspaces.active(output) else { + #[cfg(not(feature = "debug"))] + return Ok(Vec::new()); + #[cfg(feature = "debug")] + return Ok(debug_elements); + }; - let (previous_workspace, workspace) = shell_guard.workspaces.active(output); let (previous_idx, idx) = shell_guard.workspaces.active_num(&output); let previous_workspace = previous_workspace .zip(previous_idx) @@ -532,7 +566,8 @@ where ElementFilter::All }; - workspace_elements( + #[allow(unused_mut)] + let workspace_elements = workspace_elements( _gpu, renderer, shell, @@ -542,8 +577,15 @@ where workspace, cursor_mode, element_filter, - _fps, - ) + )?; + + #[cfg(feature = "debug")] + { + debug_elements.extend(workspace_elements); + Ok(debug_elements) + } + #[cfg(not(feature = "debug"))] + Ok(workspace_elements) } #[profiling::function] @@ -557,7 +599,6 @@ pub fn workspace_elements( current: (WorkspaceHandle, usize), cursor_mode: CursorMode, element_filter: ElementFilter, - _fps: Option<(&EguiState, &Timings)>, ) -> Result>, RenderError<::Error>> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, @@ -588,31 +629,6 @@ where element_filter == ElementFilter::ExcludeWorkspaceOverview, )); - #[cfg(feature = "debug")] - { - let output_geo = output.geometry(); - - if let Some((state, timings)) = _fps { - let debug_active = shell.read().unwrap().debug_active; - let fps_overlay = fps_ui( - _gpu, - debug_active, - &seats, - renderer.glow_renderer_mut(), - state, - timings, - Rectangle::from_loc_and_size( - (0, 0), - (output_geo.size.w.min(400), output_geo.size.h.min(800)), - ), - scale, - ) - .map_err(FromGlesError::from_gles_error) - .map_err(RenderError::Rendering)?; - elements.push(fps_overlay.into()); - } - } - let shell = shell.read().unwrap(); let overview = shell.overview_mode(); @@ -933,7 +949,10 @@ where Target: Clone, { let shell_ref = shell.read().unwrap(); - let (previous_workspace, workspace) = shell_ref.workspaces.active(output); + let (previous_workspace, workspace) = shell_ref + .workspaces + .active(output) + .ok_or(RenderError::OutputNoMode(OutputNoMode))?; let (previous_idx, idx) = shell_ref.workspaces.active_num(output); let previous_workspace = previous_workspace .zip(previous_idx) @@ -1099,7 +1118,6 @@ where current, cursor_mode, element_filter, - None, )?; if let Some(additional_damage) = additional_damage { diff --git a/src/input/actions.rs b/src/input/actions.rs index a85cf8a0..fa819f93 100644 --- a/src/input/actions.rs +++ b/src/input/actions.rs @@ -408,6 +408,7 @@ impl State { let new_target = shell .workspaces .active(&next_output) + .unwrap() .1 .focus_stack .get(&seat) @@ -495,6 +496,7 @@ impl State { let new_target = shell .workspaces .active(&next_output) + .unwrap() .1 .focus_stack .get(&seat) @@ -554,6 +556,7 @@ impl State { let new_target = shell .workspaces .active(&prev_output) + .unwrap() .1 .focus_stack .get(&seat) @@ -765,7 +768,7 @@ impl State { .next() .cloned(); - (shell.active_space(&active_output).handle, output) + (shell.active_space(&active_output).unwrap().handle, output) }; if let Some(next_output) = next_output { self.common @@ -785,7 +788,7 @@ impl State { .next() .cloned(); - (shell.active_space(&active_output).handle, output) + (shell.active_space(&active_output).unwrap().handle, output) }; if let Some(prev_output) = prev_output { self.common @@ -799,7 +802,7 @@ impl State { let shell = self.common.shell.read().unwrap(); ( - shell.active_space(&active_output).handle, + shell.active_space(&active_output).unwrap().handle, shell.next_output(&active_output, direction).cloned(), ) }; @@ -865,7 +868,7 @@ impl State { _ => { let current_output = seat.active_output(); let mut shell = self.common.shell.write().unwrap(); - let workspace = shell.active_space(¤t_output); + let workspace = shell.active_space(¤t_output).unwrap(); if let Some(focused_window) = workspace.focus_stack.get(seat).last() { if workspace.is_tiled(focused_window) { shell.set_overview_mode( @@ -884,7 +887,7 @@ impl State { }; let mut shell = self.common.shell.write().unwrap(); - let workspace = shell.active_space_mut(&focused_output); + let workspace = shell.active_space_mut(&focused_output).unwrap(); if workspace.get_fullscreen().is_some() { return; // TODO, is this what we want? Maybe disengage fullscreen instead? } @@ -909,7 +912,7 @@ impl State { return; }; let mut shell = self.common.shell.write().unwrap(); - let workspace = shell.active_space_mut(&focused_output); + let workspace = shell.active_space_mut(&focused_output).unwrap(); let focus_stack = workspace.focus_stack.get(seat); let focused_window = focus_stack.last().cloned(); if let Some(window) = focused_window { @@ -922,7 +925,7 @@ impl State { return; }; let mut shell = self.common.shell.write().unwrap(); - let workspace = shell.active_space(&focused_output); + let workspace = shell.active_space(&focused_output).unwrap(); let focus_stack = workspace.focus_stack.get(seat); let focused_window = focus_stack.last().cloned(); if let Some(window) = focused_window { @@ -940,14 +943,14 @@ impl State { Action::ToggleOrientation => { let output = seat.active_output(); let mut shell = self.common.shell.write().unwrap(); - let workspace = shell.active_space_mut(&output); + let workspace = shell.active_space_mut(&output).unwrap(); workspace.tiling_layer.update_orientation(None, &seat); } Action::Orientation(orientation) => { let output = seat.active_output(); let mut shell = self.common.shell.write().unwrap(); - let workspace = shell.active_space_mut(&output); + let workspace = shell.active_space_mut(&output).unwrap(); workspace .tiling_layer .update_orientation(Some(orientation), &seat); @@ -991,7 +994,7 @@ impl State { } else { let output = seat.active_output(); let mut shell = self.common.shell.write().unwrap(); - let workspace = shell.workspaces.active_mut(&output); + let workspace = shell.workspaces.active_mut(&output).unwrap(); let mut guard = self.common.workspace_state.update(); workspace.toggle_tiling(seat, &mut guard); } @@ -1002,7 +1005,7 @@ impl State { return; }; let mut shell = self.common.shell.write().unwrap(); - let workspace = shell.active_space_mut(&output); + let workspace = shell.active_space_mut(&output).unwrap(); workspace.toggle_floating_window_focused(seat); } @@ -1035,7 +1038,7 @@ impl State { let (token, data) = (token.clone(), data.clone()); let output = shell.seats.last_active().active_output(); - let workspace = shell.active_space_mut(&output); + let workspace = shell.active_space_mut(&output).unwrap(); workspace.pending_tokens.insert(token.clone()); let handle = workspace.handle; std::mem::drop(shell); diff --git a/src/input/mod.rs b/src/input/mod.rs index 68af65b2..b97aae70 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1760,8 +1760,12 @@ impl State { focused_output: &Output, ) { if let Some(focus) = current_focus { - if let Some(new_descriptor) = - shell.workspaces.active(&focused_output).1.node_desc(focus) + if let Some(new_descriptor) = shell + .workspaces + .active(&focused_output) + .unwrap() + .1 + .node_desc(focus) { let mut spaces = shell.workspaces.spaces_mut(); if old_descriptor.handle != new_descriptor.handle { @@ -1822,7 +1826,7 @@ impl State { } } } else { - let new_workspace = shell.workspaces.active(&focused_output).1.handle; + let new_workspace = shell.workspaces.active(&focused_output).unwrap().1.handle; if new_workspace != old_descriptor.handle { let spaces = shell.workspaces.spaces_mut(); let (mut old_w, mut other_w) = @@ -1867,7 +1871,7 @@ impl State { output: &Output, shell: &Shell, ) -> Option { - let (previous_workspace, workspace) = shell.workspaces.active(output); + let (previous_workspace, workspace) = shell.workspaces.active(output)?; let (previous_idx, idx) = shell.workspaces.active_num(output); let previous_workspace = previous_workspace .zip(previous_idx) @@ -1990,7 +1994,7 @@ impl State { output: &Output, shell: &Shell, ) -> Option<(PointerFocusTarget, Point)> { - let (previous_workspace, workspace) = shell.workspaces.active(output); + let (previous_workspace, workspace) = shell.workspaces.active(output)?; let (previous_idx, idx) = shell.workspaces.active_num(output); let previous_workspace = previous_workspace .zip(previous_idx) @@ -2122,22 +2126,26 @@ impl State { } } -fn cursor_sessions_for_output( - shell: &Shell, - output: &Output, -) -> impl Iterator { - let workspace = shell.active_space(&output); - let maybe_fullscreen = workspace.get_fullscreen(); - workspace - .cursor_sessions() +fn cursor_sessions_for_output<'a>( + shell: &'a Shell, + output: &'a Output, +) -> impl Iterator + 'a { + shell + .active_space(&output) .into_iter() - .chain( - maybe_fullscreen - .map(|w| w.cursor_sessions()) + .flat_map(|workspace| { + let maybe_fullscreen = workspace.get_fullscreen(); + workspace + .cursor_sessions() .into_iter() - .flatten(), - ) - .chain(output.cursor_sessions().into_iter()) + .chain( + maybe_fullscreen + .map(|w| w.cursor_sessions()) + .into_iter() + .flatten(), + ) + .chain(output.cursor_sessions().into_iter()) + }) } fn transform_output_mapped_position<'a, B, E>(output: &Output, event: &E) -> Point diff --git a/src/shell/focus/mod.rs b/src/shell/focus/mod.rs index f4a6ca17..fad3aa89 100644 --- a/src/shell/focus/mod.rs +++ b/src/shell/focus/mod.rs @@ -146,6 +146,7 @@ impl Shell { let workspace = if workspace.is_none() { //should this be the active output or the focused output? self.active_space_mut(&seat.focused_or_active_output()) + .unwrap() } else { workspace.unwrap() }; @@ -181,7 +182,7 @@ impl Shell { } let output = seat.focused_or_active_output(); - let space = self.active_space(&output); + let space = self.active_space(&output).unwrap(); let stack = space.focus_stack.get(seat); stack.last().cloned() }) @@ -404,7 +405,7 @@ impl Common { trace!("Surface dead, focus fixup"); } } else { - let workspace = shell.active_space(&output); + let workspace = shell.active_space(&output).unwrap(); let focus_stack = workspace.focus_stack.get(&seat); if focus_stack.last().is_none() { @@ -504,7 +505,7 @@ fn focus_target_is_valid( .mapped() .any(|m| m == &mapped); - let workspace = shell.active_space(&output); + let workspace = shell.active_space(&output).unwrap(); let focus_stack = workspace.focus_stack.get(&seat); let is_in_focus_stack = focus_stack.last().map(|m| m == &mapped).unwrap_or(false); let has_fullscreen = workspace.get_fullscreen().is_some(); @@ -521,11 +522,12 @@ fn focus_target_is_valid( KeyboardFocusTarget::Group(WindowGroup { node, .. }) => shell .workspaces .active(&output) + .unwrap() .1 .tiling_layer .has_node(&node), KeyboardFocusTarget::Fullscreen(window) => { - let workspace = shell.active_space(&output); + let workspace = shell.active_space(&output).unwrap(); let focus_stack = workspace.focus_stack.get(&seat); focus_stack @@ -560,15 +562,16 @@ fn update_focus_target( }) .cloned() .map(KeyboardFocusTarget::from) - } else if let Some(surface) = shell.active_space(&output).get_fullscreen() { + } else if let Some(surface) = shell.active_space(&output).unwrap().get_fullscreen() { Some(KeyboardFocusTarget::Fullscreen(surface.clone())) } else { shell .active_space(&output) + .unwrap() .focus_stack .get(&seat) .last() - .or_else(|| shell.active_space(&output).mapped().next()) + .or_else(|| shell.active_space(&output).unwrap().mapped().next()) .cloned() .map(KeyboardFocusTarget::from) } diff --git a/src/shell/grabs/menu/default.rs b/src/shell/grabs/menu/default.rs index ce227f81..461cc6a4 100644 --- a/src/shell/grabs/menu/default.rs +++ b/src/shell/grabs/menu/default.rs @@ -117,7 +117,7 @@ pub fn tab_items( let mut shell = state.common.shell.write().unwrap(); let seat = shell.seats.last_active().clone(); let output = seat.active_output(); - let workspace = shell.workspaces.active_mut(&output); + let workspace = shell.workspaces.active_mut(&output).unwrap(); if is_tiled { for mapped in workspace .mapped() diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index 5081ead8..416cf542 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -366,6 +366,7 @@ impl MoveGrab { shell .workspaces .active_mut(&self.cursor_output) + .unwrap() .tiling_layer .cleanup_drag(); self.cursor_output = current_output.clone(); @@ -763,7 +764,7 @@ impl Drop for MoveGrab { (grab_state.location.to_i32_round() + grab_state.window_offset).as_global(); let mut shell = state.common.shell.write().unwrap(); - let workspace_handle = shell.active_space(&output).handle; + let workspace_handle = shell.active_space(&output).unwrap().handle; for old_output in window_outputs.iter().filter(|o| *o != &output) { grab_state.window.output_leave(old_output); } @@ -788,9 +789,12 @@ impl Drop for MoveGrab { Some((window, location.to_global(&output))) } - ManagedLayer::Tiling if shell.active_space(&output).tiling_enabled => { + ManagedLayer::Tiling + if shell.active_space(&output).unwrap().tiling_enabled => + { let (window, location) = shell .active_space_mut(&output) + .unwrap() .tiling_layer .drop_window(grab_state.window); Some((window, location.to_global(&output))) @@ -801,7 +805,7 @@ impl Drop for MoveGrab { grab_state.window.geometry().size.as_global(), )); let theme = shell.theme.clone(); - let workspace = shell.active_space_mut(&output); + let workspace = shell.active_space_mut(&output).unwrap(); let (window, location) = workspace.floating_layer.drop_window( grab_state.window, window_location.to_local(&workspace.output), diff --git a/src/shell/layout/tiling/grabs/resize.rs b/src/shell/layout/tiling/grabs/resize.rs index 03a3cf62..eacd443d 100644 --- a/src/shell/layout/tiling/grabs/resize.rs +++ b/src/shell/layout/tiling/grabs/resize.rs @@ -222,7 +222,10 @@ impl ResizeForkGrab { if let Some(output) = self.output.upgrade() { let mut shell = data.common.shell.write().unwrap(); - let tiling_layer = &mut shell.active_space_mut(&output).tiling_layer; + let Some(workspace) = shell.active_space_mut(&output) else { + return false; + }; + let tiling_layer = &mut workspace.tiling_layer; let gaps = tiling_layer.gaps(); let tree = &mut tiling_layer.queue.trees.back_mut().unwrap().0; diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 07b240d9..5824156e 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -973,22 +973,27 @@ impl Workspaces { .and_then(|set| set.workspaces.get_mut(num)) } - pub fn active(&self, output: &Output) -> (Option<(&Workspace, WorkspaceDelta)>, &Workspace) { - let set = self.sets.get(output).or(self.backup_set.as_ref()).unwrap(); - ( - set.previously_active - .map(|(idx, start)| (&set.workspaces[idx], start)), - &set.workspaces[set.active], - ) + pub fn active( + &self, + output: &Output, + ) -> Option<(Option<(&Workspace, WorkspaceDelta)>, &Workspace)> { + self.sets + .get(output) + .or(self.backup_set.as_ref()) + .map(|set| { + ( + set.previously_active + .map(|(idx, start)| (&set.workspaces[idx], start)), + &set.workspaces[set.active], + ) + }) } - pub fn active_mut(&mut self, output: &Output) -> &mut Workspace { - let set = self - .sets + pub fn active_mut(&mut self, output: &Output) -> Option<&mut Workspace> { + self.sets .get_mut(output) .or(self.backup_set.as_mut()) - .unwrap(); - &mut set.workspaces[set.active] + .map(|set| &mut set.workspaces[set.active]) } pub fn active_num(&self, output: &Output) -> (Option, usize) { @@ -1434,11 +1439,11 @@ impl Shell { } } - pub fn active_space(&self, output: &Output) -> &Workspace { - self.workspaces.active(output).1 + pub fn active_space(&self, output: &Output) -> Option<&Workspace> { + self.workspaces.active(output).map(|(_, active)| active) } - pub fn active_space_mut(&mut self, output: &Output) -> &mut Workspace { + pub fn active_space_mut(&mut self, output: &Output) -> Option<&mut Workspace> { self.workspaces.active_mut(output) } @@ -1494,7 +1499,7 @@ impl Shell { .mapped() .any(|m| m == &elem); - let workspace = self.active_space(output); + let workspace = self.active_space(output).unwrap(); let is_mapped = workspace.mapped().any(|m| m == &elem); is_sticky || is_mapped @@ -1504,7 +1509,7 @@ impl Shell { KeyboardFocusTarget::Fullscreen(elem) => self .outputs() .find(|output| { - let workspace = self.active_space(&output); + let workspace = self.active_space(&output).unwrap(); workspace.get_fullscreen() == Some(&elem) }) .cloned(), @@ -1513,6 +1518,7 @@ impl Shell { .find(|output| { self.workspaces .active(&output) + .unwrap() .1 .tiling_layer .has_node(&node) @@ -1574,9 +1580,9 @@ impl Shell { output: &Output, xdg_activation_state: &XdgActivationState, ) { - self.workspaces - .active_mut(output) - .refresh(xdg_activation_state) + if let Some(w) = self.workspaces.active_mut(output) { + w.refresh(xdg_activation_state) + } } pub fn visible_output_for_surface(&self, surface: &WlSurface) -> Option<&Output> { @@ -1635,6 +1641,7 @@ impl Shell { .or_else(|| { self.outputs().find(|o| { self.active_space(o) + .unwrap() .mapped() .any(|e| e.has_surface(surface, WindowSurfaceType::ALL)) }) @@ -1904,10 +1911,10 @@ impl Shell { .get(output) .and_then(|set| set.sticky_layer.stacking_indicator()), ManagedLayer::Floating => self - .active_space(output) + .active_space(output)? .floating_layer .stacking_indicator(), - ManagedLayer::Tiling => self.active_space(output).tiling_layer.stacking_indicator(), + ManagedLayer::Tiling => self.active_space(output)?.tiling_layer.stacking_indicator(), } } @@ -2092,7 +2099,7 @@ impl Shell { .find(|space| space.handle == handle) .unwrap() } else { - self.workspaces.active_mut(&output) + self.workspaces.active_mut(&output).unwrap() // a seat's active output always has a workspace }; if output != workspace.output { output = workspace.output.clone(); @@ -2110,7 +2117,7 @@ impl Shell { self.remap_unfullscreened_window(mapped, &old_handle, &new_workspace_handle, layer); }; - let active_handle = self.active_space(&output).handle; + let active_handle = self.active_space(&output).unwrap().handle; let workspace = if let Some(handle) = workspace_handle.filter(|handle| { self.workspaces .spaces() @@ -2121,7 +2128,7 @@ impl Shell { .find(|space| space.handle == handle) .unwrap() } else { - self.workspaces.active_mut(&output) + self.workspaces.active_mut(&output).unwrap() }; toplevel_info.new_toplevel(&window, workspace_state); @@ -2203,7 +2210,7 @@ impl Shell { None }; - let active_space = self.active_space(&output); + let active_space = self.active_space(&output).unwrap(); for mapped in active_space.mapped() { self.update_reactive_popups(mapped); } @@ -2448,7 +2455,10 @@ impl Shell { .map(|ws| ws.handle) .ok_or(InvalidWorkspaceIndex)?; - let from_workspace = self.workspaces.active_mut(from_output); + let from_workspace = self + .workspaces + .active_mut(from_output) + .ok_or(InvalidWorkspaceIndex)?; let last_focused_window = from_workspace.focus_stack.get(seat).last().cloned(); let from = from_workspace.handle; @@ -2816,7 +2826,7 @@ impl Shell { ( initial_window_location, ManagedLayer::Sticky, - self.active_space(&cursor_output).handle, + self.active_space(&cursor_output).unwrap().handle, ) } else { return None; @@ -2896,7 +2906,7 @@ impl Shell { return FocusResult::None; }; let output = seat.active_output(); - let workspace = self.active_space(&output); + let workspace = self.active_space(&output).unwrap(); if workspace.fullscreen.is_some() { return FocusResult::None; @@ -3051,7 +3061,7 @@ impl Shell { let Some(output) = seat.focused_output() else { return MoveResult::None; }; - let workspace = self.active_space(&output); + let workspace = self.active_space(&output).unwrap(); let focus_stack = workspace.focus_stack.get(seat); let Some(last) = focus_stack.last().cloned() else { return MoveResult::None; @@ -3084,7 +3094,7 @@ impl Shell { ) } else { let theme = self.theme.clone(); - let workspace = self.active_space_mut(&output); + let workspace = self.active_space_mut(&output).unwrap(); workspace .floating_layer .move_current_element(direction, seat, ManagedLayer::Floating, theme) @@ -3697,16 +3707,20 @@ impl Shell { ) -> OutputPresentationFeedback { let mut output_presentation_feedback = OutputPresentationFeedback::new(output); - let active = self.active_space(output); - active.mapped().for_each(|mapped| { - mapped.active_window().take_presentation_feedback( - &mut output_presentation_feedback, - surface_primary_scanout_output, - |surface, _| { - surface_presentation_feedback_flags_from_states(surface, render_element_states) - }, - ); - }); + if let Some(active) = self.active_space(output) { + active.mapped().for_each(|mapped| { + mapped.active_window().take_presentation_feedback( + &mut output_presentation_feedback, + surface_primary_scanout_output, + |surface, _| { + surface_presentation_feedback_flags_from_states( + surface, + render_element_states, + ) + }, + ); + }); + } self.override_redirect_windows.iter().for_each(|or| { if let Some(wl_surface) = or.wl_surface() { diff --git a/src/state.rs b/src/state.rs index 6f5ad66c..c64ce05f 100644 --- a/src/state.rs +++ b/src/state.rs @@ -862,25 +862,26 @@ impl Common { } }); - let active = shell.active_space(output); - active.mapped().for_each(|mapped| { - for (window, _) in mapped.windows() { - if let Some(feedback) = window - .wl_surface() - .and_then(|wl_surface| { - advertised_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, - ); + if let Some(active) = shell.active_space(output) { + active.mapped().for_each(|mapped| { + for (window, _) in mapped.windows() { + if let Some(feedback) = window + .wl_surface() + .and_then(|wl_surface| { + advertised_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, + ); + } } - } - }); + }); + } shell.override_redirect_windows.iter().for_each(|or| { if let Some(wl_surface) = or.wl_surface() { @@ -1041,35 +1042,37 @@ impl Common { } }); - let active = shell.active_space(output); - active.mapped().for_each(|mapped| { - for (window, _) in mapped.windows() { - window.send_frame(output, time, throttle(&window), should_send); - } - }); - - // other (throttled) windows - active.minimized_windows.iter().for_each(|m| { - for (window, _) in m.window.windows() { - window.send_frame(output, time, throttle(&window), |_, _| None); - } - }); - for space in shell - .workspaces - .spaces_for_output(output) - .filter(|w| w.handle != active.handle) - { - space.mapped().for_each(|mapped| { + if let Some(active) = shell.active_space(output) { + active.mapped().for_each(|mapped| { for (window, _) in mapped.windows() { - let throttle = min(throttle(space), throttle(&window)); - window.send_frame(output, time, throttle, |_, _| None); + window.send_frame(output, time, throttle(&window), should_send); } }); - space.minimized_windows.iter().for_each(|m| { + + // other (throttled) windows + active.minimized_windows.iter().for_each(|m| { for (window, _) in m.window.windows() { window.send_frame(output, time, throttle(&window), |_, _| None); } - }) + }); + + for space in shell + .workspaces + .spaces_for_output(output) + .filter(|w| w.handle != active.handle) + { + space.mapped().for_each(|mapped| { + for (window, _) in mapped.windows() { + let throttle = min(throttle(space), throttle(&window)); + window.send_frame(output, time, throttle, |_, _| None); + } + }); + space.minimized_windows.iter().for_each(|m| { + for (window, _) in m.window.windows() { + window.send_frame(output, time, throttle(&window), |_, _| None); + } + }) + } } shell.override_redirect_windows.iter().for_each(|or| { diff --git a/src/wayland/handlers/toplevel_management.rs b/src/wayland/handlers/toplevel_management.rs index 7bed781f..704960e1 100644 --- a/src/wayland/handlers/toplevel_management.rs +++ b/src/wayland/handlers/toplevel_management.rs @@ -148,9 +148,10 @@ impl ToplevelManagementHandler for State { let mut shell = self.common.shell.write().unwrap(); let seat = shell.seats.last_active().clone(); if let Some(mapped) = shell.element_for_surface(window).cloned() { - if let Some(output) = output { + if let Some((output, workspace)) = + output.and_then(|output| shell.workspaces.active_mut(&output).map(|w| (output, w))) + { let from = minimize_rectangle(&output, window); - let workspace = shell.workspaces.active_mut(&output); workspace.fullscreen_request(window, None, from, &seat); } else if let Some((output, handle)) = shell .space_for(&mapped) diff --git a/src/wayland/handlers/xdg_activation.rs b/src/wayland/handlers/xdg_activation.rs index 7cce939f..7240d5c6 100644 --- a/src/wayland/handlers/xdg_activation.rs +++ b/src/wayland/handlers/xdg_activation.rs @@ -42,7 +42,7 @@ impl XdgActivationHandler for State { if let Some(seat) = data.serial.and_then(|(_, seat)| Seat::from_resource(&seat)) { let output = seat.active_output(); let mut shell = self.common.shell.write().unwrap(); - let workspace = shell.active_space_mut(&output); + let workspace = shell.active_space_mut(&output).unwrap(); workspace.pending_tokens.insert(token.clone()); let handle = workspace.handle; data.user_data @@ -86,7 +86,7 @@ impl XdgActivationHandler for State { if valid { let output = seat.active_output(); let mut shell = self.common.shell.write().unwrap(); - let workspace = shell.active_space_mut(&output); + let workspace = shell.active_space_mut(&output).unwrap(); workspace.pending_tokens.insert(token.clone()); let handle = workspace.handle; data.user_data @@ -125,7 +125,7 @@ impl XdgActivationHandler for State { } let element_workspace = shell.space_for(&element).map(|w| w.handle.clone()); - let current_workspace = shell.active_space_mut(¤t_output); + let current_workspace = shell.active_space_mut(¤t_output).unwrap(); let in_current_workspace = element_workspace .as_ref() diff --git a/src/wayland/handlers/xdg_shell/mod.rs b/src/wayland/handlers/xdg_shell/mod.rs index f3a4e5fe..7f19913c 100644 --- a/src/wayland/handlers/xdg_shell/mod.rs +++ b/src/wayland/handlers/xdg_shell/mod.rs @@ -270,13 +270,13 @@ impl XdgShellHandler for State { mapped }; - let workspace_handle = shell.active_space(&output).handle.clone(); + let workspace_handle = shell.active_space(&output).unwrap().handle.clone(); for (window, _) in mapped.windows() { toplevel_enter_output(&window, &output); toplevel_enter_workspace(&window, &workspace_handle); } - let workspace = shell.active_space_mut(&output); + let workspace = shell.active_space_mut(&output).unwrap(); workspace.floating_layer.map(mapped.clone(), None); workspace.fullscreen_request( @@ -316,13 +316,13 @@ impl XdgShellHandler for State { }; let handle = workspace.handle.clone(); - let workspace_handle = shell.active_space(&output).handle.clone(); + let workspace_handle = shell.active_space(&output).unwrap().handle.clone(); for (window, _) in mapped.windows() { toplevel_enter_output(&window, &output); toplevel_enter_workspace(&window, &workspace_handle); } - let workspace = shell.active_space_mut(&output); + let workspace = shell.active_space_mut(&output).unwrap(); workspace.floating_layer.map(mapped.clone(), None); workspace.fullscreen_request(