From 49a43c4a9bf05194ff34e88ee4dfa1387e12d461 Mon Sep 17 00:00:00 2001 From: Kirottu Date: Tue, 4 Jul 2023 19:13:27 +0300 Subject: [PATCH] Reworked runner position configuration to allow for far more flexibility --- README.md | 1 - anyrun-macros/src/lib.rs | 2 +- anyrun/src/main.rs | 109 ++++++++++++++++++++------------------- examples/config.ron | 19 ++++--- 4 files changed, 68 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 60fff88..3c07598 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,6 @@ Anyrun requires plugins to function, as they provide the results for input. The - Search and run system & user specific desktop entries. - [Symbols](plugins/symbols/README.md) - Search unicode symbols. - - [User defined symbols](plugins/symbols/README.md#User-defined-symbols) - [Rink](plugins/rink/README.md) - Calculator & unit conversion. - [Shell](plugins/shell/README.md) diff --git a/anyrun-macros/src/lib.rs b/anyrun-macros/src/lib.rs index 7678375..aaf7615 100644 --- a/anyrun-macros/src/lib.rs +++ b/anyrun-macros/src/lib.rs @@ -1,6 +1,6 @@ use proc_macro::{Span, TokenStream}; use quote::quote; -use syn::{parse_macro_input, parse_quote, Attribute, Ident, ReturnType, Type}; +use syn::{parse_macro_input, parse_quote, Ident, ReturnType, Type}; /// The function to handle the selection of an item. Takes a `Match` as its first argument, and the second argument can be one of: /// - &T diff --git a/anyrun/src/main.rs b/anyrun/src/main.rs index 04f044f..019d1ad 100644 --- a/anyrun/src/main.rs +++ b/anyrun/src/main.rs @@ -20,9 +20,10 @@ use wl_clipboard_rs::copy; #[anyrun_macros::config_args] #[derive(Deserialize)] struct Config { + x: RelativeNum, + y: RelativeNum, width: RelativeNum, - vertical_offset: RelativeNum, - position: Position, + height: RelativeNum, plugins: Vec, hide_icons: bool, hide_plugin_info: bool, @@ -36,9 +37,10 @@ struct Config { impl Default for Config { fn default() -> Self { Self { - width: RelativeNum::Absolute(800), - vertical_offset: RelativeNum::Absolute(0), - position: Position::Top, + x: RelativeNum::Fraction(0.5), + y: RelativeNum::Absolute(0), + width: RelativeNum::Fraction(0.4), + height: RelativeNum::Absolute(0), plugins: vec![ "libapplications.so".into(), "libsymbols.so".into(), @@ -71,6 +73,15 @@ enum RelativeNum { Fraction(f32), } +impl RelativeNum { + fn to_val(&self, val: u32) -> i32 { + match self { + RelativeNum::Absolute(num) => *num, + RelativeNum::Fraction(frac) => (frac * val as f32) as i32, + } + } +} + impl From<&str> for RelativeNum { fn from(value: &str) -> Self { let (ty, val) = value.split_once(':').expect("Invalid RelativeNum value"); @@ -584,57 +595,49 @@ fn activate(app: >k::Application, runtime_data: Rc>) { let main_list = main_list.clone(); configure_once.call_once(move || { - let width = match runtime_data.borrow().config.width { - RelativeNum::Absolute(width) => width, - RelativeNum::Fraction(fraction) => (event.size().0 as f32 * fraction) as i32, - }; - // The GtkFixed widget is used for absolute positioning of the main box - let fixed = gtk::Fixed::builder().build(); - let main_vbox = gtk::Box::builder() - .orientation(gtk::Orientation::Vertical) - .halign(gtk::Align::Center) - .vexpand(false) - .width_request(width) - .name(style_names::MAIN) - .build(); - main_vbox.add(&entry); + { + let runtime_data = runtime_data.borrow(); - // Display the error message - if !runtime_data.borrow().error_label.is_empty() { - main_vbox.add( - >k::Label::builder() - .label(&format!( - r#"{}"#, - runtime_data.borrow().error_label - )) - .use_markup(true) - .build(), - ); + let width = runtime_data.config.width.to_val(event.size().0); + let x = runtime_data.config.x.to_val(event.size().0) - width / 2; + let height = runtime_data.config.height.to_val(event.size().1); + let y = runtime_data.config.y.to_val(event.size().1) - height / 2; + + // The GtkFixed widget is used for absolute positioning of the main box + let fixed = gtk::Fixed::builder().build(); + let main_vbox = gtk::Box::builder() + .orientation(gtk::Orientation::Vertical) + .halign(gtk::Align::Center) + .vexpand(false) + .width_request(width) + .height_request(height) + .name(style_names::MAIN) + .build(); + main_vbox.add(&entry); + + // Display the error message + if !runtime_data.error_label.is_empty() { + main_vbox.add( + >k::Label::builder() + .label(&format!( + r#"{}"#, + runtime_data.error_label + )) + .use_markup(true) + .build(), + ); + } + + fixed.put(&main_vbox, x, y); + window.add(&fixed); + window.show_all(); + + // Add and show the list later, to avoid showing empty plugin categories on launch + main_vbox.add(&main_list); + main_list.show(); + entry.grab_focus(); // Grab the focus so typing is immediately accepted by the entry box } - let vertical_offset = match runtime_data.borrow().config.vertical_offset { - RelativeNum::Absolute(offset) => offset, - RelativeNum::Fraction(fraction) => (event.size().1 as f32 * fraction) as i32, - }; - - fixed.put( - &main_vbox, - (event.size().0 as i32 - width) / 2, - match runtime_data.borrow().config.position { - Position::Top => vertical_offset, - Position::Center => { - (event.size().1 as i32 - entry.allocated_height()) / 2 + vertical_offset - } - }, - ); - window.add(&fixed); - window.show_all(); - - // Add and show the list later, to avoid showing empty plugin categories on launch - main_vbox.add(&main_list); - main_list.show(); - entry.grab_focus(); // Grab the focus so typing is immediately accepted by the entry box - if runtime_data.borrow().config.show_results_immediately { // Get initial matches refresh_matches(String::new(), runtime_data); diff --git a/examples/config.ron b/examples/config.ron index d130152..7975469 100644 --- a/examples/config.ron +++ b/examples/config.ron @@ -3,15 +3,18 @@ Config( // Absolute(n): The absolute value in pixels // Fraction(n): A fraction of the width or height of the full screen (depends on exclusive zones and the settings related to them) window respectively - // How wide the input box and results are. - width: Absolute(800), + // The horizontal position, adjusted so that Relative(0.5) always centers the runner + x: Relative(0.5), + + // The vertical position, works the same as `x` + y: Absolute(0), + + // The width of the runner + width: Absolute(800), + + // The minimum height of the runner, the runner will expand to fit all the entries + height: Absolute(0), - // Where Anyrun is located on the screen: Top, Center - position: Top, - - // How much the runner is shifted vertically - vertical_offset: Absolute(0), - // Hide match and plugin info icons hide_icons: false,