mirror of
https://github.com/Smithay/smithay.git
synced 2024-09-28 03:21:14 +02:00
Fix ZwpTabletToolV2 reference cycles
This commit is contained in:
parent
356e8ac0b8
commit
c01d567b0a
1 changed files with 25 additions and 8 deletions
|
@ -10,6 +10,7 @@ use wayland_protocols::wp::tablet::zv2::server::{
|
|||
zwp_tablet_tool_v2::{self, ZwpTabletToolV2},
|
||||
};
|
||||
use wayland_server::protocol::wl_surface::WlSurface;
|
||||
use wayland_server::Weak;
|
||||
use wayland_server::{backend::ClientId, Client, DataInit, Dispatch, DisplayHandle, Resource};
|
||||
|
||||
use crate::{utils::Serial, wayland::compositor};
|
||||
|
@ -20,7 +21,7 @@ use super::TabletManagerState;
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct TabletTool {
|
||||
instances: Vec<ZwpTabletToolV2>,
|
||||
instances: Vec<Weak<ZwpTabletToolV2>>,
|
||||
pub(crate) focus: Option<WlSurface>,
|
||||
|
||||
is_down: bool,
|
||||
|
@ -44,7 +45,7 @@ impl TabletTool {
|
|||
) {
|
||||
let wl_tool = self.instances.iter().find(|i| i.id().same_client_as(&focus.id()));
|
||||
|
||||
if let Some(wl_tool) = wl_tool {
|
||||
if let Some(wl_tool) = wl_tool.and_then(|tool| tool.upgrade().ok()) {
|
||||
tablet.with_focused_tablet(&focus, |wl_tablet| {
|
||||
wl_tool.proximity_in(serial.into(), wl_tablet, &focus);
|
||||
// proximity_in has to be followed by motion event (required by protocol)
|
||||
|
@ -61,7 +62,7 @@ impl TabletTool {
|
|||
if let Some(ref focus) = self.focus {
|
||||
let wl_tool = self.instances.iter().find(|i| i.id().same_client_as(&focus.id()));
|
||||
|
||||
if let Some(wl_tool) = wl_tool {
|
||||
if let Some(wl_tool) = wl_tool.and_then(|tool| tool.upgrade().ok()) {
|
||||
if self.is_down {
|
||||
wl_tool.up();
|
||||
self.is_down = false;
|
||||
|
@ -76,7 +77,12 @@ impl TabletTool {
|
|||
|
||||
fn tip_down(&mut self, serial: Serial, time: u32) {
|
||||
if let Some(ref focus) = self.focus {
|
||||
if let Some(wl_tool) = self.instances.iter().find(|i| i.id().same_client_as(&focus.id())) {
|
||||
if let Some(wl_tool) = self
|
||||
.instances
|
||||
.iter()
|
||||
.find(|i| i.id().same_client_as(&focus.id()))
|
||||
.and_then(|tool| tool.upgrade().ok())
|
||||
{
|
||||
if !self.is_down {
|
||||
wl_tool.down(serial.into());
|
||||
wl_tool.frame(time);
|
||||
|
@ -89,7 +95,12 @@ impl TabletTool {
|
|||
|
||||
fn tip_up(&mut self, time: u32) {
|
||||
if let Some(ref focus) = self.focus {
|
||||
if let Some(wl_tool) = self.instances.iter().find(|i| i.id().same_client_as(&focus.id())) {
|
||||
if let Some(wl_tool) = self
|
||||
.instances
|
||||
.iter()
|
||||
.find(|i| i.id().same_client_as(&focus.id()))
|
||||
.and_then(|tool| tool.upgrade().ok())
|
||||
{
|
||||
if self.is_down {
|
||||
wl_tool.up();
|
||||
wl_tool.frame(time);
|
||||
|
@ -115,6 +126,7 @@ impl TabletTool {
|
|||
.instances
|
||||
.iter()
|
||||
.find(|i| i.id().same_client_as(&focus.0.id()))
|
||||
.and_then(|tool| tool.upgrade().ok())
|
||||
{
|
||||
let srel_loc = pos - focus.1;
|
||||
wl_tool.motion(srel_loc.x, srel_loc.y);
|
||||
|
@ -188,7 +200,12 @@ impl TabletTool {
|
|||
/// Sent whenever a button on the tool is pressed or released.
|
||||
fn button(&self, button: u32, state: ButtonState, serial: Serial, time: u32) {
|
||||
if let Some(ref focus) = self.focus {
|
||||
if let Some(wl_tool) = self.instances.iter().find(|i| i.id().same_client_as(&focus.id())) {
|
||||
if let Some(wl_tool) = self
|
||||
.instances
|
||||
.iter()
|
||||
.find(|i| i.id().same_client_as(&focus.id()))
|
||||
.and_then(|tool| tool.upgrade().ok())
|
||||
{
|
||||
wl_tool.button(serial.into(), button, state.into());
|
||||
wl_tool.frame(time);
|
||||
}
|
||||
|
@ -198,7 +215,7 @@ impl TabletTool {
|
|||
|
||||
impl Drop for TabletTool {
|
||||
fn drop(&mut self) {
|
||||
for instance in self.instances.iter() {
|
||||
for instance in self.instances.iter().filter_map(|tool| tool.upgrade().ok()) {
|
||||
// This event is sent when the tool is removed from the system and will send no further events.
|
||||
instance.removed();
|
||||
}
|
||||
|
@ -277,7 +294,7 @@ impl TabletToolHandle {
|
|||
}
|
||||
|
||||
wl_tool.done();
|
||||
self.inner.lock().unwrap().instances.push(wl_tool);
|
||||
self.inner.lock().unwrap().instances.push(wl_tool.downgrade());
|
||||
}
|
||||
|
||||
/// Notify that this tool is focused on a certain surface.
|
||||
|
|
Loading…
Reference in a new issue