Compare commits

..

No commits in common. "backup/pre-squash-libcosmic-20260525" and "master" have entirely different histories.

160 changed files with 492 additions and 1914 deletions

View file

@ -1,11 +1,6 @@
[package]
# Yoda fork: hard-renamed. Every consumer (leyoda/cosmic-files fork + each
# leyoda/cosmic-* app) depends directly on `libcosmic-yoda` by path, bypassing
# pop-os/libcosmic entirely. No [patch] shenanigans needed — transitive deps
# that used to ask for `libcosmic` are replaced by deps on our forks that ask
# for `libcosmic-yoda`.
name = "libcosmic-yoda"
version = "0.1.0-yoda.2"
name = "libcosmic"
version = "1.0.0"
edition = "2024"
rust-version = "1.90"
@ -14,10 +9,12 @@ name = "cosmic"
[features]
default = [
"winit",
"tokio",
"a11y",
"dbus-config",
"wayland",
"x11",
"iced-wayland",
"multi-window",
]
advanced-shaping = ["iced/advanced-shaping"]
@ -38,6 +35,7 @@ animated-image = [
autosize = []
applet = [
"autosize",
"winit",
"wayland",
"tokio",
"cosmic-panel-config",
@ -83,34 +81,32 @@ tokio = [
"cosmic-config/tokio",
]
# Tokio async runtime
# Wayland window support (yoda fork is Wayland-only; always active in default).
# We still need iced/winit because pop-os/iced hosts the runtime dispatcher
# (`iced_winit as shell`) there — the name is a misnomer, it's the same crate
# that provides both the winit path AND the sctk/cctk wayland path.
wayland = [
# Wayland window support
iced-wayland = [
"ashpd?/wayland",
"autosize",
"iced/winit",
"iced/wayland",
"iced_winit/wayland",
"surface-message",
]
wayland = [
"iced-wayland",
"iced_runtime/cctk",
"iced_winit/cctk",
"iced_wgpu/cctk",
"iced/cctk",
"dep:iced_winit",
"dep:cctk",
"surface-message",
]
surface-message = []
# multi-window support
multi-window = []
# Render with wgpu
wgpu = ["iced/wgpu", "iced_wgpu"]
# Compat stubs — kept empty so upstream deps (cosmic-files, cosmic-text, …)
# that still ask for `winit` / `x11` features resolve cleanly against the
# yoda fork. Activating them has no effect: no code is gated on these.
winit = []
x11 = []
# X11 window support via winit
winit = ["iced/winit", "iced_winit"]
winit_debug = ["winit", "debug"]
winit_tokio = ["winit", "tokio"]
winit_wgpu = ["winit", "wgpu"]
# Enables XDG portal integrations
xdg-portal = ["ashpd"]
qr_code = ["iced/qr_code"]
@ -123,6 +119,7 @@ async-std = [
"zbus?/async-io",
"iced/async-std",
]
x11 = ["iced/x11", "iced_winit/x11"]
[dependencies]
apply = "0.3.0"
@ -176,7 +173,7 @@ float-cmp = "0.10.0"
# Enable DBus feature on Linux targets
[target.'cfg(target_os = "linux")'.dependencies]
cosmic-config = { path = "cosmic-config", features = ["dbus"] }
cosmic-settings-daemon = { path = "../dbus-settings-bindings/cosmic-settings-daemon" }
cosmic-settings-daemon = { git = "https://github.com/pop-os/dbus-settings-bindings" }
zbus = { version = "5.14.0", default-features = false }
[target.'cfg(all(unix, not(target_os = "macos")))'.dependencies]
@ -226,17 +223,10 @@ optional = true
[dependencies.iced_tiny_skia]
path = "./iced/tiny_skia"
# Yoda: drop the x11 default → softbuffer no longer pulls tiny-xlib/x11-dl/etc.
default-features = false
features = ["wayland"]
[dependencies.iced_winit]
path = "./iced/winit"
optional = true
# Yoda: drop the x11 default → winit won't pull winit-x11/tiny-xlib/x11-dl.
# Keep wayland + wayland-dlopen (default behaviour minus x11).
default-features = false
features = ["wayland", "wayland-dlopen"]
[dependencies.iced_wgpu]
path = "./iced/wgpu"
@ -256,21 +246,12 @@ members = [
"cosmic-config",
"cosmic-config-derive",
"cosmic-theme",
"examples/*",
]
# examples/* excluded — many depend on the removed winit/x11 features.
# They will be revisited and adapted in a later phase.
exclude = ["iced", "examples"]
exclude = ["iced"]
[workspace.dependencies]
dirs = "6.0.0"
# Speed up snapshot diffing in cosmic-theme tests. Cargo silently ignores
# [profile.*] blocks in non-root manifests, so this lives at the
# workspace root.
[profile.dev.package.insta]
opt-level = 3
[profile.dev.package.similar]
opt-level = 3
[dev-dependencies]
tempfile = "3.27.0"

View file

@ -10,7 +10,7 @@ macro = ["cosmic-config-derive"]
subscription = ["iced_futures"]
[dependencies]
cosmic-settings-daemon = { path = "../../dbus-settings-bindings/cosmic-settings-daemon", optional = true }
cosmic-settings-daemon = { git = "https://github.com/pop-os/dbus-settings-bindings", optional = true }
zbus = { version = "5.14.0", default-features = false, optional = true }
atomicwrites = { git = "https://github.com/jackpot51/rust-atomicwrites" }
calloop = { version = "0.14.4", optional = true }

View file

@ -1,4 +1,4 @@
use iced_futures::futures::SinkExt;
use iced_futures::futures::{SinkExt, Stream};
use iced_futures::{futures::channel::mpsc, stream};
use notify::RecommendedWatcher;
use std::{borrow::Cow, hash::Hash};

View file

@ -34,3 +34,6 @@ thiserror = "2.0.18"
[dev-dependencies]
insta = "1.47.2"
[profile.dev.package]
insta.opt-level = 3
similar.opt-level = 3

View file

@ -953,12 +953,6 @@ impl ThemeBuilder {
}
#[allow(clippy::too_many_lines)]
// The component_hovered/pressed_overlay vars are seeded once near the
// top of this fn and then reassigned inside each container block
// (primary, secondary, …) before being read again. The initial seed
// is therefore overwritten before any read, which is what the
// unused_assignments lint flags below.
#[allow(unused_assignments)]
/// build the theme
pub fn build(self) -> Theme {
let Self {

View file

@ -1,12 +1,10 @@
use crate::{Component, Theme, composite::over, steps::steps};
use configparser::ini::Ini;
use palette::{Darken, IntoColor, Lighten, Srgba, WithAlpha, rgb::Rgba};
use std::{
fs::{self, File},
io::{self, Write},
num::NonZeroUsize,
path::Path,
process::Command,
};
use super::{OutputError, to_rgba};
@ -219,50 +217,6 @@ impl Theme {
Ok(())
}
/// Apply the preferred GTK client-side decoration button layout.
///
/// This writes the GTK 3/4 `settings.ini` value used by GTK header bars and
/// also best-effort updates GNOME's `button-layout` GSettings key for apps
/// that still consult it.
///
/// # Errors
///
/// Returns an `OutputError` if the GTK settings files cannot be written.
#[cold]
pub fn apply_gtk_decoration_layout(buttons_at_start: bool) -> Result<(), OutputError> {
let Some(config_dir) = dirs::config_dir() else {
return Err(OutputError::MissingConfigDir);
};
let layout = if buttons_at_start {
"close,minimize,maximize:"
} else {
":minimize,maximize,close"
};
for gtk_version in ["gtk-3.0", "gtk-4.0"] {
let gtk_dir = config_dir.join(gtk_version);
fs::create_dir_all(&gtk_dir).map_err(OutputError::Io)?;
Self::write_gtk_settings_key(
&gtk_dir.join("settings.ini"),
"gtk-decoration-layout",
layout,
)?;
}
// best-effort: gsettings is absent on non-GNOME systems
let _ = Command::new("gsettings")
.args([
"set",
"org.gnome.desktop.wm.preferences",
"button-layout",
layout,
])
.status();
Ok(())
}
/// Reset the applied gtk css
///
/// # Errors
@ -302,20 +256,6 @@ impl Theme {
Ok(())
}
#[cold]
fn write_gtk_settings_key(path: &Path, key: &str, value: &str) -> Result<(), OutputError> {
let mut ini = Ini::new_cs();
if path.exists() {
let file_content = fs::read_to_string(path).map_err(OutputError::Io)?;
ini.read(file_content).map_err(OutputError::Ini)?;
}
ini.setstr("Settings", key, Some(value));
ini.pretty_write(path, &super::qt_settings_ini_style())
.map_err(OutputError::Io)
}
fn is_cosmic_css(path: &Path, cosmic_css: &Path) -> io::Result<Option<bool>> {
if !path.exists() {
return Ok(None);

View file

@ -266,14 +266,6 @@ impl From<Theme> for VsTheme {
}
impl Theme {
/// Write this theme to VS Code's `settings.json` as a
/// `workbench.colorCustomizations` entry, and enable
/// `window.autoDetectColorScheme` so VS Code follows the system theme.
///
/// # Errors
///
/// Returns an `OutputError` if the user config dir is missing, the
/// settings file cannot be read/written, or its JSON is invalid.
#[cold]
pub fn apply_vs_code(self) -> Result<(), OutputError> {
let vs_theme = VsTheme::from(self);
@ -299,13 +291,6 @@ impl Theme {
Ok(())
}
/// Remove the `workbench.colorCustomizations` entry previously written
/// by [`Theme::apply_vs_code`] from VS Code's `settings.json`.
///
/// # Errors
///
/// Returns an `OutputError` if the user config dir is missing, the
/// settings file cannot be read/written, or its JSON is invalid.
#[cold]
pub fn reset_vs_code() -> Result<(), OutputError> {
let mut config_dir = dirs::config_dir().ok_or(OutputError::MissingConfigDir)?;

View file

@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
open = "5.3.3"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
path = "../../"
features = [
"debug",

View file

@ -12,7 +12,7 @@ tracing = "0.1"
env_logger = "0.10.2"
log = "0.4.29"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
path = "../../"
default-features = false
features = ["applet-token"]

View file

@ -5,12 +5,12 @@ edition = "2021"
[features]
default = ["wayland"]
wayland = ["libcosmic-yoda/wayland"]
wayland = ["libcosmic/wayland"]
[dependencies]
env_logger = "0.11"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
path = "../../"
features = [
"debug",

View file

@ -8,6 +8,6 @@ edition = "2024"
[dependencies]
jiff = "0.2"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
path = "../../"
features = ["debug", "winit", "tokio", "xdg-portal", "wgpu"]

View file

@ -8,7 +8,7 @@ tracing = "0.1.44"
tracing-subscriber = "0.3.22"
tracing-log = "0.2.0"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
path = "../../"
features = [
"debug",

View file

@ -8,7 +8,7 @@ publish = false
[dependencies]
apply = "0.3.0"
fraction = "0.15.3"
libcosmic-yoda = { path = "../..", features = [
libcosmic = { path = "../..", features = [
"debug",
"winit",
"tokio",

View file

@ -7,6 +7,6 @@ edition = "2021"
tracing = "0.1.44"
tracing-subscriber = "0.3.22"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
path = "../../"
features = ["debug", "winit", "wgpu", "tokio"]

View file

@ -8,6 +8,6 @@ tracing = "0.1.44"
tracing-subscriber = "0.3.22"
tracing-log = "0.2.0"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
path = "../../"
features = ["debug", "winit", "tokio", "xdg-portal", "wgpu"]

View file

@ -6,4 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
libcosmic-yoda = { path = "../..", features = ["debug", "winit", "tokio", "single-instance", "wgpu", "wayland"] }
libcosmic = { path = "../..", features = ["debug", "winit", "tokio", "single-instance", "wgpu", "wayland"] }

View file

@ -8,6 +8,6 @@ tracing = "0.1.44"
tracing-subscriber = "0.3.22"
tracing-log = "0.2.0"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
path = "../../"
features = ["debug", "winit", "tokio", "xdg-portal", "wgpu"]

View file

@ -5,8 +5,8 @@ edition = "2021"
[features]
default = ["xdg-portal"]
rfd = ["libcosmic-yoda/rfd"]
xdg-portal = ["libcosmic-yoda/xdg-portal"]
rfd = ["libcosmic/rfd"]
xdg-portal = ["libcosmic/xdg-portal"]
[dependencies]
apply = "0.3.0"
@ -15,6 +15,6 @@ tracing = "0.1.44"
tracing-subscriber = "0.3.22"
url = "2.5.8"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
features = ["debug", "winit", "wgpu", "wayland", "tokio"]
path = "../../"

View file

@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
fraction = "0.15.3"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
features = ["debug", "wgpu", "winit", "desktop", "tokio"]
path = "../.."
default-features = false

View file

@ -5,6 +5,6 @@ edition = "2024"
[dependencies]
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
path = "../../"
features = ["debug", "winit", "wgpu", "tokio", "xdg-portal"]

View file

@ -9,6 +9,6 @@ tracing-subscriber = "0.3.22"
tracing-log = "0.2.0"
chrono = "*"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
features = ["debug", "wgpu", "winit", "desktop", "tokio"]
path = "../.."

View file

@ -8,6 +8,6 @@ tracing = "0.1.44"
tracing-subscriber = "0.3.22"
tracing-log = "0.2.0"
[dependencies.libcosmic-yoda]
[dependencies.libcosmic]
path = "../../"
features = ["debug", "winit", "wgpu", "tokio", "xdg-portal"]

2
iced

@ -1 +1 @@
Subproject commit 81639935398a856f3164dc406fbac78922c258fc
Subproject commit 78caabba7ef91cd1030da6f70b41d266704ffece

View file

@ -1,6 +1,7 @@
// Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: MPL-2.0
#[cfg(feature = "winit")]
use crate::app;
#[cfg(feature = "single-instance")]
use crate::dbus_activation;
@ -8,6 +9,7 @@ use crate::dbus_activation;
pub const fn app<M>(message: M) -> Action<M> {
Action::App(message)
}
#[cfg(feature = "winit")]
pub const fn cosmic<M>(message: app::Action) -> Action<M> {
Action::Cosmic(message)
}
@ -21,6 +23,7 @@ pub const fn none<M>() -> Action<M> {
pub enum Action<M> {
/// Messages from the application, for the application.
App(M),
#[cfg(feature = "winit")]
/// Internal messages to be handled by libcosmic.
Cosmic(app::Action),
#[cfg(feature = "single-instance")]

View file

@ -100,10 +100,9 @@ impl<T: Application> Cosmic<T>
where
T::Message: Send + 'static,
{
pub fn init((core, flags): (Core, T::Flags)) -> (Self, iced::Task<crate::Action<T::Message>>) {
#[cfg(all(feature = "dbus-config", target_os = "linux"))]
let mut core = core;
pub fn init(
(mut core, flags): (Core, T::Flags),
) -> (Self, iced::Task<crate::Action<T::Message>>) {
#[cfg(all(feature = "dbus-config", target_os = "linux"))]
{
use iced_futures::futures::executor::block_on;
@ -365,6 +364,7 @@ where
crate::surface::Action::Task(f) => {
f().map(|sm| crate::Action::Cosmic(Action::Surface(sm)))
}
_ => iced::Task::none(),
}
#[cfg(not(feature = "surface-message"))]
@ -408,7 +408,7 @@ where
f64::from(self.app.core().scale_factor())
}
pub fn style(&self, _theme: &Theme) -> theme::Style {
pub fn style(&self, theme: &Theme) -> theme::Style {
if let Some(style) = self.app.style() {
style
} else if self.app.core().window.is_maximized {
@ -480,11 +480,12 @@ where
.into_iter()
.filter(cosmic_config::Error::is_err)
{
if let cosmic_config::Error::GetKey(_, err) = &why
&& err.kind() == std::io::ErrorKind::NotFound {
if let cosmic_config::Error::GetKey(_, err) = &why {
if err.kind() == std::io::ErrorKind::NotFound {
// No system default config installed; don't error
continue;
}
}
tracing::error!(?why, "cosmic toolkit config update error");
}
@ -620,15 +621,15 @@ impl<T: Application> Cosmic<T> {
#[allow(clippy::too_many_lines)]
fn cosmic_update(&mut self, message: Action) -> iced::Task<crate::Action<T::Message>> {
match message {
Action::WindowMaximized(_id, _maximized) => {
Action::WindowMaximized(id, maximized) => {
#[cfg(not(all(feature = "wayland", target_os = "linux")))]
if self
.app
.core()
.main_window_id()
.is_some_and(|main_id| main_id == _id)
.is_some_and(|main_id| main_id == id)
{
self.app.core_mut().window.sharp_corners = _maximized;
self.app.core_mut().window.sharp_corners = maximized;
}
}

View file

@ -136,7 +136,7 @@ pub fn run<App: Application>(settings: Settings, flags: App::Flags) -> iced::Res
crate::malloc::limit_mmap_threshold(threshold);
}
let _default_font = settings.default_font;
let default_font = settings.default_font;
let (settings, (mut core, flags), window_settings) = iced_settings::<App>(settings, flags);
#[cfg(not(feature = "multi-window"))]
{
@ -284,7 +284,7 @@ where
// app = app.window(window_settings);
core.main_window = Some(iced_core::window::Id::RESERVED);
}
let app = iced::daemon(
let mut app = iced::daemon(
BootData(Rc::new(RefCell::new(Some(BootDataInner::<App> {
flags,
core,

View file

@ -1,7 +1,7 @@
//! Distribute content vertically.
use crate::iced;
use iced::core::alignment::{self, Alignment};
use iced::core::event::Event;
use iced::core::event::{self, Event};
use iced::core::layout;
use iced::core::mouse;
use iced::core::overlay;

View file

@ -10,7 +10,11 @@ use crate::{
widget::{
self,
autosize::{self, Autosize, autosize},
column::Column,
layer_container,
row::Row,
space::horizontal,
space::vertical,
},
};
@ -213,6 +217,12 @@ impl Context {
icon: widget::icon::Handle,
) -> crate::widget::Button<'a, Message> {
let suggested = self.suggested_size(icon.symbolic);
let (applet_padding_major_axis, applet_padding_minor_axis) = self.suggested_padding(true);
let (horizontal_padding, vertical_padding) = if self.is_horizontal() {
(applet_padding_major_axis, applet_padding_minor_axis)
} else {
(applet_padding_minor_axis, applet_padding_major_axis)
};
let symbolic = icon.symbolic;
let icon = widget::icon(icon)
.class(if symbolic {
@ -455,8 +465,10 @@ impl Context {
&self,
content: impl Into<Element<'a, Message>>,
) -> Autosize<'a, Message, crate::Theme, crate::Renderer> {
let force_configured = matches!(&self.panel_type, PanelType::Other(n) if n.is_empty());
let w = autosize(content, AUTOSIZE_MAIN_ID.clone());
let mut limits = Limits::NONE;
let suggested_window_size = self.suggested_window_size();
if let Some(width) = self
.suggested_bounds
@ -567,7 +579,7 @@ pub fn run<App: Application>(flags: App::Flags) -> iced::Result {
// window_settings = window_settings.clone();
core.main_window = Some(iced_core::window::Id::RESERVED);
}
let app = iced::daemon(
let mut app = iced::daemon(
BootData(Rc::new(RefCell::new(Some(BootDataInner::<App> {
flags,
core,

View file

@ -1,7 +1,7 @@
//! Distribute content horizontally.
use crate::iced;
use iced::core::alignment::{self, Alignment};
use iced::core::event::Event;
use iced::core::event::{self, Event};
use iced::core::layout::{self, Layout};
use iced::core::mouse;
use iced::core::overlay;
@ -10,6 +10,7 @@ use iced::core::widget::{Operation, Tree};
use iced::core::{
Clipboard, Element, Length, Padding, Pixels, Rectangle, Shell, Size, Vector, Widget, widget,
};
use iced::touch;
/// A container that distributes its contents horizontally.
///

Some files were not shown because too many files have changed in this diff Show more