mirror of
https://github.com/wez/wezterm.git
synced 2024-11-22 22:42:48 +03:00
add window:keyboard_modifiers() method
This commit is contained in:
parent
572c31fb30
commit
075388fbe5
@ -21,6 +21,10 @@ usually the best available version.
|
||||
|
||||
As features stabilize some brief notes about them will accumulate here.
|
||||
|
||||
#### New
|
||||
|
||||
* [window:keyboard_modifiers](config/lua/window/keyboard_modifiers.md) #3444
|
||||
|
||||
#### Fixed
|
||||
|
||||
* Modals, such as `CharSelect` and `CommandPalette` did not respect alternative
|
||||
|
30
docs/config/lua/window/keyboard_modifiers.md
Normal file
30
docs/config/lua/window/keyboard_modifiers.md
Normal file
@ -0,0 +1,30 @@
|
||||
# window:keyboard_modifiers()
|
||||
|
||||
{{since('nightly')}}
|
||||
|
||||
Returns two values; the keyboard modifiers and the key status leds.
|
||||
|
||||
Both values are exposed to lua as strings with `|`-delimited values
|
||||
representing the various modifier keys and keyboard led states:
|
||||
|
||||
* Modifiers - is the same form as keyboard assignment modifiers
|
||||
* Leds - possible flags are `"CAPS_LOCK"` and `"NUM_LOCK"`. Note that macOS
|
||||
doesn't have a num lock concept.
|
||||
|
||||
This example shows the current modifier and led status in the right status
|
||||
area:
|
||||
|
||||
```lua
|
||||
local wezterm = require 'wezterm'
|
||||
|
||||
local config = wezterm.config_builder()
|
||||
|
||||
config.debug_key_events = true
|
||||
|
||||
wezterm.on('update-status', function(window, pane)
|
||||
local mods, leds = window:keyboard_modifiers()
|
||||
window:set_right_status('mods=' .. mods .. ' leds=' .. leds)
|
||||
end)
|
||||
|
||||
return config
|
||||
```
|
@ -257,6 +257,21 @@ impl UserData for GuiWin {
|
||||
|
||||
Ok(result)
|
||||
});
|
||||
methods.add_async_method("keyboard_modifiers", |_, this, _: ()| async move {
|
||||
let (tx, rx) = smol::channel::bounded(1);
|
||||
this.window
|
||||
.notify(TermWindowNotif::Apply(Box::new(move |term_window| {
|
||||
tx.try_send(term_window.current_modifier_and_led_state())
|
||||
.ok();
|
||||
})));
|
||||
let (mods, leds) = rx
|
||||
.recv()
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("{:#}", e))
|
||||
.map_err(luaerr)?;
|
||||
|
||||
Ok((mods.to_string(), leds.to_string()))
|
||||
});
|
||||
methods.add_async_method("active_pane", |_, this, _: ()| async move {
|
||||
let (tx, rx) = smol::channel::bounded(1);
|
||||
this.window
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::termwindow::InputMap;
|
||||
use ::window::{DeadKeyStatus, KeyCode, KeyEvent, Modifiers, RawKeyEvent, WindowOps};
|
||||
use ::window::{
|
||||
DeadKeyStatus, KeyCode, KeyEvent, KeyboardLedStatus, Modifiers, RawKeyEvent, WindowOps,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use config::keyassignment::{KeyAssignment, KeyTableEntry};
|
||||
use mux::pane::{Pane, PerformAssignmentResult};
|
||||
@ -448,6 +450,12 @@ impl super::TermWindow {
|
||||
);
|
||||
}
|
||||
|
||||
let modifier_and_leds = (key.modifiers, key.leds);
|
||||
if self.current_modifier_and_leds != modifier_and_leds {
|
||||
self.current_modifier_and_leds = modifier_and_leds;
|
||||
self.schedule_next_status_update();
|
||||
}
|
||||
|
||||
let pane = match self.get_active_pane_or_overlay() {
|
||||
Some(pane) => pane,
|
||||
None => return,
|
||||
@ -517,6 +525,10 @@ impl super::TermWindow {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn current_modifier_and_led_state(&self) -> (Modifiers, KeyboardLedStatus) {
|
||||
self.current_modifier_and_leds
|
||||
}
|
||||
|
||||
pub fn leader_is_active(&self) -> bool {
|
||||
match self.leader_is_down.as_ref() {
|
||||
Some(expiry) if *expiry > std::time::Instant::now() => {
|
||||
|
@ -395,6 +395,7 @@ pub struct TermWindow {
|
||||
|
||||
window_background: Vec<LoadedBackgroundLayer>,
|
||||
|
||||
current_modifier_and_leds: (Modifiers, KeyboardLedStatus),
|
||||
current_mouse_buttons: Vec<MousePress>,
|
||||
current_mouse_capture: Option<MouseCapture>,
|
||||
|
||||
@ -694,6 +695,7 @@ impl TermWindow {
|
||||
last_mouse_coords: (0, -1),
|
||||
window_drag_position: None,
|
||||
current_mouse_event: None,
|
||||
current_modifier_and_leds: Default::default(),
|
||||
prev_cursor: PrevCursorPos::new(),
|
||||
last_scroll_info: RenderableDimensions::default(),
|
||||
tab_state: RefCell::new(HashMap::new()),
|
||||
@ -925,6 +927,12 @@ impl TermWindow {
|
||||
self.resize(dimensions, window_state, window, live_resizing);
|
||||
Ok(true)
|
||||
}
|
||||
WindowEvent::AdviseModifiersLedStatus(modifiers, leds) => {
|
||||
self.current_modifier_and_leds = (modifiers, leds);
|
||||
self.update_title();
|
||||
window.invalidate();
|
||||
Ok(true)
|
||||
}
|
||||
WindowEvent::RawKeyEvent(event) => {
|
||||
self.raw_key_event_impl(event, window);
|
||||
Ok(true)
|
||||
|
@ -459,6 +459,22 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for KeyboardLedStatus {
|
||||
fn to_string(&self) -> String {
|
||||
let mut s = String::new();
|
||||
if self.contains(Self::CAPS_LOCK) {
|
||||
s.push_str("CAPS_LOCK");
|
||||
}
|
||||
if self.contains(Self::NUM_LOCK) {
|
||||
if !s.is_empty() {
|
||||
s.push('|');
|
||||
}
|
||||
s.push_str("NUM_LOCK");
|
||||
}
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Default, FromDynamic, ToDynamic)]
|
||||
|
@ -80,6 +80,7 @@ impl MyWindow {
|
||||
}
|
||||
WindowEvent::AppearanceChanged(_)
|
||||
| WindowEvent::AdviseDeadKeyStatus(_)
|
||||
| WindowEvent::AdviseModifiersLedStatus(_, _)
|
||||
| WindowEvent::Notification(_)
|
||||
| WindowEvent::FocusChanged(_)
|
||||
| WindowEvent::DraggedFile(_)
|
||||
|
@ -189,6 +189,8 @@ pub enum WindowEvent {
|
||||
|
||||
/// Called by menubar dispatching stuff on some systems
|
||||
PerformKeyAssignment(config::keyassignment::KeyAssignment),
|
||||
|
||||
AdviseModifiersLedStatus(Modifiers, KeyboardLedStatus),
|
||||
}
|
||||
|
||||
pub struct WindowEventSender {
|
||||
|
@ -2657,6 +2657,23 @@ impl WindowView {
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn flags_changed(this: &mut Object, _sel: Sel, nsevent: id) {
|
||||
let modifier_flags = unsafe { nsevent.modifierFlags() };
|
||||
let modifiers = key_modifiers(modifier_flags);
|
||||
let leds = if modifier_flags.bits() & (1 << 16) != 0 {
|
||||
KeyboardLedStatus::CAPS_LOCK
|
||||
} else {
|
||||
KeyboardLedStatus::empty()
|
||||
};
|
||||
|
||||
if let Some(myself) = Self::get_this(this) {
|
||||
let mut inner = myself.inner.borrow_mut();
|
||||
inner
|
||||
.events
|
||||
.dispatch(WindowEvent::AdviseModifiersLedStatus(modifiers, leds));
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn key_down(this: &mut Object, _sel: Sel, nsevent: id) {
|
||||
Self::key_common(this, nsevent, true);
|
||||
}
|
||||
@ -3101,6 +3118,11 @@ impl WindowView {
|
||||
Self::update_tracking_areas as extern "C" fn(&mut Object, Sel),
|
||||
);
|
||||
|
||||
cls.add_method(
|
||||
sel!(flagsChanged:),
|
||||
Self::flags_changed as extern "C" fn(&mut Object, Sel, id),
|
||||
);
|
||||
|
||||
// NSTextInputClient
|
||||
|
||||
cls.add_method(
|
||||
|
Loading…
Reference in New Issue
Block a user