diff --git a/jay-config/src/_private/client.rs b/jay-config/src/_private/client.rs
index 462b48b4..61c8af6c 100644
--- a/jay-config/src/_private/client.rs
+++ b/jay-config/src/_private/client.rs
@@ -903,6 +903,10 @@ impl Client {
(rate, delay)
}
+ pub fn set_forward(&self, seat: Seat, forward: bool) {
+ self.send(&ClientMessage::SetForward { seat, forward })
+ }
+
pub fn parse_keymap(&self, keymap: &str) -> Keymap {
let res = self.send_with_response(&ClientMessage::ParseKeymap { keymap });
get_response!(res, Keymap(0), ParseKeymap { keymap });
diff --git a/jay-config/src/_private/ipc.rs b/jay-config/src/_private/ipc.rs
index 844f9a47..17210fa2 100644
--- a/jay-config/src/_private/ipc.rs
+++ b/jay-config/src/_private/ipc.rs
@@ -436,6 +436,10 @@ pub enum ClientMessage<'a> {
device: InputDevice,
keymap: Keymap,
},
+ SetForward {
+ seat: Seat,
+ forward: bool,
+ },
}
#[derive(Serialize, Deserialize, Debug)]
diff --git a/jay-config/src/input.rs b/jay-config/src/input.rs
index 08322e6d..9c031a5c 100644
--- a/jay-config/src/input.rs
+++ b/jay-config/src/input.rs
@@ -335,6 +335,26 @@ impl Seat {
pub fn move_to_output(self, connector: Connector) {
get!().move_to_output(WorkspaceSource::Seat(self), connector);
}
+
+ /// Set whether the current key event is forwarded to the focused client.
+ ///
+ /// This only has an effect if called from a keyboard shortcut.
+ ///
+ /// By default, release events are forwarded and press events are consumed. Note that
+ /// consuming release events can cause clients to get stuck in the pressed state.
+ pub fn set_forward(self, forward: bool) {
+ get!().set_forward(self, forward);
+ }
+
+ /// This is a shorthand for `set_forward(true)`.
+ pub fn forward(self) {
+ self.set_forward(true)
+ }
+
+ /// This is a shorthand for `set_forward(false)`.
+ pub fn consume(self) {
+ self.set_forward(false)
+ }
}
/// Returns all seats.
diff --git a/jay-config/src/keyboard/mods.rs b/jay-config/src/keyboard/mods.rs
index 80b1dea8..d2351f0c 100644
--- a/jay-config/src/keyboard/mods.rs
+++ b/jay-config/src/keyboard/mods.rs
@@ -36,6 +36,11 @@ pub const NUM: Modifiers = MOD2;
/// Alias for `MOD4`.
pub const LOGO: Modifiers = MOD4;
+/// Synthetic modifier matching key release events.
+///
+/// This can be used to execute a callback on key release.
+pub const RELEASE: Modifiers = Modifiers(1 << 31);
+
impl BitOr for Modifiers {
type Output = Self;
diff --git a/src/config/handler.rs b/src/config/handler.rs
index 79a47237..fe78a71c 100644
--- a/src/config/handler.rs
+++ b/src/config/handler.rs
@@ -318,6 +318,12 @@ impl ConfigProxyHandler {
Ok(())
}
+ fn handle_set_forward(&self, seat: Seat, forward: bool) -> Result<(), CphError> {
+ let seat = self.get_seat(seat)?;
+ seat.set_forward(forward);
+ Ok(())
+ }
+
fn handle_set_status(&self, status: &str) {
self.state.set_status(status);
}
@@ -1764,6 +1770,9 @@ impl ConfigProxyHandler {
ClientMessage::DeviceSetKeymap { device, keymap } => self
.handle_set_device_keymap(device, keymap)
.wrn("set_device_keymap")?,
+ ClientMessage::SetForward { seat, forward } => {
+ self.handle_set_forward(seat, forward).wrn("set_forward")?
+ }
}
Ok(())
}
diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs
index 11831159..4d37ffc4 100644
--- a/src/ifs/wl_seat.rs
+++ b/src/ifs/wl_seat.rs
@@ -175,6 +175,7 @@ pub struct WlSeatGlobal {
text_input: CloneCell