add option to limit dynamic lines
This commit is contained in:
parent
9e2f4d4eac
commit
bf9cb00a45
2 changed files with 50 additions and 24 deletions
|
@ -367,9 +367,17 @@ pub struct Config {
|
||||||
#[clap(long = "hide-search")]
|
#[clap(long = "hide-search")]
|
||||||
hide_search: Option<bool>,
|
hide_search: Option<bool>,
|
||||||
|
|
||||||
|
/// If enabled, worf will resize according to the amount of displayed rows
|
||||||
|
/// defaults to false
|
||||||
#[clap(long = "dynamic-lines")]
|
#[clap(long = "dynamic-lines")]
|
||||||
dynamic_lines: Option<bool>,
|
dynamic_lines: Option<bool>,
|
||||||
|
|
||||||
|
/// If enabled, dynamic lines do not exceed the maximum height specified in the
|
||||||
|
/// `height` option. It does ot evaluate the `lines` option though
|
||||||
|
/// defaults to true
|
||||||
|
#[clap(long = "dynamic-lines-limit")]
|
||||||
|
dynamic_lines_limit: Option<bool>,
|
||||||
|
|
||||||
#[clap(long = "layer")]
|
#[clap(long = "layer")]
|
||||||
layer: Option<Layer>,
|
layer: Option<Layer>,
|
||||||
|
|
||||||
|
@ -640,6 +648,11 @@ impl Config {
|
||||||
pub fn dynamic_lines(&self) -> bool {
|
pub fn dynamic_lines(&self) -> bool {
|
||||||
self.dynamic_lines.unwrap_or(false)
|
self.dynamic_lines.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn dynamic_lines_limit(&self) -> bool {
|
||||||
|
self.dynamic_lines_limit.unwrap_or(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_false() -> bool {
|
fn default_false() -> bool {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
||||||
|
|
||||||
use crossbeam::channel::{self, Sender};
|
use crossbeam::channel::{self, Sender};
|
||||||
use gdk4::{
|
use gdk4::{
|
||||||
Display,
|
Display, Rectangle,
|
||||||
gio::File,
|
gio::File,
|
||||||
glib::{self, MainContext, Propagation},
|
glib::{self, MainContext, Propagation},
|
||||||
prelude::{Cast, DisplayExt, MonitorExt, SurfaceExt},
|
prelude::{Cast, DisplayExt, MonitorExt, SurfaceExt},
|
||||||
|
@ -992,11 +992,10 @@ fn handle_key_press<T: Clone + 'static + Send>(
|
||||||
select_first_visible_child(&*lock, &ui.main_box);
|
select_first_visible_child(&*lock, &ui.main_box);
|
||||||
drop(lock);
|
drop(lock);
|
||||||
if meta.config.dynamic_lines() {
|
if meta.config.dynamic_lines() {
|
||||||
ui.window.set_height_request(calculate_row_height(
|
if let Some(geometry) = get_monitor_geometry(ui) {
|
||||||
ui,
|
let height = calculate_dynamic_lines_window_height(&meta.config, ui, geometry);
|
||||||
visible_row_count(ui),
|
ui.window.set_height_request(height);
|
||||||
&meta.config,
|
}
|
||||||
));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1019,7 +1018,7 @@ fn handle_key_press<T: Clone + 'static + Send>(
|
||||||
custom_key.key == keyboard_key.to_upper().into()
|
custom_key.key == keyboard_key.to_upper().into()
|
||||||
} && mods.is_subset(&custom_key.modifiers);
|
} && mods.is_subset(&custom_key.modifiers);
|
||||||
|
|
||||||
log::debug!("customy key {custom_key:?}, match {custom_key_match}");
|
log::debug!("custom key {custom_key:?}, match {custom_key_match}");
|
||||||
|
|
||||||
if custom_key_match {
|
if custom_key_match {
|
||||||
let search_lock = ui.search_text.lock().unwrap();
|
let search_lock = ui.search_text.lock().unwrap();
|
||||||
|
@ -1161,16 +1160,7 @@ fn sort_menu_items_by_score<T: Clone>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window_show_resize<T: Clone + 'static>(config: &Config, ui: &Rc<UiElements<T>>) {
|
fn window_show_resize<T: Clone + 'static>(config: &Config, ui: &Rc<UiElements<T>>) {
|
||||||
// Get the surface and associated monitor geometry
|
let Some(geometry) = get_monitor_geometry(ui) else { return };
|
||||||
let Some(surface) = ui.window.surface() 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
|
// Calculate target width from config, return early if not set
|
||||||
let Some(target_width) = percent_or_absolute(&config.width(), geometry.width()) else {
|
let Some(target_width) = percent_or_absolute(&config.width(), geometry.width()) else {
|
||||||
|
@ -1181,7 +1171,7 @@ fn window_show_resize<T: Clone + 'static>(config: &Config, ui: &Rc<UiElements<T>
|
||||||
let target_height = if let Some(lines) = config.lines() {
|
let target_height = if let Some(lines) = config.lines() {
|
||||||
Some(calculate_row_height(ui, lines, config))
|
Some(calculate_row_height(ui, lines, config))
|
||||||
} else if config.dynamic_lines() {
|
} else if config.dynamic_lines() {
|
||||||
Some(calculate_row_height(ui, visible_row_count(ui), config))
|
Some(calculate_dynamic_lines_window_height(&config, ui, geometry))
|
||||||
} else if let Some(height) = percent_or_absolute(&config.height(), geometry.height()) {
|
} else if let Some(height) = percent_or_absolute(&config.height(), geometry.height()) {
|
||||||
Some(height)
|
Some(height)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1198,6 +1188,29 @@ fn window_show_resize<T: Clone + 'static>(config: &Config, ui: &Rc<UiElements<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calculate_dynamic_lines_window_height<T: Clone + 'static>(config: &Config, ui: &UiElements<T>, geometry: Rectangle) -> i32 {
|
||||||
|
if config.dynamic_lines_limit() {
|
||||||
|
calculate_row_height(ui, visible_row_count(ui), config)
|
||||||
|
.min(percent_or_absolute(&config.height(), geometry.height()).unwrap_or(0))
|
||||||
|
} else {
|
||||||
|
calculate_row_height(ui, visible_row_count(ui), config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_monitor_geometry<T: Clone>(ui: &UiElements<T>) -> Option<Rectangle> {
|
||||||
|
// Get the surface and associated monitor geometry
|
||||||
|
let Some(surface) = ui.window.surface() else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let display = surface.display();
|
||||||
|
let Some(monitor) = display.monitor_at_surface(&surface) else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
let geometry = monitor.geometry();
|
||||||
|
Some(geometry)
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::cast_possible_truncation)] // does not matter for calculating height
|
#[allow(clippy::cast_possible_truncation)] // does not matter for calculating height
|
||||||
fn calculate_row_height<T: Clone + 'static>(
|
fn calculate_row_height<T: Clone + 'static>(
|
||||||
ui: &UiElements<T>,
|
ui: &UiElements<T>,
|
||||||
|
@ -1218,7 +1231,7 @@ fn calculate_row_height<T: Clone + 'static>(
|
||||||
if baseline > 0 {
|
if baseline > 0 {
|
||||||
let factor = if lines > 1 {
|
let factor = if lines > 1 {
|
||||||
1.4 // todo find a better way to do this
|
1.4 // todo find a better way to do this
|
||||||
// most likely it will not work with all styles
|
// most likely it will not work with all styles
|
||||||
} else {
|
} else {
|
||||||
1.0
|
1.0
|
||||||
};
|
};
|
||||||
|
@ -1264,7 +1277,7 @@ fn visible_row_count<T: Clone + 'static>(ui: &UiElements<T>) -> i32 {
|
||||||
.filter(|(_, menu)| menu.visible)
|
.filter(|(_, menu)| menu.visible)
|
||||||
.count(),
|
.count(),
|
||||||
)
|
)
|
||||||
.unwrap_or(i32::MAX)
|
.unwrap_or(i32::MAX)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_selected_item<T>(
|
fn handle_selected_item<T>(
|
||||||
|
@ -1403,10 +1416,10 @@ fn create_menu_row<T: Clone + 'static + Send>(
|
||||||
element_to_add.icon_path.as_ref().map(AsRef::as_ref),
|
element_to_add.icon_path.as_ref().map(AsRef::as_ref),
|
||||||
&meta.config,
|
&meta.config,
|
||||||
)
|
)
|
||||||
.or(lookup_icon(
|
.or(lookup_icon(
|
||||||
label_img.as_ref().map(AsRef::as_ref),
|
label_img.as_ref().map(AsRef::as_ref),
|
||||||
&meta.config,
|
&meta.config,
|
||||||
));
|
));
|
||||||
|
|
||||||
if let Some(image) = img {
|
if let Some(image) = img {
|
||||||
image.set_widget_name("img");
|
image.set_widget_name("img");
|
||||||
|
|
Loading…
Add table
Reference in a new issue