mostly correct line impl
This commit is contained in:
parent
7f96889803
commit
eafd962276
3 changed files with 100 additions and 40 deletions
|
@ -99,6 +99,7 @@ This library is not available publicly yet as the interface is not stable enough
|
|||
* Color files are not supported
|
||||
* `line_wrap` is now called `line-wrap`
|
||||
* Wofi has a C-API, that is not and won't be supported, but Worf can be used as a rust library.
|
||||
* Most boolean options now need `true` or `false` as argument, as Worf is using the same struct for config and command line arguments and this is the only way to merge both data sources
|
||||
|
||||
### Dropped arguments / config values
|
||||
* `mode`, use show
|
||||
|
|
|
@ -178,11 +178,10 @@ impl FromStr for KeyDetectionType {
|
|||
#[derive(Debug, Deserialize, Serialize, Clone, Parser)]
|
||||
#[clap(about = "Worf is a wofi clone written in rust, it aims to be a drop-in replacement")]
|
||||
#[derive(Default)]
|
||||
#[allow(clippy::struct_excessive_bools)] // it's fine for config
|
||||
pub struct Config {
|
||||
/// Forks the menu so you can close the terminal
|
||||
#[clap(long = "fork")]
|
||||
fork: bool,
|
||||
#[clap(short = 'f', long = "fork")]
|
||||
fork: Option<bool>,
|
||||
|
||||
/// Selects a config file to use
|
||||
#[clap(short = 'c', long = "conf")]
|
||||
|
@ -227,8 +226,7 @@ pub struct Config {
|
|||
|
||||
/// Set to 'false' to disable images, defaults to true
|
||||
#[clap(short = 'I', long = "allow-images")]
|
||||
#[serde(default = "default_true")]
|
||||
allow_images: bool,
|
||||
allow_images: Option<bool>,
|
||||
|
||||
/// If `true` pango markup is parsed
|
||||
#[clap(short = 'm', long = "allow-markup")]
|
||||
|
@ -285,7 +283,7 @@ pub struct Config {
|
|||
no_actions: Option<bool>,
|
||||
|
||||
#[clap(short = 'L', long = "lines")]
|
||||
lines: Option<u32>, // todo support this
|
||||
lines: Option<i32>, // todo support this
|
||||
|
||||
#[clap(short = 'w', long = "columns")]
|
||||
columns: Option<u32>,
|
||||
|
@ -338,16 +336,19 @@ pub struct Config {
|
|||
// todo re-add this
|
||||
// #[serde(flatten)]
|
||||
// key_custom: Option<HashMap<String, String>>,
|
||||
global_coords: bool, // todo support this
|
||||
global_coords: Option<bool>, // todo support this
|
||||
|
||||
/// If set to `true` the search field willOption<> be hidden.
|
||||
#[clap(long = "hide-search")]
|
||||
hide_search: bool,
|
||||
dynamic_lines: bool, // todo support this
|
||||
hide_search: Option<bool>,
|
||||
#[clap(long = "dynamic-lines")]
|
||||
dynamic_lines: bool, // todo support this
|
||||
layer: Option<String>, // todo support this
|
||||
copy_exec: Option<String>, // todo support this
|
||||
single_click: bool, // todo support this
|
||||
pre_display_exec: bool, // todo support this
|
||||
#[clap(long = "single_click")]
|
||||
single_click: Option<bool>, // todo support this
|
||||
#[clap(long = "pre-display-exec")]
|
||||
pre_display_exec: Option<bool>, // todo support this
|
||||
|
||||
/// Minimum score for a fuzzy search to be shown
|
||||
#[clap(long = "fuzzy-min-score")]
|
||||
|
@ -362,7 +363,7 @@ pub struct Config {
|
|||
|
||||
/// Display only icon in emoji mode
|
||||
#[clap(long = "emoji-hide-string")]
|
||||
emoji_hide_label: bool,
|
||||
emoji_hide_label: Option<bool>,
|
||||
|
||||
#[clap(long = "keyboard-detection-type")]
|
||||
key_detection_type: Option<KeyDetectionType>,
|
||||
|
@ -371,7 +372,7 @@ pub struct Config {
|
|||
impl Config {
|
||||
#[must_use]
|
||||
pub fn fork(&self) -> bool {
|
||||
self.fork
|
||||
self.fork.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
@ -477,7 +478,7 @@ impl Config {
|
|||
|
||||
#[must_use]
|
||||
pub fn allow_images(&self) -> bool {
|
||||
self.allow_images
|
||||
self.allow_images.unwrap_or(true)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
@ -521,7 +522,7 @@ impl Config {
|
|||
|
||||
#[must_use]
|
||||
pub fn hide_search(&self) -> bool {
|
||||
self.hide_search
|
||||
self.hide_search.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
@ -551,7 +552,7 @@ impl Config {
|
|||
|
||||
#[must_use]
|
||||
pub fn emoji_hide_label(&self) -> bool {
|
||||
self.emoji_hide_label
|
||||
self.emoji_hide_label.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
@ -560,15 +561,20 @@ impl Config {
|
|||
.clone()
|
||||
.unwrap_or(KeyDetectionType::Value)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn lines(&self) -> Option<i32> {
|
||||
self.lines
|
||||
}
|
||||
}
|
||||
|
||||
fn default_false() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn default_true() -> bool {
|
||||
true
|
||||
}
|
||||
// fn default_true() -> bool {
|
||||
// true
|
||||
// }
|
||||
|
||||
//
|
||||
// // TODO
|
||||
|
|
|
@ -710,11 +710,10 @@ fn build_ui<T, P>(
|
|||
let (_changed, provider_elements) = get_provider_elements.join().unwrap();
|
||||
log::debug!("got items after {:?}", wait_for_items.elapsed());
|
||||
|
||||
let active_cfg = config.clone();
|
||||
let animate_window = ui_elements.window.clone();
|
||||
|
||||
animate_window.connect_is_active_notify(move |w| {
|
||||
window_show_resize(&active_cfg.clone(), w);
|
||||
let cfg = config.clone();
|
||||
let ui = Rc::clone(&ui_elements);
|
||||
ui_elements.window.connect_is_active_notify(move |_| {
|
||||
window_show_resize(&cfg.clone(), &ui);
|
||||
});
|
||||
|
||||
build_ui_from_menu_items(&ui_elements, &meta, provider_elements);
|
||||
|
@ -918,6 +917,7 @@ fn build_ui_from_menu_items<T: Clone + 'static + Send>(
|
|||
&lock.len(),
|
||||
start.elapsed()
|
||||
);
|
||||
|
||||
ControlFlow::Break
|
||||
} else {
|
||||
ControlFlow::Continue
|
||||
|
@ -1126,28 +1126,81 @@ fn sort_menu_items_by_score<T: Clone>(
|
|||
}
|
||||
}
|
||||
|
||||
fn window_show_resize(config: &Config, window: &ApplicationWindow) {
|
||||
if let Some(surface) = window.surface() {
|
||||
let display = surface.display();
|
||||
let monitor = display.monitor_at_surface(&surface);
|
||||
if let Some(monitor) = monitor {
|
||||
let geometry = monitor.geometry();
|
||||
let Some(target_width) = percent_or_absolute(&config.width(), geometry.width()) else {
|
||||
return;
|
||||
};
|
||||
fn window_show_resize<T: Clone + 'static>(config: &Config, ui: &Rc<UiElements<T>>) {
|
||||
// Get the surface and associated monitor geometry
|
||||
let Some(surface) = ui.window.surface() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(target_height) = percent_or_absolute(&config.height(), geometry.height())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let display = surface.display();
|
||||
let Some(monitor) = display.monitor_at_surface(&surface) else {
|
||||
return;
|
||||
};
|
||||
let geometry = monitor.geometry();
|
||||
|
||||
// Calculate target width from config, return early if not set
|
||||
let Some(target_width) = percent_or_absolute(&config.width(), geometry.width()) else {
|
||||
log::error!("width is not set");
|
||||
return;
|
||||
};
|
||||
|
||||
// Calculate target height based on either lines or absolute height
|
||||
let target_height = if let Some(lines) = config.lines() {
|
||||
let (_, _, _, height_search) = ui.search.measure(Orientation::Vertical, 10_000);
|
||||
let widget = {
|
||||
let lock = ui.menu_rows.read().unwrap();
|
||||
lock.iter().next().map(|(w, _)| w.clone())
|
||||
};
|
||||
|
||||
if let Some(widget) = widget {
|
||||
log::debug!(
|
||||
"monitor geometry: {geometry:?}, target_height {target_height}, target_width {target_width}"
|
||||
"widget, mapped: {}, realized {}, visible {}, has child {}, baseline {}, pref size {:#?}",
|
||||
widget.is_mapped(),
|
||||
widget.is_realized(),
|
||||
widget.is_visible(),
|
||||
widget.child().is_some(),
|
||||
widget.allocated_baseline(),
|
||||
widget.preferred_size()
|
||||
);
|
||||
if !widget.is_mapped() {
|
||||
let c_clone = config.clone();
|
||||
let ui_clone = Rc::clone(ui);
|
||||
widget.connect_realize(move |_| {
|
||||
window_show_resize(&c_clone, &Rc::clone(&ui_clone));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
window.set_width_request(target_width);
|
||||
window.set_height_request(target_height);
|
||||
let (_, nat, _, baseline) = widget.measure(Orientation::Vertical, 10_000);
|
||||
log::debug!("natural height base {baseline}, nat {nat}");
|
||||
// todo fix this eventually properly, so baseline is always set and not only in 85% of cases.
|
||||
let height = if baseline > 0 {
|
||||
baseline
|
||||
} else if config.allow_images() {
|
||||
i32::from(config.image_size()) // wild guess that image makes the most part of the row ...
|
||||
} else {
|
||||
nat // for my configuration way bigger than baseline
|
||||
};
|
||||
|
||||
Some((height_search + height) * lines)
|
||||
} else {
|
||||
log::warn!("No widget for height calculation available");
|
||||
Some(0)
|
||||
}
|
||||
} else if let Some(height) = percent_or_absolute(&config.height(), geometry.height()) {
|
||||
Some(height)
|
||||
} else {
|
||||
log::error!("Widget is none");
|
||||
Some(0)
|
||||
};
|
||||
|
||||
// Apply the calculated size or log an error if height missing
|
||||
if let Some(target_height) = target_height {
|
||||
log::debug!("Setting width {target_width}, height {target_height}");
|
||||
ui.window.set_height_request(target_height);
|
||||
ui.window.set_width_request(target_width);
|
||||
} else {
|
||||
log::error!("height is not set");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue