fix: update freedesktop-desktop-entry and fix app-list icons
This commit is contained in:
parent
c60a100135
commit
68fd2a6c17
5 changed files with 229 additions and 208 deletions
60
Cargo.lock
generated
60
Cargo.lock
generated
|
|
@ -904,6 +904,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cosmic-client-toolkit",
|
"cosmic-client-toolkit",
|
||||||
"cosmic-protocols",
|
"cosmic-protocols",
|
||||||
|
"freedesktop-desktop-entry 0.6.0",
|
||||||
"futures",
|
"futures",
|
||||||
"i18n-embed 0.14.1",
|
"i18n-embed 0.14.1",
|
||||||
"i18n-embed-fl 0.8.0",
|
"i18n-embed-fl 0.8.0",
|
||||||
|
|
@ -1205,7 +1206,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-config"
|
name = "cosmic-config"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomicwrites",
|
"atomicwrites",
|
||||||
"cosmic-config-derive",
|
"cosmic-config-derive",
|
||||||
|
|
@ -1227,7 +1228,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-config-derive"
|
name = "cosmic-config-derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
|
|
@ -1274,7 +1275,7 @@ name = "cosmic-panel-button"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cosmic-config",
|
"cosmic-config",
|
||||||
"freedesktop-desktop-entry",
|
"freedesktop-desktop-entry 0.5.2",
|
||||||
"libcosmic",
|
"libcosmic",
|
||||||
"serde",
|
"serde",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|
@ -1343,7 +1344,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-theme"
|
name = "cosmic-theme"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"almost",
|
"almost",
|
||||||
"cosmic-config",
|
"cosmic-config",
|
||||||
|
|
@ -2235,6 +2236,21 @@ dependencies = [
|
||||||
"xdg",
|
"xdg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "freedesktop-desktop-entry"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fefe79ec93a6aeaa938981fe3e11b4ed1b2f9deacc6bb631585bc48252d1bfa"
|
||||||
|
dependencies = [
|
||||||
|
"dirs 5.0.1",
|
||||||
|
"gettext-rs",
|
||||||
|
"memchr",
|
||||||
|
"strsim 0.11.1",
|
||||||
|
"textdistance",
|
||||||
|
"thiserror",
|
||||||
|
"xdg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "freedesktop-icons"
|
name = "freedesktop-icons"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
|
@ -2767,7 +2783,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced"
|
name = "iced"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dnd",
|
"dnd",
|
||||||
"iced_accessibility",
|
"iced_accessibility",
|
||||||
|
|
@ -2785,7 +2801,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_accessibility"
|
name = "iced_accessibility"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"accesskit",
|
"accesskit",
|
||||||
"accesskit_unix",
|
"accesskit_unix",
|
||||||
|
|
@ -2794,7 +2810,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_core"
|
name = "iced_core"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.5.0",
|
||||||
"dnd",
|
"dnd",
|
||||||
|
|
@ -2816,7 +2832,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_futures"
|
name = "iced_futures"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
|
|
@ -2829,7 +2845,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_graphics"
|
name = "iced_graphics"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.5.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
|
@ -2853,7 +2869,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_renderer"
|
name = "iced_renderer"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_graphics",
|
"iced_graphics",
|
||||||
"iced_tiny_skia",
|
"iced_tiny_skia",
|
||||||
|
|
@ -2865,7 +2881,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_runtime"
|
name = "iced_runtime"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dnd",
|
"dnd",
|
||||||
"iced_accessibility",
|
"iced_accessibility",
|
||||||
|
|
@ -2879,7 +2895,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_sctk"
|
name = "iced_sctk"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"enum-repr",
|
"enum-repr",
|
||||||
"float-cmp",
|
"float-cmp",
|
||||||
|
|
@ -2905,7 +2921,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_style"
|
name = "iced_style"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_core",
|
"iced_core",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
|
@ -2915,7 +2931,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_tiny_skia"
|
name = "iced_tiny_skia"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cosmic-text",
|
"cosmic-text",
|
||||||
|
|
@ -2932,7 +2948,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_wgpu"
|
name = "iced_wgpu"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.5.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
|
@ -2958,7 +2974,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_widget"
|
name = "iced_widget"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dnd",
|
"dnd",
|
||||||
"iced_renderer",
|
"iced_renderer",
|
||||||
|
|
@ -3694,7 +3710,7 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libcosmic"
|
name = "libcosmic"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#2af549f5b15a83b3973f3291d1107a419f1e360a"
|
source = "git+https://github.com/pop-os/libcosmic#173ddca60fdb26cf5b1784edfc1a78594acf7002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"apply",
|
"apply",
|
||||||
"ashpd",
|
"ashpd",
|
||||||
|
|
@ -3707,7 +3723,7 @@ dependencies = [
|
||||||
"css-color",
|
"css-color",
|
||||||
"derive_setters",
|
"derive_setters",
|
||||||
"fraction",
|
"fraction",
|
||||||
"freedesktop-desktop-entry",
|
"freedesktop-desktop-entry 0.5.2",
|
||||||
"freedesktop-icons",
|
"freedesktop-icons",
|
||||||
"iced",
|
"iced",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
|
|
@ -3724,9 +3740,11 @@ dependencies = [
|
||||||
"palette",
|
"palette",
|
||||||
"rfd",
|
"rfd",
|
||||||
"ron",
|
"ron",
|
||||||
|
"serde",
|
||||||
"shlex",
|
"shlex",
|
||||||
"slotmap",
|
"slotmap",
|
||||||
"taffy",
|
"taffy",
|
||||||
|
"textdistance",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|
@ -5628,6 +5646,12 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textdistance"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d321c8576c2b47e43953e9cce236550d4cd6af0a6ce518fe084340082ca6037b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.61"
|
version = "1.0.61"
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||||
tracing-log = "0.2.0"
|
tracing-log = "0.2.0"
|
||||||
cosmic-config = { git = "https://github.com/pop-os/libcosmic" }
|
cosmic-config = { git = "https://github.com/pop-os/libcosmic" }
|
||||||
serde = { version = "1.0.152", features = ["derive"] }
|
serde = { version = "1.0.152", features = ["derive"] }
|
||||||
|
freedesktop-desktop-entry = "0.6.0"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = "fat"
|
lto = "fat"
|
||||||
|
|
@ -65,4 +66,4 @@ ignored = ["libcosmic"]
|
||||||
# libcosmic = { git = "https://github.com/pop-os/libcosmic//" }
|
# libcosmic = { git = "https://github.com/pop-os/libcosmic//" }
|
||||||
|
|
||||||
[patch."https://github.com/Smithay/client-toolkit"]
|
[patch."https://github.com/Smithay/client-toolkit"]
|
||||||
sctk = { git = "https://github.com/smithay/client-toolkit//", package = "smithay-client-toolkit", rev = "3bed072" }
|
sctk = { git = "https://github.com/smithay/client-toolkit//", package = "smithay-client-toolkit", rev = "3bed072" }
|
||||||
|
|
@ -34,3 +34,4 @@ tracing-subscriber.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
url = "2.5.0"
|
url = "2.5.0"
|
||||||
zbus.workspace = true
|
zbus.workspace = true
|
||||||
|
freedesktop-desktop-entry.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,7 @@ use cctk::wayland_client::protocol::wl_seat::WlSeat;
|
||||||
use cosmic::applet::cosmic_panel_config::PanelSize;
|
use cosmic::applet::cosmic_panel_config::PanelSize;
|
||||||
use cosmic::applet::Size;
|
use cosmic::applet::Size;
|
||||||
use cosmic::cosmic_config::{Config, CosmicConfigEntry};
|
use cosmic::cosmic_config::{Config, CosmicConfigEntry};
|
||||||
use cosmic::desktop::{
|
use cosmic::desktop::IconSource;
|
||||||
app_id_or_fallback_matches, load_applications_for_app_ids, DesktopEntryData,
|
|
||||||
};
|
|
||||||
use cosmic::iced;
|
use cosmic::iced;
|
||||||
use cosmic::iced::event::listen_with;
|
use cosmic::iced::event::listen_with;
|
||||||
use cosmic::iced::wayland::actions::data_device::DataFromMimeType;
|
use cosmic::iced::wayland::actions::data_device::DataFromMimeType;
|
||||||
|
|
@ -34,7 +32,6 @@ use cosmic::iced::widget::dnd_listener;
|
||||||
use cosmic::iced::widget::vertical_rule;
|
use cosmic::iced::widget::vertical_rule;
|
||||||
use cosmic::iced::widget::vertical_space;
|
use cosmic::iced::widget::vertical_space;
|
||||||
use cosmic::iced::widget::{column, dnd_source, mouse_area, row, Column, Row};
|
use cosmic::iced::widget::{column, dnd_source, mouse_area, row, Column, Row};
|
||||||
use cosmic::iced::window::icon;
|
|
||||||
use cosmic::iced::Color;
|
use cosmic::iced::Color;
|
||||||
use cosmic::iced::Vector;
|
use cosmic::iced::Vector;
|
||||||
use cosmic::iced::{window, Subscription};
|
use cosmic::iced::{window, Subscription};
|
||||||
|
|
@ -70,6 +67,9 @@ use cosmic::{Element, Theme};
|
||||||
use cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::State;
|
use cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::State;
|
||||||
use cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1;
|
use cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1;
|
||||||
use cosmic_protocols::workspace::v1::client::zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1;
|
use cosmic_protocols::workspace::v1::client::zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1;
|
||||||
|
use freedesktop_desktop_entry as fde;
|
||||||
|
use freedesktop_desktop_entry::get_languages_from_env;
|
||||||
|
use freedesktop_desktop_entry::DesktopEntry;
|
||||||
use futures::future::pending;
|
use futures::future::pending;
|
||||||
use iced::widget::container;
|
use iced::widget::container;
|
||||||
use iced::Alignment;
|
use iced::Alignment;
|
||||||
|
|
@ -79,6 +79,7 @@ use itertools::Itertools;
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
@ -92,28 +93,6 @@ pub fn run() -> cosmic::iced::Result {
|
||||||
cosmic::applet::run::<CosmicAppList>(true, ())
|
cosmic::applet::run::<CosmicAppList>(true, ())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_applications_for_app_ids_sorted<'a, 'b>(
|
|
||||||
locale: impl Into<Option<&'a str>>,
|
|
||||||
app_ids: impl Iterator<Item = &'b str> + Clone,
|
|
||||||
fill_missing_ones: bool,
|
|
||||||
) -> Vec<DesktopEntryData> {
|
|
||||||
let mut ret = load_applications_for_app_ids(locale, app_ids.clone(), fill_missing_ones, false);
|
|
||||||
ret.sort_by(|a, b| {
|
|
||||||
app_ids
|
|
||||||
.clone()
|
|
||||||
.position(|id| id == a.id)
|
|
||||||
.unwrap_or(usize::MAX)
|
|
||||||
.cmp(
|
|
||||||
&app_ids
|
|
||||||
.clone()
|
|
||||||
.position(|id| id == b.id)
|
|
||||||
.unwrap_or(usize::MAX),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct AppletIconData {
|
struct AppletIconData {
|
||||||
icon_size: u16,
|
icon_size: u16,
|
||||||
|
|
@ -154,18 +133,26 @@ impl AppletIconData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
type DockItemId = u32;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
struct DockItem {
|
struct DockItem {
|
||||||
id: u32,
|
// ID used internally in the applet. Each dock item
|
||||||
|
// have an unique id
|
||||||
|
id: DockItemId,
|
||||||
toplevels: Vec<(ZcosmicToplevelHandleV1, ToplevelInfo, Option<WaylandImage>)>,
|
toplevels: Vec<(ZcosmicToplevelHandleV1, ToplevelInfo, Option<WaylandImage>)>,
|
||||||
desktop_info: DesktopEntryData,
|
// Information found in the .desktop file
|
||||||
|
desktop_info: DesktopEntry<'static>,
|
||||||
|
// We must use this because the id in `DesktopEntry` is an estimation.
|
||||||
|
// Thus, if we unpin an item, we want to be sure to use the real id
|
||||||
|
original_app_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataFromMimeType for DockItem {
|
impl DataFromMimeType for DockItem {
|
||||||
fn from_mime_type(&self, mime_type: &str) -> Option<Vec<u8>> {
|
fn from_mime_type(&self, mime_type: &str) -> Option<Vec<u8>> {
|
||||||
if mime_type == MIME_TYPE && self.desktop_info.path.is_some() {
|
if mime_type == MIME_TYPE {
|
||||||
Some(
|
Some(
|
||||||
Url::from_file_path(self.desktop_info.path.as_deref().unwrap())
|
Url::from_file_path(&self.desktop_info.path)
|
||||||
.ok()?
|
.ok()?
|
||||||
.to_string()
|
.to_string()
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
|
|
@ -178,18 +165,6 @@ impl DataFromMimeType for DockItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DockItem {
|
impl DockItem {
|
||||||
fn new(
|
|
||||||
id: u32,
|
|
||||||
toplevels: Vec<(ZcosmicToplevelHandleV1, ToplevelInfo, Option<WaylandImage>)>,
|
|
||||||
desktop_info: DesktopEntryData,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
id,
|
|
||||||
toplevels,
|
|
||||||
desktop_info,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_icon(
|
fn as_icon(
|
||||||
&self,
|
&self,
|
||||||
applet: &Context,
|
applet: &Context,
|
||||||
|
|
@ -209,7 +184,9 @@ impl DockItem {
|
||||||
|
|
||||||
let app_icon = AppletIconData::new(applet);
|
let app_icon = AppletIconData::new(applet);
|
||||||
|
|
||||||
let cosmic_icon = desktop_info.icon.as_cosmic_icon().size(app_icon.icon_size);
|
let cosmic_icon = IconSource::from_unknown(desktop_info.icon().unwrap_or_default())
|
||||||
|
.as_cosmic_icon()
|
||||||
|
.size(app_icon.icon_size);
|
||||||
|
|
||||||
let dots = if toplevels.is_empty() {
|
let dots = if toplevels.is_empty() {
|
||||||
(0..1)
|
(0..1)
|
||||||
|
|
@ -288,15 +265,14 @@ impl DockItem {
|
||||||
} else if toplevels.len() == 1 {
|
} else if toplevels.len() == 1 {
|
||||||
toplevels.first().map(|t| Message::Toggle(t.0.clone()))
|
toplevels.first().map(|t| Message::Toggle(t.0.clone()))
|
||||||
} else {
|
} else {
|
||||||
Some(Message::TopLevelListPopup(desktop_info.id.clone()))
|
Some(Message::TopLevelListPopup(*id))
|
||||||
})
|
})
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.height(Length::Shrink),
|
.height(Length::Shrink),
|
||||||
)
|
)
|
||||||
.on_right_release(Message::Popup(desktop_info.id.clone()))
|
.on_right_release(Message::Popup(*id))
|
||||||
.on_middle_release({
|
.on_middle_release({
|
||||||
launch_on_preferred_gpu(desktop_info, gpus)
|
launch_on_preferred_gpu(desktop_info, gpus).unwrap_or_else(|| Message::Popup(*id))
|
||||||
.unwrap_or_else(|| Message::Popup(desktop_info.id.clone()))
|
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -306,7 +282,7 @@ impl DockItem {
|
||||||
let icon_button = if dnd_source_enabled && interaction_enabled {
|
let icon_button = if dnd_source_enabled && interaction_enabled {
|
||||||
dnd_source(icon_button)
|
dnd_source(icon_button)
|
||||||
.drag_threshold(16.)
|
.drag_threshold(16.)
|
||||||
.on_drag(|_, _| Message::StartDrag(desktop_info.id.clone()))
|
.on_drag(|_, _| Message::StartDrag(*id))
|
||||||
.on_cancelled(Message::DragFinished)
|
.on_cancelled(Message::DragFinished)
|
||||||
.on_finished(Message::DragFinished)
|
.on_finished(Message::DragFinished)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -330,7 +306,7 @@ struct DndOffer {
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
struct CosmicAppList {
|
struct CosmicAppList {
|
||||||
core: cosmic::app::Core,
|
core: cosmic::app::Core,
|
||||||
popup: Option<(window::Id, u32, PopupType)>,
|
popup: Option<(window::Id, DockItemId, PopupType)>,
|
||||||
subscription_ctr: u32,
|
subscription_ctr: u32,
|
||||||
item_ctr: u32,
|
item_ctr: u32,
|
||||||
active_list: Vec<DockItem>,
|
active_list: Vec<DockItem>,
|
||||||
|
|
@ -339,13 +315,14 @@ struct CosmicAppList {
|
||||||
config: AppListConfig,
|
config: AppListConfig,
|
||||||
wayland_sender: Option<Sender<WaylandRequest>>,
|
wayland_sender: Option<Sender<WaylandRequest>>,
|
||||||
seat: Option<WlSeat>,
|
seat: Option<WlSeat>,
|
||||||
rectangle_tracker: Option<RectangleTracker<u32>>,
|
rectangle_tracker: Option<RectangleTracker<DockItemId>>,
|
||||||
rectangles: HashMap<u32, iced::Rectangle>,
|
rectangles: HashMap<DockItemId, iced::Rectangle>,
|
||||||
dnd_offer: Option<DndOffer>,
|
dnd_offer: Option<DndOffer>,
|
||||||
is_listening_for_dnd: bool,
|
is_listening_for_dnd: bool,
|
||||||
gpus: Option<Vec<Gpu>>,
|
gpus: Option<Vec<Gpu>>,
|
||||||
active_workspaces: Vec<ZcosmicWorkspaceHandleV1>,
|
active_workspaces: Vec<ZcosmicWorkspaceHandleV1>,
|
||||||
output_list: HashMap<WlOutput, OutputInfo>,
|
output_list: HashMap<WlOutput, OutputInfo>,
|
||||||
|
locales: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
|
|
@ -358,10 +335,10 @@ pub enum PopupType {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum Message {
|
enum Message {
|
||||||
Wayland(WaylandUpdate),
|
Wayland(WaylandUpdate),
|
||||||
PinApp(String),
|
PinApp(DockItemId),
|
||||||
UnpinApp(String),
|
UnpinApp(DockItemId),
|
||||||
Popup(String),
|
Popup(DockItemId),
|
||||||
TopLevelListPopup(String),
|
TopLevelListPopup(DockItemId),
|
||||||
GpuRequest(Option<Vec<Gpu>>),
|
GpuRequest(Option<Vec<Gpu>>),
|
||||||
CloseRequested(window::Id),
|
CloseRequested(window::Id),
|
||||||
ClosePopup,
|
ClosePopup,
|
||||||
|
|
@ -372,8 +349,8 @@ enum Message {
|
||||||
Ignore,
|
Ignore,
|
||||||
NewSeat(WlSeat),
|
NewSeat(WlSeat),
|
||||||
RemovedSeat(WlSeat),
|
RemovedSeat(WlSeat),
|
||||||
Rectangle(RectangleUpdate<u32>),
|
Rectangle(RectangleUpdate<DockItemId>),
|
||||||
StartDrag(String), // id of the DockItem
|
StartDrag(DockItemId),
|
||||||
DragFinished,
|
DragFinished,
|
||||||
DndEnter(f32, f32),
|
DndEnter(f32, f32),
|
||||||
DndExit,
|
DndExit,
|
||||||
|
|
@ -446,7 +423,7 @@ async fn try_get_gpus() -> Option<Vec<Gpu>> {
|
||||||
pub fn menu_button<'a, Message>(
|
pub fn menu_button<'a, Message>(
|
||||||
content: impl Into<Element<'a, Message>>,
|
content: impl Into<Element<'a, Message>>,
|
||||||
) -> cosmic::widget::Button<'a, Message> {
|
) -> cosmic::widget::Button<'a, Message> {
|
||||||
cosmic::widget::Button::new(content)
|
cosmic::widget::button(content)
|
||||||
.style(Button::AppletMenu)
|
.style(Button::AppletMenu)
|
||||||
.padding(menu_control_padding())
|
.padding(menu_control_padding())
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
|
|
@ -466,7 +443,7 @@ where
|
||||||
Msg: 'static + Clone,
|
Msg: 'static + Clone,
|
||||||
{
|
{
|
||||||
let border = 1.0;
|
let border = 1.0;
|
||||||
cosmic::widget::Button::new(
|
cosmic::widget::button(
|
||||||
container(
|
container(
|
||||||
column![
|
column![
|
||||||
container(if let Some(img) = img {
|
container(if let Some(img) = img {
|
||||||
|
|
@ -598,6 +575,33 @@ fn app_list_icon_style(selected: bool) -> cosmic::theme::Button {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_desktop_entries_from_app_ids<I, L>(ids: &[I], locales: &[L]) -> Vec<DesktopEntry<'static>>
|
||||||
|
where
|
||||||
|
I: AsRef<str>,
|
||||||
|
L: AsRef<str>,
|
||||||
|
{
|
||||||
|
let srcs = fde::Iter::new(fde::default_paths())
|
||||||
|
.filter_map(|p| fs::read_to_string(&p).ok().and_then(|e| Some((p, e))))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let entries = srcs
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(p, data)| DesktopEntry::from_str(p, data, locales).ok())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
ids.iter()
|
||||||
|
.map(|id| {
|
||||||
|
fde::matching::get_best_match(
|
||||||
|
&[id],
|
||||||
|
&entries,
|
||||||
|
fde::matching::MatchAppIdOptions::default(),
|
||||||
|
)
|
||||||
|
.unwrap_or(&fde::DesktopEntry::from_appid(id.as_ref()))
|
||||||
|
.to_owned()
|
||||||
|
})
|
||||||
|
.collect_vec()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn menu_control_padding() -> Padding {
|
pub fn menu_control_padding() -> Padding {
|
||||||
let theme = cosmic::theme::active();
|
let theme = cosmic::theme::active();
|
||||||
let cosmic = theme.cosmic();
|
let cosmic = theme.cosmic();
|
||||||
|
|
@ -618,28 +622,30 @@ impl cosmic::Application for CosmicAppList {
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|c| AppListConfig::get_entry(&c).ok())
|
.and_then(|c| AppListConfig::get_entry(&c).ok())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let mut self_ = Self {
|
|
||||||
|
let locales = get_languages_from_env();
|
||||||
|
|
||||||
|
let mut app_list = Self {
|
||||||
core,
|
core,
|
||||||
pinned_list: load_applications_for_app_ids_sorted(
|
pinned_list: load_desktop_entries_from_app_ids(&config.favorites, &locales)
|
||||||
None,
|
.into_iter()
|
||||||
config.favorites.iter().map(|s| &**s),
|
.zip(&config.favorites)
|
||||||
true,
|
.enumerate()
|
||||||
)
|
.map(|(pinned_ctr, (e, original_id))| DockItem {
|
||||||
.into_iter()
|
id: pinned_ctr as u32,
|
||||||
.enumerate()
|
toplevels: Default::default(),
|
||||||
.map(|(pinned_ctr, e)| DockItem {
|
desktop_info: e,
|
||||||
id: pinned_ctr as u32,
|
original_app_id: original_id.clone(),
|
||||||
toplevels: Default::default(),
|
})
|
||||||
desktop_info: e,
|
.collect(),
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
config,
|
config,
|
||||||
|
locales,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
self_.item_ctr = self_.pinned_list.len() as u32;
|
app_list.item_ctr = app_list.pinned_list.len() as u32;
|
||||||
|
|
||||||
(
|
(
|
||||||
self_,
|
app_list,
|
||||||
Command::perform(try_get_gpus(), |gpus| {
|
Command::perform(try_get_gpus(), |gpus| {
|
||||||
cosmic::app::Message::App(Message::GpuRequest(gpus))
|
cosmic::app::Message::App(Message::GpuRequest(gpus))
|
||||||
}),
|
}),
|
||||||
|
|
@ -667,7 +673,7 @@ impl cosmic::Application for CosmicAppList {
|
||||||
.active_list
|
.active_list
|
||||||
.iter()
|
.iter()
|
||||||
.chain(self.pinned_list.iter())
|
.chain(self.pinned_list.iter())
|
||||||
.find(|t| t.desktop_info.id == id)
|
.find(|t| t.id == id)
|
||||||
{
|
{
|
||||||
let rectangle = match self.rectangles.get(&toplevel_group.id) {
|
let rectangle = match self.rectangles.get(&toplevel_group.id) {
|
||||||
Some(r) => r,
|
Some(r) => r,
|
||||||
|
|
@ -711,7 +717,7 @@ impl cosmic::Application for CosmicAppList {
|
||||||
.active_list
|
.active_list
|
||||||
.iter()
|
.iter()
|
||||||
.chain(self.pinned_list.iter())
|
.chain(self.pinned_list.iter())
|
||||||
.find(|t| t.desktop_info.id == id)
|
.find(|t| t.id == id)
|
||||||
{
|
{
|
||||||
for (ref handle, _, _) in &toplevel_group.toplevels {
|
for (ref handle, _, _) in &toplevel_group.toplevels {
|
||||||
if let Some(tx) = self.wayland_sender.as_ref() {
|
if let Some(tx) = self.wayland_sender.as_ref() {
|
||||||
|
|
@ -770,33 +776,29 @@ impl cosmic::Application for CosmicAppList {
|
||||||
return get_popup(popup_settings);
|
return get_popup(popup_settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::PinApp(id) => {
|
Message::PinApp(id) => {
|
||||||
if let Some(i) = self
|
if let Some(i) = self.active_list.iter().position(|t| t.id == id) {
|
||||||
.active_list
|
|
||||||
.iter()
|
|
||||||
.position(|t| t.desktop_info.id == id)
|
|
||||||
{
|
|
||||||
let entry = self.active_list.remove(i);
|
let entry = self.active_list.remove(i);
|
||||||
|
self.config.add_pinned(
|
||||||
|
entry.original_app_id.clone(),
|
||||||
|
&Config::new(APP_ID, AppListConfig::VERSION).unwrap(),
|
||||||
|
);
|
||||||
self.pinned_list.push(entry);
|
self.pinned_list.push(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.config
|
|
||||||
.add_pinned(id, &Config::new(APP_ID, AppListConfig::VERSION).unwrap());
|
|
||||||
if let Some((popup_id, _toplevel, _)) = self.popup.take() {
|
if let Some((popup_id, _toplevel, _)) = self.popup.take() {
|
||||||
return destroy_popup(popup_id);
|
return destroy_popup(popup_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::UnpinApp(id) => {
|
Message::UnpinApp(id) => {
|
||||||
self.config.remove_pinned(
|
if let Some(i) = self.pinned_list.iter().position(|t| t.id == id) {
|
||||||
id.clone(),
|
|
||||||
&Config::new(APP_ID, AppListConfig::VERSION).unwrap(),
|
|
||||||
);
|
|
||||||
if let Some(i) = self
|
|
||||||
.pinned_list
|
|
||||||
.iter()
|
|
||||||
.position(|t| t.desktop_info.id == id)
|
|
||||||
{
|
|
||||||
let entry = self.pinned_list.remove(i);
|
let entry = self.pinned_list.remove(i);
|
||||||
|
|
||||||
|
self.config.remove_pinned(
|
||||||
|
&entry.original_app_id,
|
||||||
|
&Config::new(APP_ID, AppListConfig::VERSION).unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
self.rectangles.remove(&entry.id);
|
self.rectangles.remove(&entry.id);
|
||||||
if !entry.toplevels.is_empty() {
|
if !entry.toplevels.is_empty() {
|
||||||
self.active_list.push(entry);
|
self.active_list.push(entry);
|
||||||
|
|
@ -833,7 +835,7 @@ impl cosmic::Application for CosmicAppList {
|
||||||
.active_list
|
.active_list
|
||||||
.iter()
|
.iter()
|
||||||
.chain(self.pinned_list.iter())
|
.chain(self.pinned_list.iter())
|
||||||
.find(|t| t.desktop_info.id == id)
|
.find(|t| t.desktop_info.id() == id)
|
||||||
{
|
{
|
||||||
for (handle, _, _) in &toplevel_group.toplevels {
|
for (handle, _, _) in &toplevel_group.toplevels {
|
||||||
if let Some(tx) = self.wayland_sender.as_ref() {
|
if let Some(tx) = self.wayland_sender.as_ref() {
|
||||||
|
|
@ -852,21 +854,17 @@ impl cosmic::Application for CosmicAppList {
|
||||||
.active_list
|
.active_list
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|t| {
|
.find_map(|t| {
|
||||||
if t.desktop_info.id == id {
|
if t.id == id {
|
||||||
Some((false, t.clone()))
|
Some((false, t.clone()))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
if let Some(pos) = self
|
if let Some(pos) = self.pinned_list.iter().position(|t| t.id == id) {
|
||||||
.pinned_list
|
|
||||||
.iter()
|
|
||||||
.position(|t| t.desktop_info.id == id)
|
|
||||||
{
|
|
||||||
let t = self.pinned_list.remove(pos);
|
let t = self.pinned_list.remove(pos);
|
||||||
self.config.remove_pinned(
|
self.config.remove_pinned(
|
||||||
t.desktop_info.id.clone(),
|
&t.original_app_id,
|
||||||
&Config::new(APP_ID, AppListConfig::VERSION).unwrap(),
|
&Config::new(APP_ID, AppListConfig::VERSION).unwrap(),
|
||||||
);
|
);
|
||||||
Some((true, t))
|
Some((true, t))
|
||||||
|
|
@ -896,7 +894,7 @@ impl cosmic::Application for CosmicAppList {
|
||||||
.pinned_list
|
.pinned_list
|
||||||
.iter()
|
.iter()
|
||||||
.chain(self.active_list.iter())
|
.chain(self.active_list.iter())
|
||||||
.any(|t| t.desktop_info.id == toplevel_group.desktop_info.id)
|
.any(|t| t.desktop_info.id() == toplevel_group.desktop_info.id())
|
||||||
&& !toplevel_group.toplevels.is_empty()
|
&& !toplevel_group.toplevels.is_empty()
|
||||||
{
|
{
|
||||||
self.item_ctr += 1;
|
self.item_ctr += 1;
|
||||||
|
|
@ -959,9 +957,14 @@ impl cosmic::Application for CosmicAppList {
|
||||||
}
|
}
|
||||||
Message::DndData(file_path) => {
|
Message::DndData(file_path) => {
|
||||||
if let Some(DndOffer { dock_item, .. }) = self.dnd_offer.as_mut() {
|
if let Some(DndOffer { dock_item, .. }) = self.dnd_offer.as_mut() {
|
||||||
if let Some(di) = cosmic::desktop::load_desktop_file(None, file_path) {
|
if let Ok(de) = fde::DesktopEntry::from_path(file_path, &self.locales) {
|
||||||
self.item_ctr += 1;
|
self.item_ctr += 1;
|
||||||
*dock_item = Some(DockItem::new(self.item_ctr, Vec::new(), di));
|
*dock_item = Some(DockItem {
|
||||||
|
id: self.item_ctr,
|
||||||
|
toplevels: Vec::new(),
|
||||||
|
original_app_id: de.id().to_string(),
|
||||||
|
desktop_info: de,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -978,16 +981,12 @@ impl cosmic::Application for CosmicAppList {
|
||||||
if let Some((pos, is_pinned)) = self
|
if let Some((pos, is_pinned)) = self
|
||||||
.active_list
|
.active_list
|
||||||
.iter()
|
.iter()
|
||||||
.position(|DockItem { desktop_info, .. }| {
|
.position(|de| de.original_app_id == dock_item.original_app_id)
|
||||||
desktop_info.id == dock_item.desktop_info.id
|
|
||||||
})
|
|
||||||
.map(|pos| (pos, false))
|
.map(|pos| (pos, false))
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
self.pinned_list
|
self.pinned_list
|
||||||
.iter()
|
.iter()
|
||||||
.position(|DockItem { desktop_info, .. }| {
|
.position(|de| de.original_app_id == dock_item.original_app_id)
|
||||||
desktop_info.id == dock_item.desktop_info.id
|
|
||||||
})
|
|
||||||
.map(|pos| (pos, true))
|
.map(|pos| (pos, true))
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
|
@ -1000,13 +999,13 @@ impl cosmic::Application for CosmicAppList {
|
||||||
};
|
};
|
||||||
dock_item.id = self.item_ctr;
|
dock_item.id = self.item_ctr;
|
||||||
|
|
||||||
if dock_item.desktop_info.exec.is_some() {
|
if dock_item.desktop_info.exec().is_some() {
|
||||||
self.pinned_list
|
self.pinned_list
|
||||||
.insert(index.min(self.pinned_list.len()), dock_item);
|
.insert(index.min(self.pinned_list.len()), dock_item);
|
||||||
self.config.update_pinned(
|
self.config.update_pinned(
|
||||||
self.pinned_list
|
self.pinned_list
|
||||||
.iter()
|
.iter()
|
||||||
.map(|dock_item| dock_item.desktop_info.id.clone())
|
.map(|dock_item| dock_item.original_app_id.clone())
|
||||||
.collect(),
|
.collect(),
|
||||||
&Config::new(APP_ID, AppListConfig::VERSION).unwrap(),
|
&Config::new(APP_ID, AppListConfig::VERSION).unwrap(),
|
||||||
);
|
);
|
||||||
|
|
@ -1060,12 +1059,16 @@ impl cosmic::Application for CosmicAppList {
|
||||||
}
|
}
|
||||||
WaylandUpdate::Toplevel(event) => match event {
|
WaylandUpdate::Toplevel(event) => match event {
|
||||||
ToplevelUpdate::Add(handle, mut info) => {
|
ToplevelUpdate::Add(handle, mut info) => {
|
||||||
|
let new_desktop_info =
|
||||||
|
load_desktop_entries_from_app_ids(&[&info.app_id], &self.locales)
|
||||||
|
.remove(0);
|
||||||
|
|
||||||
if let Some(t) = self
|
if let Some(t) = self
|
||||||
.active_list
|
.active_list
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.chain(self.pinned_list.iter_mut())
|
.chain(self.pinned_list.iter_mut())
|
||||||
.find(|DockItem { desktop_info, .. }| {
|
.find(|DockItem { desktop_info, .. }| {
|
||||||
app_id_or_fallback_matches(&info.app_id, desktop_info)
|
desktop_info.id() == new_desktop_info.id()
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
t.toplevels.push((handle, info, None));
|
t.toplevels.push((handle, info, None));
|
||||||
|
|
@ -1074,18 +1077,12 @@ impl cosmic::Application for CosmicAppList {
|
||||||
info.app_id = format!("Unknown Application {}", self.item_ctr);
|
info.app_id = format!("Unknown Application {}", self.item_ctr);
|
||||||
}
|
}
|
||||||
self.item_ctr += 1;
|
self.item_ctr += 1;
|
||||||
let desktop_info = load_applications_for_app_ids_sorted(
|
|
||||||
None,
|
|
||||||
std::iter::once(&*info.app_id),
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
.into_iter()
|
|
||||||
.next()
|
|
||||||
.unwrap();
|
|
||||||
self.active_list.push(DockItem {
|
self.active_list.push(DockItem {
|
||||||
id: self.item_ctr,
|
id: self.item_ctr,
|
||||||
|
original_app_id: info.app_id.clone(),
|
||||||
toplevels: vec![(handle, info, None)],
|
toplevels: vec![(handle, info, None)],
|
||||||
desktop_info,
|
desktop_info: new_desktop_info,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1196,33 +1193,38 @@ impl cosmic::Application for CosmicAppList {
|
||||||
self.config = config;
|
self.config = config;
|
||||||
// drain to active list
|
// drain to active list
|
||||||
for item in self.pinned_list.drain(..) {
|
for item in self.pinned_list.drain(..) {
|
||||||
self.active_list.push(item);
|
if !item.toplevels.is_empty() {
|
||||||
|
self.active_list.push(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pull back configured items into the pinned app list
|
// pull back configured items into the favorites list
|
||||||
self.pinned_list = load_applications_for_app_ids_sorted(
|
self.pinned_list =
|
||||||
None,
|
load_desktop_entries_from_app_ids(&self.config.favorites, &self.locales)
|
||||||
self.config.favorites.iter().map(|s| &**s),
|
.into_iter()
|
||||||
true,
|
.zip(&self.config.favorites)
|
||||||
)
|
.map(|(de, original_id)| {
|
||||||
.into_iter()
|
if let Some(p) = self
|
||||||
.map(|new_dock_item| {
|
.active_list
|
||||||
if let Some(p) = self
|
.iter()
|
||||||
.active_list
|
// match using heuristic id
|
||||||
.iter()
|
.position(|dock_item| dock_item.desktop_info.id() == de.id())
|
||||||
.position(|dock_item| dock_item.desktop_info.id == new_dock_item.id)
|
{
|
||||||
{
|
let mut d = self.active_list.remove(p);
|
||||||
self.active_list.remove(p)
|
// but use the id from the config
|
||||||
} else {
|
d.original_app_id = original_id.clone();
|
||||||
self.item_ctr += 1;
|
d
|
||||||
DockItem {
|
} else {
|
||||||
id: self.item_ctr,
|
self.item_ctr += 1;
|
||||||
toplevels: Default::default(),
|
DockItem {
|
||||||
desktop_info: new_dock_item,
|
id: self.item_ctr,
|
||||||
}
|
toplevels: Default::default(),
|
||||||
}
|
desktop_info: de,
|
||||||
})
|
original_app_id: original_id.clone(),
|
||||||
.collect();
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
}
|
}
|
||||||
Message::CloseRequested(id) => {
|
Message::CloseRequested(id) => {
|
||||||
if Some(id) == self.popup.as_ref().map(|p| p.0) {
|
if Some(id) == self.popup.as_ref().map(|p| p.0) {
|
||||||
|
|
@ -1412,49 +1414,45 @@ impl cosmic::Application for CosmicAppList {
|
||||||
|
|
||||||
fn view_window(&self, id: window::Id) -> Element<Message> {
|
fn view_window(&self, id: window::Id) -> Element<Message> {
|
||||||
if let Some((_, item, _)) = self.dnd_source.as_ref().filter(|s| s.0 == id) {
|
if let Some((_, item, _)) = self.dnd_source.as_ref().filter(|s| s.0 == id) {
|
||||||
item.desktop_info
|
IconSource::from_unknown(item.desktop_info.icon().unwrap_or_default())
|
||||||
.icon
|
|
||||||
.as_cosmic_icon()
|
.as_cosmic_icon()
|
||||||
.size(self.core.applet.suggested_size(false).0)
|
.size(self.core.applet.suggested_size(false).0)
|
||||||
.into()
|
.into()
|
||||||
} else if let Some((_popup_id, id, popup_type)) = self.popup.as_ref().filter(|p| id == p.0)
|
} else if let Some((_popup_id, id, popup_type)) = self.popup.as_ref().filter(|p| id == p.0)
|
||||||
{
|
{
|
||||||
let Some(DockItem {
|
let (
|
||||||
toplevels,
|
DockItem {
|
||||||
desktop_info,
|
toplevels,
|
||||||
..
|
desktop_info,
|
||||||
}) = self
|
..
|
||||||
.pinned_list
|
},
|
||||||
.iter()
|
is_pinned,
|
||||||
.chain(self.active_list.iter())
|
) = match self.pinned_list.iter().find(|i| i.id == *id) {
|
||||||
.find(|i| i.id == *id)
|
Some(e) => (e, true),
|
||||||
else {
|
None => match self.active_list.iter().find(|i| i.id == *id) {
|
||||||
return iced::widget::text("").into();
|
Some(e) => (e, false),
|
||||||
|
None => return iced::widget::text("").into(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
match popup_type {
|
match popup_type {
|
||||||
PopupType::RightClickMenu => {
|
PopupType::RightClickMenu => {
|
||||||
let is_pinned = self
|
|
||||||
.config
|
|
||||||
.favorites
|
|
||||||
.iter()
|
|
||||||
.any(|x| app_id_or_fallback_matches(x, desktop_info));
|
|
||||||
|
|
||||||
let mut content = column![container(
|
let mut content = column![container(
|
||||||
iced::widget::text(&desktop_info.name)
|
iced::widget::text(&desktop_info.name(&self.locales).unwrap_or_default())
|
||||||
.horizontal_alignment(Horizontal::Center)
|
.horizontal_alignment(Horizontal::Center)
|
||||||
)
|
)
|
||||||
.padding(menu_control_padding()),]
|
.padding(menu_control_padding()),]
|
||||||
.padding([8, 0])
|
.padding([8, 0])
|
||||||
.align_items(Alignment::Center);
|
.align_items(Alignment::Center);
|
||||||
|
|
||||||
if let Some(exec) = desktop_info.exec.clone() {
|
if let Some(exec) = desktop_info.exec() {
|
||||||
if !toplevels.is_empty() {
|
if !toplevels.is_empty() {
|
||||||
content = content.push(
|
content = content.push(
|
||||||
menu_button(iced::widget::text(fl!("new-window")))
|
menu_button(iced::widget::text(fl!("new-window")))
|
||||||
.on_press(Message::Exec(exec, None)),
|
.on_press(Message::Exec(exec.to_string(), None)),
|
||||||
);
|
);
|
||||||
} else if let Some(gpus) = self.gpus.as_ref() {
|
} else if let Some(gpus) = self.gpus.as_ref() {
|
||||||
let default_idx = if desktop_info.prefers_dgpu {
|
let default_idx = if desktop_info.prefers_non_default_gpu() {
|
||||||
gpus.iter().position(|gpu| !gpu.default).unwrap_or(0)
|
gpus.iter().position(|gpu| !gpu.default).unwrap_or(0)
|
||||||
} else {
|
} else {
|
||||||
gpus.iter().position(|gpu| gpu.default).unwrap_or(0)
|
gpus.iter().position(|gpu| gpu.default).unwrap_or(0)
|
||||||
|
|
@ -1470,13 +1468,13 @@ impl cosmic::Application for CosmicAppList {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
)))
|
)))
|
||||||
.on_press(Message::Exec(exec.clone(), Some(i))),
|
.on_press(Message::Exec(exec.to_string(), Some(i))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
content = content.push(
|
content = content.push(
|
||||||
menu_button(iced::widget::text(fl!("run")))
|
menu_button(iced::widget::text(fl!("run")))
|
||||||
.on_press(Message::Exec(exec, None)),
|
.on_press(Message::Exec(exec.to_string(), None)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
content = content.push(divider::horizontal::default());
|
content = content.push(divider::horizontal::default());
|
||||||
|
|
@ -1501,12 +1499,12 @@ impl cosmic::Application for CosmicAppList {
|
||||||
if is_pinned {
|
if is_pinned {
|
||||||
content = content.push(
|
content = content.push(
|
||||||
menu_button(iced::widget::text(fl!("unpin")))
|
menu_button(iced::widget::text(fl!("unpin")))
|
||||||
.on_press(Message::UnpinApp(desktop_info.id.clone())),
|
.on_press(Message::UnpinApp(*id)),
|
||||||
)
|
)
|
||||||
} else if let Some(_) = desktop_info.exec.clone() {
|
} else if desktop_info.exec().is_some() {
|
||||||
content = content.push(
|
content = content.push(
|
||||||
menu_button(iced::widget::text(fl!("pin")))
|
menu_button(iced::widget::text(fl!("pin")))
|
||||||
.on_press(Message::PinApp(desktop_info.id.clone())),
|
.on_press(Message::PinApp(*id)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1514,11 +1512,11 @@ impl cosmic::Application for CosmicAppList {
|
||||||
0 => content,
|
0 => content,
|
||||||
1 => content.push(
|
1 => content.push(
|
||||||
menu_button(iced::widget::text(fl!("quit")))
|
menu_button(iced::widget::text(fl!("quit")))
|
||||||
.on_press(Message::Quit(desktop_info.id.clone())),
|
.on_press(Message::Quit(desktop_info.id().to_string())),
|
||||||
),
|
),
|
||||||
_ => content.push(
|
_ => content.push(
|
||||||
menu_button(iced::widget::text(&fl!("quit-all")))
|
menu_button(iced::widget::text(&fl!("quit-all")))
|
||||||
.on_press(Message::Quit(desktop_info.id.clone())),
|
.on_press(Message::Quit(desktop_info.id().to_string())),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
self.core.applet.popup_container(content).into()
|
self.core.applet.popup_container(content).into()
|
||||||
|
|
@ -1540,7 +1538,7 @@ impl cosmic::Application for CosmicAppList {
|
||||||
Message::Toggle(handle.clone()),
|
Message::Toggle(handle.clone()),
|
||||||
title,
|
title,
|
||||||
10.0,
|
10.0,
|
||||||
self.currently_active_toplevel().contains(&handle),
|
self.currently_active_toplevel().contains(handle),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
self.core.applet.popup_container(content).into()
|
self.core.applet.popup_container(content).into()
|
||||||
|
|
@ -1559,7 +1557,7 @@ impl cosmic::Application for CosmicAppList {
|
||||||
Message::Toggle(handle.clone()),
|
Message::Toggle(handle.clone()),
|
||||||
title,
|
title,
|
||||||
10.0,
|
10.0,
|
||||||
self.currently_active_toplevel().contains(&handle),
|
self.currently_active_toplevel().contains(handle),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
self.core.applet.popup_container(content).into()
|
self.core.applet.popup_container(content).into()
|
||||||
|
|
@ -1659,21 +1657,18 @@ impl CosmicAppList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn launch_on_preferred_gpu(
|
fn launch_on_preferred_gpu(desktop_info: &DesktopEntry, gpus: Option<&[Gpu]>) -> Option<Message> {
|
||||||
desktop_info: &DesktopEntryData,
|
let Some(exec) = desktop_info.exec() else {
|
||||||
gpus: Option<&[Gpu]>,
|
|
||||||
) -> Option<Message> {
|
|
||||||
let Some(exec) = desktop_info.exec.clone() else {
|
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let gpu_idx = gpus.map(|gpus| {
|
let gpu_idx = gpus.map(|gpus| {
|
||||||
if desktop_info.prefers_dgpu {
|
if desktop_info.prefers_non_default_gpu() {
|
||||||
gpus.iter().position(|gpu| !gpu.default).unwrap_or(0)
|
gpus.iter().position(|gpu| !gpu.default).unwrap_or(0)
|
||||||
} else {
|
} else {
|
||||||
gpus.iter().position(|gpu| gpu.default).unwrap_or(0)
|
gpus.iter().position(|gpu| gpu.default).unwrap_or(0)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(Message::Exec(exec, gpu_idx))
|
Some(Message::Exec(exec.to_string(), gpu_idx))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ impl AppListConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_pinned(&mut self, id: String, config: &Config) {
|
pub fn remove_pinned(&mut self, id: &str, config: &Config) {
|
||||||
if let Some(pos) = self.favorites.iter().position(|e| e == &id) {
|
if let Some(pos) = self.favorites.iter().position(|e| e == &id) {
|
||||||
self.favorites.remove(pos);
|
self.favorites.remove(pos);
|
||||||
let _ = self.write_entry(config);
|
let _ = self.write_entry(config);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue