Skip to content

Commit

Permalink
Add configuration option for close_tab_on_middle_mouse
Browse files Browse the repository at this point in the history
  • Loading branch information
William Calliari committed Oct 10, 2024
1 parent ed0e678 commit b85818c
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 28 deletions.
15 changes: 15 additions & 0 deletions cosmic-comp-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub struct CosmicCompConfig {
/// If set to Global, autotile applies to all windows in all workspaces
/// If set to PerWorkspace, autotile only applies to new windows, and new workspaces
pub autotile_behavior: TileBehavior,
/// Configure behavior of the stack layout.
pub stack_behavior: StackBehavior,
/// Active hint enabled
pub active_hint: bool,
/// Enables changing keyboard focus to windows when the cursor passes into them
Expand Down Expand Up @@ -55,6 +57,7 @@ impl Default for CosmicCompConfig {
xkb_config: Default::default(),
autotile: Default::default(),
autotile_behavior: Default::default(),
stack_behavior: StackBehavior::default(),
active_hint: true,
focus_follows_cursor: false,
cursor_follows_focus: false,
Expand Down Expand Up @@ -105,3 +108,15 @@ fn default_repeat_rate() -> u32 {
fn default_repeat_delay() -> u32 {
600
}


#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct StackBehavior {
pub close_tab_on_middle_click: bool,
}

impl Default for StackBehavior {
fn default() -> Self {
Self { close_tab_on_middle_click: true }
}
}
9 changes: 8 additions & 1 deletion src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ mod types;
pub use self::types::*;
use cosmic::config::CosmicTk;
use cosmic_comp_config::{
input::InputConfig, workspace::WorkspaceConfig, CosmicCompConfig, TileBehavior, XkbConfig,
input::InputConfig, workspace::WorkspaceConfig, CosmicCompConfig, StackBehavior, TileBehavior, XkbConfig
};

#[derive(Debug)]
Expand Down Expand Up @@ -690,6 +690,13 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
);
}
}
"stack_behavior" => {
let new = get_config::<StackBehavior>(&config, "stack_behavior");
if new != state.common.config.cosmic_conf.stack_behavior {
state.common.config.cosmic_conf.stack_behavior = new;
state.common.update_config();
}
}
"active_hint" => {
let new = get_config::<bool>(&config, "active_hint");
if new != state.common.config.cosmic_conf.active_hint {
Expand Down
4 changes: 3 additions & 1 deletion src/shell/element/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
utils::{iced::IcedElementInternal, prelude::*},
};
use calloop::LoopHandle;
use cosmic_comp_config::StackBehavior;
use id_tree::NodeId;
use smithay::{
backend::{
Expand Down Expand Up @@ -592,14 +593,15 @@ impl CosmicMapped {
&mut self,
(output, overlap): (&Output, Rectangle<i32, Logical>),
theme: cosmic::Theme,
config: StackBehavior,
) {
match &self.element {
CosmicMappedInternal::Window(window) => {
let surface = window.surface();
let activated = surface.is_activated(true);
let handle = window.loop_handle();

let stack = CosmicStack::new(std::iter::once(surface), handle, theme);
let stack = CosmicStack::new(std::iter::once(surface), handle, theme, config);
if let Some(geo) = self.last_geometry.lock().unwrap().clone() {
stack.set_geometry(geo.to_global(&output));
}
Expand Down
19 changes: 13 additions & 6 deletions src/shell/element/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use cosmic::{
iced_widget::scrollable::AbsoluteOffset,
theme, widget as cosmic_widget, Apply, Element as CosmicElement, Theme,
};
use cosmic_comp_config::StackBehavior;
use cosmic_settings_config::shortcuts;
use once_cell::sync::Lazy;
use shortcuts::action::{Direction, FocusDirection};
Expand Down Expand Up @@ -102,6 +103,8 @@ pub struct CosmicStackInternal {
last_seat: Arc<Mutex<Option<(Seat<State>, Serial)>>>,
geometry: Arc<Mutex<Option<Rectangle<i32, Global>>>>,
mask: Arc<Mutex<Option<tiny_skia::Mask>>>,

behavior: StackBehavior,
}

impl CosmicStackInternal {
Expand Down Expand Up @@ -129,6 +132,7 @@ impl CosmicStack {
windows: impl Iterator<Item = I>,
handle: LoopHandle<'static, crate::state::State>,
theme: cosmic::Theme,
behavior: StackBehavior,
) -> CosmicStack {
let windows = windows.map(Into::into).collect::<Vec<_>>();
assert!(!windows.is_empty());
Expand All @@ -155,6 +159,7 @@ impl CosmicStack {
last_seat: Arc::new(Mutex::new(None)),
geometry: Arc::new(Mutex::new(None)),
mask: Arc::new(Mutex::new(None)),
behavior,
},
(width, TAB_HEIGHT),
handle,
Expand Down Expand Up @@ -680,10 +685,6 @@ impl TabMessage for Message {
fn scrolled() -> Self {
Message::Scrolled
}

fn close(idx: usize) -> Self {
Message::Close(idx)
}
}

impl Program for CosmicStackInternal {
Expand Down Expand Up @@ -894,14 +895,20 @@ impl Program for CosmicStackInternal {
windows.iter().enumerate().map(|(i, w)| {
let user_data = w.user_data();
user_data.insert_if_missing(Id::unique);
Tab::new(
let mut tab = Tab::new(
w.title(),
w.app_id(),
user_data.get::<Id>().unwrap().clone(),
)
.on_press(Message::PotentialTabDragStart(i))
.on_right_click(Message::TabMenu(i))
.on_close(Message::Close(i))
.on_close(Message::Close(i));

if self.behavior.close_tab_on_middle_click {
tab = tab.on_middle_click(Message::Close(i));
}

tab
}),
active,
windows[active].is_activated(false),
Expand Down
16 changes: 13 additions & 3 deletions src/shell/element/stack/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ impl From<TabBackgroundTheme> for theme::Container {

pub trait TabMessage: Clone {
fn activate(idx: usize) -> Self;
fn close(idx: usize) -> Self;

fn scroll_further() -> Self;
fn scroll_back() -> Self;
Expand All @@ -148,6 +147,7 @@ pub struct Tab<Message: TabMessage> {
close_message: Option<Message>,
press_message: Option<Message>,
right_click_message: Option<Message>,
middle_click_message: Option<Message>,
rule_theme: TabRuleTheme,
background_theme: TabBackgroundTheme,
active: bool,
Expand All @@ -163,6 +163,7 @@ impl<Message: TabMessage + 'static> Tab<Message> {
close_message: None,
press_message: None,
right_click_message: None,
middle_click_message: None,
rule_theme: TabRuleTheme::Default,
background_theme: TabBackgroundTheme::Default,
active: false,
Expand All @@ -179,6 +180,11 @@ impl<Message: TabMessage + 'static> Tab<Message> {
self
}

pub fn on_middle_click(mut self, message: Message) -> Self {
self.middle_click_message = Some(message);
self
}

pub fn on_close(mut self, message: Message) -> Self {
self.close_message = Some(message);
self
Expand Down Expand Up @@ -255,6 +261,7 @@ impl<Message: TabMessage + 'static> Tab<Message> {
elements: items,
press_message: self.press_message,
right_click_message: self.right_click_message,
middle_click_message: self.middle_click_message,
}
}
}
Expand All @@ -274,6 +281,7 @@ pub(super) struct TabInternal<'a, Message: TabMessage> {
elements: Vec<cosmic::Element<'a, Message>>,
press_message: Option<Message>,
right_click_message: Option<Message>,
middle_click_message: Option<Message>,
}

impl<'a, Message> Widget<Message, cosmic::Theme, cosmic::Renderer> for TabInternal<'a, Message>
Expand Down Expand Up @@ -424,8 +432,10 @@ where
event,
event::Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Middle))
) {
shell.publish(Message::close(self.idx));
return event::Status::Captured;
if let Some(message) = self.middle_click_message.clone() {
shell.publish(message);
return event::Status::Captured;
}
}

}
Expand Down
7 changes: 5 additions & 2 deletions src/shell/layout/floating/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{
time::{Duration, Instant},
};

use cosmic_comp_config::StackBehavior;
use cosmic_settings_config::shortcuts::action::ResizeDirection;
use keyframe::{ease, functions::EaseInOutCubic};
use smithay::{
Expand Down Expand Up @@ -886,6 +887,7 @@ impl FloatingLayout {
&mut self,
mapped: &CosmicMapped,
mut focus_stack: FocusStackMut,
stack_behavior: &StackBehavior,
) -> Option<KeyboardFocusTarget> {
if !self.space.elements().any(|m| m == mapped) {
return None;
Expand All @@ -899,7 +901,7 @@ impl FloatingLayout {
if mapped.is_window() {
// if it is just a window
self.space.unmap_elem(&mapped);
mapped.convert_to_stack((&output, mapped.bbox()), self.theme.clone());
mapped.convert_to_stack((&output, mapped.bbox()), self.theme.clone(), stack_behavior.clone());
self.map_internal(
mapped.clone(),
Some(location.as_local()),
Expand Down Expand Up @@ -957,13 +959,14 @@ impl FloatingLayout {
&mut self,
seat: &Seat<State>,
focus_stack: FocusStackMut,
stack_behavior: &StackBehavior,
) -> Option<KeyboardFocusTarget> {
let Some(KeyboardFocusTarget::Element(elem)) = seat.get_keyboard().unwrap().current_focus()
else {
return None;
};

self.toggle_stacking(&elem, focus_stack)
self.toggle_stacking(&elem, focus_stack, stack_behavior)
}

pub fn move_element(
Expand Down
15 changes: 10 additions & 5 deletions src/shell/layout/tiling/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use crate::{
},
};

use cosmic_comp_config::StackBehavior;
use cosmic_settings_config::shortcuts::action::{FocusDirection, ResizeDirection};
use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree};
use keyframe::{
Expand Down Expand Up @@ -135,6 +136,7 @@ pub struct TilingLayout {
swapping_stack_surface_id: Id,
last_overview_hover: Option<(Option<Instant>, TargetZone)>,
pub theme: cosmic::Theme,
stack_behavior: StackBehavior,
}

#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -342,7 +344,7 @@ pub struct MinimizedTilingState {
}

impl TilingLayout {
pub fn new(theme: cosmic::Theme, output: &Output) -> TilingLayout {
pub fn new(theme: cosmic::Theme, output: &Output, stack_behavior: StackBehavior) -> TilingLayout {
TilingLayout {
queue: TreeQueue {
trees: {
Expand All @@ -358,6 +360,7 @@ impl TilingLayout {
swapping_stack_surface_id: Id::new(),
last_overview_hover: None,
theme,
stack_behavior,
}
}

Expand Down Expand Up @@ -2121,6 +2124,7 @@ impl TilingLayout {
&mut self,
mapped: &CosmicMapped,
mut focus_stack: FocusStackMut,
stack_behavior: &StackBehavior
) -> Option<KeyboardFocusTarget> {
let gaps = self.gaps();

Expand All @@ -2137,7 +2141,7 @@ impl TilingLayout {
// if it is just a window
match tree.get_mut(&node_id).unwrap().data_mut() {
Data::Mapped { mapped, .. } => {
mapped.convert_to_stack((&self.output, mapped.bbox()), self.theme.clone());
mapped.convert_to_stack((&self.output, mapped.bbox()), self.theme.clone(), stack_behavior.clone());
focus_stack.append(&mapped);
KeyboardFocusTarget::Element(mapped.clone())
}
Expand Down Expand Up @@ -2238,6 +2242,7 @@ impl TilingLayout {
&mut self,
seat: &Seat<State>,
mut focus_stack: FocusStackMut,
stack_behavior: &StackBehavior,
) -> Option<KeyboardFocusTarget> {
let gaps = self.gaps();

Expand All @@ -2251,7 +2256,7 @@ impl TilingLayout {
{
match last_active_data {
FocusedNodeData::Window(mapped) => {
return self.toggle_stacking(&mapped, focus_stack);
return self.toggle_stacking(&mapped, focus_stack, stack_behavior);
}
FocusedNodeData::Group(_, _) => {
let mut handle = None;
Expand All @@ -2274,7 +2279,7 @@ impl TilingLayout {
return None;
}
let handle = handle.unwrap();
let stack = CosmicStack::new(surfaces.into_iter(), handle, self.theme.clone());
let stack = CosmicStack::new(surfaces.into_iter(), handle, self.theme.clone(), stack_behavior.clone());

for child in tree
.children_ids(&last_active)
Expand Down Expand Up @@ -2741,7 +2746,7 @@ impl TilingLayout {
Some(TargetZone::WindowStack(window_id, _)) if tree.get(&window_id).is_ok() => {
match tree.get_mut(window_id).unwrap().data_mut() {
Data::Mapped { mapped, .. } => {
mapped.convert_to_stack((&self.output, mapped.bbox()), self.theme.clone());
mapped.convert_to_stack((&self.output, mapped.bbox()), self.theme.clone(), self.stack_behavior.clone());
let Some(stack) = mapped.stack_ref_mut() else {
unreachable!()
};
Expand Down
Loading

0 comments on commit b85818c

Please sign in to comment.