feat: add tiling variables to cosmic config

This commit is contained in:
Ashley Wulber 2024-02-08 14:25:18 -05:00 committed by GitHub
parent e43c0f648d
commit 5eb5af4675
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 189 additions and 44 deletions

View file

@ -7,13 +7,44 @@ use std::collections::HashMap;
pub mod input;
pub mod workspace;
#[derive(Clone, Debug, Default, PartialEq, CosmicConfigEntry)]
#[derive(Clone, Debug, PartialEq, CosmicConfigEntry)]
#[version = 1]
pub struct CosmicCompConfig {
pub workspaces: workspace::WorkspaceConfig,
pub input_default: input::InputConfig,
pub input_touchpad: input::InputConfig,
pub input_devices: HashMap<String, input::InputConfig>,
pub xkb_config: XkbConfig,
/// Autotiling enabled
pub autotile: bool,
/// Determines the behavior of the autotile variable
/// 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,
/// Active hint enabled
pub active_hint: bool,
}
impl Default for CosmicCompConfig {
fn default() -> Self {
Self {
workspaces: Default::default(),
input_default: Default::default(),
input_touchpad: Default::default(),
input_devices: Default::default(),
xkb_config: Default::default(),
autotile: Default::default(),
autotile_behavior: Default::default(),
active_hint: true,
}
}
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Deserialize, Serialize)]
pub enum TileBehavior {
#[default]
Global,
PerWorkspace,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]

View file

@ -578,7 +578,11 @@ where
Vec::new()
};
let active_hint = theme.active_hint as u8;
let active_hint = if state.config.cosmic_conf.active_hint {
theme.active_hint as u8
} else {
0
};
// overlay redirect windows
// they need to be over sticky windows, because they could be popups of sticky windows,
@ -664,7 +668,7 @@ where
let offset = match previous.as_ref() {
Some((previous, previous_idx, start)) => {
let layout = state.config.workspace.workspace_layout;
let layout = state.config.cosmic_conf.workspaces.workspace_layout;
let workspace = state
.shell

View file

@ -5,7 +5,7 @@ use crate::{
state::{BackendData, State},
wayland::protocols::output_configuration::OutputConfigurationState,
};
use cosmic_config::ConfigGet;
use cosmic_config::{ConfigGet, CosmicConfigEntry};
use serde::{Deserialize, Serialize};
use smithay::input::Seat;
pub use smithay::{
@ -32,25 +32,20 @@ pub use self::types::*;
use cosmic_comp_config::{
input::InputConfig,
workspace::{WorkspaceConfig, WorkspaceLayout},
XkbConfig,
CosmicCompConfig, TileBehavior, XkbConfig,
};
#[derive(Debug)]
pub struct Config {
pub static_conf: StaticConfig,
pub dynamic_conf: DynamicConfig,
pub config: cosmic_config::Config,
pub xkb: XkbConfig,
pub input_default: InputConfig,
pub input_touchpad: InputConfig,
pub input_devices: HashMap<String, InputConfig>,
pub workspace: WorkspaceConfig,
pub cosmic_helper: cosmic_config::Config,
pub cosmic_conf: CosmicCompConfig,
}
#[derive(Debug, Deserialize)]
pub struct StaticConfig {
pub key_bindings: HashMap<key_bindings::KeyPattern, key_bindings::Action>,
pub tiling_enabled: bool,
pub data_control_enabled: bool,
}
@ -172,15 +167,18 @@ impl Config {
.expect("Failed to add cosmic-config to the event loop");
let xdg = xdg::BaseDirectories::new().ok();
let workspace = get_config::<WorkspaceConfig>(&config, "workspaces");
let cosmic_comp_config =
CosmicCompConfig::get_entry(&config).unwrap_or_else(|(errs, c)| {
for err in errs {
error!(?err, "");
}
c
});
Config {
static_conf: Self::load_static(xdg.as_ref(), workspace.workspace_layout),
dynamic_conf: Self::load_dynamic(xdg.as_ref()),
xkb: get_config(&config, "xkb_config"),
input_default: get_config(&config, "input_default"),
input_touchpad: get_config(&config, "input_touchpad"),
input_devices: get_config(&config, "input_devices"),
workspace,
config,
cosmic_conf: cosmic_comp_config,
cosmic_helper: config,
}
}
@ -221,7 +219,6 @@ impl Config {
StaticConfig {
key_bindings: HashMap::new(),
tiling_enabled: false,
data_control_enabled: false,
}
}
@ -410,7 +407,7 @@ impl Config {
}
pub fn xkb_config(&self) -> XkbConfig {
self.xkb.clone()
self.cosmic_conf.xkb_config.clone()
}
pub fn read_device(&self, device: &mut InputDevice) {
@ -438,11 +435,11 @@ impl Config {
fn get_device_config(&self, device: &InputDevice) -> (Option<&InputConfig>, &InputConfig) {
let default_config = if device.config_tap_finger_count() > 0 {
&self.input_touchpad
&self.cosmic_conf.input_touchpad
} else {
&self.input_default
&self.cosmic_conf.input_default
};
let device_config = self.input_devices.get(device.name());
let device_config = self.cosmic_conf.input_devices.get(device.name());
(device_config, default_config)
}
}
@ -525,28 +522,61 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
}
}
}
state.common.config.xkb = value;
state.common.config.cosmic_conf.xkb_config = value;
}
"input_default" => {
let value = get_config::<InputConfig>(&config, "input_default");
state.common.config.input_default = value;
state.common.config.cosmic_conf.input_default = value;
update_input(state);
}
"input_touchpad" => {
let value = get_config::<InputConfig>(&config, "input_touchpad");
state.common.config.input_touchpad = value;
state.common.config.cosmic_conf.input_touchpad = value;
update_input(state);
}
"input_devices" => {
let value = get_config::<HashMap<String, InputConfig>>(&config, "input_devices");
state.common.config.input_devices = value;
state.common.config.cosmic_conf.input_devices = value;
update_input(state);
}
"workspaces" => {
state.common.config.workspace =
state.common.config.cosmic_conf.workspaces =
get_config::<WorkspaceConfig>(&config, "workspaces");
state.common.shell.update_config(&state.common.config);
}
"autotile" => {
let new = get_config::<bool>(&config, "autotile");
if new != state.common.config.cosmic_conf.autotile {
state.common.config.cosmic_conf.autotile = new;
let seats: Vec<_> = state.common.seats().cloned().collect();
let mut guard = state.common.shell.workspace_state.update();
state
.common
.shell
.workspaces
.update_autotile(new, &mut guard, seats);
}
}
"autotile_behavior" => {
let new = get_config::<TileBehavior>(&config, "autotile_behavior");
if new != state.common.config.cosmic_conf.autotile_behavior {
state.common.config.cosmic_conf.autotile_behavior = new;
let seats: Vec<_> = state.common.seats().cloned().collect();
let mut guard = state.common.shell.workspace_state.update();
state
.common
.shell
.workspaces
.update_autotile_behavior(new, &mut guard, seats);
}
}
"active_hint" => {
let new = get_config::<bool>(&config, "active_hint");
if new != state.common.config.cosmic_conf.active_hint {
state.common.config.cosmic_conf.active_hint = new;
state.common.shell.update_config(&state.common.config);
}
}
_ => {}
}
}

View file

@ -20,7 +20,8 @@ use crate::{
},
};
use calloop::{timer::Timer, RegistrationToken};
use cosmic_comp_config::workspace::WorkspaceLayout;
use cosmic_comp_config::{workspace::WorkspaceLayout, TileBehavior};
use cosmic_config::ConfigSet;
use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType;
use smithay::{
backend::input::{
@ -61,6 +62,7 @@ use std::{
any::Any,
cell::RefCell,
collections::HashMap,
thread,
time::{Duration, Instant},
};
@ -1651,7 +1653,10 @@ impl State {
_ => {}
}
} else if propagate {
match (direction, self.common.config.workspace.workspace_layout) {
match (
direction,
self.common.config.cosmic_conf.workspaces.workspace_layout,
) {
(Direction::Left, WorkspaceLayout::Horizontal)
| (Direction::Up, WorkspaceLayout::Vertical) => self.handle_action(
Action::PreviousWorkspace,
@ -1786,7 +1791,10 @@ impl State {
}
}
} else if propagate {
match (direction, self.common.config.workspace.workspace_layout) {
match (
direction,
self.common.config.cosmic_conf.workspaces.workspace_layout,
) {
(Direction::Left, WorkspaceLayout::Horizontal)
| (Direction::Up, WorkspaceLayout::Vertical) => self.handle_action(
Action::MoveToPreviousWorkspace,
@ -2048,10 +2056,31 @@ impl State {
}
}
Action::ToggleTiling => {
let output = seat.active_output();
let workspace = self.common.shell.workspaces.active_mut(&output);
let mut guard = self.common.shell.workspace_state.update();
workspace.toggle_tiling(seat, &mut guard);
if matches!(
self.common.config.cosmic_conf.autotile_behavior,
TileBehavior::Global
) {
let autotile = !self.common.config.cosmic_conf.autotile;
self.common.config.cosmic_conf.autotile = autotile;
let seats: Vec<_> = self.common.seats().cloned().collect();
let mut guard = self.common.shell.workspace_state.update();
self.common.shell.workspaces.update_autotile(
self.common.config.cosmic_conf.autotile,
&mut guard,
seats,
);
let config = self.common.config.cosmic_helper.clone();
thread::spawn(move || {
if let Err(err) = config.set("autotile", autotile) {
error!(?err, "Failed to update autotile key");
}
});
} else {
let output = seat.active_output();
let workspace = self.common.shell.workspaces.active_mut(&output);
let mut guard = self.common.shell.workspace_state.update();
workspace.toggle_tiling(seat, &mut guard);
}
}
Action::ToggleWindowFloating => {
let output = seat.active_output();

View file

@ -7,7 +7,7 @@ use std::{
};
use wayland_backend::server::ClientId;
use cosmic_comp_config::workspace::WorkspaceMode;
use cosmic_comp_config::{workspace::WorkspaceMode, TileBehavior};
use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::{
State as WState, TilingState,
};
@ -27,7 +27,10 @@ use smithay::{
ext::session_lock::v1::server::ext_session_lock_v1::ExtSessionLockV1,
xdg::shell::server::xdg_toplevel::WmCapabilities,
},
wayland_server::{protocol::wl_surface::WlSurface, Client, DisplayHandle},
wayland_server::{
protocol::{wl_seat::WlSeat, wl_surface::WlSurface},
Client, DisplayHandle,
},
},
utils::{Logical, Point, Rectangle, Serial, Size, SERIAL_COUNTER},
wayland::{
@ -477,7 +480,8 @@ pub struct Workspaces {
pub sets: IndexMap<Output, WorkspaceSet>,
backup_set: Option<WorkspaceSet>,
mode: WorkspaceMode,
tiling_enabled: bool,
autotile: bool,
autotile_behavior: TileBehavior,
theme: cosmic::Theme,
}
@ -486,8 +490,9 @@ impl Workspaces {
Workspaces {
sets: IndexMap::new(),
backup_set: None,
mode: config.workspace.workspace_mode,
tiling_enabled: config.static_conf.tiling_enabled,
mode: config.cosmic_conf.workspaces.workspace_mode,
autotile: config.cosmic_conf.autotile,
autotile_behavior: config.cosmic_conf.autotile_behavior,
theme,
}
}
@ -515,7 +520,7 @@ impl Workspaces {
workspace_state,
&output,
self.sets.len(),
self.tiling_enabled,
self.autotile,
self.theme.clone(),
)
});
@ -659,7 +664,7 @@ impl Workspaces {
xdg_activation_state: &XdgActivationState,
) {
let old_mode = self.mode;
self.mode = config.workspace.workspace_mode;
self.mode = config.cosmic_conf.workspaces.workspace_mode;
if self.sets.len() <= 1 {
return;
@ -704,7 +709,7 @@ impl Workspaces {
output,
&set.group,
false,
config.static_conf.tiling_enabled,
config.cosmic_conf.autotile,
self.theme.clone(),
),
);
@ -917,6 +922,48 @@ impl Workspaces {
}
}
}
pub fn update_autotile_behavior(
&mut self,
behavior: TileBehavior,
guard: &mut WorkspaceUpdateGuard<'_, State>,
seats: Vec<Seat<State>>,
) {
self.autotile_behavior = behavior;
self.apply_tile_change(guard, seats);
}
fn apply_tile_change(
&mut self,
guard: &mut WorkspaceUpdateGuard<'_, State>,
seats: Vec<Seat<State>>,
) {
if matches!(self.autotile_behavior, TileBehavior::Global) {
// must apply change to all workspaces now
for (_, set) in &mut self.sets {
set.tiling_enabled = self.autotile;
for w in &mut set.workspaces {
if w.tiling_enabled == self.autotile {
continue;
}
for s in &seats {
w.toggle_tiling(s, guard);
}
}
}
}
}
pub fn update_autotile(
&mut self,
autotile: bool,
guard: &mut WorkspaceUpdateGuard<'_, State>,
seats: Vec<Seat<State>>,
) {
self.autotile = autotile;
self.apply_tile_change(guard, seats);
}
}
#[derive(Debug)]
@ -2139,7 +2186,11 @@ impl Shell {
};
let button = start_data.button;
let active_hint = state.common.theme.cosmic().active_hint as u8;
let active_hint = if state.common.config.cosmic_conf.active_hint {
state.common.theme.cosmic().active_hint as u8
} else {
0
};
let pointer = seat.get_pointer().unwrap();
let pos = pointer.current_location().as_global();