Merge branch 'master' of https://github.com/Kirottu/anyrun
This commit is contained in:
10
README.md
10
README.md
@@ -53,9 +53,12 @@ After that you need to create the configuration file and place it in `~/.config/
|
|||||||
|
|
||||||
```ron
|
```ron
|
||||||
Config(
|
Config(
|
||||||
width: 800,
|
width: Absolute(800),
|
||||||
position: Top,
|
position: Top,
|
||||||
|
vertical_offset: Absolute(0), // How much the runner is shifted vertically
|
||||||
hide_icons: false,
|
hide_icons: false,
|
||||||
|
ignore_exclusive_zones: true, // ignore exclusive zones, f.e. Waybar
|
||||||
|
layer: Overlay, // GTK Layer: Bottom, Top, Background, Overlay
|
||||||
hide_plugin_info: false,
|
hide_plugin_info: false,
|
||||||
plugins: [
|
plugins: [
|
||||||
"libapplications.so",
|
"libapplications.so",
|
||||||
@@ -100,9 +103,12 @@ The config file has the following structure, and as seen in the name uses the `r
|
|||||||
|
|
||||||
```ron
|
```ron
|
||||||
Config(
|
Config(
|
||||||
width: 800, // The width of the window
|
width: Absolute(800), // The width of the window
|
||||||
position: Top,
|
position: Top,
|
||||||
|
vertical_offset: Absolute(0), // How much the runner is shifted vertically
|
||||||
hide_icons: false,
|
hide_icons: false,
|
||||||
|
ignore_exclusive_zones: true, // ignore exclusive zones, f.e. Waybar
|
||||||
|
layer: Overlay, // GTK Layer: Bottom, Top, Background, Overlay
|
||||||
hide_plugin_info: false,
|
hide_plugin_info: false,
|
||||||
plugins: [
|
plugins: [
|
||||||
"libapplications.so", // Relative paths are looked up in the <config dir>/plugins/ directory
|
"libapplications.so", // Relative paths are looked up in the <config dir>/plugins/ directory
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
#window {
|
#window {
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
box#main {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
background-color: @theme_bg_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
list#main {
|
list#main {
|
||||||
|
|||||||
@@ -8,18 +8,30 @@ use serde::Deserialize;
|
|||||||
use wl_clipboard_rs::copy;
|
use wl_clipboard_rs::copy;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
enum Position {
|
struct Config {
|
||||||
Top,
|
width: RelativeNum,
|
||||||
Center,
|
vertical_offset: RelativeNum,
|
||||||
|
position: Position,
|
||||||
|
plugins: Vec<PathBuf>,
|
||||||
|
hide_icons: bool,
|
||||||
|
hide_plugin_info: bool,
|
||||||
|
ignore_exclusive_zones: bool,
|
||||||
|
layer: Layer,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Config {
|
enum Layer {
|
||||||
width: u32,
|
Background,
|
||||||
plugins: Vec<PathBuf>,
|
Bottom,
|
||||||
position: Position,
|
Top,
|
||||||
hide_icons: bool,
|
Overlay,
|
||||||
hide_plugin_info: bool,
|
}
|
||||||
|
|
||||||
|
// Could have a better name
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
enum RelativeNum {
|
||||||
|
Absolute(i32),
|
||||||
|
Fraction(f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A "view" of plugin's info and matches
|
/// A "view" of plugin's info and matches
|
||||||
@@ -35,6 +47,12 @@ struct Args {
|
|||||||
config_dir: Option<String>,
|
config_dir: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
enum Position {
|
||||||
|
Top,
|
||||||
|
Center,
|
||||||
|
}
|
||||||
|
|
||||||
/// Actions to run after GTK has finished
|
/// Actions to run after GTK has finished
|
||||||
enum PostRunAction {
|
enum PostRunAction {
|
||||||
Copy(Vec<u8>),
|
Copy(Vec<u8>),
|
||||||
@@ -169,20 +187,31 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
let window = gtk::ApplicationWindow::builder()
|
let window = gtk::ApplicationWindow::builder()
|
||||||
.application(app)
|
.application(app)
|
||||||
.name(style_names::WINDOW)
|
.name(style_names::WINDOW)
|
||||||
.width_request(config.width as i32)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Init GTK layer shell
|
// Init GTK layer shell
|
||||||
gtk_layer_shell::init_for_window(&window);
|
gtk_layer_shell::init_for_window(&window);
|
||||||
|
|
||||||
// Anchor based on configured position
|
// Make layer-window fullscreen
|
||||||
match config.position {
|
gtk_layer_shell::set_anchor(&window, gtk_layer_shell::Edge::Top, true);
|
||||||
Position::Top => gtk_layer_shell::set_anchor(&window, gtk_layer_shell::Edge::Top, true),
|
gtk_layer_shell::set_anchor(&window, gtk_layer_shell::Edge::Bottom, true);
|
||||||
Position::Center => (),
|
gtk_layer_shell::set_anchor(&window, gtk_layer_shell::Edge::Left, true);
|
||||||
|
gtk_layer_shell::set_anchor(&window, gtk_layer_shell::Edge::Right, true);
|
||||||
|
|
||||||
|
if config.ignore_exclusive_zones {
|
||||||
|
gtk_layer_shell::set_exclusive_zone(&window, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_layer_shell::set_keyboard_mode(&window, gtk_layer_shell::KeyboardMode::Exclusive);
|
gtk_layer_shell::set_keyboard_mode(&window, gtk_layer_shell::KeyboardMode::Exclusive);
|
||||||
gtk_layer_shell::set_layer(&window, gtk_layer_shell::Layer::Overlay);
|
|
||||||
|
match config.layer {
|
||||||
|
Layer::Background => {
|
||||||
|
gtk_layer_shell::set_layer(&window, gtk_layer_shell::Layer::Background)
|
||||||
|
}
|
||||||
|
Layer::Bottom => gtk_layer_shell::set_layer(&window, gtk_layer_shell::Layer::Bottom),
|
||||||
|
Layer::Top => gtk_layer_shell::set_layer(&window, gtk_layer_shell::Layer::Top),
|
||||||
|
Layer::Overlay => gtk_layer_shell::set_layer(&window, gtk_layer_shell::Layer::Overlay),
|
||||||
|
};
|
||||||
|
|
||||||
// Try to load custom CSS, if it fails load the default CSS
|
// Try to load custom CSS, if it fails load the default CSS
|
||||||
let provider = gtk::CssProvider::new();
|
let provider = gtk::CssProvider::new();
|
||||||
@@ -306,7 +335,6 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
// Text entry box
|
// Text entry box
|
||||||
let entry = gtk::Entry::builder()
|
let entry = gtk::Entry::builder()
|
||||||
.hexpand(true)
|
.hexpand(true)
|
||||||
.has_focus(true)
|
|
||||||
.name(style_names::ENTRY)
|
.name(style_names::ENTRY)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@@ -320,28 +348,9 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let anchor_set = Rc::new(RefCell::new(false));
|
|
||||||
|
|
||||||
// Handle other key presses for selection control and all other things that may be needed
|
// Handle other key presses for selection control and all other things that may be needed
|
||||||
let entry_clone = entry.clone();
|
let entry_clone = entry.clone();
|
||||||
window.connect_key_press_event(move |window, event| {
|
window.connect_key_press_event(move |window, event| {
|
||||||
// Set margin & anchor properly after the window is already present, otherwise GTK can't figure out the right monitor
|
|
||||||
if matches!(config.position, Position::Center) && !*anchor_set.borrow() {
|
|
||||||
let monitor = window
|
|
||||||
.display()
|
|
||||||
.monitor_at_window(&window.window().unwrap())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
gtk_layer_shell::set_anchor(window, gtk_layer_shell::Edge::Top, true);
|
|
||||||
gtk_layer_shell::set_margin(
|
|
||||||
window,
|
|
||||||
gtk_layer_shell::Edge::Top,
|
|
||||||
monitor.geometry().height() / 2 - entry_clone.allocated_height() - 2,
|
|
||||||
);
|
|
||||||
|
|
||||||
*anchor_set.borrow_mut() = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
use gdk::keys::constants;
|
use gdk::keys::constants;
|
||||||
match event.keyval() {
|
match event.keyval() {
|
||||||
// Close window on escape
|
// Close window on escape
|
||||||
@@ -483,16 +492,50 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Show the window initially, so it gets allocated and configured
|
||||||
|
window.show_all();
|
||||||
|
|
||||||
|
// Create widgets here for proper positioning
|
||||||
|
window.connect_configure_event(move |window, event| {
|
||||||
|
let width = match 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()
|
let main_vbox = gtk::Box::builder()
|
||||||
.orientation(gtk::Orientation::Vertical)
|
.orientation(gtk::Orientation::Vertical)
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.vexpand(false)
|
||||||
|
.width_request(width)
|
||||||
.name(style_names::MAIN)
|
.name(style_names::MAIN)
|
||||||
.build();
|
.build();
|
||||||
main_vbox.add(&entry);
|
main_vbox.add(&entry);
|
||||||
window.add(&main_vbox);
|
|
||||||
|
let vertical_offset = match 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 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();
|
window.show_all();
|
||||||
|
|
||||||
// Add and show the list later, to avoid showing empty plugin categories on launch
|
// Add and show the list later, to avoid showing empty plugin categories on launch
|
||||||
main_vbox.add(&main_list);
|
main_vbox.add(&main_list);
|
||||||
main_list.show();
|
main_list.show();
|
||||||
|
entry.grab_focus(); // Grab the focus so typing is immediately accepted by the entry box
|
||||||
|
false
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_matches(
|
fn handle_matches(
|
||||||
|
|||||||
Reference in New Issue
Block a user