From eca367cdb41205549de0d7e9b0e03b91915984df Mon Sep 17 00:00:00 2001 From: Ferdinand Schober Date: Sun, 17 Dec 2023 17:57:17 +0100 Subject: [PATCH] Fix an issue where client could not be entered again (#51) RELEASE_MODIFIERS are now handled server side. A client exited through CTRL+ALT+SHIFT+SUPER could sometimes not be entered again when the client did not send a Modifiers (0) event. Such a client would always respond with Modifiers (RELEASE_MODIFIERS) and immediately cause the sender to exit again. To prevent this, a modifier event with all modifiers released is now sent instead when the release modifiers are detected. --- src/backend/producer/wayland.rs | 4 ---- src/server.rs | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/backend/producer/wayland.rs b/src/backend/producer/wayland.rs index 0d03242..8675bcd 100644 --- a/src/backend/producer/wayland.rs +++ b/src/backend/producer/wayland.rs @@ -753,10 +753,6 @@ impl Dispatch for State { }), )); } - if mods_depressed == 77 { - // ctrl shift super alt - app.ungrab(); - } } wl_keyboard::Event::Keymap { format: _, diff --git a/src/server.rs b/src/server.rs index 29947da..0fad1d6 100644 --- a/src/server.rs +++ b/src/server.rs @@ -22,7 +22,7 @@ use tokio::net::TcpStream; use std::{io::ErrorKind, net::SocketAddr}; -use crate::event::Event; +use crate::event::{Event, KeyboardEvent}; use crate::{ client::{ClientEvent, ClientHandle, ClientManager, Position}, config::Config, @@ -368,9 +368,21 @@ impl Server { } } - async fn handle_producer_event(&mut self, c: ClientHandle, e: Event) { + const RELEASE_MODIFIERDS: u32 = 77; // ctrl+shift+super+alt + + async fn handle_producer_event(&mut self, c: ClientHandle, mut e: Event) { log::trace!("producer: ({c}) {e:?}"); + if let Event::Keyboard(crate::event::KeyboardEvent::Modifiers { mods_depressed, mods_latched: _, mods_locked: _, group: _ }) = e { + if mods_depressed == Self::RELEASE_MODIFIERDS { + self.producer.release(); + self.state = State::Receiving; + // send an event to release all the modifiers + e = Event::Keyboard(KeyboardEvent::Modifiers { + mods_depressed: 0, mods_latched: 0, mods_locked: 0, group: 0 }); + } + } + // get client state for handle let state = match self.client_manager.get_mut(c) { Some(state) => state,