mirror of
https://github.com/YaLTeR/niri.git
synced 2024-10-26 20:04:05 +03:00
Compare commits
3 Commits
475b93595a
...
09f3f98cbc
Author | SHA1 | Date | |
---|---|---|---|
|
09f3f98cbc | ||
|
a283c34dbb | ||
|
65ebd4c8aa |
@ -48,8 +48,8 @@ pub struct Config {
|
|||||||
pub environment: Environment,
|
pub environment: Environment,
|
||||||
#[knuffel(children(name = "window-rule"))]
|
#[knuffel(children(name = "window-rule"))]
|
||||||
pub window_rules: Vec<WindowRule>,
|
pub window_rules: Vec<WindowRule>,
|
||||||
#[knuffel(child, default)]
|
#[knuffel(children(name = "binds"))]
|
||||||
pub binds: Binds,
|
pub binds: Vec<Binds>,
|
||||||
#[knuffel(child, default)]
|
#[knuffel(child, default)]
|
||||||
pub debug: DebugConfig,
|
pub debug: DebugConfig,
|
||||||
#[knuffel(children(name = "workspace"))]
|
#[knuffel(children(name = "workspace"))]
|
||||||
@ -906,8 +906,8 @@ pub struct BorderRule {
|
|||||||
pub inactive_gradient: Option<Gradient>,
|
pub inactive_gradient: Option<Gradient>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq)]
|
#[derive(Debug, Default, PartialEq, Clone)]
|
||||||
pub struct Binds(pub Vec<Bind>);
|
pub struct Binds(pub String, pub Vec<Bind>);
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Bind {
|
pub struct Bind {
|
||||||
@ -995,6 +995,8 @@ pub enum Action {
|
|||||||
MoveColumnRight,
|
MoveColumnRight,
|
||||||
MoveColumnToFirst,
|
MoveColumnToFirst,
|
||||||
MoveColumnToLast,
|
MoveColumnToLast,
|
||||||
|
MoveColumnLeftOrToMonitorLeft,
|
||||||
|
MoveColumnRightOrToMonitorRight,
|
||||||
MoveWindowDown,
|
MoveWindowDown,
|
||||||
MoveWindowUp,
|
MoveWindowUp,
|
||||||
MoveWindowDownOrToWorkspaceDown,
|
MoveWindowDownOrToWorkspaceDown,
|
||||||
@ -1039,6 +1041,7 @@ pub enum Action {
|
|||||||
MoveWorkspaceToMonitorRight,
|
MoveWorkspaceToMonitorRight,
|
||||||
MoveWorkspaceToMonitorDown,
|
MoveWorkspaceToMonitorDown,
|
||||||
MoveWorkspaceToMonitorUp,
|
MoveWorkspaceToMonitorUp,
|
||||||
|
BindingMode(#[knuffel(argument, str)] String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<niri_ipc::Action> for Action {
|
impl From<niri_ipc::Action> for Action {
|
||||||
@ -1075,6 +1078,10 @@ impl From<niri_ipc::Action> for Action {
|
|||||||
niri_ipc::Action::MoveColumnRight => Self::MoveColumnRight,
|
niri_ipc::Action::MoveColumnRight => Self::MoveColumnRight,
|
||||||
niri_ipc::Action::MoveColumnToFirst => Self::MoveColumnToFirst,
|
niri_ipc::Action::MoveColumnToFirst => Self::MoveColumnToFirst,
|
||||||
niri_ipc::Action::MoveColumnToLast => Self::MoveColumnToLast,
|
niri_ipc::Action::MoveColumnToLast => Self::MoveColumnToLast,
|
||||||
|
niri_ipc::Action::MoveColumnLeftOrToMonitorLeft => Self::MoveColumnLeftOrToMonitorLeft,
|
||||||
|
niri_ipc::Action::MoveColumnRightOrToMonitorRight => {
|
||||||
|
Self::MoveColumnRightOrToMonitorRight
|
||||||
|
}
|
||||||
niri_ipc::Action::MoveWindowDown => Self::MoveWindowDown,
|
niri_ipc::Action::MoveWindowDown => Self::MoveWindowDown,
|
||||||
niri_ipc::Action::MoveWindowUp => Self::MoveWindowUp,
|
niri_ipc::Action::MoveWindowUp => Self::MoveWindowUp,
|
||||||
niri_ipc::Action::MoveWindowDownOrToWorkspaceDown => {
|
niri_ipc::Action::MoveWindowDownOrToWorkspaceDown => {
|
||||||
@ -2187,7 +2194,11 @@ where
|
|||||||
node: &knuffel::ast::SpannedNode<S>,
|
node: &knuffel::ast::SpannedNode<S>,
|
||||||
ctx: &mut knuffel::decode::Context<S>,
|
ctx: &mut knuffel::decode::Context<S>,
|
||||||
) -> Result<Self, DecodeError<S>> {
|
) -> Result<Self, DecodeError<S>> {
|
||||||
expect_only_children(node, ctx);
|
let mode_name = node
|
||||||
|
.arguments
|
||||||
|
.first()
|
||||||
|
.map(|e| knuffel::DecodeScalar::decode(e, ctx))
|
||||||
|
.unwrap_or_else(|| Ok(String::from("default")))?;
|
||||||
|
|
||||||
let mut seen_keys = HashSet::new();
|
let mut seen_keys = HashSet::new();
|
||||||
|
|
||||||
@ -2237,7 +2248,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self(binds))
|
Ok(Self(mode_name, binds))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2915,100 +2926,105 @@ mod tests {
|
|||||||
open_on_output: None,
|
open_on_output: None,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
binds: Binds(vec![
|
binds: vec![Binds(
|
||||||
Bind {
|
"default".to_string(),
|
||||||
key: Key {
|
vec![
|
||||||
trigger: Trigger::Keysym(Keysym::t),
|
Bind {
|
||||||
modifiers: Modifiers::COMPOSITOR,
|
key: Key {
|
||||||
|
trigger: Trigger::Keysym(Keysym::t),
|
||||||
|
modifiers: Modifiers::COMPOSITOR,
|
||||||
|
},
|
||||||
|
action: Action::Spawn(vec!["alacritty".to_owned()]),
|
||||||
|
repeat: true,
|
||||||
|
cooldown: None,
|
||||||
|
allow_when_locked: true,
|
||||||
},
|
},
|
||||||
action: Action::Spawn(vec!["alacritty".to_owned()]),
|
Bind {
|
||||||
repeat: true,
|
key: Key {
|
||||||
cooldown: None,
|
trigger: Trigger::Keysym(Keysym::q),
|
||||||
allow_when_locked: true,
|
modifiers: Modifiers::COMPOSITOR,
|
||||||
},
|
},
|
||||||
Bind {
|
action: Action::CloseWindow,
|
||||||
key: Key {
|
repeat: true,
|
||||||
trigger: Trigger::Keysym(Keysym::q),
|
cooldown: None,
|
||||||
modifiers: Modifiers::COMPOSITOR,
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::CloseWindow,
|
Bind {
|
||||||
repeat: true,
|
key: Key {
|
||||||
cooldown: None,
|
trigger: Trigger::Keysym(Keysym::h),
|
||||||
allow_when_locked: false,
|
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT,
|
||||||
},
|
},
|
||||||
Bind {
|
action: Action::FocusMonitorLeft,
|
||||||
key: Key {
|
repeat: true,
|
||||||
trigger: Trigger::Keysym(Keysym::h),
|
cooldown: None,
|
||||||
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT,
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::FocusMonitorLeft,
|
Bind {
|
||||||
repeat: true,
|
key: Key {
|
||||||
cooldown: None,
|
trigger: Trigger::Keysym(Keysym::l),
|
||||||
allow_when_locked: false,
|
modifiers: Modifiers::COMPOSITOR
|
||||||
},
|
| Modifiers::SHIFT
|
||||||
Bind {
|
| Modifiers::CTRL,
|
||||||
key: Key {
|
},
|
||||||
trigger: Trigger::Keysym(Keysym::l),
|
action: Action::MoveWindowToMonitorRight,
|
||||||
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT | Modifiers::CTRL,
|
repeat: true,
|
||||||
|
cooldown: None,
|
||||||
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::MoveWindowToMonitorRight,
|
Bind {
|
||||||
repeat: true,
|
key: Key {
|
||||||
cooldown: None,
|
trigger: Trigger::Keysym(Keysym::comma),
|
||||||
allow_when_locked: false,
|
modifiers: Modifiers::COMPOSITOR,
|
||||||
},
|
},
|
||||||
Bind {
|
action: Action::ConsumeWindowIntoColumn,
|
||||||
key: Key {
|
repeat: true,
|
||||||
trigger: Trigger::Keysym(Keysym::comma),
|
cooldown: None,
|
||||||
modifiers: Modifiers::COMPOSITOR,
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::ConsumeWindowIntoColumn,
|
Bind {
|
||||||
repeat: true,
|
key: Key {
|
||||||
cooldown: None,
|
trigger: Trigger::Keysym(Keysym::_1),
|
||||||
allow_when_locked: false,
|
modifiers: Modifiers::COMPOSITOR,
|
||||||
},
|
},
|
||||||
Bind {
|
action: Action::FocusWorkspace(WorkspaceReference::Index(1)),
|
||||||
key: Key {
|
repeat: true,
|
||||||
trigger: Trigger::Keysym(Keysym::_1),
|
cooldown: None,
|
||||||
modifiers: Modifiers::COMPOSITOR,
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::FocusWorkspace(WorkspaceReference::Index(1)),
|
Bind {
|
||||||
repeat: true,
|
key: Key {
|
||||||
cooldown: None,
|
trigger: Trigger::Keysym(Keysym::_1),
|
||||||
allow_when_locked: false,
|
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT,
|
||||||
},
|
},
|
||||||
Bind {
|
action: Action::FocusWorkspace(WorkspaceReference::Name(
|
||||||
key: Key {
|
"workspace-1".to_string(),
|
||||||
trigger: Trigger::Keysym(Keysym::_1),
|
)),
|
||||||
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT,
|
repeat: true,
|
||||||
|
cooldown: None,
|
||||||
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::FocusWorkspace(WorkspaceReference::Name(
|
Bind {
|
||||||
"workspace-1".to_string(),
|
key: Key {
|
||||||
)),
|
trigger: Trigger::Keysym(Keysym::e),
|
||||||
repeat: true,
|
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT,
|
||||||
cooldown: None,
|
},
|
||||||
allow_when_locked: false,
|
action: Action::Quit(true),
|
||||||
},
|
repeat: true,
|
||||||
Bind {
|
cooldown: None,
|
||||||
key: Key {
|
allow_when_locked: false,
|
||||||
trigger: Trigger::Keysym(Keysym::e),
|
|
||||||
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT,
|
|
||||||
},
|
},
|
||||||
action: Action::Quit(true),
|
Bind {
|
||||||
repeat: true,
|
key: Key {
|
||||||
cooldown: None,
|
trigger: Trigger::WheelScrollDown,
|
||||||
allow_when_locked: false,
|
modifiers: Modifiers::COMPOSITOR,
|
||||||
},
|
},
|
||||||
Bind {
|
action: Action::FocusWorkspaceDown,
|
||||||
key: Key {
|
repeat: true,
|
||||||
trigger: Trigger::WheelScrollDown,
|
cooldown: Some(Duration::from_millis(150)),
|
||||||
modifiers: Modifiers::COMPOSITOR,
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::FocusWorkspaceDown,
|
],
|
||||||
repeat: true,
|
)],
|
||||||
cooldown: Some(Duration::from_millis(150)),
|
|
||||||
allow_when_locked: false,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
debug: DebugConfig {
|
debug: DebugConfig {
|
||||||
render_drm_device: Some(PathBuf::from("/dev/dri/renderD129")),
|
render_drm_device: Some(PathBuf::from("/dev/dri/renderD129")),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -3103,4 +3119,20 @@ mod tests {
|
|||||||
assert_eq!(config.input.keyboard.repeat_delay, 600);
|
assert_eq!(config.input.keyboard.repeat_delay, 600);
|
||||||
assert_eq!(config.input.keyboard.repeat_rate, 25);
|
assert_eq!(config.input.keyboard.repeat_rate, 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn binding_modes() {
|
||||||
|
Config::parse(
|
||||||
|
"",
|
||||||
|
r##"
|
||||||
|
binds {
|
||||||
|
A { binding-mode "test"; }
|
||||||
|
}
|
||||||
|
binds "test" {
|
||||||
|
B { binding-mode "default"; }
|
||||||
|
}
|
||||||
|
"##,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,8 @@ pub enum Request {
|
|||||||
FocusedOutput,
|
FocusedOutput,
|
||||||
/// Respond with an error (for testing error handling).
|
/// Respond with an error (for testing error handling).
|
||||||
ReturnError,
|
ReturnError,
|
||||||
|
/// Request name of the current binding mode.
|
||||||
|
BindingMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reply from niri to client.
|
/// Reply from niri to client.
|
||||||
@ -68,6 +70,8 @@ pub enum Response {
|
|||||||
Workspaces(Vec<Workspace>),
|
Workspaces(Vec<Workspace>),
|
||||||
/// Information about the focused output.
|
/// Information about the focused output.
|
||||||
FocusedOutput(Option<Output>),
|
FocusedOutput(Option<Output>),
|
||||||
|
/// Name of the current binding mode.
|
||||||
|
BindingMode(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Actions that niri can perform.
|
/// Actions that niri can perform.
|
||||||
@ -152,6 +156,10 @@ pub enum Action {
|
|||||||
MoveColumnToFirst,
|
MoveColumnToFirst,
|
||||||
/// Move the focused column to the end of the workspace.
|
/// Move the focused column to the end of the workspace.
|
||||||
MoveColumnToLast,
|
MoveColumnToLast,
|
||||||
|
/// Move the focused column to the left or to the monitor to the left.
|
||||||
|
MoveColumnLeftOrToMonitorLeft,
|
||||||
|
/// Move the focused column to the right or to the monitor to the right.
|
||||||
|
MoveColumnRightOrToMonitorRight,
|
||||||
/// Move the focused window down in a column.
|
/// Move the focused window down in a column.
|
||||||
MoveWindowDown,
|
MoveWindowDown,
|
||||||
/// Move the focused window up in a column.
|
/// Move the focused window up in a column.
|
||||||
|
@ -90,4 +90,6 @@ pub enum Msg {
|
|||||||
Version,
|
Version,
|
||||||
/// Request an error from the running niri instance.
|
/// Request an error from the running niri instance.
|
||||||
RequestError,
|
RequestError,
|
||||||
|
/// Get the binding mode name.
|
||||||
|
BindingMode,
|
||||||
}
|
}
|
||||||
|
191
src/input/mod.rs
191
src/input/mod.rs
@ -314,7 +314,7 @@ impl State {
|
|||||||
serial,
|
serial,
|
||||||
time,
|
time,
|
||||||
|this, mods, keysym| {
|
|this, mods, keysym| {
|
||||||
let bindings = &this.niri.config.borrow().binds;
|
let bindings = &this.niri.binding_mode;
|
||||||
let key_code = event.key_code();
|
let key_code = event.key_code();
|
||||||
let modified = keysym.modified_sym();
|
let modified = keysym.modified_sym();
|
||||||
let raw = keysym.raw_latin_sym_or_raw_current_sym();
|
let raw = keysym.raw_latin_sym_or_raw_current_sym();
|
||||||
@ -571,6 +571,40 @@ impl State {
|
|||||||
// FIXME: granular
|
// FIXME: granular
|
||||||
self.niri.queue_redraw_all();
|
self.niri.queue_redraw_all();
|
||||||
}
|
}
|
||||||
|
Action::MoveColumnLeftOrToMonitorLeft => {
|
||||||
|
if let Some(output) = self.niri.output_left() {
|
||||||
|
if self.niri.layout.move_column_left_or_to_output(&output)
|
||||||
|
&& !self.maybe_warp_cursor_to_focus_centered()
|
||||||
|
{
|
||||||
|
self.move_cursor_to_output(&output);
|
||||||
|
} else {
|
||||||
|
self.maybe_warp_cursor_to_focus();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.niri.layout.move_left();
|
||||||
|
self.maybe_warp_cursor_to_focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: granular
|
||||||
|
self.niri.queue_redraw_all();
|
||||||
|
}
|
||||||
|
Action::MoveColumnRightOrToMonitorRight => {
|
||||||
|
if let Some(output) = self.niri.output_right() {
|
||||||
|
if self.niri.layout.move_column_right_or_to_output(&output)
|
||||||
|
&& !self.maybe_warp_cursor_to_focus_centered()
|
||||||
|
{
|
||||||
|
self.move_cursor_to_output(&output);
|
||||||
|
} else {
|
||||||
|
self.maybe_warp_cursor_to_focus();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.niri.layout.move_right();
|
||||||
|
self.maybe_warp_cursor_to_focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: granular
|
||||||
|
self.niri.queue_redraw_all();
|
||||||
|
}
|
||||||
Action::MoveWindowDown => {
|
Action::MoveWindowDown => {
|
||||||
self.niri.layout.move_down();
|
self.niri.layout.move_down();
|
||||||
self.maybe_warp_cursor_to_focus();
|
self.maybe_warp_cursor_to_focus();
|
||||||
@ -1043,6 +1077,11 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Action::BindingMode(name) => {
|
||||||
|
if let Some(mode) = self.niri.config.borrow().binds.iter().find(|e| e.0 == name) {
|
||||||
|
self.niri.binding_mode = mode.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1466,13 +1505,11 @@ impl State {
|
|||||||
let horizontal = horizontal_amount_v120.unwrap_or(0.);
|
let horizontal = horizontal_amount_v120.unwrap_or(0.);
|
||||||
let ticks = self.niri.horizontal_wheel_tracker.accumulate(horizontal);
|
let ticks = self.niri.horizontal_wheel_tracker.accumulate(horizontal);
|
||||||
if ticks != 0 {
|
if ticks != 0 {
|
||||||
let config = self.niri.config.borrow();
|
let bindings = &self.niri.binding_mode;
|
||||||
let bindings = &config.binds;
|
|
||||||
let bind_left =
|
let bind_left =
|
||||||
find_configured_bind(bindings, comp_mod, Trigger::WheelScrollLeft, mods);
|
find_configured_bind(bindings, comp_mod, Trigger::WheelScrollLeft, mods);
|
||||||
let bind_right =
|
let bind_right =
|
||||||
find_configured_bind(bindings, comp_mod, Trigger::WheelScrollRight, mods);
|
find_configured_bind(bindings, comp_mod, Trigger::WheelScrollRight, mods);
|
||||||
drop(config);
|
|
||||||
|
|
||||||
if let Some(right) = bind_right {
|
if let Some(right) = bind_right {
|
||||||
for _ in 0..ticks {
|
for _ in 0..ticks {
|
||||||
@ -1489,13 +1526,11 @@ impl State {
|
|||||||
let vertical = vertical_amount_v120.unwrap_or(0.);
|
let vertical = vertical_amount_v120.unwrap_or(0.);
|
||||||
let ticks = self.niri.vertical_wheel_tracker.accumulate(vertical);
|
let ticks = self.niri.vertical_wheel_tracker.accumulate(vertical);
|
||||||
if ticks != 0 {
|
if ticks != 0 {
|
||||||
let config = self.niri.config.borrow();
|
let bindings = &self.niri.binding_mode;
|
||||||
let bindings = &config.binds;
|
|
||||||
let bind_up =
|
let bind_up =
|
||||||
find_configured_bind(bindings, comp_mod, Trigger::WheelScrollUp, mods);
|
find_configured_bind(bindings, comp_mod, Trigger::WheelScrollUp, mods);
|
||||||
let bind_down =
|
let bind_down =
|
||||||
find_configured_bind(bindings, comp_mod, Trigger::WheelScrollDown, mods);
|
find_configured_bind(bindings, comp_mod, Trigger::WheelScrollDown, mods);
|
||||||
drop(config);
|
|
||||||
|
|
||||||
if let Some(down) = bind_down {
|
if let Some(down) = bind_down {
|
||||||
for _ in 0..ticks {
|
for _ in 0..ticks {
|
||||||
@ -1532,8 +1567,7 @@ impl State {
|
|||||||
.horizontal_finger_scroll_tracker
|
.horizontal_finger_scroll_tracker
|
||||||
.accumulate(horizontal);
|
.accumulate(horizontal);
|
||||||
if ticks != 0 {
|
if ticks != 0 {
|
||||||
let config = self.niri.config.borrow();
|
let bindings = &self.niri.binding_mode;
|
||||||
let bindings = &config.binds;
|
|
||||||
let bind_left =
|
let bind_left =
|
||||||
find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollLeft, mods);
|
find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollLeft, mods);
|
||||||
let bind_right = find_configured_bind(
|
let bind_right = find_configured_bind(
|
||||||
@ -1542,7 +1576,6 @@ impl State {
|
|||||||
Trigger::TouchpadScrollRight,
|
Trigger::TouchpadScrollRight,
|
||||||
mods,
|
mods,
|
||||||
);
|
);
|
||||||
drop(config);
|
|
||||||
|
|
||||||
if let Some(right) = bind_right {
|
if let Some(right) = bind_right {
|
||||||
for _ in 0..ticks {
|
for _ in 0..ticks {
|
||||||
@ -1562,13 +1595,11 @@ impl State {
|
|||||||
.vertical_finger_scroll_tracker
|
.vertical_finger_scroll_tracker
|
||||||
.accumulate(vertical);
|
.accumulate(vertical);
|
||||||
if ticks != 0 {
|
if ticks != 0 {
|
||||||
let config = self.niri.config.borrow();
|
let bindings = &self.niri.binding_mode;
|
||||||
let bindings = &config.binds;
|
|
||||||
let bind_up =
|
let bind_up =
|
||||||
find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollUp, mods);
|
find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollUp, mods);
|
||||||
let bind_down =
|
let bind_down =
|
||||||
find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollDown, mods);
|
find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollDown, mods);
|
||||||
drop(config);
|
|
||||||
|
|
||||||
if let Some(down) = bind_down {
|
if let Some(down) = bind_down {
|
||||||
for _ in 0..ticks {
|
for _ in 0..ticks {
|
||||||
@ -2256,7 +2287,7 @@ fn find_configured_bind(
|
|||||||
modifiers |= Modifiers::COMPOSITOR;
|
modifiers |= Modifiers::COMPOSITOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for bind in &bindings.0 {
|
for bind in &bindings.1 {
|
||||||
if bind.key.trigger != trigger {
|
if bind.key.trigger != trigger {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2505,7 +2536,7 @@ pub fn mods_with_binds(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut rv = HashSet::new();
|
let mut rv = HashSet::new();
|
||||||
for bind in &binds.0 {
|
for bind in &binds.1 {
|
||||||
if !triggers.iter().any(|trigger| bind.key.trigger == *trigger) {
|
if !triggers.iter().any(|trigger| bind.key.trigger == *trigger) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2555,16 +2586,19 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn bindings_suppress_keys() {
|
fn bindings_suppress_keys() {
|
||||||
let close_keysym = Keysym::q;
|
let close_keysym = Keysym::q;
|
||||||
let bindings = Binds(vec![Bind {
|
let bindings = Binds(
|
||||||
key: Key {
|
String::from("default"),
|
||||||
trigger: Trigger::Keysym(close_keysym),
|
vec![Bind {
|
||||||
modifiers: Modifiers::COMPOSITOR | Modifiers::CTRL,
|
key: Key {
|
||||||
},
|
trigger: Trigger::Keysym(close_keysym),
|
||||||
action: Action::CloseWindow,
|
modifiers: Modifiers::COMPOSITOR | Modifiers::CTRL,
|
||||||
repeat: true,
|
},
|
||||||
cooldown: None,
|
action: Action::CloseWindow,
|
||||||
allow_when_locked: false,
|
repeat: true,
|
||||||
}]);
|
cooldown: None,
|
||||||
|
allow_when_locked: false,
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
|
||||||
let comp_mod = CompositorMod::Super;
|
let comp_mod = CompositorMod::Super;
|
||||||
let mut suppressed_keys = HashSet::new();
|
let mut suppressed_keys = HashSet::new();
|
||||||
@ -2688,58 +2722,61 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn comp_mod_handling() {
|
fn comp_mod_handling() {
|
||||||
let bindings = Binds(vec![
|
let bindings = Binds(
|
||||||
Bind {
|
String::from("default"),
|
||||||
key: Key {
|
vec![
|
||||||
trigger: Trigger::Keysym(Keysym::q),
|
Bind {
|
||||||
modifiers: Modifiers::COMPOSITOR,
|
key: Key {
|
||||||
|
trigger: Trigger::Keysym(Keysym::q),
|
||||||
|
modifiers: Modifiers::COMPOSITOR,
|
||||||
|
},
|
||||||
|
action: Action::CloseWindow,
|
||||||
|
repeat: true,
|
||||||
|
cooldown: None,
|
||||||
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::CloseWindow,
|
Bind {
|
||||||
repeat: true,
|
key: Key {
|
||||||
cooldown: None,
|
trigger: Trigger::Keysym(Keysym::h),
|
||||||
allow_when_locked: false,
|
modifiers: Modifiers::SUPER,
|
||||||
},
|
},
|
||||||
Bind {
|
action: Action::FocusColumnLeft,
|
||||||
key: Key {
|
repeat: true,
|
||||||
trigger: Trigger::Keysym(Keysym::h),
|
cooldown: None,
|
||||||
modifiers: Modifiers::SUPER,
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::FocusColumnLeft,
|
Bind {
|
||||||
repeat: true,
|
key: Key {
|
||||||
cooldown: None,
|
trigger: Trigger::Keysym(Keysym::j),
|
||||||
allow_when_locked: false,
|
modifiers: Modifiers::empty(),
|
||||||
},
|
},
|
||||||
Bind {
|
action: Action::FocusWindowDown,
|
||||||
key: Key {
|
repeat: true,
|
||||||
trigger: Trigger::Keysym(Keysym::j),
|
cooldown: None,
|
||||||
modifiers: Modifiers::empty(),
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::FocusWindowDown,
|
Bind {
|
||||||
repeat: true,
|
key: Key {
|
||||||
cooldown: None,
|
trigger: Trigger::Keysym(Keysym::k),
|
||||||
allow_when_locked: false,
|
modifiers: Modifiers::COMPOSITOR | Modifiers::SUPER,
|
||||||
},
|
},
|
||||||
Bind {
|
action: Action::FocusWindowUp,
|
||||||
key: Key {
|
repeat: true,
|
||||||
trigger: Trigger::Keysym(Keysym::k),
|
cooldown: None,
|
||||||
modifiers: Modifiers::COMPOSITOR | Modifiers::SUPER,
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::FocusWindowUp,
|
Bind {
|
||||||
repeat: true,
|
key: Key {
|
||||||
cooldown: None,
|
trigger: Trigger::Keysym(Keysym::l),
|
||||||
allow_when_locked: false,
|
modifiers: Modifiers::SUPER | Modifiers::ALT,
|
||||||
},
|
},
|
||||||
Bind {
|
action: Action::FocusColumnRight,
|
||||||
key: Key {
|
repeat: true,
|
||||||
trigger: Trigger::Keysym(Keysym::l),
|
cooldown: None,
|
||||||
modifiers: Modifiers::SUPER | Modifiers::ALT,
|
allow_when_locked: false,
|
||||||
},
|
},
|
||||||
action: Action::FocusColumnRight,
|
],
|
||||||
repeat: true,
|
);
|
||||||
cooldown: None,
|
|
||||||
allow_when_locked: false,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
find_configured_bind(
|
find_configured_bind(
|
||||||
@ -2752,7 +2789,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
Some(&bindings.0[0])
|
Some(&bindings.1[0])
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
find_configured_bind(
|
find_configured_bind(
|
||||||
@ -2775,7 +2812,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
Some(&bindings.0[1])
|
Some(&bindings.1[1])
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
find_configured_bind(
|
find_configured_bind(
|
||||||
@ -2807,7 +2844,7 @@ mod tests {
|
|||||||
ModifiersState::default(),
|
ModifiersState::default(),
|
||||||
)
|
)
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
Some(&bindings.0[2])
|
Some(&bindings.1[2])
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -2821,7 +2858,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
Some(&bindings.0[3])
|
Some(&bindings.1[3])
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
find_configured_bind(
|
find_configured_bind(
|
||||||
@ -2845,7 +2882,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
Some(&bindings.0[4])
|
Some(&bindings.1[4])
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
find_configured_bind(
|
find_configured_bind(
|
||||||
|
@ -20,6 +20,7 @@ pub fn handle_msg(msg: Msg, json: bool) -> anyhow::Result<()> {
|
|||||||
},
|
},
|
||||||
Msg::Workspaces => Request::Workspaces,
|
Msg::Workspaces => Request::Workspaces,
|
||||||
Msg::RequestError => Request::ReturnError,
|
Msg::RequestError => Request::ReturnError,
|
||||||
|
Msg::BindingMode => Request::BindingMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
let socket = Socket::connect().context("error connecting to the niri socket")?;
|
let socket = Socket::connect().context("error connecting to the niri socket")?;
|
||||||
@ -238,6 +239,19 @@ pub fn handle_msg(msg: Msg, json: bool) -> anyhow::Result<()> {
|
|||||||
println!("{is_active}{idx}{name}");
|
println!("{is_active}{idx}{name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Msg::BindingMode => {
|
||||||
|
let Response::BindingMode(response) = response else {
|
||||||
|
bail!("unexpected response: expected BindingMode, got {response:?}");
|
||||||
|
};
|
||||||
|
|
||||||
|
if json {
|
||||||
|
let response =
|
||||||
|
serde_json::to_string(&response).context("error formatting response")?;
|
||||||
|
println!("{response}");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
println!("{response}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -235,6 +235,16 @@ async fn process(ctx: &ClientCtx, request: Request) -> Reply {
|
|||||||
let output = result.map_err(|_| String::from("error getting active output info"))?;
|
let output = result.map_err(|_| String::from("error getting active output info"))?;
|
||||||
Response::FocusedOutput(output)
|
Response::FocusedOutput(output)
|
||||||
}
|
}
|
||||||
|
Request::BindingMode => {
|
||||||
|
let (tx, rx) = async_channel::bounded(1);
|
||||||
|
ctx.event_loop.insert_idle(move |state| {
|
||||||
|
let workspaces = state.niri.binding_mode.0.clone();
|
||||||
|
let _ = tx.send_blocking(workspaces);
|
||||||
|
});
|
||||||
|
let result = rx.recv().await;
|
||||||
|
let mode = result.map_err(|_| String::from("error getting workspace info"))?;
|
||||||
|
Response::BindingMode(mode.clone())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(response)
|
Ok(response)
|
||||||
|
@ -1196,6 +1196,36 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
monitor.move_column_to_last();
|
monitor.move_column_to_last();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn move_column_left_or_to_output(&mut self, output: &Output) -> bool {
|
||||||
|
if let Some(monitor) = self.active_monitor() {
|
||||||
|
let workspace = monitor.active_workspace();
|
||||||
|
let curr_idx = workspace.active_column_idx;
|
||||||
|
|
||||||
|
if !workspace.columns.is_empty() && curr_idx != 0 {
|
||||||
|
monitor.move_left();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.move_column_to_output(output);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn move_column_right_or_to_output(&mut self, output: &Output) -> bool {
|
||||||
|
if let Some(monitor) = self.active_monitor() {
|
||||||
|
let workspace = monitor.active_workspace();
|
||||||
|
let curr_idx = workspace.active_column_idx;
|
||||||
|
|
||||||
|
if !workspace.columns.is_empty() && curr_idx != workspace.columns.len() - 1 {
|
||||||
|
monitor.move_right();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.move_column_to_output(output);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
pub fn move_down(&mut self) {
|
pub fn move_down(&mut self) {
|
||||||
let Some(monitor) = self.active_monitor() else {
|
let Some(monitor) = self.active_monitor() else {
|
||||||
return;
|
return;
|
||||||
@ -2797,6 +2827,8 @@ mod tests {
|
|||||||
MoveColumnRight,
|
MoveColumnRight,
|
||||||
MoveColumnToFirst,
|
MoveColumnToFirst,
|
||||||
MoveColumnToLast,
|
MoveColumnToLast,
|
||||||
|
MoveColumnLeftOrToMonitorLeft(#[proptest(strategy = "1..=2u8")] u8),
|
||||||
|
MoveColumnRightOrToMonitorRight(#[proptest(strategy = "1..=2u8")] u8),
|
||||||
MoveWindowDown,
|
MoveWindowDown,
|
||||||
MoveWindowUp,
|
MoveWindowUp,
|
||||||
MoveWindowDownOrToWorkspaceDown,
|
MoveWindowDownOrToWorkspaceDown,
|
||||||
@ -3154,6 +3186,22 @@ mod tests {
|
|||||||
Op::MoveColumnRight => layout.move_right(),
|
Op::MoveColumnRight => layout.move_right(),
|
||||||
Op::MoveColumnToFirst => layout.move_column_to_first(),
|
Op::MoveColumnToFirst => layout.move_column_to_first(),
|
||||||
Op::MoveColumnToLast => layout.move_column_to_last(),
|
Op::MoveColumnToLast => layout.move_column_to_last(),
|
||||||
|
Op::MoveColumnLeftOrToMonitorLeft(id) => {
|
||||||
|
let name = format!("output{id}");
|
||||||
|
let Some(output) = layout.outputs().find(|o| o.name() == name).cloned() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout.move_column_left_or_to_output(&output);
|
||||||
|
}
|
||||||
|
Op::MoveColumnRightOrToMonitorRight(id) => {
|
||||||
|
let name = format!("output{id}");
|
||||||
|
let Some(output) = layout.outputs().find(|o| o.name() == name).cloned() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout.move_column_right_or_to_output(&output);
|
||||||
|
}
|
||||||
Op::MoveWindowDown => layout.move_down(),
|
Op::MoveWindowDown => layout.move_down(),
|
||||||
Op::MoveWindowUp => layout.move_up(),
|
Op::MoveWindowUp => layout.move_up(),
|
||||||
Op::MoveWindowDownOrToWorkspaceDown => layout.move_down_or_to_workspace_down(),
|
Op::MoveWindowDownOrToWorkspaceDown => layout.move_down_or_to_workspace_down(),
|
||||||
@ -3384,6 +3432,8 @@ mod tests {
|
|||||||
Op::FocusWindowOrWorkspaceDown,
|
Op::FocusWindowOrWorkspaceDown,
|
||||||
Op::MoveColumnLeft,
|
Op::MoveColumnLeft,
|
||||||
Op::MoveColumnRight,
|
Op::MoveColumnRight,
|
||||||
|
Op::MoveColumnLeftOrToMonitorLeft(0),
|
||||||
|
Op::MoveColumnRightOrToMonitorRight(1),
|
||||||
Op::ConsumeWindowIntoColumn,
|
Op::ConsumeWindowIntoColumn,
|
||||||
Op::ExpelWindowFromColumn,
|
Op::ExpelWindowFromColumn,
|
||||||
Op::CenterColumn,
|
Op::CenterColumn,
|
||||||
@ -3563,6 +3613,8 @@ mod tests {
|
|||||||
Op::FocusWindowOrWorkspaceDown,
|
Op::FocusWindowOrWorkspaceDown,
|
||||||
Op::MoveColumnLeft,
|
Op::MoveColumnLeft,
|
||||||
Op::MoveColumnRight,
|
Op::MoveColumnRight,
|
||||||
|
Op::MoveColumnLeftOrToMonitorLeft(0),
|
||||||
|
Op::MoveColumnRightOrToMonitorRight(1),
|
||||||
Op::ConsumeWindowIntoColumn,
|
Op::ConsumeWindowIntoColumn,
|
||||||
Op::ExpelWindowFromColumn,
|
Op::ExpelWindowFromColumn,
|
||||||
Op::CenterColumn,
|
Op::CenterColumn,
|
||||||
|
25
src/niri.rs
25
src/niri.rs
@ -152,6 +152,8 @@ const FRAME_CALLBACK_THROTTLE: Option<Duration> = Some(Duration::from_millis(995
|
|||||||
pub struct Niri {
|
pub struct Niri {
|
||||||
pub config: Rc<RefCell<Config>>,
|
pub config: Rc<RefCell<Config>>,
|
||||||
|
|
||||||
|
pub binding_mode: niri_config::Binds,
|
||||||
|
|
||||||
/// Output config from the config file.
|
/// Output config from the config file.
|
||||||
///
|
///
|
||||||
/// This does not include transient output config changes done via IPC. It is only used when
|
/// This does not include transient output config changes done via IPC. It is only used when
|
||||||
@ -992,9 +994,9 @@ impl State {
|
|||||||
if config.binds != old_config.binds {
|
if config.binds != old_config.binds {
|
||||||
self.niri.hotkey_overlay.on_hotkey_config_updated();
|
self.niri.hotkey_overlay.on_hotkey_config_updated();
|
||||||
self.niri.mods_with_wheel_binds =
|
self.niri.mods_with_wheel_binds =
|
||||||
mods_with_wheel_binds(self.backend.mod_key(), &config.binds);
|
mods_with_wheel_binds(self.backend.mod_key(), &self.niri.binding_mode);
|
||||||
self.niri.mods_with_finger_scroll_binds =
|
self.niri.mods_with_finger_scroll_binds =
|
||||||
mods_with_finger_scroll_binds(self.backend.mod_key(), &config.binds);
|
mods_with_finger_scroll_binds(self.backend.mod_key(), &self.niri.binding_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.window_rules != old_config.window_rules {
|
if config.window_rules != old_config.window_rules {
|
||||||
@ -1477,6 +1479,13 @@ impl Niri {
|
|||||||
let config_ = config.borrow();
|
let config_ = config.borrow();
|
||||||
let config_file_output_config = config_.outputs.clone();
|
let config_file_output_config = config_.outputs.clone();
|
||||||
|
|
||||||
|
let binding_mode = config_
|
||||||
|
.binds
|
||||||
|
.iter()
|
||||||
|
.find(|e| e.0 == "default")
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(|| niri_config::Binds(String::from("default"), vec![]));
|
||||||
|
|
||||||
let layout = Layout::new(&config_);
|
let layout = Layout::new(&config_);
|
||||||
|
|
||||||
let compositor_state = CompositorState::new_v6::<State>(&display_handle);
|
let compositor_state = CompositorState::new_v6::<State>(&display_handle);
|
||||||
@ -1585,14 +1594,14 @@ impl Niri {
|
|||||||
let cursor_manager =
|
let cursor_manager =
|
||||||
CursorManager::new(&config_.cursor.xcursor_theme, config_.cursor.xcursor_size);
|
CursorManager::new(&config_.cursor.xcursor_theme, config_.cursor.xcursor_size);
|
||||||
|
|
||||||
let mods_with_wheel_binds = mods_with_wheel_binds(backend.mod_key(), &config_.binds);
|
let mods_with_wheel_binds = mods_with_wheel_binds(backend.mod_key(), &binding_mode);
|
||||||
let mods_with_finger_scroll_binds =
|
let mods_with_finger_scroll_binds =
|
||||||
mods_with_finger_scroll_binds(backend.mod_key(), &config_.binds);
|
mods_with_finger_scroll_binds(backend.mod_key(), &binding_mode);
|
||||||
|
|
||||||
let screenshot_ui = ScreenshotUi::new(config.clone());
|
let screenshot_ui = ScreenshotUi::new(config.clone());
|
||||||
let config_error_notification = ConfigErrorNotification::new(config.clone());
|
let config_error_notification = ConfigErrorNotification::new(config.clone());
|
||||||
|
|
||||||
let mut hotkey_overlay = HotkeyOverlay::new(config.clone(), backend.mod_key());
|
let mut hotkey_overlay = HotkeyOverlay::new(backend.mod_key());
|
||||||
if !config_.hotkey_overlay.skip_at_startup {
|
if !config_.hotkey_overlay.skip_at_startup {
|
||||||
hotkey_overlay.show();
|
hotkey_overlay.show();
|
||||||
}
|
}
|
||||||
@ -1674,6 +1683,7 @@ impl Niri {
|
|||||||
drop(config_);
|
drop(config_);
|
||||||
Self {
|
Self {
|
||||||
config,
|
config,
|
||||||
|
binding_mode,
|
||||||
config_file_output_config,
|
config_file_output_config,
|
||||||
|
|
||||||
event_loop,
|
event_loop,
|
||||||
@ -2880,7 +2890,10 @@ impl Niri {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw the hotkey overlay on top.
|
// Draw the hotkey overlay on top.
|
||||||
if let Some(element) = self.hotkey_overlay.render(renderer, output) {
|
if let Some(element) = self
|
||||||
|
.hotkey_overlay
|
||||||
|
.render(renderer, output, &self.binding_mode.1)
|
||||||
|
{
|
||||||
elements.push(element.into());
|
elements.push(element.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,9 +2,8 @@ use std::cell::RefCell;
|
|||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::iter::zip;
|
use std::iter::zip;
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use niri_config::{Action, Config, Key, Modifiers, Trigger};
|
use niri_config::{Action, Bind, Key, Modifiers, Trigger};
|
||||||
use pangocairo::cairo::{self, ImageSurface};
|
use pangocairo::cairo::{self, ImageSurface};
|
||||||
use pangocairo::pango::{AttrColor, AttrInt, AttrList, AttrString, FontDescription, Weight};
|
use pangocairo::pango::{AttrColor, AttrInt, AttrList, AttrString, FontDescription, Weight};
|
||||||
use smithay::backend::renderer::element::Kind;
|
use smithay::backend::renderer::element::Kind;
|
||||||
@ -29,7 +28,6 @@ const TITLE: &str = "Important Hotkeys";
|
|||||||
|
|
||||||
pub struct HotkeyOverlay {
|
pub struct HotkeyOverlay {
|
||||||
is_open: bool,
|
is_open: bool,
|
||||||
config: Rc<RefCell<Config>>,
|
|
||||||
comp_mod: CompositorMod,
|
comp_mod: CompositorMod,
|
||||||
buffers: RefCell<HashMap<WeakOutput, RenderedOverlay>>,
|
buffers: RefCell<HashMap<WeakOutput, RenderedOverlay>>,
|
||||||
}
|
}
|
||||||
@ -39,10 +37,9 @@ pub struct RenderedOverlay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HotkeyOverlay {
|
impl HotkeyOverlay {
|
||||||
pub fn new(config: Rc<RefCell<Config>>, comp_mod: CompositorMod) -> Self {
|
pub fn new(comp_mod: CompositorMod) -> Self {
|
||||||
Self {
|
Self {
|
||||||
is_open: false,
|
is_open: false,
|
||||||
config,
|
|
||||||
comp_mod,
|
comp_mod,
|
||||||
buffers: RefCell::new(HashMap::new()),
|
buffers: RefCell::new(HashMap::new()),
|
||||||
}
|
}
|
||||||
@ -78,6 +75,7 @@ impl HotkeyOverlay {
|
|||||||
&self,
|
&self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
|
binds: &[Bind],
|
||||||
) -> Option<PrimaryGpuTextureRenderElement> {
|
) -> Option<PrimaryGpuTextureRenderElement> {
|
||||||
if !self.is_open {
|
if !self.is_open {
|
||||||
return None;
|
return None;
|
||||||
@ -101,7 +99,7 @@ impl HotkeyOverlay {
|
|||||||
|
|
||||||
let rendered = buffers.entry(weak).or_insert_with(|| {
|
let rendered = buffers.entry(weak).or_insert_with(|| {
|
||||||
let renderer = renderer.as_gles_renderer();
|
let renderer = renderer.as_gles_renderer();
|
||||||
render(renderer, &self.config.borrow(), self.comp_mod, scale)
|
render(renderer, binds, self.comp_mod, scale)
|
||||||
.unwrap_or_else(|_| RenderedOverlay { buffer: None })
|
.unwrap_or_else(|_| RenderedOverlay { buffer: None })
|
||||||
});
|
});
|
||||||
let buffer = rendered.buffer.as_ref()?;
|
let buffer = rendered.buffer.as_ref()?;
|
||||||
@ -127,7 +125,7 @@ impl HotkeyOverlay {
|
|||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
renderer: &mut GlesRenderer,
|
renderer: &mut GlesRenderer,
|
||||||
config: &Config,
|
binds: &[niri_config::Bind],
|
||||||
comp_mod: CompositorMod,
|
comp_mod: CompositorMod,
|
||||||
scale: f64,
|
scale: f64,
|
||||||
) -> anyhow::Result<RenderedOverlay> {
|
) -> anyhow::Result<RenderedOverlay> {
|
||||||
@ -143,8 +141,6 @@ fn render(
|
|||||||
// target_size.h -= margin * 2;
|
// target_size.h -= margin * 2;
|
||||||
// anyhow::ensure!(target_size.w > 0 && target_size.h > 0);
|
// anyhow::ensure!(target_size.w > 0 && target_size.h > 0);
|
||||||
|
|
||||||
let binds = &config.binds.0;
|
|
||||||
|
|
||||||
// Collect actions that we want to show.
|
// Collect actions that we want to show.
|
||||||
let mut actions = vec![&Action::ShowHotkeyOverlay];
|
let mut actions = vec![&Action::ShowHotkeyOverlay];
|
||||||
|
|
||||||
@ -232,9 +228,7 @@ fn render(
|
|||||||
let strings = actions
|
let strings = actions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|action| {
|
.map(|action| {
|
||||||
let key = config
|
let key = binds
|
||||||
.binds
|
|
||||||
.0
|
|
||||||
.iter()
|
.iter()
|
||||||
.find(|bind| bind.action == *action)
|
.find(|bind| bind.action == *action)
|
||||||
.map(|bind| key_name(comp_mod, &bind.key))
|
.map(|bind| key_name(comp_mod, &bind.key))
|
||||||
|
Loading…
Reference in New Issue
Block a user