Skip to content

Commit f3493ca

Browse files
committed
clean up
1 parent c8c0067 commit f3493ca

2 files changed

Lines changed: 188 additions & 129 deletions

File tree

Lines changed: 99 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,39 @@
33
windows_subsystem = "windows"
44
)]
55

6-
use std::env;
7-
use std::path::PathBuf;
8-
use std::process::Command;
6+
use std::{
7+
env,
8+
path::PathBuf,
9+
process::Command,
10+
};
911

1012
use freya::{
1113
prelude::*,
12-
winit::{dpi::LogicalPosition, window::WindowLevel},
14+
winit::{
15+
dpi::LogicalPosition,
16+
platform::x11::{
17+
WindowAttributesExtX11,
18+
WindowType,
19+
},
20+
window::WindowLevel,
21+
},
1322
};
1423

1524
fn main() {
16-
let (width, height) = (64, 800);
1725
launch(
1826
LaunchConfig::new().with_window(
1927
WindowConfig::new(app)
2028
.with_title("Dock")
21-
.with_size(width as f64, height as f64)
29+
.with_size(50., 800.)
2230
.with_decorations(false)
2331
.with_resizable(false)
24-
.with_background(Color::from_rgb(30, 30, 30))
25-
.with_window_attributes(move |attributes, el| {
26-
let attributes = attributes.with_window_level(WindowLevel::AlwaysOnTop);
27-
28-
// Position on left side of screen, centered vertically
29-
if let Some(monitor) = el
30-
.primary_monitor()
31-
.or_else(|| el.available_monitors().next())
32-
{
33-
let size = monitor.size();
34-
attributes.with_position(LogicalPosition {
35-
x: 0,
36-
y: size.height as i32 / 2 - height / 2,
37-
})
38-
} else {
39-
attributes
40-
}
32+
.with_background(Color::TRANSPARENT)
33+
.with_transparency(true)
34+
.with_window_attributes(move |attributes, _| {
35+
attributes
36+
.with_x11_window_type(vec![WindowType::Dock])
37+
.with_window_level(WindowLevel::AlwaysOnTop)
38+
.with_position(LogicalPosition { x: 54, y: 32 })
4139
}),
4240
),
4341
)
@@ -47,58 +45,78 @@ fn app() -> impl IntoElement {
4745
let apps = use_hook(get_pinned_apps);
4846

4947
rect()
50-
.width(Size::fill())
51-
.height(Size::fill())
52-
.padding(Gaps::new_all(8.))
48+
.expanded()
49+
.padding(8.)
5350
.spacing(8.)
54-
.background(Color::from_rgb(30, 30, 30))
55-
.corner_radius(8.)
51+
.background((30, 30, 30, 0.8))
5652
.children(apps.iter().filter_map(|app| {
5753
app.icon_path.as_ref().map(|icon_path| {
58-
dock_icon(icon_path.clone(), app.name.clone())
54+
DockIcon {
55+
icon_path: icon_path.clone(),
56+
name: app.name.clone(),
57+
}
58+
.into()
5959
})
6060
}))
6161
}
6262

63-
fn dock_icon(icon_path: PathBuf, name: String) -> Element {
64-
let mut hovered = use_state(|| false);
65-
66-
let background = if *hovered.read() {
67-
Color::from_rgb(60, 60, 60)
68-
} else {
69-
Color::TRANSPARENT
70-
};
63+
#[derive(PartialEq)]
64+
struct DockIcon {
65+
icon_path: PathBuf,
66+
name: String,
67+
}
7168

72-
let is_svg = icon_path
73-
.extension()
74-
.is_some_and(|ext| ext.eq_ignore_ascii_case("svg"));
75-
76-
let icon_element: Element = if is_svg {
77-
let svg_data = use_hook(|| {
78-
std::fs::read(&icon_path)
79-
.map(Bytes::from)
80-
.unwrap_or_default()
81-
});
82-
svg(svg_data).width(Size::px(40.)).height(Size::px(40.)).into()
83-
} else {
84-
ImageViewer::new(icon_path)
85-
.width(Size::px(40.))
86-
.height(Size::px(40.))
87-
.into()
88-
};
69+
impl Component for DockIcon {
70+
fn render(&self) -> impl IntoElement {
71+
let mut hovered = use_state(|| false);
72+
73+
let is_svg = self
74+
.icon_path
75+
.extension()
76+
.is_some_and(|ext| ext.eq_ignore_ascii_case("svg"));
77+
78+
let icon_element: Element = if is_svg {
79+
let icon_path = self.icon_path.clone();
80+
let svg_data = use_hook(|| {
81+
std::fs::read(&icon_path)
82+
.map(Bytes::from)
83+
.unwrap_or_default()
84+
});
85+
svg(svg_data)
86+
.width(Size::px(28.))
87+
.height(Size::px(28.))
88+
.into()
89+
} else {
90+
ImageViewer::new(self.icon_path.clone())
91+
.sampling_mode(SamplingMode::Trilinear)
92+
.width(Size::px(28.))
93+
.height(Size::px(28.))
94+
.into()
95+
};
96+
97+
let name = self.name.clone();
98+
let background = if hovered() {
99+
Color::from_rgb(60, 60, 60)
100+
} else {
101+
Color::TRANSPARENT
102+
};
103+
104+
rect()
105+
.center()
106+
.padding(4.)
107+
.corner_radius(8.)
108+
.background(background)
109+
.on_pointer_enter(move |_| hovered.set(true))
110+
.on_pointer_leave(move |_| hovered.set(false))
111+
.on_press(move |_| {
112+
println!("Clicked: {}", name);
113+
})
114+
.child(icon_element)
115+
}
89116

90-
rect()
91-
.center()
92-
.padding(Gaps::new_all(4.))
93-
.corner_radius(8.)
94-
.background(background)
95-
.on_pointer_enter(move |_| hovered.set(true))
96-
.on_pointer_leave(move |_| hovered.set(false))
97-
.on_mouse_up(move |_| {
98-
println!("Clicked: {}", name);
99-
})
100-
.child(icon_element)
101-
.into()
117+
fn render_key(&self) -> DiffKey {
118+
DiffKey::from(&self.name)
119+
}
102120
}
103121

104122
#[derive(Clone, Debug)]
@@ -151,7 +169,8 @@ fn parse_desktop_file(desktop_id: &str) -> (String, Option<String>) {
151169
Some(PathBuf::from("/usr/share/applications")),
152170
Some(PathBuf::from("/var/lib/flatpak/exports/share/applications")),
153171
home.as_ref().map(|h| h.join(".local/share/applications")),
154-
home.as_ref().map(|h| h.join(".local/share/flatpak/exports/share/applications")),
172+
home.as_ref()
173+
.map(|h| h.join(".local/share/flatpak/exports/share/applications")),
155174
Some(PathBuf::from("/var/lib/snapd/desktop/applications")),
156175
];
157176

@@ -191,9 +210,12 @@ fn find_icon_path(icon_name: &str) -> Option<PathBuf> {
191210

192211
let icon_dirs = [
193212
Some(PathBuf::from("/usr/share/icons/hicolor")),
194-
Some(PathBuf::from("/var/lib/flatpak/exports/share/icons/hicolor")),
213+
Some(PathBuf::from(
214+
"/var/lib/flatpak/exports/share/icons/hicolor",
215+
)),
195216
home.as_ref().map(|h| h.join(".local/share/icons/hicolor")),
196-
home.as_ref().map(|h| h.join(".local/share/flatpak/exports/share/icons/hicolor")),
217+
home.as_ref()
218+
.map(|h| h.join(".local/share/flatpak/exports/share/icons/hicolor")),
197219
Some(PathBuf::from("/usr/share/pixmaps")),
198220
];
199221

@@ -203,7 +225,10 @@ fn find_icon_path(icon_name: &str) -> Option<PathBuf> {
203225
// First pass: look for PNG files only
204226
for dir in icon_dirs.iter().flatten() {
205227
for size in &sizes {
206-
let icon_path = dir.join(size).join("apps").join(format!("{}.png", icon_name));
228+
let icon_path = dir
229+
.join(size)
230+
.join("apps")
231+
.join(format!("{}.png", icon_name));
207232
if icon_path.exists() {
208233
return Some(icon_path);
209234
}
@@ -219,7 +244,10 @@ fn find_icon_path(icon_name: &str) -> Option<PathBuf> {
219244
// Second pass: fall back to SVG if no PNG found
220245
for dir in icon_dirs.into_iter().flatten() {
221246
for size in &sizes {
222-
let icon_path = dir.join(size).join("apps").join(format!("{}.svg", icon_name));
247+
let icon_path = dir
248+
.join(size)
249+
.join("apps")
250+
.join(format!("{}.svg", icon_name));
223251
if icon_path.exists() {
224252
return Some(icon_path);
225253
}

0 commit comments

Comments
 (0)