Compare commits

..

No commits in common. "30d8868cca9426e9f08e74e45a6a754908f102ec" and "a103e7619b0a21b1c3c6b29debd6879d7d0bcc11" have entirely different histories.

11 changed files with 66 additions and 371 deletions

19
Cargo.lock generated
View file

@ -21,7 +21,7 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
[[package]] [[package]]
name = "accesskit" name = "accesskit"
version = "0.22.0" version = "0.22.0"
source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f"
dependencies = [ dependencies = [
"uuid", "uuid",
] ]
@ -29,7 +29,7 @@ dependencies = [
[[package]] [[package]]
name = "accesskit_consumer" name = "accesskit_consumer"
version = "0.32.0" version = "0.32.0"
source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"hashbrown 0.16.1", "hashbrown 0.16.1",
@ -38,7 +38,7 @@ dependencies = [
[[package]] [[package]]
name = "accesskit_macos" name = "accesskit_macos"
version = "0.23.0" version = "0.23.0"
source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_consumer", "accesskit_consumer",
@ -51,7 +51,7 @@ dependencies = [
[[package]] [[package]]
name = "accesskit_windows" name = "accesskit_windows"
version = "0.30.0" version = "0.30.0"
source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_consumer", "accesskit_consumer",
@ -64,7 +64,7 @@ dependencies = [
[[package]] [[package]]
name = "accesskit_winit" name = "accesskit_winit"
version = "0.30.0" version = "0.30.0"
source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_macos", "accesskit_macos",
@ -1021,7 +1021,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-settings-config" name = "cosmic-settings-config"
version = "1.9.0" version = "0.1.0"
dependencies = [ dependencies = [
"cosmic-config", "cosmic-config",
"ron 0.11.0", "ron 0.11.0",
@ -1040,7 +1040,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-settings-daemon-config" name = "cosmic-settings-daemon-config"
version = "1.9.0" version = "0.1.0"
dependencies = [ dependencies = [
"cosmic-config", "cosmic-config",
"cosmic-theme", "cosmic-theme",
@ -3072,7 +3072,6 @@ dependencies = [
"log", "log",
"palette", "palette",
"phf 0.13.1", "phf 0.13.1",
"roxmltree 0.20.0",
"rust-embed", "rust-embed",
"serde", "serde",
"slotmap", "slotmap",
@ -3136,9 +3135,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]] [[package]]
name = "libredox" name = "libredox"
version = "0.1.25" version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" checksum = "8d8f1ea3f21fd3405dcaf6c9b5c1630af9afc422d9073ea39c5f6d6c772e08ed"
dependencies = [ dependencies = [
"bitflags 2.13.2", "bitflags 2.13.2",
"libc", "libc",

View file

@ -172,7 +172,7 @@ pub enum ColorFilter {
} }
impl Config { impl Config {
pub fn load(loop_handle: &LoopHandle<'_, State>, kiosk_mode: bool) -> Config { pub fn load(loop_handle: &LoopHandle<'_, State>) -> Config {
let config = cosmic_config::Config::new("com.system76.CosmicComp", 1).unwrap(); let config = cosmic_config::Config::new("com.system76.CosmicComp", 1).unwrap();
let source = cosmic_config::calloop::ConfigWatchSource::new(&config).unwrap(); let source = cosmic_config::calloop::ConfigWatchSource::new(&config).unwrap();
loop_handle loop_handle
@ -248,48 +248,40 @@ impl Config {
// Source key bindings from com.system76.CosmicSettings.Shortcuts // Source key bindings from com.system76.CosmicSettings.Shortcuts
let settings_context = shortcuts::context().expect("Failed to load shortcuts config"); let settings_context = shortcuts::context().expect("Failed to load shortcuts config");
let mut system_actions = Default::default(); let system_actions = shortcuts::system_actions(&settings_context);
let mut shortcuts = Default::default(); let shortcuts = shortcuts::shortcuts(&settings_context);
// Kiosk mode disables shortcuts
if !kiosk_mode {
system_actions = shortcuts::system_actions(&settings_context);
shortcuts = shortcuts::shortcuts(&settings_context);
// Listen for updates to the keybindings config. // Listen for updates to the keybindings config.
match cosmic_config::calloop::ConfigWatchSource::new(&settings_context) { match cosmic_config::calloop::ConfigWatchSource::new(&settings_context) {
Ok(source) => { Ok(source) => {
if let Err(err) = if let Err(err) = loop_handle.insert_source(source, |(config, keys), (), state| {
loop_handle.insert_source(source, |(config, keys), (), state| { for key in keys {
for key in keys { match key.as_str() {
match key.as_str() { // Reload the keyboard shortcuts config.
// Reload the keyboard shortcuts config. "custom" | "defaults" => {
"custom" | "defaults" => { state.common.config.shortcuts = shortcuts::shortcuts(&config);
state.common.config.shortcuts =
shortcuts::shortcuts(&config);
}
"system_actions" => {
state.common.config.system_actions =
shortcuts::system_actions(&config);
}
_ => (),
}
} }
})
{ "system_actions" => {
warn!( state.common.config.system_actions =
?err, shortcuts::system_actions(&config);
"Failed to watch com.system76.CosmicSettings.Shortcuts config" }
);
_ => (),
}
} }
}) {
warn!(
?err,
"Failed to watch com.system76.CosmicSettings.Shortcuts config"
);
} }
Err(err) => warn!( }
?err, Err(err) => warn!(
"failed to create config watch source for com.system76.CosmicSettings.Shortcuts" ?err,
), "failed to create config watch source for com.system76.CosmicSettings.Shortcuts"
}; ),
} };
let window_rules_context = let window_rules_context =
window_rules::context().expect("Failed to load window rules config"); window_rules::context().expect("Failed to load window rules config");

View file

@ -19,7 +19,7 @@ use crate::{
Stage, render_input_order, Stage, render_input_order,
target::{KeyboardFocusTarget, PointerFocusTarget}, target::{KeyboardFocusTarget, PointerFocusTarget},
}, },
grabs::{MenuGrab, MoveGrab, ReleaseMode, ResizeEdge, ResizeGrab}, grabs::{ReleaseMode, ResizeEdge},
layout::{ layout::{
floating::ResizeGrabMarker, floating::ResizeGrabMarker,
tiling::{NodeDesc, SwapWindowGrab, TilingLayout}, tiling::{NodeDesc, SwapWindowGrab, TilingLayout},
@ -49,7 +49,7 @@ use smithay::{
PointerAxisEvent, ProximityState, TabletToolButtonEvent, TabletToolEvent, PointerAxisEvent, ProximityState, TabletToolButtonEvent, TabletToolEvent,
TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState, TouchEvent, TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState, TouchEvent,
}, },
desktop::{WindowSurfaceType, utils::under_from_surface_tree}, desktop::{PopupKeyboardGrab, WindowSurfaceType, utils::under_from_surface_tree},
input::{ input::{
Seat, Seat,
keyboard::KeyboardHandle, keyboard::KeyboardHandle,
@ -2096,21 +2096,6 @@ impl State {
backend_id, seat, modifiers, handle, serial, keycode, key_state, time, backend_id, seat, modifiers, handle, serial, keycode, key_state, time,
); );
// A modifier-only binding fires on the modifier's release, but its press was already
// forwarded. Forward the release too.
if key_state == KeyState::Released
&& matches!(&result, FilterResult::Intercept(Some((_, binding))) if binding.key.is_none())
{
seat.get_keyboard().unwrap().input_forward(
self,
keycode,
key_state,
serial,
time,
previous_modifiers != *modifiers,
);
}
if (matches!(result, FilterResult::Forward) if (matches!(result, FilterResult::Forward)
&& !seat.get_keyboard().unwrap().is_grabbed() && !seat.get_keyboard().unwrap().is_grabbed()
&& !shortcuts_inhibited && !shortcuts_inhibited
@ -2306,15 +2291,17 @@ impl State {
let keyboard = seat.get_keyboard().unwrap(); let keyboard = seat.get_keyboard().unwrap();
let pointer = seat.get_pointer().unwrap(); let pointer = seat.get_pointer().unwrap();
// Escape only cancels grabs the compositor started for its own interactions // We're only interested in filtering keyboard grabs if we initiated them.
// For keyboard: SwapWindowGrab // The easiest way to check that is to check the type of the grab.
// For pointer: MoveGrab, ResizeGrab, and MenuGrab let keyboard_grabbed = keyboard.with_grab(|_serial, grab| {
let keyboard_grabbed = grab.is::<SwapWindowGrab>() || grab.is::<PopupKeyboardGrab<State>>()
keyboard.with_grab(|_serial, grab| grab.is::<SwapWindowGrab>()) == Some(true);
let pointer_grabbed = pointer.with_grab(|_serial, grab| {
grab.is::<MoveGrab>() || grab.is::<ResizeGrab>() || grab.is::<MenuGrab>()
}) == Some(true); }) == Some(true);
let is_grabbed = keyboard_grabbed || pointer_grabbed; // A virtual-keyboard key can arrive while the seat's pointer is grabbed by that
// same on-screen keyboard's own button press (the implicit grab from clicking an OSK
// key). That pointer grab must not capture the injected key, otherwise e.g.
// pressing esc on a virtual keyboard gets swallowed here
let from_vk = matches!(backend_id, InputBackendId::VirtualKeyboard);
let is_grabbed = keyboard_grabbed || (pointer.is_grabbed() && !from_vk);
let current_focus = keyboard.current_focus(); let current_focus = keyboard.current_focus();
//this should fall back to active output since there may not be a focused output //this should fall back to active output since there may not be a focused output

View file

@ -289,7 +289,7 @@ Project home page: https://github.com/pop-os/cosmic-comp
Options: Options:
-h, --help Show this message -h, --help Show this message
--no-xwayland Run without Xwayland --no-xwayland Run without Xwayland
-V, --version Show the version of cosmic-comp"# -v, --version Show the version of cosmic-comp"#
); );
} }

View file

@ -2,18 +2,12 @@ use crate::{
shell::{CosmicSurface, MinimizedWindow, Shell, Trigger, element::CosmicMapped}, shell::{CosmicSurface, MinimizedWindow, Shell, Trigger, element::CosmicMapped},
state::{Common, State}, state::{Common, State},
utils::prelude::*, utils::prelude::*,
wayland::{ wayland::handlers::{xdg_shell::PopupGrabData, xwayland_keyboard_grab::XWaylandGrabSeatData},
handlers::{xdg_shell::PopupGrabData, xwayland_keyboard_grab::XWaylandGrabSeatData},
protocols::session_lock_layer::layer_show_on_lock,
},
}; };
use indexmap::IndexSet; use indexmap::IndexSet;
use smithay::{ use smithay::{
backend::input::InputTime, backend::input::InputTime,
desktop::{ desktop::{PopupUngrabStrategy, layer_map_for_output},
LayerSurface, PopupUngrabStrategy, WindowSurfaceType, find_popup_root_surface,
layer_map_for_output,
},
input::{Seat, pointer::MotionEvent}, input::{Seat, pointer::MotionEvent},
output::Output, output::Output,
reexports::wayland_server::{Resource, protocol::wl_surface::WlSurface}, reexports::wayland_server::{Resource, protocol::wl_surface::WlSurface},
@ -633,42 +627,19 @@ fn focus_target_is_valid(
output: &Output, output: &Output,
target: KeyboardFocusTarget, target: KeyboardFocusTarget,
) -> bool { ) -> bool {
// If a session lock is active, only lock surfaces and lock layers can be focused // If a session lock is active, only lock surfaces can be focused
if shell.session_lock.is_some() { if shell.session_lock.is_some() {
if let KeyboardFocusTarget::LayerSurface(layer) = &target {
return layer_show_on_lock(layer.wl_surface());
} else if let KeyboardFocusTarget::Popup(popup) = &target
&& let Ok(root) = find_popup_root_surface(popup)
{
return layer_show_on_lock(&root);
}
return matches!(target, KeyboardFocusTarget::LockSurface(_)); return matches!(target, KeyboardFocusTarget::LockSurface(_));
} }
// If an exclusive layer shell surface exists (on any output), only exclusive // If an exclusive layer shell surface exists (on any output), only exclusive
// shell surfaces can have focus, on the highest layer with exclusive surfaces. // shell surfaces can have focus, on the highest layer with exclusive surfaces.
// Popups are judged by their root surface, so an exclusive surface can
// still open grabbing popups (menus, dropdowns, context menus).
if let Some(layer) = exclusive_layer_surface_layer(shell) { if let Some(layer) = exclusive_layer_surface_layer(shell) {
let is_exclusive_on_layer = |layer_surface: &LayerSurface| { return if let KeyboardFocusTarget::LayerSurface(layer_surface) = target {
let data = layer_surface.cached_state(); let data = layer_surface.cached_state();
(data.keyboard_interactivity, data.layer) == (KeyboardInteractivity::Exclusive, layer) (data.keyboard_interactivity, data.layer) == (KeyboardInteractivity::Exclusive, layer)
}; } else {
return match target { false
KeyboardFocusTarget::LayerSurface(layer_surface) => {
is_exclusive_on_layer(&layer_surface)
}
KeyboardFocusTarget::Popup(popup) => find_popup_root_surface(&popup)
.ok()
.and_then(|root| {
shell.outputs().find_map(|o| {
layer_map_for_output(o)
.layer_for_surface(&root, WindowSurfaceType::ALL)
.map(&is_exclusive_on_layer)
})
})
.unwrap_or(false),
_ => false,
}; };
} }

View file

@ -22,7 +22,7 @@ use crate::{
prelude::OutputExt, prelude::OutputExt,
quirks::{WORKSPACE_OVERVIEW_NAMESPACE, workspace_overview_is_open}, quirks::{WORKSPACE_OVERVIEW_NAMESPACE, workspace_overview_is_open},
}, },
wayland::protocols::{session_lock_layer::layer_show_on_lock, workspace::WorkspaceHandle}, wayland::protocols::workspace::WorkspaceHandle,
}; };
pub enum Stage<'a> { pub enum Stage<'a> {
@ -77,8 +77,6 @@ fn render_input_order_internal<R: 'static>(
element_filter: ElementFilter, element_filter: ElementFilter,
mut callback: impl FnMut(Stage) -> ControlFlow<Result<R, OutputNoMode>, ()>, mut callback: impl FnMut(Stage) -> ControlFlow<Result<R, OutputNoMode>, ()>,
) -> ControlFlow<Result<R, OutputNoMode>, ()> { ) -> ControlFlow<Result<R, OutputNoMode>, ()> {
// NOTE: Keep in sync with other surface iteration functions
if shell if shell
.zoom_state .zoom_state
.as_ref() .as_ref()
@ -89,92 +87,7 @@ fn render_input_order_internal<R: 'static>(
// Session Lock // Session Lock
if let Some(session_lock) = &shell.session_lock { if let Some(session_lock) = &shell.session_lock {
for (layer, popup, location) in layer_popups(output, Layer::Overlay, element_filter) { return callback(Stage::SessionLock(session_lock.surfaces.get(output)));
if !layer_show_on_lock(layer.wl_surface()) {
continue;
}
callback(Stage::LayerPopup {
layer,
popup: &popup,
location,
workspace_idx: current.1,
})?;
}
for (layer, location) in layer_surfaces(output, Layer::Overlay, element_filter) {
if !layer_show_on_lock(layer.wl_surface()) {
continue;
}
callback(Stage::LayerSurface {
layer,
location,
workspace_idx: current.1,
})?;
}
for (layer, popup, location) in layer_popups(output, Layer::Top, element_filter) {
if !layer_show_on_lock(layer.wl_surface()) {
continue;
}
callback(Stage::LayerPopup {
layer,
popup: &popup,
location,
workspace_idx: current.1,
})?;
}
for (layer, location) in layer_surfaces(output, Layer::Top, element_filter) {
if !layer_show_on_lock(layer.wl_surface()) {
continue;
}
callback(Stage::LayerSurface {
layer,
location,
workspace_idx: current.1,
})?;
}
callback(Stage::SessionLock(session_lock.surfaces.get(output)))?;
for (layer, popup, location) in layer_popups(output, Layer::Bottom, element_filter) {
if !layer_show_on_lock(layer.wl_surface()) {
continue;
}
callback(Stage::LayerPopup {
layer,
popup: &popup,
location,
workspace_idx: current.1,
})?;
}
for (layer, popup, location) in layer_popups(output, Layer::Background, element_filter) {
if !layer_show_on_lock(layer.wl_surface()) {
continue;
}
callback(Stage::LayerPopup {
layer,
popup: &popup,
location,
workspace_idx: current.1,
})?;
}
for (layer, location) in layer_surfaces(output, Layer::Bottom, element_filter) {
if !layer_show_on_lock(layer.wl_surface()) {
continue;
}
callback(Stage::LayerSurface {
layer,
location,
workspace_idx: current.1,
})?;
}
for (layer, location) in layer_surfaces(output, Layer::Background, element_filter) {
if !layer_show_on_lock(layer.wl_surface()) {
continue;
}
callback(Stage::LayerSurface {
layer,
location,
workspace_idx: current.1,
})?;
}
return ControlFlow::Continue(());
} }
// Overlay-level layer shell // Overlay-level layer shell

View file

@ -19,10 +19,7 @@ use crate::{
utils, utils,
wayland::{ wayland::{
handlers::data_device::{self, get_dnd_icon}, handlers::data_device::{self, get_dnd_icon},
protocols::{ protocols::workspace::{State as WState, WorkspaceCapabilities},
session_lock_layer::layer_show_on_lock,
workspace::{State as WState, WorkspaceCapabilities},
},
}, },
}; };
use cosmic_comp_config::{ use cosmic_comp_config::{
@ -2049,27 +2046,12 @@ impl Shell {
} }
pub fn visible_output_for_surface(&self, surface: &WlSurface) -> Option<&Output> { pub fn visible_output_for_surface(&self, surface: &WlSurface) -> Option<&Output> {
// NOTE: Keep in sync with surface iteration in `render_input_order_internal`
if let Some(session_lock) = &self.session_lock { if let Some(session_lock) = &self.session_lock {
if let Some((output, _)) = session_lock return session_lock
.surfaces .surfaces
.iter() .iter()
.find(|(_, v)| v.wl_surface() == surface) .find(|(_, v)| v.wl_surface() == surface)
{ .map(|(k, _)| k);
return Some(output);
}
for o in self.outputs() {
let map = layer_map_for_output(o);
if let Some(layer_surface) = map.layer_for_surface(surface, WindowSurfaceType::ALL)
{
if layer_show_on_lock(layer_surface.wl_surface()) {
return Some(o);
} else {
return None;
}
}
}
} }
self.outputs() self.outputs()

View file

@ -23,7 +23,6 @@ use crate::{
output_configuration::OutputConfigurationState, output_configuration::OutputConfigurationState,
output_power::OutputPowerState, output_power::OutputPowerState,
overlap_notify::OverlapNotifyState, overlap_notify::OverlapNotifyState,
session_lock_layer::SessionLockLayerState,
toplevel_info::ToplevelInfoState, toplevel_info::ToplevelInfoState,
toplevel_management::{ManagementCapabilities, ToplevelManagementState}, toplevel_management::{ManagementCapabilities, ToplevelManagementState},
workspace::{WorkspaceState, WorkspaceUpdateGuard}, workspace::{WorkspaceState, WorkspaceUpdateGuard},
@ -321,7 +320,6 @@ pub struct Common {
pub xwayland_state: Option<XWaylandState>, pub xwayland_state: Option<XWaylandState>,
pub xwayland_shell_state: XWaylandShellState, pub xwayland_shell_state: XWaylandShellState,
pub pointer_focus_state: Option<PointerFocusState>, pub pointer_focus_state: Option<PointerFocusState>,
pub session_lock_layer_state: SessionLockLayerState,
#[cfg(feature = "logind")] #[cfg(feature = "logind")]
pub inhibit_lid_fd: Option<OwnedFd>, pub inhibit_lid_fd: Option<OwnedFd>,
@ -667,7 +665,7 @@ impl State {
.unwrap(); .unwrap();
let clock = Clock::new(); let clock = Clock::new();
let config = Config::load(&handle, kiosk_command.is_some()); let config = Config::load(&handle);
let compositor_state = CompositorState::new::<Self>(dh); let compositor_state = CompositorState::new::<Self>(dh);
let corner_radius_state = CornerRadiusState::new::<Self>(dh); let corner_radius_state = CornerRadiusState::new::<Self>(dh);
let data_device_state = DataDeviceState::new::<Self>(dh); let data_device_state = DataDeviceState::new::<Self>(dh);
@ -765,9 +763,6 @@ impl State {
let dbus_state = DBusState::init(&handle); let dbus_state = DBusState::init(&handle);
let session_lock_layer_state =
SessionLockLayerState::new::<State, _>(dh, client_not_sandboxed);
State { State {
common: Common { common: Common {
config, config,
@ -835,7 +830,6 @@ impl State {
pointer_focus_state: None, pointer_focus_state: None,
dbus_state, dbus_state,
keyboard_layout_state, keyboard_layout_state,
session_lock_layer_state,
#[cfg(feature = "logind")] #[cfg(feature = "logind")]
inhibit_lid_fd: None, inhibit_lid_fd: None,
@ -974,8 +968,6 @@ impl Common {
output: &Output, output: &Output,
render_element_states: &RenderElementStates, render_element_states: &RenderElementStates,
) { ) {
// NOTE: Keep in sync with surface iteration in `render_input_order_internal`
let shell = self.shell.read(); let shell = self.shell.read();
let processor = |namespace: Option<usize>| { let processor = |namespace: Option<usize>| {
move |surface: &WlSurface, states: &SurfaceData| { move |surface: &WlSurface, states: &SurfaceData| {
@ -1082,8 +1074,6 @@ impl Common {
render_element_states: &RenderElementStates, render_element_states: &RenderElementStates,
mut dmabuf_feedback: impl FnMut(DrmNode) -> Option<SurfaceDmabufFeedback>, mut dmabuf_feedback: impl FnMut(DrmNode) -> Option<SurfaceDmabufFeedback>,
) { ) {
// NOTE: Keep in sync with surface iteration in `render_input_order_internal`
let shell = self.shell.read(); let shell = self.shell.read();
if let Some(session_lock) = shell.session_lock.as_ref() if let Some(session_lock) = shell.session_lock.as_ref()
@ -1297,8 +1287,6 @@ impl Common {
#[profiling::function] #[profiling::function]
pub fn send_frames(&self, output: &Output, sequence: Option<usize>) { pub fn send_frames(&self, output: &Output, sequence: Option<usize>) {
// NOTE: Keep in sync with surface iteration in `render_input_order_internal`
let time = self.clock.now(); let time = self.clock.now();
let should_send = |surface: &WlSurface, states: &SurfaceData| { let should_send = |surface: &WlSurface, states: &SurfaceData| {
// Do the standard primary scanout output check. For pointer surfaces it deduplicates // Do the standard primary scanout output check. For pointer surfaces it deduplicates

View file

@ -243,7 +243,7 @@ impl State {
{ {
for mapped in current_workspace for mapped in current_workspace
.mapped() .mapped()
.filter(|m| m.maximized_state.lock().unwrap().is_some() && *m != &element) .filter(|m| m.maximized_state.lock().unwrap().is_some())
.cloned() .cloned()
.collect::<Vec<_>>() .collect::<Vec<_>>()
.into_iter() .into_iter()

View file

@ -8,7 +8,6 @@ pub mod keyboard_layout;
pub mod output_configuration; pub mod output_configuration;
pub mod output_power; pub mod output_power;
pub mod overlap_notify; pub mod overlap_notify;
pub mod session_lock_layer;
pub mod toplevel_info; pub mod toplevel_info;
pub mod toplevel_management; pub mod toplevel_management;
pub mod workspace; pub mod workspace;

View file

@ -1,136 +0,0 @@
use cosmic_protocols::session_lock_layer::v1::server::cosmic_session_lock_layer_manager_v1;
use smithay::{
reexports::wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, backend::GlobalId,
protocol::wl_surface,
},
wayland::{
Dispatch2, GlobalDispatch2,
compositor::{Cacheable, with_states},
shell::wlr_layer::WlrLayerShellHandler,
},
};
struct SessionLockLayerData;
#[derive(Debug)]
pub struct SessionLockLayerState {
global: GlobalId,
}
impl SessionLockLayerState {
pub fn new<D, F>(dh: &DisplayHandle, client_filter: F) -> Self
where
F: for<'a> Fn(&'a Client) -> bool + Clone + Send + Sync + 'static,
D: GlobalDispatch<
cosmic_session_lock_layer_manager_v1::CosmicSessionLockLayerManagerV1,
SessionLockLayerGlobalData,
> + 'static,
{
let global = dh
.create_global::<D, cosmic_session_lock_layer_manager_v1::CosmicSessionLockLayerManagerV1, _>(
1,
SessionLockLayerGlobalData {
filter: Box::new(client_filter.clone()),
},
);
Self { global }
}
pub fn global_id(&self) -> GlobalId {
self.global.clone()
}
}
#[doc(hidden)]
pub struct SessionLockLayerGlobalData {
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
}
impl<D> GlobalDispatch2<cosmic_session_lock_layer_manager_v1::CosmicSessionLockLayerManagerV1, D>
for SessionLockLayerGlobalData
where
D: Dispatch<
cosmic_session_lock_layer_manager_v1::CosmicSessionLockLayerManagerV1,
SessionLockLayerData,
>,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<cosmic_session_lock_layer_manager_v1::CosmicSessionLockLayerManagerV1>,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, SessionLockLayerData);
}
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
#[derive(Clone, Copy, Default)]
struct SessionLockLayerSurfaceData {
show_on_lock: bool,
}
impl Cacheable for SessionLockLayerSurfaceData {
fn commit(&mut self, _dh: &DisplayHandle) -> Self {
*self
}
fn merge_into(self, into: &mut Self, _dh: &DisplayHandle) {
*into = self;
}
}
pub fn layer_show_on_lock(wl_surface: &wl_surface::WlSurface) -> bool {
with_states(wl_surface, |states| {
if states.cached_state.has::<SessionLockLayerSurfaceData>() {
let mut state = states.cached_state.get::<SessionLockLayerSurfaceData>();
state.current().show_on_lock
} else {
false
}
})
}
impl<D> Dispatch2<cosmic_session_lock_layer_manager_v1::CosmicSessionLockLayerManagerV1, D>
for SessionLockLayerData
where
D: WlrLayerShellHandler,
{
fn request(
&self,
state: &mut D,
_: &Client,
_: &cosmic_session_lock_layer_manager_v1::CosmicSessionLockLayerManagerV1,
request: cosmic_session_lock_layer_manager_v1::Request,
_: &DisplayHandle,
_: &mut DataInit<'_, D>,
) {
let (layer, value) = match request {
cosmic_session_lock_layer_manager_v1::Request::SetShowOnLock { layer } => (layer, true),
cosmic_session_lock_layer_manager_v1::Request::UnsetShowOnLock { layer } => {
(layer, false)
}
cosmic_session_lock_layer_manager_v1::Request::Destroy => {
return;
}
_ => unreachable!(),
};
if let Some(layer) = state
.shell_state()
.layer_surfaces()
.find(|surface| surface.shell_surface() == &layer)
{
with_states(layer.wl_surface(), |states| {
let mut state = states.cached_state.get::<SessionLockLayerSurfaceData>();
state.pending().show_on_lock = value;
});
}
}
}