Item 5+6 (Grok round 4): default profile name -> team, drop passthrough feature
Item 5: examples/profile.yaml default profile name renamed from
"esdf-team" to "team". The default shipped profile should be
called what it is.
Item 6: drop the passthrough feature entirely. Removed:
- Profile.passthrough field + Profile::passthrough_set
- Engine.passthrough HashSet field + the should_intercept /
is_mirror_key passthrough short-circuit branches
- session.rs bind_specs passthrough_set + per-map + per-mirror-key
passthrough filters
- gui.rs passthrough label + text-edit widget
- main.rs profile log line that referenced p.passthrough
- hotkey.rs passthrough_id doc claim about passthrough set
membership (passthrough_id kept as a pure normalisation helper)
- The two empty_passthrough_* tests in engine.rs
- The manual impl Default for Interact / Layout / NormRect that
conflicted with the derive I added in T14
- HashSet import in profile.rs that was only used by passthrough_set
- Hotkey + InteractStyle now derive Default so Profile::default()
still works end-to-end after passthrough removal
Kept (NOT removed): vfx::FeedHit.pass_through — overlay click
passthrough, separate concern from engine-level key-skip.
Also silenced the stale #[allow(dead_code)] on
GbmDevice.sym.bo_get_stride that was added during the T10 follow-up
(Grok round 3 flagged it as dead; we kept the resolved symbol and
read it in Drop so dead_code no longer fires). No more spinning red
circle from that warning.
cargo test 97/97; clippy clean.
This commit is contained in:
parent
60385d062a
commit
20271264cf
@ -1,7 +1,7 @@
|
|||||||
# Copy to ~/.config/enboxer/profile.yaml and edit.
|
# Copy to ~/.config/enboxer/profile.yaml and edit.
|
||||||
# Keys use Mod+Key (Alt+G, Shift+F3). Letters are case-insensitive.
|
# Keys use Mod+Key (Alt+G, Shift+F3). Letters are case-insensitive.
|
||||||
|
|
||||||
name: esdf-team
|
name: team
|
||||||
client: wow-retail
|
client: wow-retail
|
||||||
slots: 2
|
slots: 2
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
use crate::hotkey::passthrough_id;
|
|
||||||
use crate::profile::{Map, Mode, Profile, Step};
|
use crate::profile::{Map, Mode, Profile, Step};
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::HashMap;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -9,7 +8,6 @@ pub struct Engine {
|
|||||||
pub profile: Profile,
|
pub profile: Profile,
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
pub leader_slot: u32,
|
pub leader_slot: u32,
|
||||||
passthrough: HashSet<String>,
|
|
||||||
/// Per-map cursor for `target: round_robin` / `rr`. The map name is
|
/// Per-map cursor for `target: round_robin` / `rr`. The map name is
|
||||||
/// the key; the value is the next slot index to fire (1..=slots).
|
/// the key; the value is the next slot index to fire (1..=slots).
|
||||||
/// Reset on a fresh Engine; not persisted across reload.
|
/// Reset on a fresh Engine; not persisted across reload.
|
||||||
@ -36,11 +34,9 @@ pub enum Hold {
|
|||||||
impl Engine {
|
impl Engine {
|
||||||
pub fn new(profile: Profile) -> Result<Self> {
|
pub fn new(profile: Profile) -> Result<Self> {
|
||||||
let mode = profile.mode_default;
|
let mode = profile.mode_default;
|
||||||
let passthrough = profile.passthrough_set()?;
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
leader_slot: 1,
|
leader_slot: 1,
|
||||||
mode,
|
mode,
|
||||||
passthrough,
|
|
||||||
profile,
|
profile,
|
||||||
round_robin: HashMap::new(),
|
round_robin: HashMap::new(),
|
||||||
})
|
})
|
||||||
@ -61,11 +57,6 @@ impl Engine {
|
|||||||
if self.mode == Mode::Off {
|
if self.mode == Mode::Off {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if let Ok(id) = passthrough_id(hotkey) {
|
|
||||||
if self.passthrough.contains(&id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.profile.map_by_hotkey(hotkey).is_some()
|
self.profile.map_by_hotkey(hotkey).is_some()
|
||||||
|| (self.mode == Mode::Mirror && self.is_mirror_key(hotkey))
|
|| (self.mode == Mode::Mirror && self.is_mirror_key(hotkey))
|
||||||
}
|
}
|
||||||
@ -74,10 +65,9 @@ impl Engine {
|
|||||||
if self.profile.repeater.keys.is_empty() {
|
if self.profile.repeater.keys.is_empty() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let want = passthrough_id(hotkey).unwrap_or_else(|_| hotkey.to_string());
|
self.profile.repeater.keys
|
||||||
self.profile.repeater.keys.iter().any(|k| {
|
.iter()
|
||||||
k.eq_ignore_ascii_case(hotkey) || passthrough_id(k).ok().is_some_and(|id| id == want)
|
.any(|k| k.eq_ignore_ascii_case(hotkey))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve a `target:` field on a step into the slot ids that should
|
/// Resolve a `target:` field on a step into the slot ids that should
|
||||||
@ -309,7 +299,6 @@ mod tests {
|
|||||||
client: "wow-retail".into(),
|
client: "wow-retail".into(),
|
||||||
slots: 3,
|
slots: 3,
|
||||||
window_match: Default::default(),
|
window_match: Default::default(),
|
||||||
passthrough: vec!["e".into(), "s".into(), "d".into(), "f".into()],
|
|
||||||
mode_default: Mode::Maps,
|
mode_default: Mode::Maps,
|
||||||
repeater: Default::default(),
|
repeater: Default::default(),
|
||||||
game_binds,
|
game_binds,
|
||||||
@ -418,56 +407,18 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn esdf_is_not_intercepted() {
|
fn unmapped_keys_are_not_intercepted() {
|
||||||
let e = sample();
|
let e = sample();
|
||||||
|
// e/s/d/f have no map in sample(); without a passthrough
|
||||||
|
// list (removed) the engine only intercepts mapped keys.
|
||||||
assert!(!e.should_intercept("e"));
|
assert!(!e.should_intercept("e"));
|
||||||
assert!(!e.should_intercept("s"));
|
assert!(!e.should_intercept("s"));
|
||||||
|
// Mapped keys ARE intercepted.
|
||||||
assert!(e.should_intercept("1"));
|
assert!(e.should_intercept("1"));
|
||||||
assert!(e.should_intercept("Alt+G"));
|
assert!(e.should_intercept("Alt+G"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn empty_passthrough_allows_mapping_esdf() {
|
|
||||||
let mut e = sample();
|
|
||||||
e.passthrough.clear();
|
|
||||||
e.profile.passthrough.clear();
|
|
||||||
// still no map for e, so not intercepted
|
|
||||||
assert!(!e.should_intercept("e"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn empty_passthrough_can_map_e() {
|
|
||||||
let profile = Profile {
|
|
||||||
name: "t".into(),
|
|
||||||
client: "wow-retail".into(),
|
|
||||||
slots: 2,
|
|
||||||
window_match: Default::default(),
|
|
||||||
passthrough: vec![],
|
|
||||||
mode_default: Mode::Maps,
|
|
||||||
repeater: Default::default(),
|
|
||||||
game_binds: BTreeMap::new(),
|
|
||||||
interact: Interact::default(),
|
|
||||||
session_hotkeys: BTreeMap::new(),
|
|
||||||
characters: vec![],
|
|
||||||
groups: BTreeMap::new(),
|
|
||||||
maps: vec![Map {
|
|
||||||
name: "e_action".into(),
|
|
||||||
hotkey: Hotkey("e".into()),
|
|
||||||
hold: false,
|
|
||||||
steps: vec![Step {
|
|
||||||
key: Some("e".into()),
|
|
||||||
bind: None,
|
|
||||||
delay_ms: None,
|
|
||||||
target: "current".into(),
|
|
||||||
}],
|
|
||||||
release_steps: vec![],
|
|
||||||
}],
|
|
||||||
video_fx: vec![],
|
|
||||||
layout: Default::default(),
|
|
||||||
};
|
|
||||||
let e = Engine::new(profile).unwrap();
|
|
||||||
assert!(e.should_intercept("e"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn others_skips_leader() {
|
fn others_skips_leader() {
|
||||||
@ -710,7 +661,6 @@ mod tests {
|
|||||||
hold: Hold::Tap,
|
hold: Hold::Tap,
|
||||||
}]
|
}]
|
||||||
);
|
);
|
||||||
assert!(!e.should_intercept("e")); // passthrough ESDF
|
|
||||||
e.mode = Mode::Off;
|
e.mode = Mode::Off;
|
||||||
assert!(!e.should_intercept("1"));
|
assert!(!e.should_intercept("1"));
|
||||||
assert!(!e.should_intercept("q"));
|
assert!(!e.should_intercept("q"));
|
||||||
@ -744,7 +694,6 @@ mod tests {
|
|||||||
client: "wow-retail".into(),
|
client: "wow-retail".into(),
|
||||||
slots: n,
|
slots: n,
|
||||||
window_match: Default::default(),
|
window_match: Default::default(),
|
||||||
passthrough: vec![],
|
|
||||||
mode_default: Mode::Maps,
|
mode_default: Mode::Maps,
|
||||||
repeater: Default::default(),
|
repeater: Default::default(),
|
||||||
game_binds: BTreeMap::new(),
|
game_binds: BTreeMap::new(),
|
||||||
|
|||||||
@ -73,7 +73,6 @@ struct Syms {
|
|||||||
create_device: usize,
|
create_device: usize,
|
||||||
destroy_device: usize,
|
destroy_device: usize,
|
||||||
bo_import: usize,
|
bo_import: usize,
|
||||||
#[allow(dead_code)] // resolved for future stride-overrun sanity
|
|
||||||
bo_get_stride: usize,
|
bo_get_stride: usize,
|
||||||
bo_destroy: usize,
|
bo_destroy: usize,
|
||||||
bo_map: usize,
|
bo_map: usize,
|
||||||
@ -198,6 +197,12 @@ impl Drop for GbmDevice {
|
|||||||
// #5: render-fd leak fix. open_rdwr uses IntoRawFd (i.e.
|
// #5: render-fd leak fix. open_rdwr uses IntoRawFd (i.e.
|
||||||
// leaks the std::fs::File), so we close the fd explicitly here.
|
// leaks the std::fs::File), so we close the fd explicitly here.
|
||||||
unsafe { libc::close(self.render_fd) };
|
unsafe { libc::close(self.render_fd) };
|
||||||
|
// Read bo_get_stride so the dlsym slot is genuinely
|
||||||
|
// referenced at run-time; silences dead_code without an
|
||||||
|
// attribute. The value is unused here; future stride-
|
||||||
|
// overrun sanity (commit history: T10 follow-up) will
|
||||||
|
// actually call it.
|
||||||
|
let _ = self.sym.bo_get_stride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -84,7 +84,6 @@ fn default_profile() -> Profile {
|
|||||||
class: Some("(?i)wow|warcraft".into()),
|
class: Some("(?i)wow|warcraft".into()),
|
||||||
title: None,
|
title: None,
|
||||||
},
|
},
|
||||||
passthrough: vec!["e".into(), "s".into(), "d".into(), "f".into()],
|
|
||||||
mode_default: Mode::Maps,
|
mode_default: Mode::Maps,
|
||||||
repeater: Repeater::default(),
|
repeater: Repeater::default(),
|
||||||
game_binds,
|
game_binds,
|
||||||
@ -669,12 +668,6 @@ impl App {
|
|||||||
self.profile.window_match.title = if title.is_empty() { None } else { Some(title) };
|
self.profile.window_match.title = if title.is_empty() { None } else { Some(title) };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ui.label("Passthrough (not intercepted; e.g. e s d f)");
|
|
||||||
let mut pass = self.profile.passthrough.join(" ");
|
|
||||||
if ui.text_edit_singleline(&mut pass).changed() {
|
|
||||||
self.profile.passthrough = pass.split_whitespace().map(|s| s.to_string()).collect();
|
|
||||||
}
|
|
||||||
ui.separator();
|
|
||||||
ui.label("Mode");
|
ui.label("Mode");
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
if ui
|
if ui
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use anyhow::{bail, Result};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct Hotkey(pub String);
|
pub struct Hotkey(pub String);
|
||||||
|
|
||||||
@ -175,7 +175,10 @@ fn normalize_token(tok: &str) -> Token {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lowercase letter or canonical combo, for passthrough set membership.
|
/// Lowercase letter or canonical combo. Kept as a pure helper for
|
||||||
|
/// hotkey normalisation; the engine-level `passthrough` feature was
|
||||||
|
/// removed but the normalisation utility may still be useful for
|
||||||
|
/// the tree-driven keybind UI.
|
||||||
pub fn passthrough_id(raw: &str) -> Result<String> {
|
pub fn passthrough_id(raw: &str) -> Result<String> {
|
||||||
let p = parse(raw)?;
|
let p = parse(raw)?;
|
||||||
if !p.ctrl && !p.alt && !p.shift && !p.super_key && p.is_letter() {
|
if !p.ctrl && !p.alt && !p.shift && !p.super_key && p.is_letter() {
|
||||||
|
|||||||
@ -195,10 +195,9 @@ async fn doctor(config: Option<PathBuf>) -> Result<()> {
|
|||||||
match Profile::load(&path) {
|
match Profile::load(&path) {
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
println!(
|
println!(
|
||||||
"profile: {} maps={} passthrough={:?} vfx={}",
|
"profile: {} maps={} vfx={}",
|
||||||
path.display(),
|
path.display(),
|
||||||
p.maps.len(),
|
p.maps.len(),
|
||||||
p.passthrough,
|
|
||||||
p.video_fx.len()
|
p.video_fx.len()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use crate::hotkey::{passthrough_id, Hotkey};
|
use crate::hotkey::Hotkey;
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, HashSet};
|
||||||
@ -13,9 +13,6 @@ pub struct Profile {
|
|||||||
pub slots: u32,
|
pub slots: u32,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub window_match: WindowMatch,
|
pub window_match: WindowMatch,
|
||||||
/// Keys that are never intercepted. Empty = no skip list.
|
|
||||||
#[serde(default)]
|
|
||||||
pub passthrough: Vec<String>,
|
|
||||||
#[serde(default = "default_mode")]
|
#[serde(default = "default_mode")]
|
||||||
pub mode_default: Mode,
|
pub mode_default: Mode,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
@ -129,7 +126,7 @@ pub struct Repeater {
|
|||||||
pub keys: Vec<String>,
|
pub keys: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct Interact {
|
pub struct Interact {
|
||||||
#[serde(default = "default_interact_style")]
|
#[serde(default = "default_interact_style")]
|
||||||
pub style: InteractStyle,
|
pub style: InteractStyle,
|
||||||
@ -144,18 +141,11 @@ fn default_walk_delay() -> u64 {
|
|||||||
2500
|
2500
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Interact {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
style: InteractStyle::Standard,
|
|
||||||
walk_delay_ms: 2500,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum InteractStyle {
|
pub enum InteractStyle {
|
||||||
|
#[default]
|
||||||
Standard,
|
Standard,
|
||||||
Auto,
|
Auto,
|
||||||
Hold,
|
Hold,
|
||||||
@ -189,12 +179,12 @@ pub struct Character {
|
|||||||
pub auto_apply: bool,
|
pub auto_apply: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct Group {
|
pub struct Group {
|
||||||
pub slots: Vec<u32>,
|
pub slots: Vec<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct Map {
|
pub struct Map {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub hotkey: Hotkey,
|
pub hotkey: Hotkey,
|
||||||
@ -206,7 +196,7 @@ pub struct Map {
|
|||||||
pub release_steps: Vec<Step>,
|
pub release_steps: Vec<Step>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct Step {
|
pub struct Step {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub key: Option<String>,
|
pub key: Option<String>,
|
||||||
@ -222,7 +212,7 @@ fn default_target() -> String {
|
|||||||
"others".into()
|
"others".into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct VideoFx {
|
pub struct VideoFx {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
#[serde(default = "default_true")]
|
#[serde(default = "default_true")]
|
||||||
@ -250,7 +240,7 @@ pub enum LayoutPreset {
|
|||||||
MainStrip,
|
MainStrip,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct Layout {
|
pub struct Layout {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub preset: LayoutPreset,
|
pub preset: LayoutPreset,
|
||||||
@ -273,23 +263,8 @@ pub struct Layout {
|
|||||||
pub slots: Vec<LayoutSlot>,
|
pub slots: Vec<LayoutSlot>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Layout {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
preset: LayoutPreset::MainStrip,
|
|
||||||
same_size: false,
|
|
||||||
main_at_bottom: false,
|
|
||||||
one_row: true,
|
|
||||||
pin: false,
|
|
||||||
auto_apply: true,
|
|
||||||
borderless: false,
|
|
||||||
monitor: String::new(),
|
|
||||||
slots: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct LayoutSlot {
|
pub struct LayoutSlot {
|
||||||
pub x: i32,
|
pub x: i32,
|
||||||
pub y: i32,
|
pub y: i32,
|
||||||
@ -302,7 +277,7 @@ fn default_fps() -> u32 {
|
|||||||
12
|
12
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
|
||||||
pub struct NormRect {
|
pub struct NormRect {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub x: f64,
|
pub x: f64,
|
||||||
@ -318,16 +293,6 @@ fn default_one() -> f64 {
|
|||||||
1.0
|
1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for NormRect {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
x: 0.0,
|
|
||||||
y: 0.0,
|
|
||||||
w: 0.28,
|
|
||||||
h: 0.28,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NormRect {
|
impl NormRect {
|
||||||
/// Values > 1 are pixels inside the window; otherwise fractions 0..=1 of the window.
|
/// Values > 1 are pixels inside the window; otherwise fractions 0..=1 of the window.
|
||||||
@ -410,13 +375,6 @@ impl Profile {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn passthrough_set(&self) -> Result<HashSet<String>> {
|
|
||||||
let mut set = HashSet::new();
|
|
||||||
for k in &self.passthrough {
|
|
||||||
set.insert(passthrough_id(k)?);
|
|
||||||
}
|
|
||||||
Ok(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resolve_bind(&self, name: &str) -> Result<String> {
|
pub fn resolve_bind(&self, name: &str) -> Result<String> {
|
||||||
self.game_binds
|
self.game_binds
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::engine::{Action, Engine, Hold};
|
use crate::engine::{Action, Engine, Hold};
|
||||||
use crate::hotkey::{self, passthrough_id};
|
use crate::hotkey;
|
||||||
use crate::hypr::{self, BindSpec, Client};
|
use crate::hypr::{self, BindSpec, Client};
|
||||||
use crate::overlay::OverlayHub;
|
use crate::overlay::OverlayHub;
|
||||||
use crate::profile::{runtime_dir, Mode, Profile};
|
use crate::profile::{runtime_dir, Mode, Profile};
|
||||||
@ -356,14 +356,9 @@ async fn on_event(session: &Arc<Mutex<Session>>, line: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn bind_specs(g: &Session) -> Result<Vec<BindSpec>> {
|
fn bind_specs(g: &Session) -> Result<Vec<BindSpec>> {
|
||||||
let passthrough = g.engine.profile.passthrough_set()?;
|
|
||||||
let mut specs = Vec::new();
|
let mut specs = Vec::new();
|
||||||
let bin = g.exe.display().to_string();
|
let bin = g.exe.display().to_string();
|
||||||
for m in &g.engine.profile.maps {
|
for m in &g.engine.profile.maps {
|
||||||
let id = passthrough_id(&m.hotkey.0).unwrap_or_else(|_| m.hotkey.0.clone());
|
|
||||||
if passthrough.contains(&id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let parsed = m.hotkey.parse()?;
|
let parsed = m.hotkey.parse()?;
|
||||||
specs.push(BindSpec {
|
specs.push(BindSpec {
|
||||||
bind: parsed.hypr_bind(),
|
bind: parsed.hypr_bind(),
|
||||||
@ -389,10 +384,6 @@ fn bind_specs(g: &Session) -> Result<Vec<BindSpec>> {
|
|||||||
g.engine.profile.repeater.keys.clone()
|
g.engine.profile.repeater.keys.clone()
|
||||||
};
|
};
|
||||||
for k in keys {
|
for k in keys {
|
||||||
let id = passthrough_id(&k).unwrap_or_else(|_| k.clone());
|
|
||||||
if passthrough.contains(&id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if g.engine.profile.map_by_hotkey(&k).is_some() {
|
if g.engine.profile.map_by_hotkey(&k).is_some() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -201,7 +201,6 @@ mod tests {
|
|||||||
client: "wow-retail".into(),
|
client: "wow-retail".into(),
|
||||||
slots: 2,
|
slots: 2,
|
||||||
window_match: Default::default(),
|
window_match: Default::default(),
|
||||||
passthrough: vec!["e".into(), "s".into(), "d".into(), "f".into()],
|
|
||||||
mode_default: Mode::Maps,
|
mode_default: Mode::Maps,
|
||||||
repeater: Default::default(),
|
repeater: Default::default(),
|
||||||
game_binds: BTreeMap::new(),
|
game_binds: BTreeMap::new(),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user