Settings > System & Accounts > Default Applications
Default applications panel allows people to set preferences for default web browser, file browser, music applications and others.
I would appreciate a section for setting default applications by protocol and file extension. Instead of showing all of the available extensions and protocols to configure, I would like to start off with a blank or minimal list which the user can add to if desired through search or by scrolling a list in a dropdown. By minimal list, I mean commonly used extensions and protocols such as .PNG, .JPEG, and HTTPS://. That could make those settings less overwhelming compared to a long list of extensions and protocols that the user doesn't recognize.
@Nyxiad I'm working on implementing this, I agree that there should be a way to edit all all registered mime types (i.e. everything in /usr/share/mime, we don't have to deal with whether the association is by file extension, file magic or protocol, that is handled by xdg stuff), but I don't agree on the design:
I think it should look exactly like the design above for the very common associations people would want to change, these should be very accessible, and their naming and order is important - having it empty by default will make for a very bad experience for people not familiar with computers, and slower in general because you first have to process that there is a dropdown, then look for the common types mixed with all the uncommon types (they can be first in the list but it's still more options). Then below it (potentially under an "advanced" nested page), there should be a filterable by search list with all associations (this is more for the technical reason that on a typical system you'll already have dozens of associations even if you didn't add them in the settings, check your ~/.config/mimeapps.list under [Default Applications], it's not going to be minimal either way) both their xdg name, and their mime type next to it in smaller/thinner/grayer text both for advanced users and to further differentiate them from the common file types.
To illustrate what I mean, here's most of the ui:
Also is there currently a way in libcosmic to display views in the placeholder and dropdown list? pick_list, dropdown and combo_box all only support displaying strings...
Also for the actual implementation, using the xdg-mime crate is fine right? Also I'm not sure I entirely understand the separation between cosmic-settings and cosmic-settings-daemon, because some of the logic seems to here in cosmic-settings, should things be in the daemon only if they're potentially useful for applets?
I was wondering, how the default terminal is implemented ?
xdg-terminal-exec, and on Debian systems there's also update-alternatives --config x-terminal-emulator.
I think a document reader should be added to the list, as it's used frequently and since one is already in the works. The proposed approach to select default applications per mime type is a nice suggestion as well. Though I'd argue a document reader is such a common application, that it warrants a spot on the list.
Would there be an option to add extension to a type such as (.heic, .jxl) to image type if not configured by default?
@bbb651 Do you have a branch that you'd like to submit? We are ready to work on this now.
I haven't make progress on this since only the UI is implemented (I'm posting it like this instead of making a commit because got a bit mixed with the launcher ctrl-shift-tab feature I was working on and I haven't rebased the plumbing code, it wasn't interesting anyways):
default_apps.rs
// Copyright 2024 bbb651 <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only
use cosmic::{
iced::{color, Alignment, Length},
iced_widget::row,
widget::{self, combo_box, dropdown, settings, text},
Apply, Command, Element,
};
use cosmic_settings_page::{self as page, section, Section};
use slotmap::SlotMap;
#[derive(Clone, Debug)]
pub enum Message {
None,
}
#[derive(Clone, Debug, Default)]
pub struct Page {}
impl page::AutoBind<crate::pages::Message> for Page {}
impl page::Page<crate::pages::Message> for Page {
fn content(
&self,
sections: &mut SlotMap<section::Entity, Section<crate::pages::Message>>,
) -> Option<cosmic_settings_page::Content> {
Some(vec![sections.insert(apps()), sections.insert(other())])
}
fn info(&self) -> page::Info {
page::Info::new("default-apps", "application-default-symbolic")
.title(fl!("default-apps"))
.description(fl!("default-apps", "desc"))
}
}
impl Page {
pub fn update(&mut self, message: Message) -> Command<crate::Message> {
match message {
Message::None => (),
}
Command::none()
}
}
fn apps() -> Section<crate::pages::Message> {
Section::default().view::<Page>(move |_binder, _page, section| {
settings::view_section(§ion.title)
.add(settings::flex_item(
fl!("default-apps", "web-browser"),
dropdown(&["Firefox", "Brave"], Some(0), |_| Message::None),
))
.add(settings::flex_item(
fl!("default-apps", "file-manager"),
dropdown(&["COSMIC Files", "Brave"], Some(0), |_| Message::None),
))
.add(settings::flex_item(
fl!("default-apps", "mail-client"),
dropdown(&["Thunderbird", "Brave"], Some(0), |_| Message::None),
))
.add(settings::flex_item(
fl!("default-apps", "music"),
dropdown(&["Videos", "Brave"], Some(0), |_| Message::None),
))
.add(settings::flex_item(
fl!("default-apps", "video"),
dropdown(&["Videos", "Brave"], Some(0), |_| Message::None),
))
.add(settings::flex_item(
fl!("default-apps", "photos"),
dropdown(&["Image viewer", "Brave"], Some(0), |_| Message::None),
))
.add(settings::flex_item(
fl!("default-apps", "calendar"),
dropdown(&["Thunderbird", "Brave"], Some(0), |_| Message::None),
))
.add(settings::flex_item(
fl!("default-apps", "terminal"),
dropdown(&["COSMIC Terminal", "Brave"], Some(0), |_| Message::None),
))
.apply(Element::from)
.map(crate::pages::Message::DefaultApps)
})
}
fn other() -> Section<crate::pages::Message> {
Section::default()
.title(fl!("default-apps", "other-associations"))
.view::<Page>(move |_binder, _page, section| {
let search = widget::search_input(fl!("type-to-search"), "")
.center_x(314)
.on_clear(Message::None)
.on_input(|_| Message::None)
.apply(widget::container)
.width(Length::Fill);
settings::view_section(§ion.title)
.add(settings::item_row(vec![search.into()]))
.add(settings::flex_item_row(
vec![
row![
text("PDF document"),
text("application/pdf")
.size(12.0)
.style(cosmic::style::Text::Color(color!(0xaaaaaa))),
]
.spacing(10.0)
.align_items(Alignment::Center)
.into(),
dropdown(&["Firefox", "Brave"], Some(0), |_| Message::None).into(),
]
.into(),
))
.add(settings::flex_item_row(
vec![
row![
text("RDP"),
text("x-scheme-handler/rdp")
.size(12.0)
.style(cosmic::style::Text::Color(color!(0xaaaaaa))),
]
.spacing(10.0)
.align_items(Alignment::Center)
.into(),
dropdown(&["Remmina", "Brave"], Some(0), |_| Message::None).into(),
]
.into(),
))
.apply(Element::from)
.map(crate::pages::Message::DefaultApps)
})
}
// TODO: Add actual settings to cosmic-settings-deamon, read from it to populate options and write back to it, add rest of options
cosmic_settings.ftl
diff --git a/i18n/en/cosmic_settings.ftl b/i18n/en/cosmic_settings.ftl
index 575ed7e..52d7ef6 100644
--- a/i18n/en/cosmic_settings.ftl
+++ b/i18n/en/cosmic_settings.ftl
@@ -751,3 +752,17 @@ firmware = Firmware
users = Users
.desc = Authentication and user accounts.
+
+## System: Default Applications
+
+default-apps = Default Applications
+ .desc = Default applications and file associations.
+ .web-browser = Web browser
+ .file-manager = File manager
+ .mail-client = Mail client
+ .music = Music
+ .video = Video
+ .photos = Photos
+ .calendar = Calendar
+ .terminal = Terminal
+ .other-associations = Other Associations
Feel free to use it as a base
Implemented in 508b05135aca4da3eaa172147b7bb39017df8cb0