Skip to content

Commit d915d08

Browse files
committed
input: Don't follow focus for resize borders
1 parent 7ccfd73 commit d915d08

File tree

6 files changed

+83
-27
lines changed

6 files changed

+83
-27
lines changed

src/debug.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,15 +287,15 @@ fn format_pointer_focus(focus: Option<PointerFocusTarget>) -> String {
287287
}
288288
_ => format!("Surface {}", surface.id().protocol_id()),
289289
},
290-
Some(StackUI(stack)) => format!(
290+
Some(StackUI { stack, .. }) => format!(
291291
"Stack SSD {} ({})",
292292
match stack.active().0.underlying_surface() {
293293
WindowSurface::Wayland(t) => t.wl_surface().id().protocol_id(),
294294
WindowSurface::X11(x) => x.window_id(),
295295
},
296296
stack.active().title()
297297
),
298-
Some(WindowUI(window)) => format!(
298+
Some(WindowUI { window, .. }) => format!(
299299
"Window SSD {} ({})",
300300
match window.surface().0.underlying_surface() {
301301
WindowSurface::Wayland(t) => t.wl_surface().id().protocol_id(),

src/input/mod.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
tiling::{NodeDesc, SwapWindowGrab, TilingLayout},
2323
},
2424
zoom::ZoomState,
25-
LastModifierChange, SeatExt, Trigger,
25+
LastAcknowlegedElement, LastModifierChange, SeatExt, Trigger,
2626
},
2727
utils::{float::NextDown, prelude::*, quirks::workspace_overview_is_open},
2828
wayland::{
@@ -391,18 +391,33 @@ impl State {
391391
//If the pointer isn't grabbed, we should check if the focused element should be updated
392392
} else if self.common.config.cosmic_conf.focus_follows_cursor {
393393
let shell = self.common.shell.read();
394-
let old_keyboard_target = State::element_under(
395-
original_position,
396-
&current_output,
397-
&*shell,
398-
&seat,
399-
);
394+
let old_keyboard_target = seat
395+
.user_data()
396+
.get::<LastAcknowlegedElement>()
397+
.unwrap()
398+
.0
399+
.lock()
400+
.unwrap()
401+
.clone();
400402
let new_keyboard_target =
401403
State::element_under(position, &output, &*shell, &seat);
402404

403405
if old_keyboard_target != new_keyboard_target
404406
&& new_keyboard_target.is_some()
407+
&& new_under.as_ref().is_some_and(|(target, relative_offset)| {
408+
target.should_follow_focus(
409+
position.as_logical() - relative_offset.clone(),
410+
)
411+
})
405412
{
413+
*seat
414+
.user_data()
415+
.get::<LastAcknowlegedElement>()
416+
.unwrap()
417+
.0
418+
.lock()
419+
.unwrap() = new_keyboard_target.clone();
420+
406421
let create_source = if self.common.pointer_focus_state.is_none() {
407422
true
408423
} else {

src/shell/element/stack.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,14 +507,20 @@ impl CosmicStack {
507507
&& point_i32.y - geo.loc.y < geo.size.h + TAB_HEIGHT + RESIZE_BORDER)
508508
{
509509
stack_ui = Some((
510-
PointerFocusTarget::StackUI(self.clone()),
510+
PointerFocusTarget::StackUI {
511+
stack: self.clone(),
512+
is_border: true,
513+
},
511514
Point::from((0., 0.)),
512515
));
513516
}
514517

515518
if point_i32.y - geo.loc.y < TAB_HEIGHT {
516519
stack_ui = Some((
517-
PointerFocusTarget::StackUI(self.clone()),
520+
PointerFocusTarget::StackUI {
521+
stack: self.clone(),
522+
is_border: false,
523+
},
518524
Point::from((0., 0.)),
519525
));
520526
}

src/shell/element/window.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,20 @@ impl CosmicWindow {
262262
&& point_i32.y - geo.loc.y < geo.size.h + ssd_height + RESIZE_BORDER)
263263
{
264264
window_ui = Some((
265-
PointerFocusTarget::WindowUI(self.clone()),
265+
PointerFocusTarget::WindowUI {
266+
window: self.clone(),
267+
is_border: true,
268+
},
266269
Point::from((0., 0.)),
267270
));
268271
}
269272

270273
if has_ssd && (point_i32.y - geo.loc.y < SSD_HEIGHT) {
271274
window_ui = Some((
272-
PointerFocusTarget::WindowUI(self.clone()),
275+
PointerFocusTarget::WindowUI {
276+
window: self.clone(),
277+
is_border: false,
278+
},
273279
Point::from((0., 0.)),
274280
));
275281
}

src/shell/focus/target.rs

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,14 @@ pub enum PointerFocusTarget {
4242
surface: WlSurface,
4343
toplevel: Option<PointerFocusToplevel>,
4444
},
45-
StackUI(CosmicStack),
46-
WindowUI(CosmicWindow),
45+
StackUI {
46+
stack: CosmicStack,
47+
is_border: bool,
48+
},
49+
WindowUI {
50+
window: CosmicWindow,
51+
is_border: bool,
52+
},
4753
ResizeFork(ResizeForkTarget),
4854
ZoomUI(ZoomFocusTarget),
4955
}
@@ -114,8 +120,8 @@ impl PointerFocusTarget {
114120
fn inner_pointer_target(&self) -> &dyn PointerTarget<State> {
115121
match self {
116122
PointerFocusTarget::WlSurface { surface, .. } => surface,
117-
PointerFocusTarget::StackUI(u) => u,
118-
PointerFocusTarget::WindowUI(u) => u,
123+
PointerFocusTarget::StackUI { stack, .. } => stack,
124+
PointerFocusTarget::WindowUI { window, .. } => window,
119125
PointerFocusTarget::ResizeFork(f) => f,
120126
PointerFocusTarget::ZoomUI(e) => e,
121127
}
@@ -124,8 +130,8 @@ impl PointerFocusTarget {
124130
fn inner_touch_target(&self) -> &dyn TouchTarget<State> {
125131
match self {
126132
PointerFocusTarget::WlSurface { surface, .. } => surface,
127-
PointerFocusTarget::StackUI(u) => u,
128-
PointerFocusTarget::WindowUI(u) => u,
133+
PointerFocusTarget::StackUI { stack, .. } => stack,
134+
PointerFocusTarget::WindowUI { window, .. } => window,
129135
PointerFocusTarget::ResizeFork(f) => f,
130136
PointerFocusTarget::ZoomUI(e) => e,
131137
}
@@ -174,8 +180,8 @@ impl PointerFocusTarget {
174180
.find(|(w, _)| w.wl_surface().map(|s2| s == *s2).unwrap_or(false))
175181
.map(|(s, _)| s)
176182
}),
177-
PointerFocusTarget::StackUI(stack) => Some(stack.active()),
178-
PointerFocusTarget::WindowUI(window) => Some(window.surface()),
183+
PointerFocusTarget::StackUI { stack, .. } => Some(stack.active()),
184+
PointerFocusTarget::WindowUI { window, .. } => Some(window.surface()),
179185
_ => None,
180186
}
181187
}
@@ -188,6 +194,24 @@ impl PointerFocusTarget {
188194
_ => false,
189195
}
190196
}
197+
198+
pub fn should_follow_focus(&self, relative_pos: Point<f64, Logical>) -> bool {
199+
match self {
200+
PointerFocusTarget::WlSurface { toplevel, .. } => {
201+
toplevel.as_ref().is_none_or(|toplevel| match toplevel {
202+
PointerFocusToplevel::Popup(popup) => {
203+
popup.geometry().contains(relative_pos.to_i32_round())
204+
}
205+
PointerFocusToplevel::Surface(surface) => {
206+
surface.0.geometry().contains(relative_pos.to_i32_round())
207+
}
208+
})
209+
}
210+
PointerFocusTarget::StackUI { is_border, .. }
211+
| PointerFocusTarget::WindowUI { is_border, .. } => !*is_border,
212+
PointerFocusTarget::ResizeFork(_) | PointerFocusTarget::ZoomUI(_) => false,
213+
}
214+
}
191215
}
192216

193217
impl KeyboardFocusTarget {
@@ -259,8 +283,8 @@ impl IsAlive for PointerFocusTarget {
259283
match self {
260284
// XXX? does this change anything
261285
PointerFocusTarget::WlSurface { surface, .. } => surface.alive(),
262-
PointerFocusTarget::StackUI(e) => e.alive(),
263-
PointerFocusTarget::WindowUI(e) => e.alive(),
286+
PointerFocusTarget::StackUI { stack, .. } => stack.alive(),
287+
PointerFocusTarget::WindowUI { window, .. } => window.alive(),
264288
PointerFocusTarget::ResizeFork(f) => f.alive(),
265289
PointerFocusTarget::ZoomUI(_) => true,
266290
}
@@ -547,8 +571,8 @@ impl WaylandFocus for PointerFocusTarget {
547571
Some(match self {
548572
PointerFocusTarget::WlSurface { surface, .. } => Cow::Borrowed(surface),
549573
PointerFocusTarget::ResizeFork(_)
550-
| PointerFocusTarget::StackUI(_)
551-
| PointerFocusTarget::WindowUI(_)
574+
| PointerFocusTarget::StackUI { .. }
575+
| PointerFocusTarget::WindowUI { .. }
552576
| PointerFocusTarget::ZoomUI(_) => {
553577
return None;
554578
}
@@ -557,12 +581,12 @@ impl WaylandFocus for PointerFocusTarget {
557581
fn same_client_as(&self, object_id: &ObjectId) -> bool {
558582
match self {
559583
PointerFocusTarget::WlSurface { surface, .. } => surface.id().same_client_as(object_id),
560-
PointerFocusTarget::StackUI(stack) => stack
584+
PointerFocusTarget::StackUI { stack, .. } => stack
561585
.active()
562586
.wl_surface()
563587
.map(|s| s.id().same_client_as(object_id))
564588
.unwrap_or(false),
565-
PointerFocusTarget::WindowUI(window) => window
589+
PointerFocusTarget::WindowUI { window, .. } => window
566590
.wl_surface()
567591
.map(|s| s.id().same_client_as(object_id))
568592
.unwrap_or(false),

src/shell/seats.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{
66
backend::render::cursor::CursorState,
77
config::{xkb_config_to_wl, Config},
88
input::{ModifiersShortcutQueue, SupressedButtons, SupressedKeys},
9+
shell::focus::target::KeyboardFocusTarget,
910
state::State,
1011
};
1112
use smithay::{
@@ -175,6 +176,9 @@ struct FocusedOutput(pub Mutex<Option<Output>>);
175176
#[derive(Default)]
176177
pub struct LastModifierChange(pub Mutex<Option<Serial>>);
177178

179+
#[derive(Default)]
180+
pub struct LastAcknowlegedElement(pub Mutex<Option<KeyboardFocusTarget>>);
181+
178182
pub fn create_seat(
179183
dh: &DisplayHandle,
180184
seat_state: &mut SeatState<State>,
@@ -190,6 +194,7 @@ pub fn create_seat(
190194
userdata.insert_if_missing(SupressedButtons::default);
191195
userdata.insert_if_missing(ModifiersShortcutQueue::default);
192196
userdata.insert_if_missing(LastModifierChange::default);
197+
userdata.insert_if_missing(LastAcknowlegedElement::default);
193198
userdata.insert_if_missing_threadsafe(SeatMoveGrabState::default);
194199
userdata.insert_if_missing_threadsafe(SeatMenuGrabState::default);
195200
userdata.insert_if_missing_threadsafe(CursorState::default);

0 commit comments

Comments
 (0)