Daylight bar chrome + embedded launcher, v0.7.5 pins #5
1 changed files with 62 additions and 1 deletions
63
src/panel.rs
63
src/panel.rs
|
|
@ -5,18 +5,31 @@
|
|||
//! *below* the exclusive zone, and Hyprland slides `breadbar-panel` in from
|
||||
//! the right.
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use gtk4::gdk::Key;
|
||||
use gtk4::prelude::*;
|
||||
use gtk4_layer_shell::{KeyboardMode, LayerShell};
|
||||
use gtk4_layer_shell::{Edge, KeyboardMode, LayerShell};
|
||||
|
||||
use crate::{bind_layer_monitor, theme};
|
||||
|
||||
/// A boxed, ref-counted, optionally-unset click-away callback — see
|
||||
/// `PanelSet::on_dismiss`'s own doc comment.
|
||||
type DismissCallback = Rc<RefCell<Option<Rc<dyn Fn()>>>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PanelSet {
|
||||
pub connectivity: gtk4::Window,
|
||||
pub control: gtk4::Window,
|
||||
pub media: gtk4::Window,
|
||||
dismiss: gtk4::Window,
|
||||
// Theme 04/spotlight's capsule (plan §7 phase 6c): an extra click-away
|
||||
// callback invoked alongside the popover-dismiss path below, so the
|
||||
// SAME `breadbar-dismiss` surface/click-catcher also collapses the
|
||||
// capsule's drawer — see `show_capsule_dismiss`/`hide_dismiss` and
|
||||
// `set_on_dismiss`. `None` under every other theme (never set).
|
||||
on_dismiss: DismissCallback,
|
||||
}
|
||||
|
||||
impl PanelSet {
|
||||
|
|
@ -36,6 +49,7 @@ impl PanelSet {
|
|||
control,
|
||||
media,
|
||||
dismiss,
|
||||
on_dismiss: Rc::new(RefCell::new(None)),
|
||||
};
|
||||
set.wire_dismiss();
|
||||
set.wire_escape();
|
||||
|
|
@ -52,6 +66,10 @@ impl PanelSet {
|
|||
|
||||
pub fn show(&self, which: >k4::Window) {
|
||||
self.hide_panels();
|
||||
// A prior capsule search (see `show_capsule_dismiss`) may have left
|
||||
// the shared dismiss surface's top margin pushed down past its
|
||||
// popover-shaped default — restore it before this popover uses it.
|
||||
self.reset_dismiss_margin();
|
||||
// Dismiss first so the panel maps above it (same Overlay layer).
|
||||
self.dismiss.set_visible(true);
|
||||
self.dismiss.present();
|
||||
|
|
@ -70,12 +88,55 @@ impl PanelSet {
|
|||
self.media.set_visible(false);
|
||||
}
|
||||
|
||||
/// Theme 04/spotlight's capsule (plan §7 phase 6c): registers `cb` to
|
||||
/// run whenever the shared dismiss surface is clicked, alongside the
|
||||
/// popovers' own `hide_all`. `cb` is expected to no-op when the capsule
|
||||
/// isn't actually open (matching `close_fn`'s own guard in main.rs), so
|
||||
/// this firing on an ordinary popover click-away is harmless.
|
||||
pub fn set_on_dismiss(&self, cb: impl Fn() + 'static) {
|
||||
*self.on_dismiss.borrow_mut() = Some(Rc::new(cb));
|
||||
}
|
||||
|
||||
/// Shows the dismiss scrim with its clickable region starting at
|
||||
/// `top_margin` px from the screen top, rather than the theme's own
|
||||
/// popover-shaped default. See the call site in main.rs's capsule
|
||||
/// `open_fn` for why this needs to be at least the capsule's own row
|
||||
/// height plus the drawer's maximum possible height: the dismiss
|
||||
/// surface's layer (`overlay`) always renders above the bar's own
|
||||
/// (`top`), so if its clickable region ever reached up into where the
|
||||
/// drawer is actually drawn, it would swallow clicks meant for a
|
||||
/// result row instead of forwarding them.
|
||||
pub fn show_capsule_dismiss(&self, top_margin: i32) {
|
||||
self.dismiss.set_margin(Edge::Top, top_margin);
|
||||
self.dismiss.set_visible(true);
|
||||
self.dismiss.present();
|
||||
}
|
||||
|
||||
/// Hides the dismiss scrim and restores its margin to the theme's own
|
||||
/// popover default, so a later popover `show()` isn't left with a
|
||||
/// leftover capsule-sized gap.
|
||||
pub fn hide_dismiss(&self) {
|
||||
self.reset_dismiss_margin();
|
||||
self.dismiss.set_visible(false);
|
||||
}
|
||||
|
||||
fn reset_dismiss_margin(&self) {
|
||||
let theme = theme::shell_theme();
|
||||
if let Some(surf) = theme.surfaces().get("breadbar-dismiss") {
|
||||
let top = surf.offset.first().copied().unwrap_or(0.0) as i32;
|
||||
self.dismiss.set_margin(Edge::Top, top);
|
||||
}
|
||||
}
|
||||
|
||||
fn wire_dismiss(&self) {
|
||||
let set = self.clone();
|
||||
let click = gtk4::GestureClick::new();
|
||||
click.set_button(0);
|
||||
click.connect_pressed(move |_, _, _, _| {
|
||||
set.hide_all();
|
||||
if let Some(cb) = set.on_dismiss.borrow().as_ref() {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
if let Some(child) = self.dismiss.child() {
|
||||
child.add_controller(click);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue