feat: add config option for xdg activation behavior

This commit is contained in:
Robin Nehls 2026-05-22 17:06:49 +02:00 committed by Victoria Brekenfeld
parent 56f84fba2d
commit 2f7c34f29a
3 changed files with 58 additions and 6 deletions

View file

@ -101,6 +101,7 @@ pub struct CosmicCompConfig {
pub appearance_settings: AppearanceConfig, pub appearance_settings: AppearanceConfig,
/// Hide the cursor after this many seconds of pointer inactivity (None disables) /// Hide the cursor after this many seconds of pointer inactivity (None disables)
pub cursor_hide_timeout: Option<u32>, pub cursor_hide_timeout: Option<u32>,
pub activation_policy: ActivationPolicy,
} }
impl Default for CosmicCompConfig { impl Default for CosmicCompConfig {
@ -138,6 +139,7 @@ impl Default for CosmicCompConfig {
accessibility_zoom: ZoomConfig::default(), accessibility_zoom: ZoomConfig::default(),
appearance_settings: AppearanceConfig::default(), appearance_settings: AppearanceConfig::default(),
cursor_hide_timeout: None, cursor_hide_timeout: None,
activation_policy: ActivationPolicy::default(),
} }
} }
} }
@ -227,6 +229,14 @@ pub enum EavesdroppingKeyboardMode {
All, All,
} }
#[derive(Debug, Deserialize, Serialize, Clone, Copy, Default, PartialEq, Eq)]
pub enum ActivationPolicy {
#[default]
Focus,
FocusIfActiveWorkspace,
Urgent,
}
#[derive(Debug, Deserialize, Serialize, Clone, Copy, Default, PartialEq, Eq)] #[derive(Debug, Deserialize, Serialize, Clone, Copy, Default, PartialEq, Eq)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
pub enum XwaylandDescaling { pub enum XwaylandDescaling {

View file

@ -45,8 +45,8 @@ mod types;
use cosmic::config::CosmicTk; use cosmic::config::CosmicTk;
pub use cosmic_comp_config::EdidProduct; pub use cosmic_comp_config::EdidProduct;
use cosmic_comp_config::{ use cosmic_comp_config::{
AppearanceConfig, CosmicCompConfig, KeyboardConfig, TileBehavior, XkbConfig, XwaylandDescaling, ActivationPolicy, AppearanceConfig, CosmicCompConfig, KeyboardConfig, TileBehavior, XkbConfig,
XwaylandEavesdropping, ZoomConfig, XwaylandDescaling, XwaylandEavesdropping, ZoomConfig,
input::{DeviceState as InputDeviceState, InputConfig, TouchpadOverride}, input::{DeviceState as InputDeviceState, InputConfig, TouchpadOverride},
output::comp::{ output::comp::{
OutputConfig, OutputInfo, OutputState, OutputsConfig, TransformDef, load_outputs, OutputConfig, OutputInfo, OutputState, OutputsConfig, TransformDef, load_outputs,
@ -966,6 +966,12 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
} }
} }
} }
"activation_policy" => {
let new = get_config::<ActivationPolicy>(&config, "activation_policy");
if new != state.common.config.cosmic_conf.activation_policy {
state.common.config.cosmic_conf.activation_policy = new;
}
}
_ => {} _ => {}
} }
} }

View file

@ -5,6 +5,7 @@ use crate::{
state::State, state::State,
wayland::protocols::workspace::{State as WState, WorkspaceHandle}, wayland::protocols::workspace::{State as WState, WorkspaceHandle},
}; };
use cosmic_comp_config::ActivationPolicy;
use smithay::{ use smithay::{
input::Seat, input::Seat,
reexports::wayland_server::protocol::wl_surface::WlSurface, reexports::wayland_server::protocol::wl_surface::WlSurface,
@ -115,10 +116,45 @@ impl XdgActivationHandler for State {
} }
} }
ActivationContext::Workspace(_) => { ActivationContext::Workspace(_) => {
self.activate_surface( match self.common.config.cosmic_conf.activation_policy {
&surface, ActivationPolicy::Focus => {
Some((ActivationKey::Wayland(surface.clone()), *context)), self.activate_surface(
); &surface,
Some((ActivationKey::Wayland(surface.clone()), *context)),
);
}
ActivationPolicy::FocusIfActiveWorkspace => {
let shell = self.common.shell.write();
let Some((target_workspace, _)) = shell.workspace_for_surface(&surface)
else {
// surface not found, maybe log warning?
return;
};
let seat = shell.seats.last_active().clone();
let current_output = seat.active_output();
let current_workspace = shell.active_space(&current_output).unwrap().handle;
if target_workspace == current_workspace {
std::mem::drop(shell);
self.activate_surface(
&surface,
Some((ActivationKey::Wayland(surface.clone()), *context)),
);
} else {
let mut workspace_guard = self.common.workspace_state.update();
workspace_guard.add_workspace_state(&target_workspace, WState::Urgent);
}
}
ActivationPolicy::Urgent => {
let shell = self.common.shell.write();
if let Some((workspace, _output)) = shell.workspace_for_surface(&surface) {
let mut workspace_guard = self.common.workspace_state.update();
workspace_guard.add_workspace_state(&workspace, WState::Urgent);
}
}
}
} }
} }
} }