1
0
Fork 0
forked from wry/wry

config: allow consuming/forwarding key events

This commit is contained in:
Julian Orth 2024-04-15 18:42:59 +02:00
parent 6ee4fdb9f4
commit 18bc86d14f
12 changed files with 106 additions and 13 deletions

View file

@ -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 });

View file

@ -436,6 +436,10 @@ pub enum ClientMessage<'a> {
device: InputDevice,
keymap: Keymap,
},
SetForward {
seat: Seat,
forward: bool,
},
}
#[derive(Serialize, Deserialize, Debug)]

View file

@ -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.

View file

@ -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(())
}

View file

@ -175,6 +175,7 @@ pub struct WlSeatGlobal {
text_input: CloneCell<Option<Rc<ZwpTextInputV3>>>,
input_method: CloneCell<Option<Rc<ZwpInputMethodV2>>>,
input_method_grab: CloneCell<Option<Rc<ZwpInputMethodKeyboardGrabV2>>>,
forward: Cell<bool>,
}
const CHANGE_CURSOR_MOVED: u32 = 1 << 0;
@ -243,6 +244,7 @@ impl WlSeatGlobal {
text_input: Default::default(),
input_method: Default::default(),
input_method_grab: Default::default(),
forward: Cell::new(false),
});
state.add_cursor_size(*DEFAULT_CURSOR_SIZE);
let seat = slf.clone();
@ -1146,6 +1148,10 @@ impl WlSeatGlobal {
}
}
}
pub fn set_forward(&self, forward: bool) {
self.forward.set(forward);
}
}
global_base!(WlSeatGlobal, WlSeat, WlSeatError);

View file

@ -35,7 +35,7 @@ use {
wire::WlDataOfferId,
xkbcommon::{KeyboardState, XkbState, XKB_KEY_DOWN, XKB_KEY_UP},
},
isnt::std_1::primitive::IsntSlice2Ext,
isnt::std_1::primitive::{IsntSlice2Ext, IsntSliceExt},
jay_config::keyboard::{
mods::{Modifiers, CAPS, NUM, RELEASE},
syms::KeySym,
@ -397,22 +397,28 @@ impl WlSeatGlobal {
});
let node = self.keyboard_node.get();
let input_method_grab = self.input_method_grab.get();
if shortcuts.is_empty() {
let mut forward = true;
if shortcuts.is_not_empty() {
self.forward.set(state == wl_keyboard::RELEASED);
if let Some(config) = self.state.config.get() {
let id = xkb_state.kb_state.id;
drop(xkb_state);
for shortcut in shortcuts {
config.invoke_shortcut(self.id(), &shortcut);
}
xkb_state_rc = get_state();
xkb_state = xkb_state_rc.borrow_mut();
if id != xkb_state.kb_state.id {
return;
}
}
forward = self.forward.get();
}
if forward {
match &input_method_grab {
Some(g) => g.on_key(time_usec, key, state, &xkb_state.kb_state),
_ => node.node_on_key(self, time_usec, key, state, &xkb_state.kb_state),
}
} else if let Some(config) = self.state.config.get() {
let id = xkb_state.kb_state.id;
drop(xkb_state);
for shortcut in shortcuts {
config.invoke_shortcut(self.id(), &shortcut);
}
xkb_state_rc = get_state();
xkb_state = xkb_state_rc.borrow_mut();
if id != xkb_state.kb_state.id {
return;
}
}
if new_mods {
self.state.for_each_seat_tester(|t| {

View file

@ -49,6 +49,7 @@ pub enum SimpleCommand {
ToggleFullscreen,
ToggleMono,
ToggleSplit,
Forward(bool),
}
#[derive(Debug, Clone)]

View file

@ -109,6 +109,8 @@ impl ActionParser<'_> {
"reload-config-toml" => ReloadConfigToml,
"reload-config-so" => ReloadConfigSo,
"none" => None,
"forward" => Forward(true),
"consume" => Forward(false),
_ => {
return Err(ActionParserError::UnknownSimpleAction(string.to_string()).spanned(span))
}

View file

@ -61,6 +61,7 @@ impl Action {
}
SimpleCommand::ReloadConfigSo => Box::new(reload),
SimpleCommand::None => Box::new(|| ()),
SimpleCommand::Forward(bool) => Box::new(move || s.set_forward(bool)),
},
Action::Multi { actions } => {
let mut actions: Vec<_> = actions.into_iter().map(|a| a.into_fn(state)).collect();

View file

@ -1053,6 +1053,8 @@
"quit",
"reload-config-toml",
"reload-config-to",
"consume",
"forward",
"none"
]
},

View file

@ -2224,6 +2224,26 @@ The string should have one of the following values:
Reload the `config.so`.
- `consume`:
Consume the current key event. Don't forward it to the focused application.
This action only has an effect in shortcuts.
Key-press events events that trigger shortcuts are consumed by default.
Key-release events events that trigger shortcuts are forwarded by default.
Note that consuming key-release events can cause keys to get stuck in the focused
application.
See the `forward` action to achieve the opposite effect.
- `forward`:
Forward the current key event to the focused application.
See the `consume` action for more details.
- `none`:
Perform no action.

View file

@ -668,6 +668,24 @@ SimpleActionName:
description: Reload the `config.toml`.
- value: reload-config-to
description: Reload the `config.so`.
- value: consume
description: |
Consume the current key event. Don't forward it to the focused application.
This action only has an effect in shortcuts.
Key-press events events that trigger shortcuts are consumed by default.
Key-release events events that trigger shortcuts are forwarded by default.
Note that consuming key-release events can cause keys to get stuck in the focused
application.
See the `forward` action to achieve the opposite effect.
- value: forward
description: |
Forward the current key event to the focused application.
See the `consume` action for more details.
- value: none
description: |
Perform no action.