Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,15 +287,15 @@ fn format_pointer_focus(focus: Option<PointerFocusTarget>) -> String {
}
_ => format!("Surface {}", surface.id().protocol_id()),
},
Some(StackUI(stack)) => format!(
Some(StackUI { stack, .. }) => format!(
"Stack SSD {} ({})",
match stack.active().0.underlying_surface() {
WindowSurface::Wayland(t) => t.wl_surface().id().protocol_id(),
WindowSurface::X11(x) => x.window_id(),
},
stack.active().title()
),
Some(WindowUI(window)) => format!(
Some(WindowUI { window, .. }) => format!(
"Window SSD {} ({})",
match window.surface().0.underlying_surface() {
WindowSurface::Wayland(t) => t.wl_surface().id().protocol_id(),
Expand Down
29 changes: 22 additions & 7 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
tiling::{NodeDesc, SwapWindowGrab, TilingLayout},
},
zoom::ZoomState,
LastModifierChange, SeatExt, Trigger,
LastAcknowlegedElement, LastModifierChange, SeatExt, Trigger,
},
utils::{float::NextDown, prelude::*, quirks::workspace_overview_is_open},
wayland::{
Expand Down Expand Up @@ -391,18 +391,33 @@ impl State {
//If the pointer isn't grabbed, we should check if the focused element should be updated
} else if self.common.config.cosmic_conf.focus_follows_cursor {
let shell = self.common.shell.read();
let old_keyboard_target = State::element_under(
original_position,
&current_output,
&*shell,
&seat,
);
let old_keyboard_target = seat
.user_data()
.get::<LastAcknowlegedElement>()
.unwrap()
.0
.lock()
.unwrap()
.clone();
let new_keyboard_target =
State::element_under(position, &output, &*shell, &seat);

if old_keyboard_target != new_keyboard_target
&& new_keyboard_target.is_some()
&& new_under.as_ref().is_some_and(|(target, relative_offset)| {
target.should_follow_focus(
position.as_logical() - relative_offset.clone(),
)
})
{
*seat
.user_data()
.get::<LastAcknowlegedElement>()
.unwrap()
.0
.lock()
.unwrap() = new_keyboard_target.clone();

let create_source = if self.common.pointer_focus_state.is_none() {
true
} else {
Expand Down
10 changes: 8 additions & 2 deletions src/shell/element/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,14 +507,20 @@ impl CosmicStack {
&& point_i32.y - geo.loc.y < geo.size.h + TAB_HEIGHT + RESIZE_BORDER)
{
stack_ui = Some((
PointerFocusTarget::StackUI(self.clone()),
PointerFocusTarget::StackUI {
stack: self.clone(),
is_border: true,
},
Point::from((0., 0.)),
));
}

if point_i32.y - geo.loc.y < TAB_HEIGHT {
stack_ui = Some((
PointerFocusTarget::StackUI(self.clone()),
PointerFocusTarget::StackUI {
stack: self.clone(),
is_border: false,
},
Point::from((0., 0.)),
));
}
Expand Down
10 changes: 8 additions & 2 deletions src/shell/element/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,14 +262,20 @@ impl CosmicWindow {
&& point_i32.y - geo.loc.y < geo.size.h + ssd_height + RESIZE_BORDER)
{
window_ui = Some((
PointerFocusTarget::WindowUI(self.clone()),
PointerFocusTarget::WindowUI {
window: self.clone(),
is_border: true,
},
Point::from((0., 0.)),
));
}

if has_ssd && (point_i32.y - geo.loc.y < SSD_HEIGHT) {
window_ui = Some((
PointerFocusTarget::WindowUI(self.clone()),
PointerFocusTarget::WindowUI {
window: self.clone(),
is_border: false,
},
Point::from((0., 0.)),
));
}
Expand Down
52 changes: 38 additions & 14 deletions src/shell/focus/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,14 @@ pub enum PointerFocusTarget {
surface: WlSurface,
toplevel: Option<PointerFocusToplevel>,
},
StackUI(CosmicStack),
WindowUI(CosmicWindow),
StackUI {
stack: CosmicStack,
is_border: bool,
},
WindowUI {
window: CosmicWindow,
is_border: bool,
},
ResizeFork(ResizeForkTarget),
ZoomUI(ZoomFocusTarget),
}
Expand Down Expand Up @@ -114,8 +120,8 @@ impl PointerFocusTarget {
fn inner_pointer_target(&self) -> &dyn PointerTarget<State> {
match self {
PointerFocusTarget::WlSurface { surface, .. } => surface,
PointerFocusTarget::StackUI(u) => u,
PointerFocusTarget::WindowUI(u) => u,
PointerFocusTarget::StackUI { stack, .. } => stack,
PointerFocusTarget::WindowUI { window, .. } => window,
PointerFocusTarget::ResizeFork(f) => f,
PointerFocusTarget::ZoomUI(e) => e,
}
Expand All @@ -124,8 +130,8 @@ impl PointerFocusTarget {
fn inner_touch_target(&self) -> &dyn TouchTarget<State> {
match self {
PointerFocusTarget::WlSurface { surface, .. } => surface,
PointerFocusTarget::StackUI(u) => u,
PointerFocusTarget::WindowUI(u) => u,
PointerFocusTarget::StackUI { stack, .. } => stack,
PointerFocusTarget::WindowUI { window, .. } => window,
PointerFocusTarget::ResizeFork(f) => f,
PointerFocusTarget::ZoomUI(e) => e,
}
Expand Down Expand Up @@ -174,8 +180,8 @@ impl PointerFocusTarget {
.find(|(w, _)| w.wl_surface().map(|s2| s == *s2).unwrap_or(false))
.map(|(s, _)| s)
}),
PointerFocusTarget::StackUI(stack) => Some(stack.active()),
PointerFocusTarget::WindowUI(window) => Some(window.surface()),
PointerFocusTarget::StackUI { stack, .. } => Some(stack.active()),
PointerFocusTarget::WindowUI { window, .. } => Some(window.surface()),
_ => None,
}
}
Expand All @@ -188,6 +194,24 @@ impl PointerFocusTarget {
_ => false,
}
}

pub fn should_follow_focus(&self, relative_pos: Point<f64, Logical>) -> bool {
match self {
PointerFocusTarget::WlSurface { toplevel, .. } => {
toplevel.as_ref().is_none_or(|toplevel| match toplevel {
PointerFocusToplevel::Popup(popup) => {
popup.geometry().contains(relative_pos.to_i32_round())
}
PointerFocusToplevel::Surface(surface) => {
surface.0.geometry().contains(relative_pos.to_i32_round())
}
})
}
PointerFocusTarget::StackUI { is_border, .. }
| PointerFocusTarget::WindowUI { is_border, .. } => !*is_border,
PointerFocusTarget::ResizeFork(_) | PointerFocusTarget::ZoomUI(_) => false,
}
}
}

impl KeyboardFocusTarget {
Expand Down Expand Up @@ -259,8 +283,8 @@ impl IsAlive for PointerFocusTarget {
match self {
// XXX? does this change anything
PointerFocusTarget::WlSurface { surface, .. } => surface.alive(),
PointerFocusTarget::StackUI(e) => e.alive(),
PointerFocusTarget::WindowUI(e) => e.alive(),
PointerFocusTarget::StackUI { stack, .. } => stack.alive(),
PointerFocusTarget::WindowUI { window, .. } => window.alive(),
PointerFocusTarget::ResizeFork(f) => f.alive(),
PointerFocusTarget::ZoomUI(_) => true,
}
Expand Down Expand Up @@ -547,8 +571,8 @@ impl WaylandFocus for PointerFocusTarget {
Some(match self {
PointerFocusTarget::WlSurface { surface, .. } => Cow::Borrowed(surface),
PointerFocusTarget::ResizeFork(_)
| PointerFocusTarget::StackUI(_)
| PointerFocusTarget::WindowUI(_)
| PointerFocusTarget::StackUI { .. }
| PointerFocusTarget::WindowUI { .. }
| PointerFocusTarget::ZoomUI(_) => {
return None;
}
Expand All @@ -557,12 +581,12 @@ impl WaylandFocus for PointerFocusTarget {
fn same_client_as(&self, object_id: &ObjectId) -> bool {
match self {
PointerFocusTarget::WlSurface { surface, .. } => surface.id().same_client_as(object_id),
PointerFocusTarget::StackUI(stack) => stack
PointerFocusTarget::StackUI { stack, .. } => stack
.active()
.wl_surface()
.map(|s| s.id().same_client_as(object_id))
.unwrap_or(false),
PointerFocusTarget::WindowUI(window) => window
PointerFocusTarget::WindowUI { window, .. } => window
.wl_surface()
.map(|s| s.id().same_client_as(object_id))
.unwrap_or(false),
Expand Down
5 changes: 5 additions & 0 deletions src/shell/seats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
backend::render::cursor::CursorState,
config::{xkb_config_to_wl, Config},
input::{ModifiersShortcutQueue, SupressedButtons, SupressedKeys},
shell::focus::target::KeyboardFocusTarget,
state::State,
};
use smithay::{
Expand Down Expand Up @@ -175,6 +176,9 @@ struct FocusedOutput(pub Mutex<Option<Output>>);
#[derive(Default)]
pub struct LastModifierChange(pub Mutex<Option<Serial>>);

#[derive(Default)]
pub struct LastAcknowlegedElement(pub Mutex<Option<KeyboardFocusTarget>>);

pub fn create_seat(
dh: &DisplayHandle,
seat_state: &mut SeatState<State>,
Expand All @@ -190,6 +194,7 @@ pub fn create_seat(
userdata.insert_if_missing(SupressedButtons::default);
userdata.insert_if_missing(ModifiersShortcutQueue::default);
userdata.insert_if_missing(LastModifierChange::default);
userdata.insert_if_missing(LastAcknowlegedElement::default);
userdata.insert_if_missing_threadsafe(SeatMoveGrabState::default);
userdata.insert_if_missing_threadsafe(SeatMenuGrabState::default);
userdata.insert_if_missing_threadsafe(CursorState::default);
Expand Down
Loading