mirror of
https://github.com/YaLTeR/niri.git
synced 2024-10-26 20:04:05 +03:00
Compare commits
3 Commits
496525cf8c
...
0704e1e330
Author | SHA1 | Date | |
---|---|---|---|
|
0704e1e330 | ||
|
a283c34dbb | ||
|
f9fe86ee3e |
@ -995,6 +995,8 @@ pub enum Action {
|
|||||||
MoveColumnRight,
|
MoveColumnRight,
|
||||||
MoveColumnToFirst,
|
MoveColumnToFirst,
|
||||||
MoveColumnToLast,
|
MoveColumnToLast,
|
||||||
|
MoveColumnLeftOrToMonitorLeft,
|
||||||
|
MoveColumnRightOrToMonitorRight,
|
||||||
MoveWindowDown,
|
MoveWindowDown,
|
||||||
MoveWindowUp,
|
MoveWindowUp,
|
||||||
MoveWindowDownOrToWorkspaceDown,
|
MoveWindowDownOrToWorkspaceDown,
|
||||||
@ -1075,6 +1077,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 => {
|
||||||
|
@ -153,6 +153,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.
|
||||||
|
@ -405,6 +405,8 @@ impl Tty {
|
|||||||
self.device_changed(node.dev_id(), niri);
|
self.device_changed(node.dev_id(), niri);
|
||||||
|
|
||||||
// Apply pending gamma changes and restore our existing gamma.
|
// Apply pending gamma changes and restore our existing gamma.
|
||||||
|
//
|
||||||
|
// Also, restore our VRR.
|
||||||
let device = self.devices.get_mut(&node).unwrap();
|
let device = self.devices.get_mut(&node).unwrap();
|
||||||
for (crtc, surface) in device.surfaces.iter_mut() {
|
for (crtc, surface) in device.surfaces.iter_mut() {
|
||||||
if let Some(ramp) = surface.pending_gamma_change.take() {
|
if let Some(ramp) = surface.pending_gamma_change.take() {
|
||||||
@ -422,6 +424,45 @@ impl Tty {
|
|||||||
warn!("error restoring gamma: {err:?}");
|
warn!("error restoring gamma: {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore VRR.
|
||||||
|
let Some(connector) =
|
||||||
|
surface.compositor.pending_connectors().into_iter().next()
|
||||||
|
else {
|
||||||
|
error!("surface pending connectors is empty");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(connector) = device.drm_scanner.connectors().get(&connector)
|
||||||
|
else {
|
||||||
|
error!("missing enabled connector in drm_scanner");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let output = niri
|
||||||
|
.global_space
|
||||||
|
.outputs()
|
||||||
|
.find(|output| {
|
||||||
|
let tty_state: &TtyOutputState = output.user_data().get().unwrap();
|
||||||
|
tty_state.node == node && tty_state.crtc == *crtc
|
||||||
|
})
|
||||||
|
.cloned();
|
||||||
|
let Some(output) = output else {
|
||||||
|
error!("missing output for crtc: {crtc:?}");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(output_state) = niri.output_state.get_mut(&output) else {
|
||||||
|
error!("missing state for output {:?}", surface.name);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
try_to_change_vrr(
|
||||||
|
&device.drm,
|
||||||
|
connector,
|
||||||
|
*crtc,
|
||||||
|
surface,
|
||||||
|
output_state,
|
||||||
|
surface.vrr_enabled,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1671,32 +1712,14 @@ impl Tty {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if change_vrr {
|
if change_vrr {
|
||||||
if is_vrr_capable(&device.drm, connector.handle()) == Some(true) {
|
try_to_change_vrr(
|
||||||
let word = if config.variable_refresh_rate {
|
&device.drm,
|
||||||
"enabling"
|
connector,
|
||||||
} else {
|
crtc,
|
||||||
"disabling"
|
surface,
|
||||||
};
|
output_state,
|
||||||
|
config.variable_refresh_rate,
|
||||||
match set_vrr_enabled(&device.drm, crtc, config.variable_refresh_rate) {
|
);
|
||||||
Ok(enabled) => {
|
|
||||||
if enabled != config.variable_refresh_rate {
|
|
||||||
warn!("output {:?}: failed {} VRR", surface.name, word);
|
|
||||||
}
|
|
||||||
|
|
||||||
surface.vrr_enabled = enabled;
|
|
||||||
output_state.frame_clock.set_vrr(enabled);
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
warn!("output {:?}: error {} VRR: {err:?}", surface.name, word);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if config.variable_refresh_rate {
|
|
||||||
warn!(
|
|
||||||
"output {:?}: cannot enable VRR because connector is not vrr_capable",
|
|
||||||
surface.name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if change_mode {
|
if change_mode {
|
||||||
@ -2345,6 +2368,40 @@ pub fn set_gamma_for_crtc(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_to_change_vrr(
|
||||||
|
device: &DrmDevice,
|
||||||
|
connector: &connector::Info,
|
||||||
|
crtc: crtc::Handle,
|
||||||
|
surface: &mut Surface,
|
||||||
|
output_state: &mut crate::niri::OutputState,
|
||||||
|
enable_vrr: bool,
|
||||||
|
) {
|
||||||
|
let _span = tracy_client::span!("try_to_change_vrr");
|
||||||
|
|
||||||
|
if is_vrr_capable(device, connector.handle()) == Some(true) {
|
||||||
|
let word = if enable_vrr { "enabling" } else { "disabling" };
|
||||||
|
|
||||||
|
match set_vrr_enabled(device, crtc, enable_vrr) {
|
||||||
|
Ok(enabled) => {
|
||||||
|
if enabled != enable_vrr {
|
||||||
|
warn!("output {:?}: failed {} VRR", surface.name, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
surface.vrr_enabled = enabled;
|
||||||
|
output_state.frame_clock.set_vrr(enabled);
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
warn!("output {:?}: error {} VRR: {err:?}", surface.name, word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if enable_vrr {
|
||||||
|
warn!(
|
||||||
|
"output {:?}: cannot enable VRR because connector is not vrr_capable",
|
||||||
|
surface.name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -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();
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user