Justering/expand/marginaler, hover-popup med peek, appikon
All checks were successful
check / check (push) Successful in 1m37s
All checks were successful
check / check (push) Successful in 1m37s
- Ny layoutmodell: alignment (center/start/end längs kanten), expand (ö eller täck hela kanten) och tre marginaler — A från kanten, B/C i början/slutet av kanten. Funkar för alla fyra positionerna. - Settings → Layout har en ritad illustration (cairo) som visar vad A/B/C betyder för vald position och uppdateras live. - Fönsterlistan för grupper kan öppnas vid hover (group_popup) och stängs när pekaren lämnar den; hover på en rad kan peeka (alla andra fönster tonas ner via Wayfires alpha-plugin) eller fokusera fönstret (list_hover: peek/focus/none). - Appikon (assets/waydock.svg) + .desktop-fil; installeras av install.sh och används av settings-fönstret. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
102
src/dock.rs
102
src/dock.rs
@@ -16,8 +16,8 @@ use gtk4_layer_shell::{Edge, KeyboardMode, Layer, LayerShell};
|
||||
use log::{debug, info};
|
||||
|
||||
use crate::config::{
|
||||
AutohideMode, ClickAction, Layer as CfgLayer, MiddleClick, Position, ScrollAction,
|
||||
SharedConfig,
|
||||
Alignment, AutohideMode, ClickAction, GroupPopup, Layer as CfgLayer, MiddleClick,
|
||||
Position, ScrollAction, SharedConfig,
|
||||
};
|
||||
use crate::icons::{self, AppMeta};
|
||||
use crate::menu;
|
||||
@@ -45,7 +45,7 @@ pub struct Ctx {
|
||||
|
||||
pub struct Dock {
|
||||
pub window: gtk::ApplicationWindow,
|
||||
pub panel: gtk::Box,
|
||||
pub items_box: gtk::Box,
|
||||
pub revealer: gtk::Revealer,
|
||||
pub connector: String,
|
||||
/// pekaren är över dockan just nu
|
||||
@@ -103,12 +103,28 @@ fn configure_layer(win: >k::ApplicationWindow, ctx: &Ctx, monitor: &gdk::Monit
|
||||
win.set_keyboard_mode(KeyboardMode::None);
|
||||
|
||||
let edge = main_edge(&cfg.position);
|
||||
let (side_a, side_b) = side_edges(&cfg.position);
|
||||
let (side_start, side_end) = side_edges(&cfg.position);
|
||||
win.set_anchor(edge, true);
|
||||
win.set_margin(edge, cfg.margin);
|
||||
if !cfg.centered {
|
||||
win.set_anchor(side_a, true);
|
||||
win.set_anchor(side_b, true);
|
||||
if cfg.expand {
|
||||
// täck hela kanten; start/slut-marginalerna drar in baren
|
||||
win.set_anchor(side_start, true);
|
||||
win.set_anchor(side_end, true);
|
||||
win.set_margin(side_start, cfg.margin_start);
|
||||
win.set_margin(side_end, cfg.margin_end);
|
||||
} else {
|
||||
// ö: förankra bara i vald ände (ingen sidoförankring = centrerad)
|
||||
match cfg.alignment {
|
||||
Alignment::Center => {}
|
||||
Alignment::Start => {
|
||||
win.set_anchor(side_start, true);
|
||||
win.set_margin(side_start, cfg.margin_start);
|
||||
}
|
||||
Alignment::End => {
|
||||
win.set_anchor(side_end, true);
|
||||
win.set_margin(side_end, cfg.margin_end);
|
||||
}
|
||||
}
|
||||
}
|
||||
if cfg.avoid_windows && !cfg.autohide.enabled {
|
||||
win.auto_exclusive_zone_enable();
|
||||
@@ -158,8 +174,30 @@ fn build_dock(ctx: &Rc<Ctx>, monitor: &gdk::Monitor, connector: String) -> Rc<Do
|
||||
let orient = orientation(&cfg.position);
|
||||
let panel = gtk::Box::new(orient, 0);
|
||||
panel.add_css_class("dock-panel");
|
||||
panel.set_halign(gtk::Align::Center);
|
||||
panel.set_valign(gtk::Align::Center);
|
||||
let items_align = match cfg.alignment {
|
||||
Alignment::Center => gtk::Align::Center,
|
||||
Alignment::Start => gtk::Align::Start,
|
||||
Alignment::End => gtk::Align::End,
|
||||
};
|
||||
let items_box = gtk::Box::new(orient, 0);
|
||||
if cfg.expand {
|
||||
// panelbakgrunden täcker kanten; ikonerna läggs enligt alignment
|
||||
panel.set_halign(gtk::Align::Fill);
|
||||
panel.set_valign(gtk::Align::Fill);
|
||||
if orient == gtk::Orientation::Horizontal {
|
||||
panel.set_hexpand(true);
|
||||
items_box.set_hexpand(true);
|
||||
items_box.set_halign(items_align);
|
||||
} else {
|
||||
panel.set_vexpand(true);
|
||||
items_box.set_vexpand(true);
|
||||
items_box.set_valign(items_align);
|
||||
}
|
||||
} else {
|
||||
panel.set_halign(gtk::Align::Center);
|
||||
panel.set_valign(gtk::Align::Center);
|
||||
}
|
||||
panel.append(&items_box);
|
||||
|
||||
// yttre marginal = plats för skuggan att rita
|
||||
let outer = gtk::Box::new(orient, 0);
|
||||
@@ -198,7 +236,7 @@ fn build_dock(ctx: &Rc<Ctx>, monitor: &gdk::Monitor, connector: String) -> Rc<Do
|
||||
|
||||
let dock = Rc::new(Dock {
|
||||
window: win.clone(),
|
||||
panel: panel.clone(),
|
||||
items_box: items_box.clone(),
|
||||
revealer,
|
||||
connector,
|
||||
hover: Cell::new(false),
|
||||
@@ -481,13 +519,13 @@ pub fn refresh_items(ctx: &Rc<Ctx>) {
|
||||
.unwrap_or_default();
|
||||
|
||||
for dock in ctx.docks.borrow().iter() {
|
||||
while let Some(child) = dock.panel.first_child() {
|
||||
dock.panel.remove(&child);
|
||||
while let Some(child) = dock.items_box.first_child() {
|
||||
dock.items_box.remove(&child);
|
||||
}
|
||||
add_special_buttons(ctx, dock);
|
||||
for item in build_items(ctx, &dock.connector, &snapshot) {
|
||||
let widget = build_item_widget(ctx, &dock.connector, Rc::new(item));
|
||||
dock.panel.append(&widget);
|
||||
dock.items_box.append(&widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -509,7 +547,7 @@ fn add_special_buttons(ctx: &Rc<Ctx>, dock: &Rc<Dock>) {
|
||||
if specials.overview && wayfire_ipc::available() {
|
||||
let btn = special_button("view-grid-symbolic", "Översikt (scale)");
|
||||
btn.connect_clicked(|_| wayfire_ipc::toggle_scale());
|
||||
dock.panel.append(&btn);
|
||||
dock.items_box.append(&btn);
|
||||
}
|
||||
if specials.show_desktop {
|
||||
let btn = special_button("user-desktop-symbolic", "Visa skrivbordet");
|
||||
@@ -519,7 +557,7 @@ fn add_special_buttons(ctx: &Rc<Ctx>, dock: &Rc<Dock>) {
|
||||
service.toggle_show_desktop();
|
||||
}
|
||||
});
|
||||
dock.panel.append(&btn);
|
||||
dock.items_box.append(&btn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,6 +648,33 @@ fn build_item_widget(ctx: &Rc<Ctx>, connector: &str, item: Rc<Item>) -> gtk::But
|
||||
}
|
||||
btn.add_controller(click);
|
||||
|
||||
// hover-popup för grupperade appar (om valt i configen)
|
||||
if item.windows.len() > 1
|
||||
&& ctx.cfg.borrow().behavior.group_popup == GroupPopup::Hover
|
||||
{
|
||||
let hover_ctl = gtk::EventControllerMotion::new();
|
||||
let ctx2 = ctx.clone();
|
||||
let item2 = item.clone();
|
||||
let btn2 = btn.clone();
|
||||
let conn2 = connector.to_string();
|
||||
hover_ctl.connect_enter(move |ctl, _, _| {
|
||||
let ctx3 = ctx2.clone();
|
||||
let item3 = item2.clone();
|
||||
let btn3 = btn2.clone();
|
||||
let conn3 = conn2.clone();
|
||||
let ctl2 = ctl.clone();
|
||||
glib::timeout_add_local_once(Duration::from_millis(350), move || {
|
||||
if ctl2.contains_pointer() {
|
||||
let live = live_item(&ctx3, &conn3, &item3);
|
||||
if live.windows.len() > 1 {
|
||||
menu::popup_group_list(&ctx3, &live, &btn3);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
btn.add_controller(hover_ctl);
|
||||
}
|
||||
|
||||
// skroll: växla mellan gruppens fönster
|
||||
let scroll = gtk::EventControllerScroll::new(gtk::EventControllerScrollFlags::VERTICAL);
|
||||
{
|
||||
@@ -649,8 +714,11 @@ fn primary_action(ctx: &Rc<Ctx>, item: &Rc<Item>, anchor: >k::Button) {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let click = ctx.cfg.borrow().behavior.click.clone();
|
||||
if click == ClickAction::Cycle {
|
||||
let (click, popup) = {
|
||||
let b = &ctx.cfg.borrow().behavior;
|
||||
(b.click.clone(), b.group_popup.clone())
|
||||
};
|
||||
if click == ClickAction::Cycle || popup == GroupPopup::Hover {
|
||||
cycle_windows(ctx, item, true);
|
||||
} else {
|
||||
menu::popup_group_list(ctx, item, anchor);
|
||||
|
||||
Reference in New Issue
Block a user