Skip to content

wayland/pointer_constraints: call remove_constraint when pointer leave surface - #2107

Open
skygrango wants to merge 2 commits into
Smithay:masterfrom
skygrango:fix_pointer_constraint
Open

wayland/pointer_constraints: call remove_constraint when pointer leave surface#2107
skygrango wants to merge 2 commits into
Smithay:masterfrom
skygrango:fix_pointer_constraint

Conversation

@skygrango

Copy link
Copy Markdown
Contributor

Description

related: #2027 (comment)

The implementation ensures that remove_constraint() is invoked when the pointer leaves the surface, allowing the last saved cursor position hint to be applied.

This both improves the expected behavior of Lifetime::Persistent and ensures that pointer focus changes are handled immediately.

Checklist

@skygrango

Copy link
Copy Markdown
Contributor Author

@YaLTeR Does this meet your needs ?

@skygrango
skygrango force-pushed the fix_pointer_constraint branch 3 times, most recently from 7ea2362 to b665e57 Compare July 22, 2026 03:42
@skygrango

Copy link
Copy Markdown
Contributor Author

Introducing the PointerConstraintsHandler trait significantly increases the scope of the changes. Perhaps we should move remove_constraint() out of PointerConstraintsHandler

Comment thread src/wayland/seat/pointer.rs Outdated
Comment on lines +258 to +260
if deactivated {
data.remove_constraint(self, &pointer);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would imagine that this code should go inside deactivate() itself to avoid putting it into every caller?

Or I guess data is inaccessible from there? Hmm, not sure how to structure this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the signature of deactivate(), which I believe addresses your suggestion.

However, the downside is that PointerConstraintsHandler has now become a trait dependency of PointerTarget.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks like the change that I had in mind, yeah.

It also doesn't seem like the repeated remove_constraint() call from destroyed() is a problem, because the constraint is required to be unique per surface, so the surface must destroy the previous constraint before making a new one, so it shouldn't be possible for a repeated remove_constraint() call to operate on a cursor position hint from a different constraint. Is my reasoning correct here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Lifetime::Oneshot, explicitly calling deactivate() does result in one extra invocation of remove_constraint(). However, I don't think this has any practical impact. The compositor should ensure that only a single surface's cursor position hint is stored at any given time(per seat), and that the hint is consumed after it has been been applied. Consequently, the second invocation becomes a no-op because there is no cursor position hint remaining to apply.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and I am thinking through whether it's possible to end up with the incorrect stored hint through overlapping pointer constraint objects, and so far I don't see any way.

@skygrango
skygrango force-pushed the fix_pointer_constraint branch 7 times, most recently from c731f38 to d551a7f Compare July 22, 2026 10:07
@skygrango

Copy link
Copy Markdown
Contributor Author

I moved remove_constraint() to SeatHandler, which significantly reduces the amount of trait boilerplate and maintenance.

Since remove_constraint() may be called while with_pointer_constraint() is active, the PointerConstraint is passed to the compositor so it can inspect the RegionAttributes without re-entering with_pointer_constraint().

Comment thread anvil/src/state.rs Outdated
self.backend_data.update_led_state(led_state)
}

fn remove_constraint(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Urgh, I am not sure I like the move here. So if you don't expose the constrains-protocol, you still have to implement this function? That makes no sense.

Comment thread src/wayland/seat/pointer.rs Outdated
with_pointer_constraint(self, &pointer, |constraint| {
if let Some(constraint) = constraint {
constraint.deactivate();
constraint.deactivate(data, &self, &pointer);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the issue is this call, right? (This would be so easy, if we had specialization.)

I would honestly rather have the PointerTarget impl for WlSurface require the PointerContraintsHandler, than remove_constraint to be part of the SeatHandler, if nobody has a better idea.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do you think about

/// Callback that returns a reference to the pointer constraints handler, if implemented.
fn pointer_constraints_handler(&mut self) -> Option<&mut dyn PointerConstraintsHandler<Self>> {
    None
}

for SeatHandler

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No please. The SeatHandler should not expose anything related to pointer constraints. If our WlSurface implementation of PointerTarget needs it, just add a requirement for the PointerConstraintsHandler.

@skygrango
skygrango force-pushed the fix_pointer_constraint branch 4 times, most recently from 4b0ab03 to 9698623 Compare July 25, 2026 04:03
@skygrango
skygrango force-pushed the fix_pointer_constraint branch from 29c3be2 to 43ee475 Compare July 25, 2026 04:22
@skygrango

Copy link
Copy Markdown
Contributor Author

@Drakulix Following your suggestion, I added PointerConstraintsHandler to PointerTarget. Could you please let me know if this is good enough? I'll clean up the Git history later.

@Drakulix Drakulix left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

I'll clean up the Git history later.

I can simply squash the commits on merge, if you want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants