diff --git a/src/hyprland_binds.rs b/src/hyprland_binds.rs
index d500749..4ec74b8 100644
--- a/src/hyprland_binds.rs
+++ b/src/hyprland_binds.rs
@@ -158,6 +158,7 @@ pub fn register_hyprland_binds(config: &ScytheConfig) {
"float, class:^(scythe-toast)$",
"pin, class:^(scythe-toast)$",
"noborder, class:^(scythe-toast)$",
+ "move 100%-w 16, class:^(scythe-toast)$",
"float, class:^(vrec-overlay)$",
"move 0 0, class:^(vrec-overlay)$",
"size 100% 100%, class:^(vrec-overlay)$",
diff --git a/src/overlay.rs b/src/overlay.rs
index 57c31f4..3b56c66 100644
--- a/src/overlay.rs
+++ b/src/overlay.rs
@@ -199,7 +199,7 @@ pub fn show_shadowplay_toast(title: &str, subtitle: &str, icon: ToastIcon) {
_ => ("#38bdf8", (0.220, 0.741, 0.973)),
};
- let (active_accent_hex, active_accent) = if icon == ToastIcon::Record {
+ let (_active_accent_hex, active_accent) = if icon == ToastIcon::Record {
("#ef4444", (0.937, 0.267, 0.267))
} else {
(accent_hex, accent_rgb)
@@ -229,8 +229,8 @@ pub fn show_shadowplay_toast(title: &str, subtitle: &str, icon: ToastIcon) {
app.connect_activate(move |app| {
let window = ApplicationWindow::builder()
.application(app)
- .default_width(360)
- .default_height(64)
+ .default_width(320)
+ .default_height(56)
.build();
#[cfg(target_os = "linux")]
@@ -250,8 +250,8 @@ pub fn show_shadowplay_toast(title: &str, subtitle: &str, icon: ToastIcon) {
}
window.set_anchor(gtk_layer_shell::Edge::Top, true);
window.set_anchor(gtk_layer_shell::Edge::Right, true);
- window.set_layer_shell_margin(gtk_layer_shell::Edge::Top, 28);
- window.set_layer_shell_margin(gtk_layer_shell::Edge::Right, 28);
+ window.set_layer_shell_margin(gtk_layer_shell::Edge::Top, 16);
+ window.set_layer_shell_margin(gtk_layer_shell::Edge::Right, 0); // flush on screen right edge
window.set_keyboard_interactivity(false);
} else {
window.set_decorated(false);
@@ -260,8 +260,8 @@ pub fn show_shadowplay_toast(title: &str, subtitle: &str, icon: ToastIcon) {
window.set_accept_focus(false);
if let Some(ref mon) = active_monitor {
let geom = mon.geometry();
- let x = geom.x() + geom.width() - 360 - 28;
- let y = geom.y() + 28;
+ let x = geom.x() + geom.width() - 320;
+ let y = geom.y() + 16;
window.move_(x, y);
}
}
@@ -289,14 +289,12 @@ pub fn show_shadowplay_toast(title: &str, subtitle: &str, icon: ToastIcon) {
box-shadow: none;
}}
.toast-card {{
- background-color: rgba(14, 16, 21, 0.96);
- border: 1px solid rgba(255, 255, 255, 0.14);
- border-left: 4px solid {accent};
+ background-color: rgba(10, 10, 10, 0.65);
+ border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 0px;
- box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.75);
+ box-shadow: none;
}}
"#,
- accent = active_accent_hex
);
let _ = css_provider.load_from_data(css.as_bytes());
if let Some(screen) = gdk::Screen::default() {
@@ -316,31 +314,20 @@ pub fn show_shadowplay_toast(title: &str, subtitle: &str, icon: ToastIcon) {
hbox.connect_draw(move |widget, cr| {
let w = widget.allocated_width() as f64;
let h = widget.allocated_height() as f64;
- let card_h = (h - 4.0).max(10.0);
cr.set_operator(gtk::cairo::Operator::Over);
- // 1. Drop shadow (soft dark shadow offset down by 4px)
- cr.set_source_rgba(0.0, 0.0, 0.0, 0.60);
- cr.rectangle(0.0, 4.0, w, card_h);
+ // Sleek translucent neutral dark glass background (matching HUD cards)
+ cr.set_source_rgba(10.0 / 255.0, 10.0 / 255.0, 10.0 / 255.0, 0.65);
+ cr.rectangle(0.0, 0.0, w, h);
let _ = cr.fill();
- // 2. Solid obsidian dark slate background (matching egui rgba(14, 16, 21, 0.96))
- cr.set_source_rgba(14.0 / 255.0, 16.0 / 255.0, 21.0 / 255.0, 0.96);
- cr.rectangle(0.0, 0.0, w, card_h);
- let _ = cr.fill();
-
- // 3. Subtle white border (1px inside)
- cr.set_source_rgba(1.0, 1.0, 1.0, 0.14);
+ // Refined subtle accent stroke framing the card
+ cr.set_source_rgba(active_accent.0, active_accent.1, active_accent.2, 0.55);
cr.set_line_width(1.0);
- cr.rectangle(0.5, 0.5, w - 1.0, card_h - 1.0);
+ cr.rectangle(0.5, 0.5, w - 1.0, h - 1.0);
let _ = cr.stroke();
- // 4. Left accent bar (4.0px width)
- cr.set_source_rgb(active_accent.0, active_accent.1, active_accent.2);
- cr.rectangle(0.0, 0.0, 4.0, card_h);
- let _ = cr.fill();
-
gtk::glib::Propagation::Proceed
});
@@ -355,75 +342,75 @@ pub fn show_shadowplay_toast(title: &str, subtitle: &str, icon: ToastIcon) {
let cy = 16.0;
match icon_type {
ToastIcon::Replay => {
- let r = 10.0;
cr.set_source_rgb(accent_rgb.0, accent_rgb.1, accent_rgb.2);
- cr.set_line_width(2.2);
- cr.arc(cx, cy, r, 0.25 * PI, 1.80 * PI);
- let _ = cr.stroke();
-
- let a_x = cx + r * (0.25 * PI).cos();
- let a_y = cy + r * (0.25 * PI).sin();
- cr.move_to(a_x, a_y);
- cr.line_to(a_x - 4.5, a_y + 0.5);
- cr.line_to(a_x - 0.5, a_y - 4.5);
- cr.close_path();
- let _ = cr.fill();
-
- let tri_r = 4.0;
- cr.move_to(cx + tri_r + 0.5, cy);
- cr.line_to(cx - tri_r * 0.6 + 0.5, cy - tri_r * 0.86);
- cr.line_to(cx - tri_r * 0.6 + 0.5, cy + tri_r * 0.86);
- cr.close_path();
- let _ = cr.fill();
+ cr.set_line_width(1.8);
+ cr.set_line_cap(gtk::cairo::LineCap::Round);
+ cr.set_line_join(gtk::cairo::LineJoin::Round);
+ let ch_h = 7.0;
+ let ch_w = 4.4;
+ let gap = 4.2;
+ let start_x = cx - (ch_w + gap) * 0.5;
+ for i in 0..2 {
+ let tip_x = start_x + (i as f64) * gap;
+ let base_x = tip_x + ch_w;
+ cr.move_to(base_x, cy - ch_h);
+ cr.line_to(tip_x, cy);
+ cr.line_to(base_x, cy + ch_h);
+ let _ = cr.stroke();
+ }
}
ToastIcon::Record => {
- cr.set_source_rgba(0.937, 0.267, 0.267, 0.25);
- cr.arc(cx, cy, 13.0, 0.0, PI * 2.0);
- let _ = cr.fill();
-
- cr.set_source_rgb(0.937, 0.267, 0.267);
- cr.set_line_width(1.8);
- cr.arc(cx, cy, 10.0, 0.0, PI * 2.0);
+ let red = (0.937, 0.267, 0.267);
+ cr.set_source_rgb(red.0, red.1, red.2);
+ cr.set_line_width(1.6);
+ let half = 8.5;
+ let arm = 3.2;
+ cr.move_to(cx - half + arm, cy - half); cr.line_to(cx - half, cy - half); cr.line_to(cx - half, cy - half + arm);
+ cr.move_to(cx + half - arm, cy - half); cr.line_to(cx + half, cy - half); cr.line_to(cx + half, cy - half + arm);
+ cr.move_to(cx - half + arm, cy + half); cr.line_to(cx - half, cy + half); cr.line_to(cx - half, cy + half - arm);
+ cr.move_to(cx + half - arm, cy + half); cr.line_to(cx + half, cy + half); cr.line_to(cx + half, cy + half - arm);
let _ = cr.stroke();
-
- cr.arc(cx, cy, 5.0, 0.0, PI * 2.0);
+ cr.arc(cx, cy, 3.5, 0.0, PI * 2.0);
let _ = cr.fill();
}
ToastIcon::Save => {
cr.set_source_rgb(accent_rgb.0, accent_rgb.1, accent_rgb.2);
- cr.set_line_width(2.5);
+ cr.set_line_width(2.0);
cr.set_line_cap(gtk::cairo::LineCap::Round);
cr.set_line_join(gtk::cairo::LineJoin::Round);
- cr.move_to(cx - 7.0, cy);
- cr.line_to(cx - 2.0, cy + 5.0);
- cr.line_to(cx + 7.0, cy - 5.0);
+ cr.move_to(cx - 6.0, cy + 0.5);
+ cr.line_to(cx - 2.0, cy + 4.5);
+ cr.line_to(cx + 6.0, cy - 4.5);
let _ = cr.stroke();
}
ToastIcon::Cursor => {
cr.set_source_rgb(accent_rgb.0, accent_rgb.1, accent_rgb.2);
cr.set_line_width(1.8);
- cr.move_to(cx - 6.0, cy - 8.0);
- cr.line_to(cx + 6.0, cy - 1.0);
- cr.line_to(cx, cy + 1.0);
- cr.line_to(cx + 2.0, cy + 7.0);
- cr.line_to(cx - 1.0, cy + 8.0);
- cr.line_to(cx - 3.0, cy + 2.0);
- cr.line_to(cx - 6.0, cy + 4.0);
+ cr.set_line_cap(gtk::cairo::LineCap::Round);
+ cr.set_line_join(gtk::cairo::LineJoin::Round);
+ cr.move_to(cx - 5.0, cy - 7.0);
+ cr.line_to(cx - 5.0, cy + 5.0);
+ cr.line_to(cx - 1.5, cy + 2.0);
+ cr.line_to(cx + 1.5, cy + 7.0);
+ cr.line_to(cx + 3.5, cy + 6.0);
+ cr.line_to(cx + 0.5, cy + 1.0);
+ cr.line_to(cx + 5.0, cy + 1.0);
cr.close_path();
- let _ = cr.fill();
+ let _ = cr.stroke();
}
ToastIcon::Error => {
cr.set_source_rgb(0.937, 0.267, 0.267);
- cr.set_line_width(2.2);
- cr.move_to(cx - 6.0, cy - 6.0);
- cr.line_to(cx + 6.0, cy + 6.0);
- cr.move_to(cx + 6.0, cy - 6.0);
- cr.line_to(cx - 6.0, cy + 6.0);
+ cr.set_line_width(2.0);
+ cr.set_line_cap(gtk::cairo::LineCap::Round);
+ cr.move_to(cx - 5.0, cy - 5.0);
+ cr.line_to(cx + 5.0, cy + 5.0);
+ cr.move_to(cx + 5.0, cy - 5.0);
+ cr.line_to(cx - 5.0, cy + 5.0);
let _ = cr.stroke();
}
ToastIcon::Info => {
cr.set_source_rgb(accent_rgb.0, accent_rgb.1, accent_rgb.2);
- cr.arc(cx, cy, 6.0, 0.0, PI * 2.0);
+ cr.arc(cx, cy, 4.5, 0.0, PI * 2.0);
let _ = cr.fill();
}
}
@@ -437,14 +424,14 @@ pub fn show_shadowplay_toast(title: &str, subtitle: &str, icon: ToastIcon) {
let title_lbl = Label::new(None);
title_lbl.set_markup(&format!(
- "{}",
+ "{}",
gtk::glib::markup_escape_text(&title_text)
));
title_lbl.set_halign(gtk::Align::Start);
let sub_lbl = Label::new(None);
sub_lbl.set_markup(&format!(
- "{}",
+ "{}",
gtk::glib::markup_escape_text(&sub_text)
));
sub_lbl.set_halign(gtk::Align::Start);
@@ -456,8 +443,8 @@ pub fn show_shadowplay_toast(title: &str, subtitle: &str, icon: ToastIcon) {
hbox.pack_start(&vbox, true, true, 0);
let fixed = Fixed::new();
- fixed.set_size_request(360, 64);
- fixed.put(&hbox, 360, 4);
+ fixed.set_size_request(320, 56);
+ fixed.put(&hbox, 320, 0);
window.add(&fixed);
window.show_all();
@@ -476,17 +463,17 @@ pub fn show_shadowplay_toast(title: &str, subtitle: &str, icon: ToastIcon) {
let slide_x = if elapsed < 0.35 {
let t = (elapsed / 0.35).min(1.0);
let ease = 1.0 - (1.0 - t).powi(3);
- (1.0 - ease) * 360.0
+ (1.0 - ease) * 320.0
} else if elapsed < 2.40 {
0.0
} else {
let t = ((elapsed - 2.40) / 0.40).min(1.0);
let ease = t.powi(3);
- ease * 360.0
+ ease * 320.0
};
- let target_x = (slide_x + 14.0).round() as i32;
- fixed_clone.move_(&hbox_clone, target_x, 4);
+ let target_x = slide_x.round() as i32;
+ fixed_clone.move_(&hbox_clone, target_x, 0);
window_clone.queue_draw();
gtk::glib::ControlFlow::Continue
});
diff --git a/src/overlay_egui.rs b/src/overlay_egui.rs
index 470db09..8876009 100644
--- a/src/overlay_egui.rs
+++ b/src/overlay_egui.rs
@@ -525,7 +525,7 @@ fn draw_replay_icon(painter: &egui::Painter, center: egui::Pos2, radius: f32, is
};
// Minimalist Line Chevrons (≪) - Crisp, high-tech stroked rewind glyph
- let stroke_w = 2.4_f32;
+ let stroke_w = (radius * 0.10).clamp(1.7, 2.4);
let stroke = Stroke::new(stroke_w, color);
let chevron_h = radius * 0.62;
let chevron_w = radius * 0.38;
@@ -2173,72 +2173,91 @@ impl ScytheOverlayApp {
let card_w = 320.0;
let card_h = 56.0;
let toast_rect = egui::Rect::from_min_size(
- egui::pos2(screen_w - card_w - 28.0 + slide_x, 28.0),
+ egui::pos2(screen_w - card_w + slide_x, 16.0),
egui::vec2(card_w, card_h),
);
let painter = ui.painter();
- // Drop shadow
+ // Sleek translucent neutral dark glass toast card (matching HUD cards)
painter.rect_filled(
- toast_rect.translate(Vec2::new(0.0, 4.0)),
- CornerRadius::ZERO,
- Color32::from_rgba_unmultiplied(0, 0, 0, 140),
- );
-
- // Modern sleek dark glass toast card
- painter.rect(
toast_rect,
CornerRadius::ZERO,
- Color32::from_rgba_unmultiplied(12, 13, 16, 252),
- Stroke::new(1.0_f32, Color32::from_rgba_unmultiplied(255, 255, 255, 30)),
+ Color32::from_rgba_unmultiplied(10, 10, 10, 165),
+ );
+
+ // Refined subtle accent stroke framing the card
+ let stroke_color = if notif.icon == crate::overlay::ToastIcon::Record || notif.icon == crate::overlay::ToastIcon::Error {
+ Color32::from_rgba_unmultiplied(239, 68, 68, 140)
+ } else {
+ Color32::from_rgba_unmultiplied(accent.r(), accent.g(), accent.b(), 140)
+ };
+ painter.rect_stroke(
+ toast_rect,
+ CornerRadius::ZERO,
+ Stroke::new(1.0_f32, stroke_color),
egui::StrokeKind::Inside,
);
- // Left vertical accent bar
- let line_color = if notif.icon == crate::overlay::ToastIcon::Record {
- Color32::from_rgb(239, 68, 68)
- } else {
- accent
- };
- let accent_line = egui::Rect::from_min_size(toast_rect.min + Vec2::new(1.0, 1.0), Vec2::new(3.5, toast_rect.height() - 2.0));
- painter.rect_filled(accent_line, CornerRadius::ZERO, line_color);
-
- // Left icon area (32x32 at center-left)
+ // Left icon area (centered vertically at x = 24.0)
let icon_center = egui::pos2(toast_rect.left() + 24.0, toast_rect.center().y);
match notif.icon {
crate::overlay::ToastIcon::Replay => {
- draw_replay_icon(painter, icon_center, 9.5, true, accent);
+ draw_replay_icon(painter, icon_center, 12.0, true, accent);
}
crate::overlay::ToastIcon::Record => {
- painter.circle_filled(icon_center, 5.5, Color32::from_rgb(239, 68, 68));
- painter.circle_stroke(icon_center, 9.5, Stroke::new(1.2_f32, Color32::from_rgba_unmultiplied(239, 68, 68, 120)));
+ let red_bright = Color32::from_rgb(239, 68, 68);
+ let half = 8.5;
+ let arm = 3.2;
+ let stroke = Stroke::new(1.6_f32, red_bright);
+ painter.line_segment([icon_center + Vec2::new(-half + arm, -half), icon_center + Vec2::new(-half, -half)], stroke);
+ painter.line_segment([icon_center + Vec2::new(-half, -half), icon_center + Vec2::new(-half, -half + arm)], stroke);
+ painter.line_segment([icon_center + Vec2::new(half - arm, -half), icon_center + Vec2::new(half, -half)], stroke);
+ painter.line_segment([icon_center + Vec2::new(half, -half), icon_center + Vec2::new(half, -half + arm)], stroke);
+ painter.line_segment([icon_center + Vec2::new(-half + arm, half), icon_center + Vec2::new(-half, half)], stroke);
+ painter.line_segment([icon_center + Vec2::new(-half, half), icon_center + Vec2::new(-half, half - arm)], stroke);
+ painter.line_segment([icon_center + Vec2::new(half - arm, half), icon_center + Vec2::new(half, half)], stroke);
+ painter.line_segment([icon_center + Vec2::new(half, half), icon_center + Vec2::new(half, half - arm)], stroke);
+ painter.circle_filled(icon_center, 3.5, red_bright);
}
crate::overlay::ToastIcon::Save => {
- let c = icon_center;
- let p1 = c + Vec2::new(-5.5, 0.0);
- let p2 = c + Vec2::new(-1.5, 4.0);
- let p3 = c + Vec2::new(5.5, -4.0);
- painter.line_segment([p1, p2], Stroke::new(2.2_f32, accent));
- painter.line_segment([p2, p3], Stroke::new(2.2_f32, accent));
+ painter.add(egui::epaint::PathShape::line(
+ vec![
+ icon_center + Vec2::new(-6.0, 0.5),
+ icon_center + Vec2::new(-2.0, 4.5),
+ icon_center + Vec2::new(6.0, -4.5),
+ ],
+ Stroke::new(2.0_f32, accent),
+ ));
}
crate::overlay::ToastIcon::Cursor => {
- let c = icon_center;
- painter.text(c, egui::Align2::CENTER_CENTER, "⯈", FontId::proportional(14.0), accent);
+ painter.add(egui::epaint::PathShape::line(
+ vec![
+ icon_center + Vec2::new(-5.0, -7.0),
+ icon_center + Vec2::new(-5.0, 5.0),
+ icon_center + Vec2::new(-1.5, 2.0),
+ icon_center + Vec2::new(1.5, 7.0),
+ icon_center + Vec2::new(3.5, 6.0),
+ icon_center + Vec2::new(0.5, 1.0),
+ icon_center + Vec2::new(5.0, 1.0),
+ icon_center + Vec2::new(-5.0, -7.0),
+ ],
+ Stroke::new(1.8_f32, accent),
+ ));
}
crate::overlay::ToastIcon::Error => {
- let c = icon_center;
let red = Color32::from_rgb(239, 68, 68);
- painter.line_segment([c + Vec2::new(-4.0, -4.0), c + Vec2::new(4.0, 4.0)], Stroke::new(2.0_f32, red));
- painter.line_segment([c + Vec2::new(4.0, -4.0), c + Vec2::new(-4.0, 4.0)], Stroke::new(2.0_f32, red));
+ let stroke = Stroke::new(2.0_f32, red);
+ painter.line_segment([icon_center + Vec2::new(-5.0, -5.0), icon_center + Vec2::new(5.0, 5.0)], stroke);
+ painter.line_segment([icon_center + Vec2::new(5.0, -5.0), icon_center + Vec2::new(-5.0, 5.0)], stroke);
}
crate::overlay::ToastIcon::Info => {
- painter.circle_filled(icon_center, 5.0, accent);
+ painter.circle_filled(icon_center, 4.5, accent);
}
}
// Text stack (Title + Subtitle)
- let text_left = toast_rect.left() + 48.0;
+ let text_left = toast_rect.left() + 46.0;
painter.text(
egui::pos2(text_left, toast_rect.top() + 19.0),
egui::Align2::LEFT_CENTER,
@@ -2251,7 +2270,7 @@ impl ScytheOverlayApp {
egui::Align2::LEFT_CENTER,
¬if.subtitle,
FontId::proportional(11.0),
- Color32::from_rgb(160, 160, 168),
+ Color32::from_rgb(175, 180, 190),
);
} else {
self.hud_notification = None;
@@ -2641,13 +2660,13 @@ impl eframe::App for ShadowPlayToastApp {
let slide_x = if elapsed < 0.35 {
let t = (elapsed / 0.35).min(1.0);
let ease = 1.0 - (1.0 - t).powi(3);
- (1.0 - ease) * 340.0
+ (1.0 - ease) * 320.0
} else if elapsed < total_dur - 0.40 {
0.0
} else {
let t = ((elapsed - (total_dur - 0.40)) / 0.40).min(1.0);
let ease = t.powi(3);
- ease * 340.0
+ ease * 320.0
};
let mut visuals = egui::Visuals::dark();
@@ -2659,71 +2678,90 @@ impl eframe::App for ShadowPlayToastApp {
.frame(egui::Frame::NONE.fill(Color32::TRANSPARENT))
.show(ctx, |ui| {
let rect = egui::Rect::from_min_size(
- egui::pos2(slide_x + 10.0, 4.0),
+ egui::pos2(slide_x, 0.0),
Vec2::new(320.0, 56.0),
);
let painter = ui.painter();
- // Drop shadow
+ // Sleek translucent neutral dark glass toast card (matching HUD cards)
painter.rect_filled(
- rect.translate(Vec2::new(0.0, 4.0)),
- CornerRadius::ZERO,
- Color32::from_rgba_unmultiplied(0, 0, 0, 140),
- );
-
- // Modern sleek dark glass toast card
- painter.rect(
rect,
CornerRadius::ZERO,
- Color32::from_rgba_unmultiplied(12, 13, 16, 252),
- Stroke::new(1.0_f32, Color32::from_rgba_unmultiplied(255, 255, 255, 30)),
+ Color32::from_rgba_unmultiplied(10, 10, 10, 165),
+ );
+
+ // Refined subtle accent stroke framing the card
+ let stroke_color = if self.icon == crate::overlay::ToastIcon::Record || self.icon == crate::overlay::ToastIcon::Error {
+ Color32::from_rgba_unmultiplied(239, 68, 68, 140)
+ } else {
+ Color32::from_rgba_unmultiplied(self.accent.r(), self.accent.g(), self.accent.b(), 140)
+ };
+ painter.rect_stroke(
+ rect,
+ CornerRadius::ZERO,
+ Stroke::new(1.0_f32, stroke_color),
egui::StrokeKind::Inside,
);
- // Left accent line
- let line_color = if self.icon == crate::overlay::ToastIcon::Record {
- Color32::from_rgb(239, 68, 68)
- } else {
- self.accent
- };
- let accent_line = egui::Rect::from_min_size(rect.min + Vec2::new(1.0, 1.0), Vec2::new(3.5, rect.height() - 2.0));
- painter.rect_filled(accent_line, CornerRadius::ZERO, line_color);
-
- // Left icon area (32x32 at center-left)
+ // Left icon area (centered vertically at x = 24.0)
let icon_center = egui::pos2(rect.left() + 24.0, rect.center().y);
match self.icon {
crate::overlay::ToastIcon::Replay => {
- draw_replay_icon(painter, icon_center, 9.5, true, self.accent);
+ draw_replay_icon(painter, icon_center, 12.0, true, self.accent);
}
crate::overlay::ToastIcon::Record => {
- painter.circle_filled(icon_center, 5.5, Color32::from_rgb(239, 68, 68));
- painter.circle_stroke(icon_center, 9.5, Stroke::new(1.2_f32, Color32::from_rgba_unmultiplied(239, 68, 68, 120)));
+ let red_bright = Color32::from_rgb(239, 68, 68);
+ let half = 8.5;
+ let arm = 3.2;
+ let stroke = Stroke::new(1.6_f32, red_bright);
+ painter.line_segment([icon_center + Vec2::new(-half + arm, -half), icon_center + Vec2::new(-half, -half)], stroke);
+ painter.line_segment([icon_center + Vec2::new(-half, -half), icon_center + Vec2::new(-half, -half + arm)], stroke);
+ painter.line_segment([icon_center + Vec2::new(half - arm, -half), icon_center + Vec2::new(half, -half)], stroke);
+ painter.line_segment([icon_center + Vec2::new(half, -half), icon_center + Vec2::new(half, -half + arm)], stroke);
+ painter.line_segment([icon_center + Vec2::new(-half + arm, half), icon_center + Vec2::new(-half, half)], stroke);
+ painter.line_segment([icon_center + Vec2::new(-half, half), icon_center + Vec2::new(-half, half - arm)], stroke);
+ painter.line_segment([icon_center + Vec2::new(half - arm, half), icon_center + Vec2::new(half, half)], stroke);
+ painter.line_segment([icon_center + Vec2::new(half, half), icon_center + Vec2::new(half, half - arm)], stroke);
+ painter.circle_filled(icon_center, 3.5, red_bright);
}
crate::overlay::ToastIcon::Save => {
- let c = icon_center;
- let p1 = c + Vec2::new(-5.5, 0.0);
- let p2 = c + Vec2::new(-1.5, 4.0);
- let p3 = c + Vec2::new(5.5, -4.0);
- painter.line_segment([p1, p2], Stroke::new(2.2_f32, self.accent));
- painter.line_segment([p2, p3], Stroke::new(2.2_f32, self.accent));
+ painter.add(egui::epaint::PathShape::line(
+ vec![
+ icon_center + Vec2::new(-6.0, 0.5),
+ icon_center + Vec2::new(-2.0, 4.5),
+ icon_center + Vec2::new(6.0, -4.5),
+ ],
+ Stroke::new(2.0_f32, self.accent),
+ ));
}
crate::overlay::ToastIcon::Cursor => {
- let c = icon_center;
- painter.text(c, egui::Align2::CENTER_CENTER, "⯈", FontId::proportional(14.0), self.accent);
+ painter.add(egui::epaint::PathShape::line(
+ vec![
+ icon_center + Vec2::new(-5.0, -7.0),
+ icon_center + Vec2::new(-5.0, 5.0),
+ icon_center + Vec2::new(-1.5, 2.0),
+ icon_center + Vec2::new(1.5, 7.0),
+ icon_center + Vec2::new(3.5, 6.0),
+ icon_center + Vec2::new(0.5, 1.0),
+ icon_center + Vec2::new(5.0, 1.0),
+ icon_center + Vec2::new(-5.0, -7.0),
+ ],
+ Stroke::new(1.8_f32, self.accent),
+ ));
}
crate::overlay::ToastIcon::Error => {
- let c = icon_center;
let red = Color32::from_rgb(239, 68, 68);
- painter.line_segment([c + Vec2::new(-4.0, -4.0), c + Vec2::new(4.0, 4.0)], Stroke::new(2.0_f32, red));
- painter.line_segment([c + Vec2::new(4.0, -4.0), c + Vec2::new(-4.0, 4.0)], Stroke::new(2.0_f32, red));
+ let stroke = Stroke::new(2.0_f32, red);
+ painter.line_segment([icon_center + Vec2::new(-5.0, -5.0), icon_center + Vec2::new(5.0, 5.0)], stroke);
+ painter.line_segment([icon_center + Vec2::new(5.0, -5.0), icon_center + Vec2::new(-5.0, 5.0)], stroke);
}
crate::overlay::ToastIcon::Info => {
- painter.circle_filled(icon_center, 5.0, self.accent);
+ painter.circle_filled(icon_center, 4.5, self.accent);
}
}
// Text stack (Title + Subtitle)
- let text_left = rect.left() + 48.0;
+ let text_left = rect.left() + 46.0;
painter.text(
egui::pos2(text_left, rect.top() + 19.0),
egui::Align2::LEFT_CENTER,
@@ -2736,7 +2774,7 @@ impl eframe::App for ShadowPlayToastApp {
egui::Align2::LEFT_CENTER,
&self.subtitle,
FontId::proportional(11.0),
- Color32::from_rgb(160, 160, 168),
+ Color32::from_rgb(175, 180, 190),
);
});
}
@@ -2746,8 +2784,8 @@ pub fn run_egui_toast(title: &str, subtitle: &str, icon: crate::overlay::ToastIc
let cfg = ScytheConfig::load();
let accent = resolve_accent_color(&cfg.accent_color);
- let toast_w: f32 = 340.0;
- let toast_h: f32 = 64.0;
+ let toast_w: f32 = 320.0;
+ let toast_h: f32 = 56.0;
let toast_pid_path = crate::ipc::get_toast_pid_path();
if let Ok(prev_pid_str) = std::fs::read_to_string(&toast_pid_path)
@@ -2778,8 +2816,8 @@ pub fn run_egui_toast(title: &str, subtitle: &str, icon: crate::overlay::ToastIc
#[cfg(not(target_os = "windows"))]
let (mon_x, _mon_y, screen_w, _screen_h) = query_focused_monitor_rect();
- let pos_x = (mon_x + screen_w - toast_w - 28.0).max(10.0);
- let pos_y = 28.0;
+ let pos_x = (mon_x + screen_w - toast_w).max(0.0);
+ let pos_y = 16.0;
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default()