Compare commits
20
Commits
wayland_bump
...
wldash1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70e53c1246 | ||
|
|
b2ae30bab4 | ||
|
|
2538e41f00 | ||
|
|
3eb7cddb6c | ||
|
|
2813ae0eff | ||
|
|
1b1ffc4435 | ||
|
|
cf9fabb052 | ||
|
|
43fe73bf09 | ||
|
|
d291e36b3f | ||
|
|
fe37c15f95 | ||
|
|
d4f62da6f5 | ||
|
|
1edefd9cad | ||
|
|
90ffa7df27 | ||
|
|
d69e941ec1 | ||
|
|
5e5e8876f6 | ||
|
|
886d595f91 | ||
|
|
e04237b928 | ||
|
|
ef84c519a2 | ||
|
|
1e647c7036 | ||
|
|
56f6b1668d |
@@ -1,4 +1,3 @@
|
|||||||
# These are supported funding model platforms
|
# These are supported funding model platforms
|
||||||
|
|
||||||
liberapay: kennylevinsen
|
liberapay: kennylevinsen
|
||||||
custom: https://donate.kl.wtf/
|
|
||||||
|
|||||||
Generated
+636
-214
File diff suppressed because it is too large
Load Diff
+20
-18
@@ -1,8 +1,8 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wldash"
|
name = "wldash"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
authors = ["Kenny Levinsen <kl@kl.wtf>"]
|
authors = ["Kenny Levinsen <kl@kl.wtf>"]
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = "fat"
|
lto = "fat"
|
||||||
@@ -20,29 +20,31 @@ alsa-widget = ["alsa"]
|
|||||||
pulseaudio-widget = ["libpulse-binding"]
|
pulseaudio-widget = ["libpulse-binding"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.3"
|
byteorder = "1.4"
|
||||||
bitflags = "1.0"
|
bitflags = "1.3"
|
||||||
dlib = "0.4"
|
dlib = "0.5"
|
||||||
rusttype = "^0.9"
|
rusttype = "^0.9"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
nix = "0.16"
|
nix = "0.26"
|
||||||
memmap = "0.7"
|
memmap = "0.7"
|
||||||
os_pipe = "0.9"
|
os_pipe = "1.1"
|
||||||
wayland-client = { version = "0.28"}
|
wayland-client = { version = "0.29"}
|
||||||
wayland-protocols = { version = "0.28", features = ["client", "unstable_protocols"] }
|
wayland-protocols = { version = "0.29", features = ["client", "unstable_protocols"] }
|
||||||
dbus = "0.6"
|
dbus = "0.6"
|
||||||
fuzzy-matcher = "0.3"
|
fuzzy-matcher = "0.3"
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
rcalc_lib = "0.9"
|
rcalc_lib = "1.0"
|
||||||
rust-ini = "0.14"
|
rust-ini = "0.18"
|
||||||
shlex = "0.1"
|
shlex = "1.1"
|
||||||
timerfd = "1.0.0"
|
timerfd = "1.4.0"
|
||||||
|
walkdir = "2.3"
|
||||||
|
itertools = "0.10"
|
||||||
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = { version = "1.0", optional = true }
|
serde_json = { version = "1.0", optional = true }
|
||||||
serde_yaml = { version = "0.8", optional = true }
|
serde_yaml = { version = "0.9", optional = true }
|
||||||
|
|
||||||
libpulse-binding = { version = "2.22", optional = true }
|
libpulse-binding = { version = "2.26", optional = true }
|
||||||
alsa = { version = "0.4.0", optional = true }
|
alsa = { version = "0.7.0", optional = true }
|
||||||
fontconfig = "0.2.0"
|
fontconfig = "0.6.0"
|
||||||
unicode-segmentation = "1.6.0"
|
unicode-segmentation = "1.10.0"
|
||||||
|
|||||||
@@ -66,3 +66,7 @@ The launcher also accepts prefix operators to change its mode:
|
|||||||
- Configurability
|
- Configurability
|
||||||
- Cleanup and reorganization
|
- Cleanup and reorganization
|
||||||
- Proper line editor for the launcher
|
- Proper line editor for the launcher
|
||||||
|
|
||||||
|
## How to discuss
|
||||||
|
|
||||||
|
Go to #kennylevinsen @ irc.libera.chat to discuss, or use [~kennylevinsen/public-inbox@lists.sr.ht](https://lists.sr.ht/~kennylevinsen/public-inbox).
|
||||||
|
|||||||
+2
-2
@@ -37,8 +37,8 @@
|
|||||||
{"launcher": {
|
{"launcher": {
|
||||||
"font_size": 32.0,
|
"font_size": 32.0,
|
||||||
"length": 1200,
|
"length": 1200,
|
||||||
"app_opener": "swaymsg exec ",
|
"app_opener": "swaymsg exec -- ",
|
||||||
"term_opener": "alacritty -e ",
|
"term_opener": "foot --",
|
||||||
"url_opener": "xdg-open "
|
"url_opener": "xdg-open "
|
||||||
}}
|
}}
|
||||||
]}
|
]}
|
||||||
|
|||||||
+2
-2
@@ -45,6 +45,6 @@ widget:
|
|||||||
- launcher:
|
- launcher:
|
||||||
font_size: 32.0
|
font_size: 32.0
|
||||||
length: 1200
|
length: 1200
|
||||||
app_opener: "swaymsg exec "
|
app_opener: "swaymsg exec --"
|
||||||
term_opener: "alacritty -e "
|
term_opener: "foot --"
|
||||||
url_opener: "xdg-open "
|
url_opener: "xdg-open "
|
||||||
|
|||||||
+41
-41
@@ -5,11 +5,9 @@ use std::sync::{Arc, Mutex};
|
|||||||
|
|
||||||
use chrono::{Duration, Local, NaiveDateTime};
|
use chrono::{Duration, Local, NaiveDateTime};
|
||||||
|
|
||||||
use crate::keyboard::{
|
use crate::keyboard::{keysyms, map_keyboard, Event as KbEvent, KeyState, ModifiersState};
|
||||||
keysyms, map_keyboard, Event as KbEvent, KeyState, ModifiersState,
|
|
||||||
};
|
|
||||||
|
|
||||||
use wayland_client::protocol::{wl_compositor, wl_output, wl_pointer, wl_shm, wl_surface, wl_seat};
|
use wayland_client::protocol::{wl_compositor, wl_output, wl_pointer, wl_seat, wl_shm, wl_surface};
|
||||||
use wayland_client::{Display, EventQueue, GlobalEvent, GlobalManager, Main};
|
use wayland_client::{Display, EventQueue, GlobalEvent, GlobalManager, Main};
|
||||||
use wayland_protocols::wlr::unstable::layer_shell::v1::client::{
|
use wayland_protocols::wlr::unstable::layer_shell::v1::client::{
|
||||||
zwlr_layer_shell_v1, zwlr_layer_surface_v1,
|
zwlr_layer_shell_v1, zwlr_layer_surface_v1,
|
||||||
@@ -17,7 +15,7 @@ use wayland_protocols::wlr::unstable::layer_shell::v1::client::{
|
|||||||
|
|
||||||
use crate::buffer::Buffer;
|
use crate::buffer::Buffer;
|
||||||
use crate::color::Color;
|
use crate::color::Color;
|
||||||
use crate::widget::{WaitContext, DrawContext, Widget};
|
use crate::widget::{DrawContext, WaitContext, Widget};
|
||||||
|
|
||||||
use crate::cmd::Cmd;
|
use crate::cmd::Cmd;
|
||||||
use crate::doublemempool::DoubleMemPool;
|
use crate::doublemempool::DoubleMemPool;
|
||||||
@@ -68,30 +66,31 @@ impl AppInner {
|
|||||||
Main<wl_surface::WlSurface>,
|
Main<wl_surface::WlSurface>,
|
||||||
Main<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1>,
|
Main<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1>,
|
||||||
) {
|
) {
|
||||||
let surface = compositor
|
let surface = compositor.create_surface();
|
||||||
.create_surface();
|
|
||||||
|
|
||||||
let this_is_stupid = AtomicBool::new(false);
|
let this_is_stupid = AtomicBool::new(false);
|
||||||
|
|
||||||
let shell_surface = shell
|
let shell_surface = shell.get_layer_surface(
|
||||||
.get_layer_surface(
|
&surface,
|
||||||
&surface,
|
output,
|
||||||
output,
|
zwlr_layer_shell_v1::Layer::Overlay,
|
||||||
zwlr_layer_shell_v1::Layer::Overlay,
|
"".to_string(),
|
||||||
"".to_string());
|
|
||||||
shell_surface.quick_assign(move |layer, event, _| match event {
|
|
||||||
zwlr_layer_surface_v1::Event::Configure { serial, .. } => {
|
|
||||||
if !this_is_stupid.compare_and_swap(false, true, Ordering::SeqCst) {
|
|
||||||
*(configured_surfaces.lock().unwrap()) += 1;
|
|
||||||
layer.ack_configure(serial);
|
|
||||||
tx.send(Cmd::ForceDraw).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
shell_surface.quick_assign(move |layer, event, _| match event {
|
||||||
|
zwlr_layer_surface_v1::Event::Configure { serial, .. } => {
|
||||||
|
if this_is_stupid
|
||||||
|
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
*(configured_surfaces.lock().unwrap()) += 1;
|
||||||
|
layer.ack_configure(serial);
|
||||||
|
tx.send(Cmd::ForceDraw).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
});
|
||||||
|
|
||||||
shell_surface.set_keyboard_interactivity(1);
|
shell_surface.set_keyboard_interactivity(zwlr_layer_surface_v1::KeyboardInteractivity::Exclusive);
|
||||||
shell_surface.set_size(1, 1);
|
shell_surface.set_size(1, 1);
|
||||||
surface.set_buffer_scale(scale as i32);
|
surface.set_buffer_scale(scale as i32);
|
||||||
surface.commit();
|
surface.commit();
|
||||||
@@ -401,8 +400,7 @@ impl<'a> App<'a> {
|
|||||||
version,
|
version,
|
||||||
} => {
|
} => {
|
||||||
if let "wl_output" = &interface[..] {
|
if let "wl_output" = &interface[..] {
|
||||||
let output = registry
|
let output = registry.bind(std::cmp::min(version, 3), id);
|
||||||
.bind(version, id);
|
|
||||||
inner_global.lock().unwrap().add_output(id, output);
|
inner_global.lock().unwrap().add_output(id, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,8 +413,8 @@ impl<'a> App<'a> {
|
|||||||
|
|
||||||
// double sync to retrieve the global list
|
// double sync to retrieve the global list
|
||||||
// and the globals metadata
|
// and the globals metadata
|
||||||
event_queue.sync_roundtrip(&mut(), |_, _, _|{}).unwrap();
|
event_queue.sync_roundtrip(&mut (), |_, _, _| {}).unwrap();
|
||||||
event_queue.sync_roundtrip(&mut(), |_, _, _|{}).unwrap();
|
event_queue.sync_roundtrip(&mut (), |_, _, _| {}).unwrap();
|
||||||
|
|
||||||
// wl_compositor
|
// wl_compositor
|
||||||
let compositor = manager
|
let compositor = manager
|
||||||
@@ -435,10 +433,8 @@ impl<'a> App<'a> {
|
|||||||
//
|
//
|
||||||
// Get our seat
|
// Get our seat
|
||||||
//
|
//
|
||||||
let seat: Main<wl_seat::WlSeat> = manager
|
let seat: Main<wl_seat::WlSeat> = manager.instantiate_range(1, 6).unwrap();
|
||||||
.instantiate_range(1, 6)
|
event_queue.sync_roundtrip(&mut (), |_, _, _| {}).unwrap();
|
||||||
.unwrap();
|
|
||||||
event_queue.sync_roundtrip(&mut(), |_, _, _|{}).unwrap();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Keyboard processing
|
// Keyboard processing
|
||||||
@@ -453,7 +449,7 @@ impl<'a> App<'a> {
|
|||||||
num_lock: false,
|
num_lock: false,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let keyboard = Arc::new(Mutex::new(AppKeyboard{
|
let keyboard = Arc::new(Mutex::new(AppKeyboard {
|
||||||
current: None,
|
current: None,
|
||||||
delay: 0,
|
delay: 0,
|
||||||
rate: 0,
|
rate: 0,
|
||||||
@@ -485,7 +481,10 @@ impl<'a> App<'a> {
|
|||||||
let mut kbd = kb2.lock().unwrap();
|
let mut kbd = kb2.lock().unwrap();
|
||||||
kbd.current = Some(ev.clone());
|
kbd.current = Some(ev.clone());
|
||||||
kbd.next = if kbd.delay > 0 {
|
kbd.next = if kbd.delay > 0 {
|
||||||
Some(Local::now().naive_local() + Duration::milliseconds(kbd.delay.into()))
|
Some(
|
||||||
|
Local::now().naive_local()
|
||||||
|
+ Duration::milliseconds(kbd.delay.into()),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@@ -496,10 +495,10 @@ impl<'a> App<'a> {
|
|||||||
} else {
|
} else {
|
||||||
kb2.lock().unwrap().next = None;
|
kb2.lock().unwrap().next = None;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
KbEvent::Leave { .. } => {
|
KbEvent::Leave { .. } => {
|
||||||
kb2.lock().unwrap().next = None;
|
kb2.lock().unwrap().next = None;
|
||||||
},
|
}
|
||||||
KbEvent::RepeatInfo { delay, rate } => {
|
KbEvent::RepeatInfo { delay, rate } => {
|
||||||
let mut kbd = kb2.lock().unwrap();
|
let mut kbd = kb2.lock().unwrap();
|
||||||
kbd.delay = delay;
|
kbd.delay = delay;
|
||||||
@@ -513,15 +512,16 @@ impl<'a> App<'a> {
|
|||||||
//
|
//
|
||||||
// Prepare shell so that we can create our shell surface
|
// Prepare shell so that we can create our shell surface
|
||||||
//
|
//
|
||||||
inner.lock().unwrap().set_shell(Some(
|
inner
|
||||||
if let Ok(layer) = manager.instantiate_exact(1) {
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.set_shell(Some(if let Ok(layer) = manager.instantiate_exact(1) {
|
||||||
layer
|
layer
|
||||||
} else {
|
} else {
|
||||||
panic!("server didn't advertise `zwlr_layer_shell_v1`");
|
panic!("server didn't advertise `zwlr_layer_shell_v1`");
|
||||||
},
|
}));
|
||||||
));
|
|
||||||
|
|
||||||
event_queue.sync_roundtrip(&mut(), |_, _, _|{}).unwrap();
|
event_queue.sync_roundtrip(&mut (), |_, _, _| {}).unwrap();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Cursor processing
|
// Cursor processing
|
||||||
|
|||||||
+1
-1
@@ -345,6 +345,6 @@ impl Default for Config {
|
|||||||
fn get_font<'a>(name: &str, map: &'a FontMap) -> FontRef<'a> {
|
fn get_font<'a>(name: &str, map: &'a FontMap) -> FontRef<'a> {
|
||||||
match map.get(name) {
|
match map.get(name) {
|
||||||
Some(f) => f,
|
Some(f) => f,
|
||||||
None => panic!(format!("Font {} is missing from the config", name)),
|
None => panic!("Font {} is missing from the config", name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::env;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fs::{create_dir_all, File, OpenOptions};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, Default)]
|
||||||
|
pub struct Data {
|
||||||
|
pub entries: HashMap<String, i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Data {
|
||||||
|
pub fn load() -> Result<Data, Box<dyn Error>> {
|
||||||
|
Ok(serde_yaml::from_reader(Self::read_file()?)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(&self) -> Result<(), Box<dyn Error>> {
|
||||||
|
Ok(serde_yaml::to_writer(Self::write_file()?, self)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_file() -> Result<File, Box<dyn Error>> {
|
||||||
|
Ok(OpenOptions::new()
|
||||||
|
.create(true)
|
||||||
|
.write(true)
|
||||||
|
.read(true)
|
||||||
|
.open(Self::path()?)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_file() -> Result<File, Box<dyn Error>> {
|
||||||
|
Ok(OpenOptions::new()
|
||||||
|
.create(true)
|
||||||
|
.write(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(Self::path()?)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path() -> Result<PathBuf, Box<dyn Error>> {
|
||||||
|
let xdg_cache = match env::var_os("XDG_CACHE_HOME") {
|
||||||
|
Some(s) => s
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| "Unable to resolve $XDG_CACHE_HOME")?,
|
||||||
|
None => format!(
|
||||||
|
"{}/.cache",
|
||||||
|
env::var_os("HOME")
|
||||||
|
.ok_or("Unable to resolve $HOME")?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| "Unable to resolve $HOME")?
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
let cache_dir = PathBuf::from(xdg_cache).join("wldash");
|
||||||
|
create_dir_all(&cache_dir)?;
|
||||||
|
|
||||||
|
Ok(cache_dir.join("data.yaml"))
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-2
@@ -1,11 +1,12 @@
|
|||||||
extern crate ini;
|
extern crate ini;
|
||||||
use ini::{Ini, ParseOption};
|
use ini::{Ini, ParseOption};
|
||||||
|
use itertools::Itertools;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs;
|
|
||||||
use std::io::Error as io_error;
|
use std::io::Error as io_error;
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, Hash)]
|
#[derive(Clone, Debug, Eq, Hash)]
|
||||||
pub struct Desktop {
|
pub struct Desktop {
|
||||||
@@ -56,7 +57,7 @@ impl Desktop {
|
|||||||
|
|
||||||
fn parse_dir(d: &str) -> Result<Vec<Desktop>, Box<dyn Error>> {
|
fn parse_dir(d: &str) -> Result<Vec<Desktop>, Box<dyn Error>> {
|
||||||
let mut files: Vec<Desktop> = Vec::with_capacity(16);
|
let mut files: Vec<Desktop> = Vec::with_capacity(16);
|
||||||
for entry in fs::read_dir(d)? {
|
for entry in WalkDir::new(d) {
|
||||||
let entry = entry?;
|
let entry = entry?;
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
|
|
||||||
@@ -107,5 +108,6 @@ pub fn load_desktop_files() -> Vec<Desktop> {
|
|||||||
.filter(|d| {
|
.filter(|d| {
|
||||||
!d.hidden && !d.no_display && (d.entry_type == "Application" || d.entry_type == "Link")
|
!d.hidden && !d.no_display && (d.entry_type == "Application" || d.entry_type == "Link")
|
||||||
})
|
})
|
||||||
|
.unique_by(|x| x.name.clone())
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-13
@@ -182,10 +182,9 @@ fn create_shm_fd() -> io::Result<RawFd> {
|
|||||||
memfd::MemFdCreateFlag::MFD_CLOEXEC,
|
memfd::MemFdCreateFlag::MFD_CLOEXEC,
|
||||||
) {
|
) {
|
||||||
Ok(fd) => return Ok(fd),
|
Ok(fd) => return Ok(fd),
|
||||||
Err(nix::Error::Sys(Errno::EINTR)) => continue,
|
Err(Errno::EINTR) => continue,
|
||||||
Err(nix::Error::Sys(Errno::ENOSYS)) => break,
|
Err(Errno::ENOSYS) => break,
|
||||||
Err(nix::Error::Sys(errno)) => return Err(io::Error::from(errno)),
|
Err(errno) => return Err(io::Error::from(errno)),
|
||||||
Err(err) => unreachable!(err),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,14 +205,12 @@ fn create_shm_fd() -> io::Result<RawFd> {
|
|||||||
) {
|
) {
|
||||||
Ok(fd) => match mman::shm_unlink(mem_file_handle.as_str()) {
|
Ok(fd) => match mman::shm_unlink(mem_file_handle.as_str()) {
|
||||||
Ok(_) => return Ok(fd),
|
Ok(_) => return Ok(fd),
|
||||||
Err(nix::Error::Sys(errno)) => match unistd::close(fd) {
|
Err(errno) => match unistd::close(fd) {
|
||||||
Ok(_) => return Err(io::Error::from(errno)),
|
Ok(_) => return Err(io::Error::from(errno)),
|
||||||
Err(nix::Error::Sys(errno)) => return Err(io::Error::from(errno)),
|
Err(errno) => return Err(io::Error::from(errno)),
|
||||||
Err(err) => panic!(err),
|
|
||||||
},
|
},
|
||||||
Err(err) => panic!(err),
|
|
||||||
},
|
},
|
||||||
Err(nix::Error::Sys(Errno::EEXIST)) => {
|
Err(Errno::EEXIST) => {
|
||||||
// If a file with that handle exists then change the handle
|
// If a file with that handle exists then change the handle
|
||||||
mem_file_handle = format!(
|
mem_file_handle = format!(
|
||||||
"/smithay-client-toolkit-{}",
|
"/smithay-client-toolkit-{}",
|
||||||
@@ -221,14 +218,12 @@ fn create_shm_fd() -> io::Result<RawFd> {
|
|||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Err(nix::Error::Sys(Errno::EINTR)) => continue,
|
Err(Errno::EINTR) => continue,
|
||||||
Err(nix::Error::Sys(errno)) => return Err(io::Error::from(errno)),
|
Err(errno) => return Err(io::Error::from(errno)),
|
||||||
Err(err) => unreachable!(err),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct DoubleMemPool {
|
pub struct DoubleMemPool {
|
||||||
pool1: MemPool,
|
pool1: MemPool,
|
||||||
pool2: MemPool,
|
pool2: MemPool,
|
||||||
|
|||||||
+11
-9
@@ -8,16 +8,16 @@ struct CachedGlyph {
|
|||||||
dimensions: (u32, u32),
|
dimensions: (u32, u32),
|
||||||
origin: (i32, i32),
|
origin: (i32, i32),
|
||||||
render: Vec<f32>,
|
render: Vec<f32>,
|
||||||
|
advance: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CachedGlyph {
|
impl CachedGlyph {
|
||||||
fn new(font: FontRef, size: f32, ch: char) -> CachedGlyph {
|
fn new(font: FontRef, size: f32, ch: char) -> CachedGlyph {
|
||||||
let scale = Scale::uniform(size);
|
let scale = Scale::uniform(size);
|
||||||
let v_metrics = font.v_metrics(scale);
|
let v_metrics = font.v_metrics(scale);
|
||||||
let glyph = font
|
let glyph = font.glyph(ch).scaled(scale);
|
||||||
.glyph(ch)
|
let advance = glyph.h_metrics().advance_width as i32;
|
||||||
.scaled(scale)
|
let glyph = glyph.positioned(point(0.0, v_metrics.ascent));
|
||||||
.positioned(point(0.0, v_metrics.ascent));
|
|
||||||
|
|
||||||
if let Some(bounding_box) = glyph.pixel_bounding_box() {
|
if let Some(bounding_box) = glyph.pixel_bounding_box() {
|
||||||
let origin = (bounding_box.min.x, bounding_box.min.y);
|
let origin = (bounding_box.min.x, bounding_box.min.y);
|
||||||
@@ -35,12 +35,14 @@ impl CachedGlyph {
|
|||||||
origin,
|
origin,
|
||||||
dimensions,
|
dimensions,
|
||||||
render,
|
render,
|
||||||
|
advance,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CachedGlyph {
|
CachedGlyph {
|
||||||
origin: (0, 0),
|
origin: (0, 0),
|
||||||
dimensions: ((size / 4.0) as u32, 0),
|
dimensions: (0, 0),
|
||||||
render: Vec::new(),
|
render: Vec::new(),
|
||||||
|
advance: (size / 4.0) as i32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +120,7 @@ impl<'a> Font<'a> {
|
|||||||
}
|
}
|
||||||
for glyph in glyphs {
|
for glyph in glyphs {
|
||||||
glyph.draw(buf, (x_off, -off), bg, c);
|
glyph.draw(buf, (x_off, -off), bg, c);
|
||||||
x_off += glyph.dimensions.0 as i32 + glyph.origin.0;
|
x_off += glyph.advance;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((x_off as u32, self.size as u32))
|
Ok((x_off as u32, self.size as u32))
|
||||||
@@ -157,7 +159,7 @@ impl<'a> Font<'a> {
|
|||||||
self.draw_cursor(buf, c, x_off as u32, height)?;
|
self.draw_cursor(buf, c, x_off as u32, height)?;
|
||||||
}
|
}
|
||||||
glyph.draw(buf, (x_off, -off), bg, c);
|
glyph.draw(buf, (x_off, -off), bg, c);
|
||||||
x_off += glyph.dimensions.0 as i32 + glyph.origin.0;
|
x_off += glyph.advance;
|
||||||
}
|
}
|
||||||
if cursor == glyphs.len() {
|
if cursor == glyphs.len() {
|
||||||
self.draw_cursor(buf, c, x_off as u32, height)?;
|
self.draw_cursor(buf, c, x_off as u32, height)?;
|
||||||
@@ -193,7 +195,7 @@ impl<'a> Font<'a> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let width = glyph.dimensions.0 as i32 + glyph.origin.0;
|
let width = glyph.advance;
|
||||||
if width > max {
|
if width > max {
|
||||||
max = width
|
max = width
|
||||||
}
|
}
|
||||||
@@ -285,7 +287,7 @@ impl<'a> Font<'a> {
|
|||||||
}
|
}
|
||||||
for (idx, glyph) in glyphs.into_iter().enumerate() {
|
for (idx, glyph) in glyphs.into_iter().enumerate() {
|
||||||
glyph.draw(buf, (x_off, -off), bg, &color[idx]);
|
glyph.draw(buf, (x_off, -off), bg, &color[idx]);
|
||||||
x_off += glyph.dimensions.0 as i32 + glyph.origin.0;
|
x_off += glyph.advance;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((x_off as u32, self.size as u32))
|
Ok((x_off as u32, self.size as u32))
|
||||||
|
|||||||
+3
-1
@@ -256,9 +256,11 @@ functions:
|
|||||||
|
|
||||||
lazy_static::lazy_static!(
|
lazy_static::lazy_static!(
|
||||||
pub static ref XKBCOMMON_OPTION: Option<XkbCommon> = {
|
pub static ref XKBCOMMON_OPTION: Option<XkbCommon> = {
|
||||||
XkbCommon::open("libxkbcommon.so.0")
|
unsafe {
|
||||||
|
XkbCommon::open("libxkbcommon.so.0")
|
||||||
.or_else(|_| XkbCommon::open("libxkbcommon.so"))
|
.or_else(|_| XkbCommon::open("libxkbcommon.so"))
|
||||||
.ok()
|
.ok()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
pub static ref XKBCOMMON_HANDLE: &'static XkbCommon = {
|
pub static ref XKBCOMMON_HANDLE: &'static XkbCommon = {
|
||||||
XKBCOMMON_OPTION.as_ref().expect("Library libxkbcommon.so could not be loaded.")
|
XKBCOMMON_OPTION.as_ref().expect("Library libxkbcommon.so could not be loaded.")
|
||||||
|
|||||||
+14
-14
@@ -1,17 +1,17 @@
|
|||||||
#![allow(missing_docs, non_upper_case_globals, unused_parens, clippy::all)]
|
#![allow(missing_docs, non_upper_case_globals, unused_parens, clippy::all)]
|
||||||
|
|
||||||
pub const XKB_KEY_BackSpace :u32 = 0xff08; /* Back space, back char */
|
pub const XKB_KEY_BackSpace: u32 = 0xff08; /* Back space, back char */
|
||||||
pub const XKB_KEY_Tab :u32 = 0xff09;
|
pub const XKB_KEY_Tab: u32 = 0xff09;
|
||||||
pub const XKB_KEY_Return :u32 = 0xff0d; /* Return, enter */
|
pub const XKB_KEY_Return: u32 = 0xff0d; /* Return, enter */
|
||||||
pub const XKB_KEY_Escape :u32 = 0xff1b;
|
pub const XKB_KEY_Escape: u32 = 0xff1b;
|
||||||
pub const XKB_KEY_Delete :u32 = 0xffff; /* Delete, rubout */
|
pub const XKB_KEY_Delete: u32 = 0xffff; /* Delete, rubout */
|
||||||
pub const XKB_KEY_Home :u32 = 0xff50;
|
pub const XKB_KEY_Home: u32 = 0xff50;
|
||||||
pub const XKB_KEY_Left :u32 = 0xff51; /* Move left, left arrow */
|
pub const XKB_KEY_Left: u32 = 0xff51; /* Move left, left arrow */
|
||||||
pub const XKB_KEY_Right :u32 = 0xff53; /* Move right, right arrow */
|
pub const XKB_KEY_Right: u32 = 0xff53; /* Move right, right arrow */
|
||||||
pub const XKB_KEY_End :u32 = 0xff57; /* EOL */
|
pub const XKB_KEY_End: u32 = 0xff57; /* EOL */
|
||||||
|
|
||||||
pub const XKB_KEY_ISO_Left_Tab :u32 = 0xfe20;
|
pub const XKB_KEY_ISO_Left_Tab: u32 = 0xfe20;
|
||||||
pub const XKB_KEY_e :u32 = 0x0065; /* U+0065 LATIN SMALL LETTER E */
|
pub const XKB_KEY_e: u32 = 0x0065; /* U+0065 LATIN SMALL LETTER E */
|
||||||
pub const XKB_KEY_a :u32 = 0x0061; /* U+0061 LATIN SMALL LETTER A */
|
pub const XKB_KEY_a: u32 = 0x0061; /* U+0061 LATIN SMALL LETTER A */
|
||||||
pub const XKB_KEY_c :u32 = 0x0063; /* U+0063 LATIN SMALL LETTER C */
|
pub const XKB_KEY_c: u32 = 0x0063; /* U+0063 LATIN SMALL LETTER C */
|
||||||
pub const XKB_KEY_u :u32 = 0x0075; /* U+0075 LATIN SMALL LETTER U */
|
pub const XKB_KEY_u: u32 = 0x0075; /* U+0075 LATIN SMALL LETTER U */
|
||||||
|
|||||||
+14
-8
@@ -23,8 +23,8 @@ use wayland_client::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
mod ffi;
|
mod ffi;
|
||||||
mod state;
|
|
||||||
pub mod keysyms;
|
pub mod keysyms;
|
||||||
|
mod state;
|
||||||
|
|
||||||
use self::state::KbState;
|
use self::state::KbState;
|
||||||
pub use self::state::{ModifiersState, RMLVO};
|
pub use self::state::{ModifiersState, RMLVO};
|
||||||
@@ -118,10 +118,7 @@ where
|
|||||||
let callback = Rc::new(RefCell::new(callback));
|
let callback = Rc::new(RefCell::new(callback));
|
||||||
|
|
||||||
// prepare the handler
|
// prepare the handler
|
||||||
let mut kbd_handler = KbdHandler {
|
let mut kbd_handler = KbdHandler { callback, state };
|
||||||
callback,
|
|
||||||
state,
|
|
||||||
};
|
|
||||||
|
|
||||||
keyboard.quick_assign(move |keyboard, event, data| {
|
keyboard.quick_assign(move |keyboard, event, data| {
|
||||||
kbd_handler.event(keyboard.detach(), event, data)
|
kbd_handler.event(keyboard.detach(), event, data)
|
||||||
@@ -331,8 +328,17 @@ impl KbdHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn repeat_info(&mut self, object: wl_keyboard::WlKeyboard, rate: i32, delay: i32, dispatch_data: wayland_client::DispatchData) {
|
fn repeat_info(
|
||||||
(&mut *self.callback.borrow_mut())(Event::RepeatInfo { rate, delay }, object, dispatch_data);
|
&mut self,
|
||||||
|
object: wl_keyboard::WlKeyboard,
|
||||||
|
rate: i32,
|
||||||
|
delay: i32,
|
||||||
|
dispatch_data: wayland_client::DispatchData,
|
||||||
|
) {
|
||||||
|
(&mut *self.callback.borrow_mut())(
|
||||||
|
Event::RepeatInfo { rate, delay },
|
||||||
|
object,
|
||||||
|
dispatch_data,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -398,4 +398,3 @@ impl Drop for KbState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -12,15 +12,16 @@ use timerfd::{SetTimeFlags, TimerFd, TimerState};
|
|||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
mod keyboard;
|
|
||||||
mod cmd;
|
mod cmd;
|
||||||
mod color;
|
mod color;
|
||||||
mod config;
|
mod config;
|
||||||
mod configfmt;
|
mod configfmt;
|
||||||
|
mod data;
|
||||||
mod desktop;
|
mod desktop;
|
||||||
mod doublemempool;
|
mod doublemempool;
|
||||||
mod draw;
|
mod draw;
|
||||||
mod fonts;
|
mod fonts;
|
||||||
|
mod keyboard;
|
||||||
mod widget;
|
mod widget;
|
||||||
mod widgets;
|
mod widgets;
|
||||||
|
|
||||||
@@ -206,7 +207,10 @@ fn main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let mut timer = TimerFd::new().unwrap();
|
let mut timer = TimerFd::new().unwrap();
|
||||||
let ev_fd = PollFd::new(app.event_queue().display().get_connection_fd(), PollFlags::POLLIN);
|
let ev_fd = PollFd::new(
|
||||||
|
app.event_queue().display().get_connection_fd(),
|
||||||
|
PollFlags::POLLIN,
|
||||||
|
);
|
||||||
let rx_fd = PollFd::new(rx_pipe.as_raw_fd(), PollFlags::POLLIN);
|
let rx_fd = PollFd::new(rx_pipe.as_raw_fd(), PollFlags::POLLIN);
|
||||||
let tm_fd = PollFd::new(timer.as_raw_fd(), PollFlags::POLLIN);
|
let tm_fd = PollFd::new(timer.as_raw_fd(), PollFlags::POLLIN);
|
||||||
let ipc_fd = PollFd::new(listener.as_raw_fd(), PollFlags::POLLIN);
|
let ipc_fd = PollFd::new(listener.as_raw_fd(), PollFlags::POLLIN);
|
||||||
@@ -323,7 +327,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.event_queue()
|
app.event_queue()
|
||||||
.dispatch_pending(&mut (), |_, _, _|{})
|
.dispatch_pending(&mut (), |_, _, _| {})
|
||||||
.expect("Failed to dispatch all messages.");
|
.expect("Failed to dispatch all messages.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,8 +1,8 @@
|
|||||||
use crate::buffer::Buffer;
|
use crate::buffer::Buffer;
|
||||||
use crate::color::Color;
|
use crate::color::Color;
|
||||||
|
pub use crate::keyboard::{KeyState, ModifiersState};
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use nix::poll::PollFd;
|
use nix::poll::PollFd;
|
||||||
pub use crate::keyboard::{KeyState, ModifiersState};
|
|
||||||
|
|
||||||
pub struct DrawContext<'a> {
|
pub struct DrawContext<'a> {
|
||||||
pub buf: &'a mut Buffer<'a>,
|
pub buf: &'a mut Buffer<'a>,
|
||||||
|
|||||||
@@ -15,11 +15,7 @@ const SELEM_ID: u32 = 0u32;
|
|||||||
fn alsa_error_to_io_error(fail: &'static str, err: &alsa::Error) -> ::std::io::Error {
|
fn alsa_error_to_io_error(fail: &'static str, err: &alsa::Error) -> ::std::io::Error {
|
||||||
let kind = ::std::io::ErrorKind::Other;
|
let kind = ::std::io::ErrorKind::Other;
|
||||||
let func = err.func();
|
let func = err.func();
|
||||||
let errno = err
|
::std::io::Error::new(kind, format!("{}: {}{}", fail, func, err.errno()))
|
||||||
.errno()
|
|
||||||
.map(|errno| format!("; errno = {}", errno))
|
|
||||||
.unwrap_or_default();
|
|
||||||
::std::io::Error::new(kind, format!("{}: {}{}", fail, func, errno))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -99,7 +95,7 @@ impl BarWidgetImpl for Alsa {
|
|||||||
fn value(&self) -> f32 {
|
fn value(&self) -> f32 {
|
||||||
match self.get_master_volume() {
|
match self.get_master_volume() {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => panic!(e),
|
Err(e) => panic!("{}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn color(&self) -> Color {
|
fn color(&self) -> Color {
|
||||||
@@ -107,12 +103,12 @@ impl BarWidgetImpl for Alsa {
|
|||||||
}
|
}
|
||||||
fn inc(&mut self, diff: f32) {
|
fn inc(&mut self, diff: f32) {
|
||||||
if let Err(e) = self.inc_master_volume(diff) {
|
if let Err(e) = self.inc_master_volume(diff) {
|
||||||
panic!(e)
|
panic!("{}", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn set(&mut self, abs: f32) {
|
fn set(&mut self, abs: f32) {
|
||||||
if let Err(e) = self.set_master_volume(abs) {
|
if let Err(e) = self.set_master_volume(abs) {
|
||||||
panic!(e)
|
panic!("{}", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn toggle(&mut self) {}
|
fn toggle(&mut self) {}
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ impl<'a> Widget for Calendar<'a> {
|
|||||||
let cals = self.sections - 1;
|
let cals = self.sections - 1;
|
||||||
let pre_cals = cals / 2;
|
let pre_cals = cals / 2;
|
||||||
for _ in 0..pre_cals {
|
for _ in 0..pre_cals {
|
||||||
t = t.pred().with_day(1).unwrap();
|
t = t.pred_opt().unwrap().with_day(1).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if o != 0 {
|
if o != 0 {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ impl<'a> Clock<'a> {
|
|||||||
clock_cache.add_str_to_cache("0123456789:");
|
clock_cache.add_str_to_cache("0123456789:");
|
||||||
|
|
||||||
let digit = clock_cache.auto_widest("123456789")?;
|
let digit = clock_cache.auto_widest("123456789")?;
|
||||||
let colon = (clock_cache.auto_widest(":")? as f32 * 1.25) as u32;
|
let colon = clock_cache.auto_widest(":")?;
|
||||||
|
|
||||||
Ok(Box::new(Clock {
|
Ok(Box::new(Clock {
|
||||||
cur_time: time,
|
cur_time: time,
|
||||||
|
|||||||
+29
-12
@@ -14,8 +14,10 @@ use std::collections::HashMap;
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
|
|
||||||
use fuzzy_matcher::skim::{fuzzy_indices, fuzzy_match};
|
use crate::data::Data;
|
||||||
use crate::keyboard::keysyms;
|
use crate::keyboard::keysyms;
|
||||||
|
use fuzzy_matcher::skim::SkimMatcherV2;
|
||||||
|
use fuzzy_matcher::FuzzyMatcher;
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
pub struct Launcher<'a> {
|
pub struct Launcher<'a> {
|
||||||
@@ -33,6 +35,7 @@ pub struct Launcher<'a> {
|
|||||||
length: u32,
|
length: u32,
|
||||||
dirty: bool,
|
dirty: bool,
|
||||||
tx: Sender<Cmd>,
|
tx: Sender<Cmd>,
|
||||||
|
counter: Data,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Launcher<'a> {
|
impl<'a> Launcher<'a> {
|
||||||
@@ -60,6 +63,7 @@ impl<'a> Launcher<'a> {
|
|||||||
length,
|
length,
|
||||||
dirty: true,
|
dirty: true,
|
||||||
tx: listener,
|
tx: listener,
|
||||||
|
counter: Data::load().unwrap_or_default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,15 +94,17 @@ impl<'a> Launcher<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut width_remaining: i32 = (width - x_off) as i32;
|
let mut width_remaining: i32 = (width - x_off) as i32;
|
||||||
|
let fuzzy_matcher = SkimMatcherV2::default();
|
||||||
for (idx, m) in self.matches.iter().enumerate() {
|
for (idx, m) in self.matches.iter().enumerate() {
|
||||||
let mut b = match buf.offset((x_off, 0)) {
|
let mut b = match buf.offset((x_off, 0)) {
|
||||||
Ok(b) => b,
|
Ok(b) => b,
|
||||||
Err(_) => break,
|
Err(_) => break,
|
||||||
};
|
};
|
||||||
let size = if idx == self.offset && !self.input.is_empty() {
|
let size = if idx == self.offset {
|
||||||
let (_, indices) =
|
let (_, indices) = fuzzy_matcher
|
||||||
fuzzy_indices(&m.name.to_lowercase(), &self.input.to_lowercase())
|
.fuzzy_indices(&m.name.to_lowercase(), &self.input.to_lowercase())
|
||||||
.unwrap_or((0, vec![]));
|
.unwrap_or((0, vec![]));
|
||||||
|
|
||||||
let mut colors = Vec::with_capacity(m.name.len());
|
let mut colors = Vec::with_capacity(m.name.len());
|
||||||
for pos in 0..m.name.len() {
|
for pos in 0..m.name.len() {
|
||||||
if indices.contains(&pos) {
|
if indices.contains(&pos) {
|
||||||
@@ -213,17 +219,20 @@ fn wlcopy(s: &str) -> Result<(), String> {
|
|||||||
|
|
||||||
struct Matcher {
|
struct Matcher {
|
||||||
matches: HashMap<Desktop, i64>,
|
matches: HashMap<Desktop, i64>,
|
||||||
|
counter: Data,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Matcher {
|
impl Matcher {
|
||||||
fn new() -> Self {
|
fn new(counter: Data) -> Self {
|
||||||
Self {
|
Self {
|
||||||
matches: HashMap::new(),
|
matches: HashMap::new(),
|
||||||
|
counter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_match(&mut self, dtop: Desktop, val: &str, input: &str, prio: f32) {
|
fn try_match(&mut self, dtop: Desktop, val: &str, input: &str, prio: f32) {
|
||||||
if let Some(ma) = fuzzy_match(val, input) {
|
let fuzzy_matcher = SkimMatcherV2::default();
|
||||||
|
if let Some(ma) = fuzzy_matcher.fuzzy_match(val, input) {
|
||||||
let ma = ((ma as f32) * prio) as i64;
|
let ma = ((ma as f32) * prio) as i64;
|
||||||
if let Some(ma_old) = self.matches.get(&dtop) {
|
if let Some(ma_old) = self.matches.get(&dtop) {
|
||||||
// Skip over new matches for the same program that are worse
|
// Skip over new matches for the same program that are worse
|
||||||
@@ -245,9 +254,12 @@ impl Matcher {
|
|||||||
.collect::<Vec<(i64, Desktop)>>();
|
.collect::<Vec<(i64, Desktop)>>();
|
||||||
|
|
||||||
m.sort_by(|(ma1, d1), (ma2, d2)| {
|
m.sort_by(|(ma1, d1), (ma2, d2)| {
|
||||||
if ma1 > ma2 {
|
let count1 = self.counter.entries.get(&d1.name).unwrap_or(&0);
|
||||||
|
let count2 = self.counter.entries.get(&d2.name).unwrap_or(&0);
|
||||||
|
|
||||||
|
if ma1 + count1 > ma2 + count2 {
|
||||||
Ordering::Less
|
Ordering::Less
|
||||||
} else if ma1 < ma2 {
|
} else if ma1 + count1 < ma2 + count2 {
|
||||||
Ordering::Greater
|
Ordering::Greater
|
||||||
} else if d1.name.len() < d2.name.len() {
|
} else if d1.name.len() < d2.name.len() {
|
||||||
Ordering::Less
|
Ordering::Less
|
||||||
@@ -303,7 +315,7 @@ impl<'a> Widget for Launcher<'a> {
|
|||||||
}
|
}
|
||||||
Some('!') => (),
|
Some('!') => (),
|
||||||
_ => {
|
_ => {
|
||||||
let mut matcher = Matcher::new();
|
let mut matcher = Matcher::new(self.counter.clone());
|
||||||
|
|
||||||
for desktop in self.options.iter() {
|
for desktop in self.options.iter() {
|
||||||
matcher.try_match(
|
matcher.try_match(
|
||||||
@@ -417,13 +429,18 @@ impl<'a> Widget for Launcher<'a> {
|
|||||||
&self.app_opener
|
&self.app_opener
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut lexed = shlex::split(&exec).unwrap();
|
||||||
let lexed = if !prefix.is_empty() {
|
let lexed = if !prefix.is_empty() {
|
||||||
let mut prefix = shlex::split(prefix).unwrap();
|
let mut prefix = shlex::split(prefix).unwrap();
|
||||||
prefix.push(exec);
|
prefix.append(&mut lexed);
|
||||||
prefix
|
prefix
|
||||||
} else {
|
} else {
|
||||||
shlex::split(&exec).unwrap()
|
lexed
|
||||||
};
|
};
|
||||||
|
|
||||||
|
*self.counter.entries.entry(d.name.clone()).or_insert(0) += 1;
|
||||||
|
self.counter.save().expect("Unable to save data");
|
||||||
|
|
||||||
if !lexed.is_empty() {
|
if !lexed.is_empty() {
|
||||||
let _ =
|
let _ =
|
||||||
Command::new(lexed[0].clone()).args(&lexed[1..]).spawn();
|
Command::new(lexed[0].clone()).args(&lexed[1..]).spawn();
|
||||||
|
|||||||
Reference in New Issue
Block a user