Handle session lock surfaces in visible_outputs_for_surface
Fixes issue with re-draw not being queued on initial surface commit until cursor is moved.
This commit is contained in:
parent
14867a0893
commit
440cd03371
6 changed files with 49 additions and 41 deletions
|
|
@ -13,9 +13,10 @@ use crate::debug::{fps_ui, profiler_ui};
|
||||||
use crate::{
|
use crate::{
|
||||||
shell::{
|
shell::{
|
||||||
focus::target::WindowGroup, grabs::SeatMoveGrabState, layout::tiling::ANIMATION_DURATION,
|
focus::target::WindowGroup, grabs::SeatMoveGrabState, layout::tiling::ANIMATION_DURATION,
|
||||||
CosmicMapped, CosmicMappedRenderElement, OverviewMode, Trigger, WorkspaceRenderElement,
|
CosmicMapped, CosmicMappedRenderElement, OverviewMode, SessionLock, Trigger,
|
||||||
|
WorkspaceRenderElement,
|
||||||
},
|
},
|
||||||
state::{Common, Fps, SessionLock},
|
state::{Common, Fps},
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
wayland::{
|
wayland::{
|
||||||
handlers::{
|
handlers::{
|
||||||
|
|
@ -487,7 +488,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// If session locked, only show session lock surfaces
|
// If session locked, only show session lock surfaces
|
||||||
if let Some(session_lock) = &state.session_lock {
|
if let Some(session_lock) = &state.shell.session_lock {
|
||||||
elements.extend(
|
elements.extend(
|
||||||
session_lock_elements(renderer, output, session_lock)
|
session_lock_elements(renderer, output, session_lock)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ use crate::{
|
||||||
floating::ResizeGrabMarker,
|
floating::ResizeGrabMarker,
|
||||||
tiling::{SwapWindowGrab, TilingLayout},
|
tiling::{SwapWindowGrab, TilingLayout},
|
||||||
},
|
},
|
||||||
Direction, FocusResult, MoveResult, OverviewMode, ResizeDirection, ResizeMode, Trigger,
|
Direction, FocusResult, MoveResult, OverviewMode, ResizeDirection, ResizeMode, SessionLock,
|
||||||
Workspace,
|
Trigger, Workspace,
|
||||||
},
|
},
|
||||||
state::{Common, SessionLock},
|
state::Common,
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
wayland::{
|
wayland::{
|
||||||
handlers::{screencopy::ScreencopySessions, xdg_activation::ActivationContext},
|
handlers::{screencopy::ScreencopySessions, xdg_activation::ActivationContext},
|
||||||
|
|
@ -569,7 +569,7 @@ impl State {
|
||||||
&self.common.shell.override_redirect_windows,
|
&self.common.shell.override_redirect_windows,
|
||||||
overview.0.clone(),
|
overview.0.clone(),
|
||||||
workspace,
|
workspace,
|
||||||
self.common.session_lock.as_ref(),
|
self.common.shell.session_lock.as_ref(),
|
||||||
)
|
)
|
||||||
.map(|(target, pos)| (target, pos.as_logical()));
|
.map(|(target, pos)| (target, pos.as_logical()));
|
||||||
|
|
||||||
|
|
@ -651,7 +651,7 @@ impl State {
|
||||||
&self.common.shell.override_redirect_windows,
|
&self.common.shell.override_redirect_windows,
|
||||||
overview.0,
|
overview.0,
|
||||||
workspace,
|
workspace,
|
||||||
self.common.session_lock.as_ref(),
|
self.common.shell.session_lock.as_ref(),
|
||||||
)
|
)
|
||||||
.map(|(target, pos)| (target, pos.as_logical()));
|
.map(|(target, pos)| (target, pos.as_logical()));
|
||||||
|
|
||||||
|
|
@ -777,7 +777,7 @@ impl State {
|
||||||
&self.common.shell.override_redirect_windows,
|
&self.common.shell.override_redirect_windows,
|
||||||
overview.0,
|
overview.0,
|
||||||
workspace,
|
workspace,
|
||||||
self.common.session_lock.as_ref(),
|
self.common.shell.session_lock.as_ref(),
|
||||||
)
|
)
|
||||||
.map(|(target, pos)| (target, pos.as_logical()));
|
.map(|(target, pos)| (target, pos.as_logical()));
|
||||||
|
|
||||||
|
|
@ -843,18 +843,20 @@ impl State {
|
||||||
&& !seat.get_keyboard().map(|k| k.is_grabbed()).unwrap_or(false)
|
&& !seat.get_keyboard().map(|k| k.is_grabbed()).unwrap_or(false)
|
||||||
{
|
{
|
||||||
let output = seat.active_output();
|
let output = seat.active_output();
|
||||||
|
|
||||||
let pos = seat.get_pointer().unwrap().current_location().as_global();
|
let pos = seat.get_pointer().unwrap().current_location().as_global();
|
||||||
let relative_pos = pos.to_local(&output);
|
let relative_pos = pos.to_local(&output);
|
||||||
let overview = self.common.shell.overview_mode();
|
let overview = self.common.shell.overview_mode();
|
||||||
let workspace = self.common.shell.active_space_mut(&output);
|
|
||||||
let mut under = None;
|
let mut under = None;
|
||||||
|
|
||||||
if let Some(session_lock) = self.common.session_lock.as_ref() {
|
if let Some(session_lock) = self.common.shell.session_lock.as_ref() {
|
||||||
under = session_lock
|
under = session_lock
|
||||||
.surfaces
|
.surfaces
|
||||||
.get(&output)
|
.get(&output)
|
||||||
.map(|lock| lock.clone().into());
|
.map(|lock| lock.clone().into());
|
||||||
} else if let Some(window) = workspace.get_fullscreen() {
|
} else if let Some(window) =
|
||||||
|
self.common.shell.active_space(&output).get_fullscreen()
|
||||||
|
{
|
||||||
let layers = layer_map_for_output(&output);
|
let layers = layer_map_for_output(&output);
|
||||||
if let Some(layer) =
|
if let Some(layer) =
|
||||||
layers.layer_under(WlrLayer::Overlay, relative_pos.as_logical())
|
layers.layer_under(WlrLayer::Overlay, relative_pos.as_logical())
|
||||||
|
|
@ -874,6 +876,7 @@ impl State {
|
||||||
under = Some(window.clone().into());
|
under = Some(window.clone().into());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let workspace = self.common.shell.active_space_mut(&output);
|
||||||
let done = {
|
let done = {
|
||||||
let layers = layer_map_for_output(&output);
|
let layers = layer_map_for_output(&output);
|
||||||
if let Some(layer) = layers
|
if let Some(layer) = layers
|
||||||
|
|
@ -1157,7 +1160,7 @@ impl State {
|
||||||
) {
|
) {
|
||||||
// TODO: Detect if started from login manager or tty, and only allow
|
// TODO: Detect if started from login manager or tty, and only allow
|
||||||
// `Terminate` if it will return to login manager.
|
// `Terminate` if it will return to login manager.
|
||||||
if self.common.session_lock.is_some()
|
if self.common.shell.session_lock.is_some()
|
||||||
&& !matches!(action, Action::Terminate | Action::Debug)
|
&& !matches!(action, Action::Terminate | Action::Debug)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,7 @@ fn focus_target_is_valid(
|
||||||
target: KeyboardFocusTarget,
|
target: KeyboardFocusTarget,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// If a session lock is active, only lock surfaces can be focused
|
// If a session lock is active, only lock surfaces can be focused
|
||||||
if state.common.session_lock.is_some() {
|
if state.common.shell.session_lock.is_some() {
|
||||||
return matches!(target, KeyboardFocusTarget::LockSurface(_));
|
return matches!(target, KeyboardFocusTarget::LockSurface(_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -361,7 +361,7 @@ fn update_focus_target(
|
||||||
seat: &Seat<State>,
|
seat: &Seat<State>,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
) -> Option<KeyboardFocusTarget> {
|
) -> Option<KeyboardFocusTarget> {
|
||||||
if let Some(session_lock) = &state.common.session_lock {
|
if let Some(session_lock) = &state.common.shell.session_lock {
|
||||||
session_lock
|
session_lock
|
||||||
.surfaces
|
.surfaces
|
||||||
.get(output)
|
.get(output)
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,15 @@ use smithay::{
|
||||||
Seat,
|
Seat,
|
||||||
},
|
},
|
||||||
output::Output,
|
output::Output,
|
||||||
reexports::wayland_server::{protocol::wl_surface::WlSurface, Client, DisplayHandle},
|
reexports::{
|
||||||
|
wayland_protocols::ext::session_lock::v1::server::ext_session_lock_v1::ExtSessionLockV1,
|
||||||
|
wayland_server::{protocol::wl_surface::WlSurface, Client, DisplayHandle},
|
||||||
|
},
|
||||||
utils::{Point, Rectangle, Serial, SERIAL_COUNTER},
|
utils::{Point, Rectangle, Serial, SERIAL_COUNTER},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::with_states,
|
compositor::with_states,
|
||||||
seat::WaylandFocus,
|
seat::WaylandFocus,
|
||||||
|
session_lock::LockSurface,
|
||||||
shell::{
|
shell::{
|
||||||
wlr_layer::{
|
wlr_layer::{
|
||||||
KeyboardInteractivity, Layer, LayerSurfaceCachedState, WlrLayerShellState,
|
KeyboardInteractivity, Layer, LayerSurfaceCachedState, WlrLayerShellState,
|
||||||
|
|
@ -175,6 +179,7 @@ pub struct Shell {
|
||||||
pub pending_layers: Vec<(LayerSurface, Output, Seat<State>)>,
|
pub pending_layers: Vec<(LayerSurface, Output, Seat<State>)>,
|
||||||
pub pending_activations: HashMap<ActivationKey, ActivationContext>,
|
pub pending_activations: HashMap<ActivationKey, ActivationContext>,
|
||||||
pub override_redirect_windows: Vec<X11Surface>,
|
pub override_redirect_windows: Vec<X11Surface>,
|
||||||
|
pub session_lock: Option<SessionLock>,
|
||||||
|
|
||||||
// wayland_state
|
// wayland_state
|
||||||
pub layer_shell_state: WlrLayerShellState,
|
pub layer_shell_state: WlrLayerShellState,
|
||||||
|
|
@ -199,6 +204,12 @@ pub struct Shell {
|
||||||
resize_indicator: Option<ResizeIndicator>,
|
resize_indicator: Option<ResizeIndicator>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SessionLock {
|
||||||
|
pub ext_session_lock: ExtSessionLockV1,
|
||||||
|
pub surfaces: HashMap<Output, LockSurface>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WorkspaceSet {
|
pub struct WorkspaceSet {
|
||||||
previously_active: Option<(usize, Instant)>,
|
previously_active: Option<(usize, Instant)>,
|
||||||
|
|
@ -916,6 +927,7 @@ impl Shell {
|
||||||
pending_layers: Vec::new(),
|
pending_layers: Vec::new(),
|
||||||
pending_activations: HashMap::new(),
|
pending_activations: HashMap::new(),
|
||||||
override_redirect_windows: Vec::new(),
|
override_redirect_windows: Vec::new(),
|
||||||
|
session_lock: None,
|
||||||
|
|
||||||
layer_shell_state,
|
layer_shell_state,
|
||||||
toplevel_info_state,
|
toplevel_info_state,
|
||||||
|
|
@ -1015,6 +1027,15 @@ impl Shell {
|
||||||
&'a self,
|
&'a self,
|
||||||
surface: &'a WlSurface,
|
surface: &'a WlSurface,
|
||||||
) -> impl Iterator<Item = Output> + 'a {
|
) -> impl Iterator<Item = Output> + 'a {
|
||||||
|
if let Some(session_lock) = &self.session_lock {
|
||||||
|
let output = session_lock
|
||||||
|
.surfaces
|
||||||
|
.iter()
|
||||||
|
.find(|(_, v)| v.wl_surface() == surface)
|
||||||
|
.map(|(k, _)| k.clone());
|
||||||
|
return Box::new(output.into_iter()) as Box<dyn Iterator<Item = Output>>;
|
||||||
|
}
|
||||||
|
|
||||||
match self
|
match self
|
||||||
.outputs()
|
.outputs()
|
||||||
.find(|o| {
|
.find(|o| {
|
||||||
|
|
|
||||||
20
src/state.rs
20
src/state.rs
|
|
@ -50,7 +50,6 @@ use smithay::{
|
||||||
output::{Mode as OutputMode, Output, Scale},
|
output::{Mode as OutputMode, Output, Scale},
|
||||||
reexports::{
|
reexports::{
|
||||||
calloop::{LoopHandle, LoopSignal},
|
calloop::{LoopHandle, LoopSignal},
|
||||||
wayland_protocols::ext::session_lock::v1::server::ext_session_lock_v1::ExtSessionLockV1,
|
|
||||||
wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decoration_manager::Mode,
|
wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decoration_manager::Mode,
|
||||||
wayland_server::{
|
wayland_server::{
|
||||||
backend::{ClientData, ClientId, DisconnectReason},
|
backend::{ClientData, ClientId, DisconnectReason},
|
||||||
|
|
@ -75,7 +74,7 @@ use smithay::{
|
||||||
data_device::DataDeviceState, primary_selection::PrimarySelectionState,
|
data_device::DataDeviceState, primary_selection::PrimarySelectionState,
|
||||||
wlr_data_control::DataControlState,
|
wlr_data_control::DataControlState,
|
||||||
},
|
},
|
||||||
session_lock::{LockSurface, SessionLockManagerState},
|
session_lock::SessionLockManagerState,
|
||||||
shell::{kde::decoration::KdeDecorationState, xdg::decoration::XdgDecorationState},
|
shell::{kde::decoration::KdeDecorationState, xdg::decoration::XdgDecorationState},
|
||||||
shm::ShmState,
|
shm::ShmState,
|
||||||
text_input::TextInputManagerState,
|
text_input::TextInputManagerState,
|
||||||
|
|
@ -87,10 +86,7 @@ use smithay::{
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use std::{cell::RefCell, ffi::OsString, time::Duration};
|
use std::{cell::RefCell, ffi::OsString, time::Duration};
|
||||||
use std::{
|
use std::{collections::VecDeque, time::Instant};
|
||||||
collections::{HashMap, VecDeque},
|
|
||||||
time::Instant,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(RustEmbed)]
|
#[derive(RustEmbed)]
|
||||||
#[folder = "resources/i18n"]
|
#[folder = "resources/i18n"]
|
||||||
|
|
@ -173,8 +169,6 @@ pub struct Common {
|
||||||
pub kde_decoration_state: KdeDecorationState,
|
pub kde_decoration_state: KdeDecorationState,
|
||||||
pub xdg_decoration_state: XdgDecorationState,
|
pub xdg_decoration_state: XdgDecorationState,
|
||||||
|
|
||||||
pub session_lock: Option<SessionLock>,
|
|
||||||
|
|
||||||
// xwayland state
|
// xwayland state
|
||||||
pub xwayland_state: Option<XWaylandState>,
|
pub xwayland_state: Option<XWaylandState>,
|
||||||
}
|
}
|
||||||
|
|
@ -195,12 +189,6 @@ pub struct SurfaceDmabufFeedback {
|
||||||
pub scanout_feedback: DmabufFeedback,
|
pub scanout_feedback: DmabufFeedback,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct SessionLock {
|
|
||||||
pub ext_session_lock: ExtSessionLockV1,
|
|
||||||
pub surfaces: HashMap<Output, LockSurface>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BackendData {
|
impl BackendData {
|
||||||
pub fn kms(&mut self) -> &mut KmsState {
|
pub fn kms(&mut self) -> &mut KmsState {
|
||||||
match self {
|
match self {
|
||||||
|
|
@ -414,8 +402,6 @@ impl State {
|
||||||
kde_decoration_state,
|
kde_decoration_state,
|
||||||
xdg_decoration_state,
|
xdg_decoration_state,
|
||||||
|
|
||||||
session_lock: None,
|
|
||||||
|
|
||||||
xwayland_state: None,
|
xwayland_state: None,
|
||||||
},
|
},
|
||||||
backend: BackendData::Unset,
|
backend: BackendData::Unset,
|
||||||
|
|
@ -515,7 +501,7 @@ impl Common {
|
||||||
let time = self.clock.now();
|
let time = self.clock.now();
|
||||||
let throttle = Some(Duration::from_secs(1));
|
let throttle = Some(Duration::from_secs(1));
|
||||||
|
|
||||||
if let Some(session_lock) = self.session_lock.as_ref() {
|
if let Some(session_lock) = self.shell.session_lock.as_ref() {
|
||||||
if let Some(lock_surface) = session_lock.surfaces.get(output) {
|
if let Some(lock_surface) = session_lock.surfaces.get(output) {
|
||||||
with_surfaces_surface_tree(lock_surface.wl_surface(), |_surface, states| {
|
with_surfaces_surface_tree(lock_surface.wl_surface(), |_surface, states| {
|
||||||
with_fractional_scale(states, |fraction_scale| {
|
with_fractional_scale(states, |fraction_scale| {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use crate::{
|
use crate::{shell::SessionLock, state::State, utils::prelude::*};
|
||||||
state::{SessionLock, State},
|
|
||||||
utils::prelude::*,
|
|
||||||
};
|
|
||||||
use smithay::{
|
use smithay::{
|
||||||
delegate_session_lock,
|
delegate_session_lock,
|
||||||
output::Output,
|
output::Output,
|
||||||
|
|
@ -22,7 +19,7 @@ impl SessionLockHandler for State {
|
||||||
|
|
||||||
fn lock(&mut self, locker: SessionLocker) {
|
fn lock(&mut self, locker: SessionLocker) {
|
||||||
// Reject lock if sesion lock exists and is still valid
|
// Reject lock if sesion lock exists and is still valid
|
||||||
if let Some(session_lock) = self.common.session_lock.as_ref() {
|
if let Some(session_lock) = self.common.shell.session_lock.as_ref() {
|
||||||
if self
|
if self
|
||||||
.common
|
.common
|
||||||
.display_handle
|
.display_handle
|
||||||
|
|
@ -35,18 +32,18 @@ impl SessionLockHandler for State {
|
||||||
|
|
||||||
let ext_session_lock = locker.ext_session_lock().clone();
|
let ext_session_lock = locker.ext_session_lock().clone();
|
||||||
locker.lock();
|
locker.lock();
|
||||||
self.common.session_lock = Some(SessionLock {
|
self.common.shell.session_lock = Some(SessionLock {
|
||||||
ext_session_lock,
|
ext_session_lock,
|
||||||
surfaces: HashMap::new(),
|
surfaces: HashMap::new(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unlock(&mut self) {
|
fn unlock(&mut self) {
|
||||||
self.common.session_lock = None;
|
self.common.shell.session_lock = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_surface(&mut self, lock_surface: LockSurface, wl_output: WlOutput) {
|
fn new_surface(&mut self, lock_surface: LockSurface, wl_output: WlOutput) {
|
||||||
if let Some(session_lock) = &mut self.common.session_lock {
|
if let Some(session_lock) = &mut self.common.shell.session_lock {
|
||||||
if let Some(output) = Output::from_resource(&wl_output) {
|
if let Some(output) = Output::from_resource(&wl_output) {
|
||||||
lock_surface.with_pending_state(|states| {
|
lock_surface.with_pending_state(|states| {
|
||||||
let size = output.geometry().size;
|
let size = output.geometry().size;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue