Fixa dött vänsterklick + setting för skroll på ej startad app
All checks were successful
check / check (push) Successful in 1m37s

Vänsterklick nådde ALDRIG fram: GtkButtons interna klickgest claimar
knapp 1 före vår GestureClick, så released-callbacken avfyrades bara
för mitt/höger. Primäraktionen går nu via knappens clicked-signal
(gesten hanterar bara knapp 2/3). Därmed funkar fokus/minimera,
grupplista-vid-klick och start av pinnade appar.

Ny setting behavior.scroll_stopped (none|launch): vad skroll gör på en
app utan fönster — som du bad om, eget beteende för ej startade appar.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-30 00:55:11 +02:00
parent 1c6ed7815b
commit 266e25a9ff
4 changed files with 49 additions and 7 deletions

View File

@@ -79,6 +79,7 @@ inställningar; "Återställ skärmen till globalt" tar bort dem.
"group_apps": true, "group_apps": true,
"tooltips": true, "tooltips": true,
"urgent_pulse": true, "urgent_pulse": true,
"scroll_stopped": "none", // none | launch — skroll på app som inte är igång
"group_popup": "click", // click | hover — hur fönsterlistan öppnas "group_popup": "click", // click | hover — hur fönsterlistan öppnas
"list_hover": "peek" // peek (visa bara det fönstret, tona ner andra) "list_hover": "peek" // peek (visa bara det fönstret, tona ner andra)
// | focus (fokusera vid hover) | none // | focus (fokusera vid hover) | none

View File

@@ -45,6 +45,14 @@ pub enum GroupPopup {
Hover, Hover,
} }
/// Vad skroll gör på en app som inte är igång (pinnad, 0 fönster).
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ScrollStopped {
None,
Launch,
}
/// Vad som händer när man hovrar en rad i fönsterlistan. /// Vad som händer när man hovrar en rad i fönsterlistan.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
@@ -181,6 +189,7 @@ pub struct Behavior {
pub urgent_pulse: bool, pub urgent_pulse: bool,
pub group_popup: GroupPopup, pub group_popup: GroupPopup,
pub list_hover: ListHover, pub list_hover: ListHover,
pub scroll_stopped: ScrollStopped,
} }
impl Default for Behavior { impl Default for Behavior {
fn default() -> Self { fn default() -> Self {
@@ -193,6 +202,7 @@ impl Default for Behavior {
urgent_pulse: true, urgent_pulse: true,
group_popup: GroupPopup::Click, group_popup: GroupPopup::Click,
list_hover: ListHover::Peek, list_hover: ListHover::Peek,
scroll_stopped: ScrollStopped::None,
} }
} }
} }

View File

@@ -17,7 +17,7 @@ use log::{debug, info};
use crate::config::{ use crate::config::{
Alignment, AutohideMode, ClickAction, Config, GroupPopup, Layer as CfgLayer, Alignment, AutohideMode, ClickAction, Config, GroupPopup, Layer as CfgLayer,
MiddleClick, Position, ScrollAction, SharedConfig, MiddleClick, Position, ScrollAction, ScrollStopped, SharedConfig,
}; };
use crate::icons::{self, AppMeta}; use crate::icons::{self, AppMeta};
use crate::menu; use crate::menu;
@@ -679,7 +679,19 @@ fn build_item_widget(ctx: &Rc<Ctx>, connector: &str, item: Rc<Item>) -> gtk::But
}); });
} }
// klick: vänster/mitt/höger // vänsterklick: via knappens egna clicked-signal — GtkButtons interna
// gest claimar vänsterknappen, så en egen GestureClick för knapp 1
// avfyras aldrig (buggen som gjorde vänsterklick dött)
{
let ctx = ctx.clone();
let item = item.clone();
let conn2 = connector.to_string();
btn.connect_clicked(move |btn| {
let live = live_item(&ctx, &conn2, &item);
primary_action(&ctx, &conn2, &live, btn);
});
}
// mitt- och högerklick via egen gest
let click = gtk::GestureClick::new(); let click = gtk::GestureClick::new();
click.set_button(0); click.set_button(0);
{ {
@@ -688,10 +700,13 @@ fn build_item_widget(ctx: &Rc<Ctx>, connector: &str, item: Rc<Item>) -> gtk::But
let btn2 = btn.clone(); let btn2 = btn.clone();
let conn2 = connector.to_string(); let conn2 = connector.to_string();
click.connect_released(move |gesture, _, _, _| { click.connect_released(move |gesture, _, _, _| {
let button = gesture.current_button();
if button != 2 && button != 3 {
return; // vänsterklick sköts av knappen själv
}
gesture.set_state(gtk::EventSequenceState::Claimed); gesture.set_state(gtk::EventSequenceState::Claimed);
let live = live_item(&ctx, &conn2, &item); let live = live_item(&ctx, &conn2, &item);
match gesture.current_button() { match button {
1 => primary_action(&ctx, &conn2, &live, &btn2),
2 => middle_action(&ctx, &conn2, &live), 2 => middle_action(&ctx, &conn2, &live),
3 => menu::popup_item_menu(&ctx, &live, &btn2), 3 => menu::popup_item_menu(&ctx, &live, &btn2),
_ => {} _ => {}
@@ -743,8 +758,17 @@ fn build_item_widget(ctx: &Rc<Ctx>, connector: &str, item: Rc<Item>) -> gtk::But
step(dy); step(dy);
return glib::Propagation::Stop; return glib::Propagation::Stop;
} }
if ctx.cfg.borrow().for_output(&conn2).behavior.scroll == ScrollAction::CycleWindows { let behavior = ctx.cfg.borrow().for_output(&conn2).behavior;
let live = live_item(&ctx, &conn2, &item); let live = live_item(&ctx, &conn2, &item);
if live.windows.is_empty() {
// egen setting för appar som inte är igång
if behavior.scroll_stopped == ScrollStopped::Launch {
icons::launch(&live.meta);
return glib::Propagation::Stop;
}
return glib::Propagation::Proceed;
}
if behavior.scroll == ScrollAction::CycleWindows {
cycle_windows(&ctx, &live, dy > 0.0); cycle_windows(&ctx, &live, dy > 0.0);
glib::Propagation::Stop glib::Propagation::Stop
} else { } else {

View File

@@ -15,7 +15,7 @@ use log::warn;
use crate::config::{ use crate::config::{
self, Alignment, AutohideMode, ClickAction, GroupPopup, HotspotAction, IndicatorStyle, self, Alignment, AutohideMode, ClickAction, GroupPopup, HotspotAction, IndicatorStyle,
Layer, ListHover, MenuItem, MiddleClick, Position, ScrollAction, Layer, ListHover, MenuItem, MiddleClick, Position, ScrollAction, ScrollStopped,
}; };
use crate::dock::Ctx; use crate::dock::Ctx;
@@ -541,6 +541,13 @@ fn build_behavior_page(ctx: &Rc<Ctx>) -> gtk::ScrolledWindow {
row(&list, "Skroll", &dropdown(ctx, &["Växla fönster", "Inget"], scroll_idx, |c, i| { row(&list, "Skroll", &dropdown(ctx, &["Växla fönster", "Inget"], scroll_idx, |c, i| {
c.behavior.scroll = if i == 1 { ScrollAction::None } else { ScrollAction::CycleWindows }; c.behavior.scroll = if i == 1 { ScrollAction::None } else { ScrollAction::CycleWindows };
})); }));
let ss_idx = match b.scroll_stopped {
ScrollStopped::None => 0,
ScrollStopped::Launch => 1,
};
row(&list, "Skroll på ej startad app", &dropdown(ctx, &["Gör inget", "Starta appen"], ss_idx, |c, i| {
c.behavior.scroll_stopped = if i == 1 { ScrollStopped::Launch } else { ScrollStopped::None };
}));
heading(&list, "Gruppering & popup"); heading(&list, "Gruppering & popup");
row(&list, "Gruppera appar", &switch(ctx, b.group_apps, |c, v| c.behavior.group_apps = v)); row(&list, "Gruppera appar", &switch(ctx, b.group_apps, |c, v| c.behavior.group_apps = v));