New switch-output command

timeout_old
Tassilo Horn 3 years ago
parent 4c17f110f4
commit b6fc87901a
  1. 3
      NEWS.md
  2. 15
      src/cmds.rs
  3. 24
      src/config.rs
  4. 9
      src/tree.rs

@ -1,6 +1,9 @@
swayr v0.11.0
=============
- New command: `switch-output` shows all outputs in the menu and focuses the
selected one. Since outputs must now be printable in the menu program,
there's a new `format.output_format` spec.
- New command: `configure-outputs` lets you repeatedly issue output commands
until you abort the menu program.
- Formats can now include a `{output_name}` placeholder which is replaced by

@ -71,6 +71,8 @@ pub enum SwayrCommand {
SwitchWindow,
/// Switch to the selected workspace.
SwitchWorkspace,
/// Switch to the selected workspace.
SwitchOutput,
/// Switch to the selected workspace or focus the selected window.
SwitchWorkspaceOrWindow,
/// Switch to the selected workspace or focus the selected container, or
@ -241,6 +243,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
SwayrCommand::SwitchWorkspace => {
switch_workspace(&*props.read().unwrap())
}
SwayrCommand::SwitchOutput => switch_output(&*props.read().unwrap()),
SwayrCommand::SwitchWorkspaceOrWindow => {
switch_workspace_or_window(&*props.read().unwrap())
}
@ -370,6 +373,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
SwayrCommand::QuitWorkspaceOrWindow,
SwayrCommand::SwitchWindow,
SwayrCommand::SwitchWorkspace,
SwayrCommand::SwitchOutput,
SwayrCommand::SwitchWorkspaceOrWindow,
SwayrCommand::SwitchToUrgentOrLRUWindow,
SwayrCommand::ConfigureOutputs,
@ -515,6 +519,11 @@ fn handle_non_matching_input(input: &str) {
fn select_and_focus(prompt: &str, choices: &[t::DisplayNode]) {
match util::select_from_menu(prompt, choices) {
Ok(tn) => match tn.node.get_type() {
t::Type::Output => {
if !tn.node.is_scratchpad() {
run_sway_command(&["focus output", tn.node.get_name()]);
}
}
t::Type::Workspace => {
if !tn.node.is_scratchpad() {
run_sway_command(&["workspace", tn.node.get_name()]);
@ -545,6 +554,12 @@ pub fn switch_workspace(extra_props: &HashMap<i64, t::ExtraProps>) {
select_and_focus("Select workspace", &tree.get_workspaces());
}
pub fn switch_output(extra_props: &HashMap<i64, t::ExtraProps>) {
let root = get_tree(false);
let tree = t::get_tree(&root, extra_props);
select_and_focus("Select output", &tree.get_outputs());
}
pub fn switch_workspace_or_window(extra_props: &HashMap<i64, t::ExtraProps>) {
let root = get_tree(true);
let tree = t::get_tree(&root, extra_props);

@ -63,12 +63,12 @@ impl Config {
.expect("No menu.args defined.")
}
pub fn get_format_window_format(&self) -> String {
pub fn get_format_output_format(&self) -> String {
self.format
.as_ref()
.and_then(|f| f.window_format.clone())
.or_else(|| Format::default().window_format)
.expect("No format.window_format defined.")
.and_then(|f| f.output_format.clone())
.or_else(|| Format::default().output_format)
.expect("No format.output_format defined.")
}
pub fn get_format_workspace_format(&self) -> String {
@ -87,6 +87,14 @@ impl Config {
.expect("No format.container_format defined.")
}
pub fn get_format_window_format(&self) -> String {
self.format
.as_ref()
.and_then(|f| f.window_format.clone())
.or_else(|| Format::default().window_format)
.expect("No format.window_format defined.")
}
pub fn get_format_indent(&self) -> String {
self.format
.as_ref()
@ -161,9 +169,10 @@ pub struct Menu {
#[derive(Debug, Serialize, Deserialize)]
pub struct Format {
window_format: Option<String>,
output_format: Option<String>,
workspace_format: Option<String>,
container_format: Option<String>,
window_format: Option<String>,
indent: Option<String>,
urgency_start: Option<String>,
urgency_end: Option<String>,
@ -215,6 +224,11 @@ impl Default for Menu {
impl Default for Format {
fn default() -> Self {
Format {
output_format: Some(
"{indent}<b>Output {name}</b> \
<span alpha=\"20000\">({id})</span>"
.to_string(),
),
workspace_format: Some(
"{indent}<b>Workspace {name} [{layout}]</b> \
on output {output_name} \

@ -257,8 +257,11 @@ impl<'a> Tree<'a> {
}
pub fn get_outputs(&self) -> Vec<DisplayNode> {
let outputs: Vec<&s::Node> =
self.root.iter().filter(|n| !n.is_scratchpad()).collect();
let outputs: Vec<&s::Node> = self
.root
.iter()
.filter(|n| n.get_type() == Type::Output && !n.is_scratchpad())
.collect();
self.as_display_nodes(&outputs, IndentLevel::Fixed(0))
}
@ -450,7 +453,7 @@ impl DisplayFormat for DisplayNode<'_> {
let fmt = match self.node.get_type() {
Type::Root => String::from("Cannot format Root"),
Type::Output => String::from("Cannot format Output"),
Type::Output => cfg.get_format_output_format(),
Type::Workspace => cfg.get_format_workspace_format(),
Type::Container => cfg.get_format_container_format(),
Type::Window => cfg.get_format_window_format(),

Loading…
Cancel
Save