Merge remote-tracking branch 'upstream/master' into yoda-dock-magnification

# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	cosmic-app-list/src/app.rs
#	cosmic-applet-audio/src/lib.rs
#	cosmic-applet-input-sources/Cargo.toml
#	cosmic-applet-input-sources/src/lib.rs
#	cosmic-applet-status-area/src/components/app.rs
#	cosmic-panel-button/src/lib.rs
This commit is contained in:
Lionel DARNIS 2026-08-19 22:04:42 +02:00
commit 673547dc52
119 changed files with 2247 additions and 1190 deletions

1152
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -75,13 +75,9 @@ ignored = ["libcosmic"]
# cosmic-config = { path = "../libcosmic/cosmic-config" } # cosmic-config = { path = "../libcosmic/cosmic-config" }
# libcosmic = { path = "../libcosmic" } # libcosmic = { path = "../libcosmic" }
# iced_futures = { path = "../libcosmic/iced/futures" } # iced_futures = { path = "../libcosmic/iced/futures" }
# cosmic-config = { git = "https://github.com/pop-os/libcosmic//" } # cosmic-config = { git = "https://github.com/pop-os/libcosmic//", branch = "theme-v2" }
# libcosmic = { git = "https://github.com/pop-os/libcosmic//" } # libcosmic = { git = "https://github.com/pop-os/libcosmic//", branch = "theme-v2" }
# iced_futures = { git = "https://github.com/pop-os/libcosmic//" } # iced_futures = { git = "https://github.com/pop-os/libcosmic//", branch = "theme-v2" }
# [patch."https://github.com/pop-os/winit.git"]
# winit = { git = "https://github.com/rust-windowing/winit.git", rev = "241b7a80bba96c91fa3901729cd5dec66abb9be4" }
# winit = { path = "../winit" }
[patch."https://github.com/pop-os/libcosmic"] [patch."https://github.com/pop-os/libcosmic"]
cosmic-config = { path = "/home/lionel/Projets/COSMIC/libcosmic/cosmic-config" } cosmic-config = { path = "/home/lionel/Projets/COSMIC/libcosmic/cosmic-config" }

View file

@ -1,6 +1,6 @@
cosmic-app-list = دُرج التطبيقات cosmic-app-list = دُرج التطبيقات
pin = ثبِّت في درج التطبيقات pin = ثبِّت في درج التطبيقات
quit = أنهِ quit = إنهِ
quit-all = أنهِ الكل quit-all = أنهِ الكل
new-window = نافذة جديدة new-window = نافذة جديدة
run = شغِّل run = شغِّل

View file

@ -1,5 +1,5 @@
cosmic-app-list = Panel aplikací cosmic-app-list = Oblast aplikací
pin = Připnout do panelu aplikací pin = Připnout do oblasti aplikací
quit = Ukončit quit = Ukončit
quit-all = Ukončit vše quit-all = Ukončit vše
new-window = Nové okno new-window = Nové okno

View file

@ -0,0 +1,8 @@
run = Kør
run-on = Kør på { $gpu }
run-on-default = (Standard)
cosmic-app-list = Programbakke
new-window = Nyt Vindue
quit = Afslut
quit-all = Forlad Alle
pin = Fastgør til app-skuffe

View file

@ -1,5 +1,5 @@
new-window = Νέο παράθυρο new-window = Νέο παράθυρο
quit = Έξοδος quit = Τερματισμός
cosmic-app-list = Περιοχή εφαρμογών cosmic-app-list = Περιοχή εφαρμογών
run = Εκτέλεση run = Εκτέλεση
run-on = Εκτέλεση με { $gpu } run-on = Εκτέλεση με { $gpu }

View file

@ -0,0 +1,8 @@
cosmic-app-list = App Tray
new-window = New Window
quit = Quit
run = Run
run-on = Run on { $gpu }
quit-all = Quit All
run-on-default = (Default)
pin = Pin to app tray

View file

@ -1,8 +1,8 @@
cosmic-app-list = سینی برنامه‌ها cosmic-app-list = نوار برنامه‌ها
pin = سنجاق کردن به سینی برنامه‌ها pin = افزودن به نوار برنامه‌ها
quit = بستن quit = خروج
quit-all = بستن همه quit-all = خروج از همه
new-window = پنجره جدید new-window = پنجره جدید
run = اجرا run = اجرا
run-on = اجرا روی {$gpu} run-on = اجرا با { $gpu }
run-on-default = (پیش‌فرض) run-on-default = (پیش‌فرض)

View file

@ -0,0 +1,8 @@
quit = Pechar
run = Executar
cosmic-app-list = Bandexa de aplicacións
pin = Fixar na bandexa de aplicacións
quit-all = Quitar todo
new-window = Nova Xanela
run-on = Executar en { $gpu }
run-on-default = (Por defecto)

View file

@ -1,6 +1,6 @@
cosmic-app-list = ऐप ट्रे cosmic-app-list = ऐप ट्रे
pin = ऐप ट्रे में पिन करें pin = ऐप ट्रे में पिन करें
quit = बंद करें quit = बाहर जाएँ
quit-all = सभी बंद करें quit-all = सभी बंद करें
new-window = नई विंडो new-window = नई विंडो
run = चलाएँ run = चलाएँ

View file

@ -1,8 +1,8 @@
cosmic-app-list = Barra applicazioni cosmic-app-list = Area applicazioni
pin = Fissa nella barra delle applicazioni pin = Fissa nella barra delle applicazioni
quit = Esci quit = Esci
quit-all = Chiudi tutto quit-all = Chiudi tutto
new-window = Nuova finestra new-window = Nuova finestra
run = Esegui run = Esegui
run-on = Esegui usando la GPU: { $gpu } run-on = Esegui su { $gpu }
run-on-default = (default) run-on-default = (Predefinito)

View file

@ -1,5 +1,5 @@
new-window = Naujas Langas new-window = Naujas Langas
quit = Išeiti quit = Išjungti
run = Paleisti run = Paleisti
run-on = Paleisti naudojantis { $gpu } run-on = Paleisti naudojantis { $gpu }
run-on-default = (Numatytas) run-on-default = (Numatytas)

View file

@ -0,0 +1 @@
cosmic-app-list = Cinta d’aplicacions

View file

@ -1,4 +1,4 @@
quit = ਬਾਹਰ quit = ਸਮਾਪਤ
cosmic-app-list = ਐਪ ਟਰੇ cosmic-app-list = ਐਪ ਟਰੇ
pin = ਐਪ ਟਰੇ ਵਿੱਚ ਟੰਗੋ pin = ਐਪ ਟਰੇ ਵਿੱਚ ਟੰਗੋ
quit-all = ਸਭ ਵਿੱਚੋਂ ਬਾਹਰ quit-all = ਸਭ ਵਿੱਚੋਂ ਬਾਹਰ

View file

@ -1,6 +1,6 @@
cosmic-app-list = Zasobnik aplikacji cosmic-app-list = Zasobnik aplikacji
pin = Przypnij do zasobnika aplikacji pin = Przypnij do zasobnika aplikacji
quit = Zamknij quit = Zakończ
quit-all = Zamknij wszystkie quit-all = Zamknij wszystkie
new-window = Nowe okno new-window = Nowe okno
run = Uruchom run = Uruchom

View file

@ -1,6 +1,6 @@
cosmic-app-list = Bandeja de aplicativos cosmic-app-list = Bandeja de aplicativos
pin = Fixar na bandeja de aplicativos pin = Fixar na bandeja de aplicativos
quit = Sair quit = Encerrar
quit-all = Sair de Todos quit-all = Sair de Todos
new-window = Nova Janela new-window = Nova Janela
run = Executar run = Executar

View file

@ -1,6 +1,6 @@
cosmic-app-list = Область приложений cosmic-app-list = Область приложений
pin = Закрепить на панели приложений pin = Закрепить на панели приложений
quit = Выйти quit = Завершить
quit-all = Завершить все quit-all = Завершить все
new-window = Новое окно new-window = Новое окно
run = Выполнить run = Выполнить

View file

@ -0,0 +1,2 @@
run-on = { $gpu } ᱨᱮ ᱫᱟᱹᱲ ᱟᱭ
run-on-default = (ᱢᱩᱞ)

View file

@ -1,6 +1,6 @@
cosmic-app-list = Панель застосунків cosmic-app-list = Панель застосунків
pin = Закріпити pin = Закріпити
quit = Вийти quit = Завершити
quit-all = Закрити всі quit-all = Закрити всі
new-window = Нове вікно new-window = Нове вікно
run = Виконати run = Виконати

View file

@ -1,8 +1,8 @@
cosmic-app-list = 應用程式匣盤 cosmic-app-list = 應用程式托盤
pin = 釘選至應用程式匣盤 pin = 釘選至應用程式托盤
quit = 退出 quit = 結束
quit-all = 全部退出 quit-all = 全部退出
new-window = 新建視窗 new-window = 新增視窗
run = 執行 run = 執行
run-on = 在 { $gpu } 上執行 run-on = 在 { $gpu } 上執行
run-on-default = (預設) run-on-default = (預設)

View file

@ -28,25 +28,28 @@ use cosmic::{
}, },
cosmic_config::{Config, CosmicConfigEntry}, cosmic_config::{Config, CosmicConfigEntry},
desktop::IconSourceExt, desktop::IconSourceExt,
iced::runtime::{core::event, dnd::peek_dnd},
iced::{ iced::{
self, Alignment, Background, Border, Length, Limits, Padding, Subscription, self, Alignment, Background, Border, Length, Limits, Padding, Subscription,
advanced::text::{Ellipsize, EllipsizeHeightLimit}, advanced::text::{Ellipsize, EllipsizeHeightLimit},
clipboard::mime::{AllowedMimeTypes, AsMimeTypes}, clipboard::mime::{AllowedMimeTypes, AsMimeTypes},
event::listen_with, event::listen_with,
platform_specific::shell::commands::popup::{destroy_popup, get_popup}, platform_specific::shell::commands::popup::{destroy_popup, get_popup},
runtime::{core::event, dnd::peek_dnd, platform_specific::wayland::CornerRadius},
widget::{ widget::{
Column, Row, column, mouse_area, row, rule::vertical as vertical_rule, Column, Row, column, mouse_area, row,
space::horizontal as horizontal_space, space::vertical as vertical_space, stack, rule::vertical as vertical_rule,
space::{horizontal as horizontal_space, vertical as vertical_space},
stack,
}, },
window, window,
}, },
surface, surface::{self, action::LiveSettings},
theme::{self, Button, Container}, theme::{self, Button, Container},
widget::{ widget::{
DndDestination, Image, button, container, divider, dnd_source, grid, DndDestination, Image, button, container, divider, dnd_source, grid,
icon::{self, from_name}, icon::{self, from_name},
image::Handle, image::Handle,
menu,
rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription}, rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription},
scrollable, svg, text, text_input, scrollable, svg, text, text_input,
}, },
@ -1249,21 +1252,27 @@ impl cosmic::Application for CosmicAppList {
.iter() .iter()
.chain(self.pinned_list.iter()) .chain(self.pinned_list.iter())
.find(|t| t.id == id) .find(|t| t.id == id)
.cloned()
{ {
let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()) else { let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()).copied()
else {
tracing::error!("No rectangle found for toplevel group"); tracing::error!("No rectangle found for toplevel group");
return Task::none(); return Task::none();
}; };
let corners = self.core.system_theme().cosmic().corner_radii.radius_s;
let popup_task =
cosmic::surface::surface_task(cosmic::surface::action::app_popup(
move |_| LiveSettings::default(),
move |app: &mut Self| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup = Some(Popup { app.popup = Some(Popup {
parent: parent_window_id, parent: parent_window_id,
id: new_id, id: new_id,
dock_item: toplevel_group.clone(), dock_item: toplevel_group.clone(),
popup_type: PopupType::RightClickMenu, popup_type: PopupType::RightClickMenu,
}); });
let mut popup_settings = self.core.applet.get_popup_settings( let mut popup_settings = app.core.applet.get_popup_settings(
parent_window_id, parent_window_id,
new_id, new_id,
None, None,
@ -1275,18 +1284,22 @@ impl cosmic::Application for CosmicAppList {
y, y,
width, width,
height, height,
} = *rectangle; } = rectangle;
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> { popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: x as i32, x: x as i32,
y: y as i32, y: y as i32,
width: width as i32, width: width as i32,
height: height as i32, height: height as i32,
}; };
popup_settings
},
None,
));
let gpu_update = Task::perform(try_get_gpus(), |gpus| { let gpu_update = Task::perform(try_get_gpus(), |gpus| {
cosmic::Action::App(Message::GpuRequest(gpus)) cosmic::Action::App(Message::GpuRequest(gpus))
}); });
return Task::batch([gpu_update, get_popup(popup_settings)]); return Task::batch([gpu_update, popup_task]);
} }
} }
Message::ToplevelListPopup(id, parent_window_id) => { Message::ToplevelListPopup(id, parent_window_id) => {
@ -1317,10 +1330,10 @@ impl cosmic::Application for CosmicAppList {
} }
} }
let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()) else { let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()).copied()
else {
return Task::none(); return Task::none();
}; };
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup = Some(Popup { self.popup = Some(Popup {
parent: parent_window_id, parent: parent_window_id,
@ -1328,8 +1341,11 @@ impl cosmic::Application for CosmicAppList {
dock_item: toplevel_group.clone(), dock_item: toplevel_group.clone(),
popup_type: PopupType::ToplevelList, popup_type: PopupType::ToplevelList,
}); });
let popup_task =
let mut popup_settings = self.core.applet.get_popup_settings( cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let mut popup_settings = app.core.applet.get_popup_settings(
parent_window_id, parent_window_id,
new_id, new_id,
None, None,
@ -1341,7 +1357,7 @@ impl cosmic::Application for CosmicAppList {
y, y,
width, width,
height, height,
} = *rectangle; } = rectangle;
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> { popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: x as i32, x: x as i32,
y: y as i32, y: y as i32,
@ -1350,7 +1366,8 @@ impl cosmic::Application for CosmicAppList {
}; };
let max_windows = 7.0; let max_windows = 7.0;
let window_spacing = 8.0; let window_spacing = 8.0;
popup_settings.positioner.size_limits = match self.core.applet.anchor { popup_settings.positioner.size_limits = match app.core.applet.anchor
{
PanelAnchor::Right | PanelAnchor::Left => Limits::NONE PanelAnchor::Right | PanelAnchor::Left => Limits::NONE
.min_width(100.0) .min_width(100.0)
.min_height(30.0) .min_height(30.0)
@ -1368,8 +1385,12 @@ impl cosmic::Application for CosmicAppList {
) )
.max_height(window_spacing * 2.0 + TOPLEVEL_BUTTON_HEIGHT), .max_height(window_spacing * 2.0 + TOPLEVEL_BUTTON_HEIGHT),
}; };
popup_settings
},
None,
));
return get_popup(popup_settings); return popup_task;
} }
} }
Message::ToplevelHoverChanged(handle, entering) => { Message::ToplevelHoverChanged(handle, entering) => {
@ -2148,39 +2169,46 @@ impl cosmic::Application for CosmicAppList {
if create_new { if create_new {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.overflow_active_popup = Some(new_id); self.overflow_active_popup = Some(new_id);
let rectangle = self.rectangles.get(&DockItemId::ActiveOverflow); let Some(iced::Rectangle {
let mut popup_settings = self.core.applet.get_popup_settings( x,
self.core.main_window_id().unwrap(), y,
width,
height,
}) = self.rectangles.get(&DockItemId::ActiveOverflow).copied()
else {
return Task::none();
};
let popup_task =
cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let mut popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
if let Some(iced::Rectangle {
x,
y,
width,
height,
}) = rectangle
{
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> { popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: *x as i32, x: x as i32,
y: *y as i32, y: y as i32,
width: *width as i32, width: width as i32,
height: *height as i32, height: height as i32,
}; };
}
let applet_suggested_size = self.core.applet.suggested_size(false).0 let applet_suggested_size = app.core.applet.suggested_size(false).0
+ 2 * self.core.applet.suggested_padding(false).0; + 2 * app.core.applet.suggested_padding(false).0;
let (_favorite_popup_cutoff, active_popup_cutoff) = let (_favorite_popup_cutoff, active_popup_cutoff) =
self.panel_overflow_lengths(); app.panel_overflow_lengths();
let popup_applet_count = let popup_applet_count = app.active_list.len().saturating_sub(
self.active_list.len().saturating_sub(
(active_popup_cutoff.unwrap_or_default()).saturating_sub(1), (active_popup_cutoff.unwrap_or_default()).saturating_sub(1),
) as f32; ) as f32;
let popup_applet_size = applet_suggested_size as f32 * popup_applet_count let popup_applet_size = applet_suggested_size as f32
* popup_applet_count
+ 4.0 * (popup_applet_count - 1.); + 4.0 * (popup_applet_count - 1.);
let (max_width, max_height) = match self.core.applet.anchor { let (max_width, max_height) = match app.core.applet.anchor {
PanelAnchor::Top | PanelAnchor::Bottom => { PanelAnchor::Top | PanelAnchor::Bottom => {
(popup_applet_size, applet_suggested_size as f32) (popup_applet_size, applet_suggested_size as f32)
} }
@ -2193,7 +2221,11 @@ impl cosmic::Application for CosmicAppList {
.min_width(1.) .min_width(1.)
.max_height(max_height) .max_height(max_height)
.min_height(1.); .min_height(1.);
cmds.push(get_popup(popup_settings)); popup_settings
},
None,
));
cmds.push(popup_task);
} }
return Task::batch(cmds); return Task::batch(cmds);
} }
@ -2205,39 +2237,46 @@ impl cosmic::Application for CosmicAppList {
if create_new { if create_new {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.overflow_favorites_popup = Some(new_id); self.overflow_favorites_popup = Some(new_id);
let rectangle = self.rectangles.get(&DockItemId::FavoritesOverflow); let Some(iced::Rectangle {
let mut popup_settings = self.core.applet.get_popup_settings( x,
self.core.main_window_id().unwrap(), y,
width,
height,
}) = self.rectangles.get(&DockItemId::FavoritesOverflow).copied()
else {
return Task::none();
};
let popup_task =
cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let mut popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
if let Some(iced::Rectangle {
x,
y,
width,
height,
}) = rectangle
{
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> { popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: *x as i32, x: x as i32,
y: *y as i32, y: y as i32,
width: *width as i32, width: width as i32,
height: *height as i32, height: height as i32,
}; };
}
let applet_suggested_size = self.core.applet.suggested_size(false).0 let applet_suggested_size = app.core.applet.suggested_size(false).0
+ 2 * self.core.applet.suggested_padding(false).0; + 2 * app.core.applet.suggested_padding(false).0;
let (favorite_popup_cutoff, _active_popup_cutoff) = let (favorite_popup_cutoff, _active_popup_cutoff) =
self.panel_overflow_lengths(); app.panel_overflow_lengths();
let popup_applet_count = let popup_applet_count = app.pinned_list.len().saturating_sub(
self.pinned_list.len().saturating_sub(
favorite_popup_cutoff.unwrap_or_default().saturating_sub(1), favorite_popup_cutoff.unwrap_or_default().saturating_sub(1),
) as f32; ) as f32;
let popup_applet_size = applet_suggested_size as f32 * popup_applet_count let popup_applet_size = applet_suggested_size as f32
* popup_applet_count
+ 4.0 * (popup_applet_count - 1.); + 4.0 * (popup_applet_count - 1.);
let (max_width, max_height) = match self.core.applet.anchor { let (max_width, max_height) = match app.core.applet.anchor {
PanelAnchor::Top | PanelAnchor::Bottom => { PanelAnchor::Top | PanelAnchor::Bottom => {
(popup_applet_size, applet_suggested_size as f32) (popup_applet_size, applet_suggested_size as f32)
} }
@ -2250,7 +2289,11 @@ impl cosmic::Application for CosmicAppList {
.min_width(1.) .min_width(1.)
.max_height(max_height) .max_height(max_height)
.min_height(1.); .min_height(1.);
cmds.push(get_popup(popup_settings)); popup_settings
},
None,
));
cmds.push(popup_task);
} }
return Task::batch(cmds); return Task::batch(cmds);
} }
@ -2660,7 +2703,8 @@ impl cosmic::Application for CosmicAppList {
.width(Length::Fill) .width(Length::Fill)
} }
let mut content = column![].align_x(Alignment::Center); let mut content =
menu::menu_column::MenuColumn::with_capacity(4).align_x(Alignment::Center);
if let Some(exec) = desktop_info.exec() { if let Some(exec) = desktop_info.exec() {
if !toplevels.is_empty() { if !toplevels.is_empty() {
@ -2784,22 +2828,6 @@ impl cosmic::Application for CosmicAppList {
.popup_container( .popup_container(
container(content) container(content)
.padding(1) .padding(1)
//TODO: move style to libcosmic
.class(theme::Container::custom(|theme| {
let cosmic = theme.cosmic();
let component = &cosmic.background(false).component;
container::Style {
icon_color: Some(component.on.into()),
text_color: Some(component.on.into()),
background: Some(Background::Color(component.base.into())),
border: Border {
radius: cosmic.radius_s().into(),
width: 1.0,
color: component.divider.into(),
},
..Default::default()
}
}))
.height(Length::Shrink) .height(Length::Shrink)
.width(Length::Fill), .width(Length::Fill),
) )

View file

@ -0,0 +1,6 @@
magnifier = Lupa
screen-reader = Narrador
invert-colors = Colors invertits
settings = Configuració d'accessibilitat...
filter-colors = Filtres de colors
high-contrast = Mode d'alt contrast

View file

@ -0,0 +1,6 @@
screen-reader = Skærmlæser
invert-colors = Invertér farver
high-contrast = Høj kontrast
filter-colors = Filtrér farver
settings = Tilgængelighedsindstillinger...
magnifier = Forstørrelsesglas

View file

@ -1,6 +1,6 @@
screen-reader = Bildschirmleser screen-reader = Bildschirmleser
magnifier = Vergrößerungsglas magnifier = Vergrößerungsglas
invert-colors = Farben invertieren invert-colors = Farben invertieren
settings = Barrierefreiheitseinstellungen… settings = Barrierefreiheitseinstellungen ...
filter-colors = Farben filtern filter-colors = Farben filtern
high-contrast = Hoher Kontrast high-contrast = Hoher Kontrast

View file

@ -0,0 +1,6 @@
screen-reader = Screen reader
invert-colors = Invert colours
high-contrast = High contrast
filter-colors = Filter colours
settings = Accessibility settings...
magnifier = Magnifier

View file

@ -1,6 +1,6 @@
screen-reader = صفحه‌خوان screen-reader = صفحه‌خوان
magnifier = ذره‌بین magnifier = ذره‌بین
invert-colors = وارونه‌سازی رنگ‌ها invert-colors = وارونه کردن رنگ‌ها
settings = تنظیمات دسترسی‌پذیری... settings = تنظیمات دسترسی‌پذیری...
filter-colors = فیلتر رنگ‌ها filter-colors = فیلتر رنگ‌ها
high-contrast = کنتراست بالا high-contrast = کنتراست بالا

View file

@ -0,0 +1,6 @@
screen-reader = Lector de pantalla
magnifier = Lupa
invert-colors = Invertir cores
settings = Configuración de accesibilidade...
filter-colors = Filtro de cores
high-contrast = Alto contraste

View file

@ -1,4 +1,6 @@
screen-reader = स्क्रीन रीडर screen-reader = स्क्रीन रीडर
filter-colors = रंग फ़िल्टर filter-colors = रंग फ़िल्टर करें
settings = सुलभता सेटिंग..। settings = एक्सेसिबिलिटी सेटिंग्स..।
magnifier = आवर्धक magnifier = मैग्नीफायर
high-contrast = उच्च कंट्रास्ट
invert-colors = रंग उल्टे करें

View file

@ -2,5 +2,5 @@ screen-reader = Lettore dello schermo
magnifier = Lente di ingrandimento magnifier = Lente di ingrandimento
invert-colors = Inverti colori invert-colors = Inverti colori
settings = Impostazioni accessibilità... settings = Impostazioni accessibilità...
filter-colors = Filtra colori filter-colors = Filtri colore
high-contrast = Contrasto elevato high-contrast = Contrasto elevato

View file

@ -0,0 +1,2 @@
screen-reader = ᱥᱠᱨᱤᱱ ᱨᱤᱰᱟᱨ
invert-colors = ᱨᱚᱝ ᱩᱞᱴᱟᱹ ᱪᱷᱚ

View file

@ -133,20 +133,27 @@ impl cosmic::Application for CosmicA11yApplet {
} }
Message::TogglePopup => { Message::TogglePopup => {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
return destroy_popup(p); return cosmic::surface::surface_task(cosmic::surface::action::destroy_popup(
p,
));
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut CosmicA11yApplet| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
let popup_settings = self.core.applet.get_popup_settings( let popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
Some((1, 1)), Some((1, 1)),
None, None,
None, None,
); );
popup_settings
return get_popup(popup_settings); },
None,
));
} }
} }
Message::CloseRequested(id) => { Message::CloseRequested(id) => {

View file

@ -0,0 +1,7 @@
output = Sortida
show-media-controls = Mostra els controls multimèdia a la barra
disconnected = PulseAudio desconnectat
no-device = No s'ha seleccionat cap dispositiu
input = Entrada
unknown-artist = Desconegut
sound-settings = Configuració de so...

View file

@ -0,0 +1,7 @@
show-media-controls = Vis mediekontrol på panel
disconnected = PulseAudio Afbrudt
no-device = Ingen enhed valgt
input = Indgang
output = Udgang
unknown-artist = Ukendt
sound-settings = Lydindstillinger...

View file

@ -0,0 +1,7 @@
show-media-controls = Show media controls on panel
disconnected = PulseAudio Disconnected
no-device = No device selected
input = Input
output = Output
unknown-artist = Unknown
sound-settings = Sound Settings...

View file

@ -0,0 +1,7 @@
output = Saída
input = Entrada
show-media-controls = Mostrar os controis multimedia no panel
sound-settings = Axustes do son...
disconnected = PulseAudio Desconectado
no-device = Ningún dipositivo seleccionado
unknown-artist = Descoñecido

View file

@ -4,4 +4,4 @@ no-device = Nepasirinktas įrenginys
input = Įvestis input = Įvestis
output = Išvestis output = Išvestis
unknown-artist = Nežinomas atlikėjas unknown-artist = Nežinomas atlikėjas
sound-settings = Garso Nustatymai... sound-settings = Garso Nuostatos...

View file

@ -0,0 +1 @@
output = ᱟᱨᱡᱟᱣ

View file

@ -33,10 +33,15 @@ use cosmic::{
}; };
use cosmic_settings_audio_client::{self as audio_client, CosmicAudioProxy}; use cosmic_settings_audio_client::{self as audio_client, CosmicAudioProxy};
use futures::SinkExt; use futures::SinkExt;
use iced::platform_specific::shell::wayland::commands::popup::{destroy_popup, get_popup};
use mpris_subscription::{MprisRequest, MprisUpdate}; use mpris_subscription::{MprisRequest, MprisUpdate};
use mpris2_zbus::player::PlaybackStatus; use mpris2_zbus::player::PlaybackStatus;
use std::{cell::RefCell, rc::Rc, sync::Arc}; use std::{
sync::{
Arc,
atomic::{self, AtomicU32},
},
time::Duration,
};
mod config; mod config;
mod mpris_subscription; mod mpris_subscription;
@ -58,11 +63,15 @@ pub struct Audio {
/// Track the applet's popup window. /// Track the applet's popup window.
popup: Option<window::Id>, popup: Option<window::Id>,
/// Varlink connection to `com.system76.CosmicSettings.Audio`. /// Varlink connection to `com.system76.CosmicSettings.Audio`.
audio_client: Option<Rc<RefCell<audio_client::Client>>>, audio_client: Option<audio_client::Client>,
/// Known audio device state /// Known audio device state
model: model::Model, model: model::Model,
/// Whether to expand the revealer of a source or sink device. /// Whether to expand the revealer of a source or sink device.
is_open: IsOpen, is_open: IsOpen,
/// Used to debounce sink volume updates.
applied_sink_volume: Arc<AtomicU32>,
/// Used to deboune source volume updates.
applied_source_volume: Arc<AtomicU32>,
/// Max slider volume for the sink device, as determined by the amplification property. /// Max slider volume for the sink device, as determined by the amplification property.
max_sink_volume: u32, max_sink_volume: u32,
/// Max slider volume for the source device, as determined by the amplification property. /// Max slider volume for the source device, as determined by the amplification property.
@ -140,26 +149,27 @@ enum IsOpen {
pub enum Message { pub enum Message {
/// Connection to `com.system76.CosmicSettings`. /// Connection to `com.system76.CosmicSettings`.
Client(Arc<audio_client::Client>), Client(Arc<audio_client::Client>),
Ignore,
SetSinkVolume(u32),
SetSourceVolume(u32),
ToggleSinkMute,
ToggleSourceMute,
SetDefaultSink(usize),
SetDefaultSource(usize),
OutputToggle,
InputToggle,
TogglePopup,
CloseRequested(window::Id), CloseRequested(window::Id),
ToggleMediaControlsInTopPanel(bool),
ConfigChanged(AudioAppletConfig), ConfigChanged(AudioAppletConfig),
Ignore,
InputToggle,
Mpris(mpris_subscription::MprisUpdate), Mpris(mpris_subscription::MprisUpdate),
MprisRequest(MprisRequest), MprisRequest(MprisRequest),
Token(TokenUpdate),
OpenSettings, OpenSettings,
OutputToggle,
ReattachClient(Arc<audio_client::Client>),
Rectangle(RectangleUpdate<u32>),
SetDefaultSink(usize),
SetDefaultSource(usize),
SetSinkVolume(u32),
SetSourceVolume(u32),
Subscription(audio_client::Event), Subscription(audio_client::Event),
Surface(surface::Action), Surface(surface::Action),
Rectangle(RectangleUpdate<u32>), ToggleMediaControlsInTopPanel(bool),
TogglePopup,
ToggleSinkMute,
ToggleSourceMute,
Token(TokenUpdate),
} }
// TODO // TODO
@ -302,24 +312,34 @@ impl cosmic::Application for Audio {
self.rectangle_tracker.replace(tracker); self.rectangle_tracker.replace(tracker);
} }
}, },
Message::ReattachClient(client) => {
if let Some(client) = Arc::into_inner(client) {
self.audio_client = Some(client);
}
}
Message::Ignore => {} Message::Ignore => {}
Message::TogglePopup => { Message::TogglePopup => {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
return destroy_popup(p); return cosmic::surface::surface_task(cosmic::surface::action::destroy_popup(
p,
));
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
self.refresh_volume_limits(); self.refresh_volume_limits();
let mut popup_settings = self.core.applet.get_popup_settings( let mut popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
if let Some(r) = self.rectangle { if let Some(r) = app.rectangle {
popup_settings.positioner.anchor_rect = Rectangle { popup_settings.positioner.anchor_rect = Rectangle {
x: r.x as i32, x: r.x as i32,
y: r.y as i32, y: r.y as i32,
@ -327,7 +347,10 @@ impl cosmic::Application for Audio {
height: r.height as i32, height: r.height as i32,
}; };
} }
return get_popup(popup_settings); popup_settings
},
None,
));
} }
} }
@ -355,7 +378,7 @@ impl cosmic::Application for Audio {
&& let Some(client) = self.audio_client.as_mut() && let Some(client) = self.audio_client.as_mut()
{ {
futures::executor::block_on(async { futures::executor::block_on(async {
_ = client.borrow_mut().conn.set_default(node_id, true).await; _ = client.conn.set_default(node_id, true).await;
}); });
} }
} }
@ -366,7 +389,7 @@ impl cosmic::Application for Audio {
&& let Some(client) = self.audio_client.as_mut() && let Some(client) = self.audio_client.as_mut()
{ {
futures::executor::block_on(async { futures::executor::block_on(async {
_ = client.borrow_mut().conn.set_default(node_id, true).await; _ = client.conn.set_default(node_id, true).await;
}); });
} }
} }
@ -374,7 +397,7 @@ impl cosmic::Application for Audio {
Message::ToggleSinkMute => { Message::ToggleSinkMute => {
if let Some(ref mut client) = self.audio_client { if let Some(ref mut client) = self.audio_client {
futures::executor::block_on(async { futures::executor::block_on(async {
_ = client.borrow_mut().conn.sink_mute_toggle().await; _ = client.conn.sink_mute_toggle().await;
}); });
} }
} }
@ -382,27 +405,43 @@ impl cosmic::Application for Audio {
Message::ToggleSourceMute => { Message::ToggleSourceMute => {
if let Some(ref mut client) = self.audio_client { if let Some(ref mut client) = self.audio_client {
futures::executor::block_on(async { futures::executor::block_on(async {
_ = client.borrow_mut().conn.source_mute_toggle().await; _ = client.conn.source_mute_toggle().await;
}); });
} }
} }
Message::SetSinkVolume(volume) => { Message::SetSinkVolume(volume) => {
if let Some(ref mut client) = self.audio_client { self.applied_sink_volume
.store(volume, atomic::Ordering::Relaxed);
self.model.active_sink.volume = volume; self.model.active_sink.volume = volume;
self.model.active_sink.volume_text = volume.to_string(); self.model.active_sink.volume_text = volume.to_string();
futures::executor::block_on(async { if let Some(mut client) = self.audio_client.take() {
_ = client.borrow_mut().conn.set_sink_volume(volume).await; let volume = Arc::clone(&self.applied_sink_volume);
return cosmic::Task::future(async move {
tokio::time::sleep(Duration::from_millis(128)).await;
_ = client
.conn
.set_sink_volume(volume.load(atomic::Ordering::Relaxed))
.await;
Message::ReattachClient(Arc::new(client)).into()
}); });
} }
} }
Message::SetSourceVolume(volume) => { Message::SetSourceVolume(volume) => {
if let Some(ref mut client) = self.audio_client { self.applied_source_volume
.store(volume, atomic::Ordering::Relaxed);
self.model.active_source.volume = volume; self.model.active_source.volume = volume;
self.model.active_source.volume_text = volume.to_string(); self.model.active_source.volume_text = volume.to_string();
futures::executor::block_on(async { if let Some(mut client) = self.audio_client.take() {
_ = client.borrow_mut().conn.set_source_volume(volume).await; let volume = Arc::clone(&self.applied_source_volume);
return cosmic::Task::future(async move {
tokio::time::sleep(Duration::from_millis(128)).await;
_ = client
.conn
.set_sink_volume(volume.load(atomic::Ordering::Relaxed))
.await;
Message::ReattachClient(Arc::new(client)).into()
}); });
} }
} }
@ -513,7 +552,7 @@ impl cosmic::Application for Audio {
} }
Message::Client(client) => { Message::Client(client) => {
if let Some(client) = Arc::into_inner(client) { if let Some(client) = Arc::into_inner(client) {
self.audio_client = Some(Rc::new(RefCell::new(client))); self.audio_client = Some(client);
self.model = model::Model::default(); self.model = model::Model::default();
} }
} }

View file

@ -0,0 +1,14 @@
power-settings = Strøm- og Batteriindstillinger...
hours = t
until-empty = indtil tom
battery-desc = Reduceret strømforbrug og ydeevne.
max-charge = Forøg dit batteris levetid, ved at angive en maksimal opladningsværdi på 80%
balanced = Balanceret
battery = Batteri
seconds = s
dgpu-running = Diskret GPU er aktiv og kan reducere batterilevetiden
performance = Høj Ydeevne
performance-desc = Høj ydeevne og strømforbrug.
minutes = m
balanced-desc = Standard ydeevne og batteriforbrug.
dgpu-applications = Applikationer som bruger { $gpu_name } diskret GPU

View file

@ -0,0 +1,14 @@
power-settings = Power & Battery settings...
hours = h
until-empty = until empty
battery-desc = Reduced power usage and performance.
max-charge = Increase the lifespan of your battery by setting a maximum charge value of 80%
balanced = Balanced
battery = Battery
seconds = s
dgpu-running = Discrete GPU is active and can reduce battery life
performance = High Performance
performance-desc = High performance and power usage.
minutes = m
balanced-desc = Standard performance and battery usage.
dgpu-applications = Applications using { $gpu_name } discrete GPU

View file

@ -0,0 +1,14 @@
battery = Batería
battery-desc = Reduce o consumo de enerxía e o rendemento.
balanced = Balanceado
balanced-desc = Rendemento e consumo de batería estándar.
performance = Alto rendemento
performance-desc = Alto rendemento e maior consumo de enerxía.
max-charge = Aumenta a vida útil da batería limitando a carga máxima ao 80 %
seconds = s
minutes = m
hours = h
until-empty = ata baleirar
power-settings = Axustes de enexía e batería...
dgpu-running = A GPU dedicada está activa e pode reducir a duración da batería
dgpu-applications = Aplicacións que están a usar a GPU dedicada { $gpu_name }

View file

@ -1,14 +1,14 @@
battery = Risparmio energetico battery = Batteria
battery-desc = Consumi minimi, performance ridotta. battery-desc = Prestazioni e consumo energetico ridotti.
balanced = Bilanciato balanced = Equilibrato
balanced-desc = Consumi bilanciati, performance dinamica. balanced-desc = Prestazioni e consumo energetico normali.
performance = Performance performance = Prestazioni elevate
performance-desc = Consumi alti, performance massima. performance-desc = Prestazioni elevate e consumo energetico.
max-charge = Migliora la durata di vita della batteria caricandola fino all'80% max-charge = Aumenta la durata della batteria impostando un valore massimo di carica dell’80%
seconds = s seconds = s
minutes = m minutes = m
hours = h hours = h
until-empty = fino alla scarica until-empty = finché non è vuoto
power-settings = Impostazioni energetiche... power-settings = Impostazioni energetiche...
dgpu-running = La GPU discreta è attiva e può ridurre la durata della batteria dgpu-running = La GPU discreta è attiva e può ridurre la durata della batteria
dgpu-applications = Applicazioni che stanno usando la GPU discreta { $gpu_name } dgpu-applications = Applicazioni che stanno usando la GPU discreta { $gpu_name }

View file

@ -2,7 +2,7 @@ battery = Betarî
seconds = ç seconds = ç
minutes = x minutes = x
hours = d hours = d
until-empty = Heya vala dibe until-empty = heya vala dibe
power-settings = Sazkariyên hêz û betariyê... power-settings = Sazkariyên hêz û betariyê...
battery-desc = Bikaranîna hêzê kêmkirî û performans. battery-desc = Bikaranîna hêzê kêmkirî û performans.
balanced = Hevseng balanced = Hevseng

View file

@ -1,14 +1,14 @@
battery = Bateria battery = Economia de energia
battery-desc = Uso reduzido de energia e desempenho limitado. battery-desc = Uso reduzido de energia e desempenho limitado.
balanced = Balanceado balanced = Balanceado
balanced-desc = Desempenho padrão e uso de bateria moderado. balanced-desc = Desempenho padrão e uso de bateria moderado.
performance = Alto Desempenho performance = Alto desempenho
performance-desc = Máximo desempenho e alto uso de energia. performance-desc = Máximo desempenho e alto uso de energia.
max-charge = Aumente a vida útil da sua bateria definindo um valor máximo de carga de 80% max-charge = Aumente a vida útil da sua bateria definindo um valor máximo de carga de 80%
seconds = s seconds = s
minutes = m minutes = m
hours = h hours = h
until-empty = até esvaziar until-empty = até ficar descarregada
power-settings = Configurações de energia e bateria... power-settings = Configurações de energia e bateria...
dgpu-running = GPU discreta está ativa e pode reduzir a vida útil da bateria dgpu-running = A GPU dedicada está ativa e pode reduzir a vida útil da bateria
dgpu-applications = Aplicativos usando GPU discreta { $gpu_name } dgpu-applications = Aplicativos usando a GPU dedicada { $gpu_name }

View file

@ -6,9 +6,9 @@ performance = 高效能
performance-desc = 高效能與高耗電量。 performance-desc = 高效能與高耗電量。
max-charge = 將電池充電上限設定為 80%,以延長電池使用壽命 max-charge = 將電池充電上限設定為 80%,以延長電池使用壽命
seconds = 秒 seconds = 秒
minutes = 分 minutes = 分鍾
hours = 時 hours = 小時
until-empty = 直到電量耗盡 until-empty = 直到電量耗盡
power-settings = 電源與電池設定… power-settings = 電源與電池設定…
dgpu-running = 獨立顯示卡已啟用,可能會縮短電池續航力 dgpu-running = 獨立顯示卡已啟用,可能會縮短電池續航力
dgpu-applications = 使用 { $gpu_name } 獨立顯示卡的應用程式 dgpu-applications = 使用獨立顯示卡 { $gpu_name } 的應用程式

View file

@ -366,23 +366,31 @@ impl cosmic::Application for CosmicBatteryApplet {
let _ = tx.send(KeyboardBacklightRequest::Get); let _ = tx.send(KeyboardBacklightRequest::Get);
} }
let new_id = window::Id::unique();
self.popup.replace(new_id);
let popup_settings = self.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(),
new_id,
Some((1, 1)),
None,
None,
);
if let Some(tx) = self.power_profile_sender.as_ref() { if let Some(tx) = self.power_profile_sender.as_ref() {
let _ = tx.send(PowerProfileRequest::Get); let _ = tx.send(PowerProfileRequest::Get);
} }
if let Some(tx) = self.update_trigger.as_ref() { if let Some(tx) = self.update_trigger.as_ref() {
let _ = tx.send(()); let _ = tx.send(());
} }
let mut tasks = vec![get_popup(popup_settings)]; let mut tasks = vec![cosmic::surface::surface_task(
cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique();
app.popup.replace(new_id);
let popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id,
Some((1, 1)),
None,
None,
);
popup_settings
},
None,
),
)];
if let Some(tx) = &self.settings_daemon_sender { if let Some(tx) = &self.settings_daemon_sender {
let _ = tx.send(settings_daemon::Request::GetDisplayBrightness); let _ = tx.send(settings_daemon::Request::GetDisplayBrightness);
let _ = tx.send(settings_daemon::Request::GetMaxDisplayBrightness); let _ = tx.send(settings_daemon::Request::GetMaxDisplayBrightness);

View file

@ -0,0 +1,12 @@
cancel = Annuller
confirm-pin = Bekræft venligst, at følgende pinkode matcher den, der vises på { $deviceName }
bluetooth = Bluetooth
unsuccessful = Parring Mislykkedes
pairable = Parbare
try-again = Prøv Igen
check-device = Sørg for, at { $deviceName } er slået til, inden for rækkevidde og klar til parring.
other-devices = Andre Bluetooth-enheder
connected = Forbundet
confirm = Bekræft
settings = Bluetooth-indstillinger...
discoverable = Synlig

View file

@ -0,0 +1,12 @@
cancel = Cancel
confirm-pin = Please confirm that the following PIN matches the one displayed on { $deviceName }
bluetooth = Bluetooth
unsuccessful = Pairing Unsuccessful
pairable = Pairable
try-again = Try Again
check-device = Make sure { $deviceName } is turned on, in range, and is ready to pair.
other-devices = Other Bluetooth devices
connected = Connected
confirm = Confirm
settings = Bluetooth settings...
discoverable = Discoverable

View file

@ -0,0 +1,12 @@
cancel = Cancelar
bluetooth = Bluetooth
other-devices = Outros dispositivos Bluetooth
settings = Axustes Bluetooth…
connected = Conectado
confirm-pin = Por favor, confirme que o seguinte PIN coincide co que se mostra en{ $deviceName }
confirm = Confirmar
unsuccessful = Enparellamento non exitoso
check-device = Asegurate de que { $deviceName } está acendido, dentro do alcance e listo para emparellar.
try-again = Reintentar
discoverable = Atopable
pairable = Emparellable

View file

@ -0,0 +1 @@
cancel = ᱵᱟᱹᱛᱤᱞ

View file

@ -1,7 +1,7 @@
bluetooth = 藍牙 bluetooth = 藍牙
other-devices = 其他藍牙裝置 other-devices = 其他藍牙裝置
settings = 藍牙設定… settings = 藍牙設定…
connected = 已經連線 connected = 已連線
confirm-pin = 請確認此 PIN 碼與 { $deviceName } 上顯示的是否相符 confirm-pin = 請確認此 PIN 碼與 { $deviceName } 上顯示的是否相符
confirm = 確認 confirm = 確認
cancel = 取消 cancel = 取消

View file

@ -121,20 +121,25 @@ impl cosmic::Application for CosmicBluetoothApplet {
} else { } else {
set_discovery(true); set_discovery(true);
// TODO request update of state maybe let get_popup_task =
cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
app.core.applet.get_popup_settings(
let popup_settings = self.core.applet.get_popup_settings( app.core.main_window_id().unwrap(),
self.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); )
},
None,
));
return Task::batch([ return Task::batch([
get_popup(popup_settings), get_popup_task,
cosmic::task::future(set_tick(Duration::from_secs(3))) cosmic::task::future(set_tick(Duration::from_secs(3)))
.map(|()| cosmic::Action::App(Message::Ignore)), .map(|()| cosmic::Action::App(Message::Ignore)),
]); ]);

View file

@ -5,7 +5,9 @@ edition = "2024"
license = "GPL-3.0-only" license = "GPL-3.0-only"
[dependencies] [dependencies]
cctk.workspace = true
cosmic-comp-config.workspace = true cosmic-comp-config.workspace = true
futures.workspace = true
i18n-embed-fl.workspace = true i18n-embed-fl.workspace = true
i18n-embed.workspace = true i18n-embed.workspace = true
cosmic.workspace = true cosmic.workspace = true

View file

@ -12,4 +12,5 @@ NoDisplay=true
X-CosmicApplet=true X-CosmicApplet=true
X-CosmicShrinkable=true X-CosmicShrinkable=true
X-CosmicHoverPopup=Auto X-CosmicHoverPopup=Auto
X-HostWaylandDisplay=true
X-OverflowPriority=10 X-OverflowPriority=10

View file

@ -0,0 +1,2 @@
show-keyboard-layout = Mostra la disposició de teclat...
keyboard-settings = Configuració de teclat...

View file

@ -0,0 +1,2 @@
show-keyboard-layout = Vis Tastaturopsætning...
keyboard-settings = Tastaturindstillinger...

View file

@ -0,0 +1,2 @@
show-keyboard-layout = Mostrar a disposición do teclado...
keyboard-settings = Axustes do teclado...

View file

@ -3,19 +3,23 @@
mod localize; mod localize;
use cctk::{
cosmic_protocols::keyboard_layout::v1::client::zcosmic_keyboard_layout_v1::ZcosmicKeyboardLayoutV1,
wayland_client::{Connection, Proxy, backend::Backend},
};
use cosmic::{ use cosmic::{
app, app,
app::Core, app::Core,
applet::{self}, applet::{self},
cosmic_config::{self, ConfigSet, CosmicConfigEntry},
cosmic_theme::Spacing, cosmic_theme::Spacing,
iced::Subscription, iced::Subscription,
iced::core::window,
iced::{ iced::{
Rectangle, Task, self, Rectangle, Task,
event::wayland::{Event as WaylandEvent, OutputEvent},
platform_specific::shell::commands::popup::{destroy_popup, get_popup}, platform_specific::shell::commands::popup::{destroy_popup, get_popup},
window::Id, window::Id,
}, },
iced::core::window,
prelude::*, prelude::*,
surface, theme, surface, theme,
widget::{ widget::{
@ -23,14 +27,35 @@ use cosmic::{
rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription}, rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription},
}, },
}; };
use cosmic_comp_config::CosmicCompConfig; use cosmic_comp_config::{CosmicCompConfig, XkbConfig};
use std::sync::LazyLock; use std::{
os::unix::{
io::{FromRawFd, RawFd},
net::UnixStream,
},
sync::LazyLock,
};
use xkb_data::KeyboardLayout; use xkb_data::KeyboardLayout;
mod wayland;
static AUTOSIZE_MAIN_ID: LazyLock<widget::Id> = LazyLock::new(|| widget::Id::new("autosize-main")); static AUTOSIZE_MAIN_ID: LazyLock<widget::Id> = LazyLock::new(|| widget::Id::new("autosize-main"));
pub const ID: &str = "com.system76.CosmicAppletInputSources"; pub const ID: &str = "com.system76.CosmicAppletInputSources";
pub fn run() -> cosmic::iced::Result { pub fn run() -> cosmic::iced::Result {
let socket = std::env::var("X_PRIVILEGED_WAYLAND_SOCKET")
.ok()
.and_then(|fd| {
fd.parse::<RawFd>()
.ok()
.map(|fd| unsafe { UnixStream::from_raw_fd(fd) })
});
let wayland_connection = if let Some(socket) = socket {
Some(Connection::from_socket(socket).unwrap())
} else {
None
};
localize::localize(); localize::localize();
let layouts = match xkb_data::all_keyboard_layouts() { let layouts = match xkb_data::all_keyboard_layouts() {
@ -41,27 +66,8 @@ pub fn run() -> cosmic::iced::Result {
} }
}; };
let (comp_config_handler, comp_config) =
match cosmic_config::Config::new("com.system76.CosmicComp", CosmicCompConfig::VERSION) {
Ok(config_handler) => {
let config = match CosmicCompConfig::get_entry(&config_handler) {
Ok(ok) => ok,
Err((errs, config)) => {
tracing::error!("errors loading config: {:?}", errs);
config
}
};
(Some(config_handler), config)
}
Err(err) => {
tracing::error!("failed to create config handler: {}", err);
(None, CosmicCompConfig::default())
}
};
cosmic::applet::run::<Window>(Flags { cosmic::applet::run::<Window>(Flags {
comp_config, wayland_connection,
comp_config_handler,
layouts: layouts.layout_list.layout, layouts: layouts.layout_list.layout,
}) })
} }
@ -76,12 +82,13 @@ pub struct ActiveLayout {
pub struct Window { pub struct Window {
core: Core, core: Core,
popup: Option<Id>, popup: Option<Id>,
comp_config: CosmicCompConfig,
comp_config_handler: Option<cosmic_config::Config>,
layouts: Vec<KeyboardLayout>, layouts: Vec<KeyboardLayout>,
active_layouts: Vec<ActiveLayout>, active_layouts: Vec<ActiveLayout>,
rectangle_tracker: Option<RectangleTracker<u32>>, rectangle_tracker: Option<RectangleTracker<u32>>,
rectangle: Rectangle, rectangle: Rectangle,
wayland_connection: Option<Connection>,
keyboard_layout: Option<ZcosmicKeyboardLayoutV1>,
current_layout: usize,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -93,12 +100,13 @@ pub enum Message {
KeyboardSettings, KeyboardSettings,
Surface(surface::Action), Surface(surface::Action),
Rectangle(RectangleUpdate<u32>), Rectangle(RectangleUpdate<u32>),
WaylandConnection(Backend),
Wayland(wayland::Event),
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Flags { pub struct Flags {
pub comp_config: CosmicCompConfig, wayland_connection: Option<Connection>,
pub comp_config_handler: Option<cosmic_config::Config>,
pub layouts: Vec<KeyboardLayout>, pub layouts: Vec<KeyboardLayout>,
} }
@ -119,14 +127,15 @@ impl cosmic::Application for Window {
fn init(core: Core, flags: Self::Flags) -> (Self, app::Task<Self::Message>) { fn init(core: Core, flags: Self::Flags) -> (Self, app::Task<Self::Message>) {
let window = Window { let window = Window {
comp_config_handler: flags.comp_config_handler,
layouts: flags.layouts, layouts: flags.layouts,
core, core,
popup: None, popup: None,
comp_config: flags.comp_config,
active_layouts: Vec::new(), active_layouts: Vec::new(),
rectangle_tracker: None, rectangle_tracker: None,
rectangle: Rectangle::default(), rectangle: Rectangle::default(),
wayland_connection: flags.wayland_connection,
keyboard_layout: None,
current_layout: 0,
}; };
(window, Task::none()) (window, Task::none())
} }
@ -139,19 +148,24 @@ impl cosmic::Application for Window {
match message { match message {
Message::TogglePopup => { Message::TogglePopup => {
return if let Some(p) = self.popup.take() { return if let Some(p) = self.popup.take() {
destroy_popup(p) return crate::surface::surface_task(crate::surface::action::destroy_popup(p));
} else { } else {
return crate::surface::surface_task(crate::surface::action::app_popup(
|_| Default::default(),
|app: &mut Window| {
let new_id = Id::unique(); let new_id = Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
let popup_settings = self.core.applet.get_popup_settings( let popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
popup_settings
get_popup(popup_settings) },
None,
));
}; };
} }
Message::PopupClosed(id) => { Message::PopupClosed(id) => {
@ -160,8 +174,7 @@ impl cosmic::Application for Window {
} }
} }
Message::CompConfig(config) => { Message::CompConfig(config) => {
self.comp_config = *config; self.active_layouts = self.update_xkb(&config.xkb_config);
self.active_layouts = self.update_xkb();
} }
Message::KeyboardSettings => { Message::KeyboardSettings => {
let mut cmd = std::process::Command::new("cosmic-settings"); let mut cmd = std::process::Command::new("cosmic-settings");
@ -169,31 +182,10 @@ impl cosmic::Application for Window {
tokio::spawn(cosmic::process::spawn(cmd)); tokio::spawn(cosmic::process::spawn(cmd));
} }
Message::SetActiveLayout(pos) => { Message::SetActiveLayout(pos) => {
if pos == 0 { if let Some(keyboard_layout) = &self.keyboard_layout {
return Task::none(); keyboard_layout.set_group(pos as u32);
} if let Some(backend) = keyboard_layout.backend().upgrade() {
let _ = backend.flush();
self.active_layouts.swap(0, pos);
let mut new_layout = String::new();
let mut new_variant = String::new();
for layout in &self.active_layouts {
new_layout.push_str(&layout.layout);
new_layout.push(',');
new_variant.push_str(&layout.variant);
new_variant.push(',');
}
let _excess_comma = new_layout.pop();
let _excess_comma = new_variant.pop();
self.comp_config.xkb_config.layout = new_layout;
self.comp_config.xkb_config.variant = new_variant;
if let Some(comp_config_handler) = &self.comp_config_handler {
if let Err(err) =
comp_config_handler.set("xkb_config", &self.comp_config.xkb_config)
{
tracing::error!("Failed to set config 'xkb_config' {err}");
} }
} }
} }
@ -210,13 +202,26 @@ impl cosmic::Application for Window {
self.rectangle_tracker = Some(tracker); self.rectangle_tracker = Some(tracker);
} }
}, },
Message::WaylandConnection(backend) => {
if self.wayland_connection.is_none() {
self.wayland_connection = Some(Connection::from_backend(backend));
}
}
Message::Wayland(w) => match w {
wayland::Event::KeyboardLayout(keyboard_layout) => {
self.keyboard_layout = Some(keyboard_layout);
}
wayland::Event::Group(group) => {
self.current_layout = group as usize;
}
},
} }
Task::none() Task::none()
} }
fn view(&self) -> Element<'_, Self::Message> { fn view(&self) -> Element<'_, Self::Message> {
let applet_text = if let Some(l) = self.active_layouts.first() { let applet_text = if let Some(l) = self.active_layouts.get(self.current_layout) {
if !l.variant.is_empty() { if !l.variant.is_empty() {
format!("{} ({})", l.layout, l.variant) format!("{} ({})", l.layout, l.variant)
} else { } else {
@ -249,8 +254,13 @@ impl cosmic::Application for Window {
let mut content_list = let mut content_list =
widget::column::with_capacity(4 + self.active_layouts.len()).padding([8, 0]); widget::column::with_capacity(4 + self.active_layouts.len()).padding([8, 0]);
for (id, layout) in self.active_layouts.iter().enumerate() { for (id, layout) in self.active_layouts.iter().enumerate() {
let font = if id == self.current_layout {
cosmic::font::bold()
} else {
cosmic::font::default()
};
let group = widget::column::with_capacity(2) let group = widget::column::with_capacity(2)
.push(widget::text::body(layout.description.as_str())) .push(widget::text::body(layout.description.as_str()).font(font))
.push(widget::text::caption(layout.layout.as_str())); .push(widget::text::caption(layout.layout.as_str()));
content_list = content_list content_list = content_list
.push(applet::menu_button(group).on_press(Message::SetActiveLayout(id))); .push(applet::menu_button(group).on_press(Message::SetActiveLayout(id)));
@ -271,7 +281,7 @@ impl cosmic::Application for Window {
} }
fn subscription(&self) -> Subscription<Self::Message> { fn subscription(&self) -> Subscription<Self::Message> {
Subscription::batch(vec![ let mut subscriptions = vec![
rectangle_tracker_subscription(0).map(|e| Message::Rectangle(e.1)), rectangle_tracker_subscription(0).map(|e| Message::Rectangle(e.1)),
self.core self.core
.watch_config("com.system76.CosmicComp") .watch_config("com.system76.CosmicComp")
@ -285,7 +295,23 @@ impl cosmic::Application for Window {
} }
Message::CompConfig(Box::new(update.config)) Message::CompConfig(Box::new(update.config))
}), }),
]) ];
subscriptions.push(if let Some(connection) = &self.wayland_connection {
wayland::subscription(connection.clone()).map(Message::Wayland)
} else {
iced::event::listen_with(|evt, _, _| match evt {
iced::Event::PlatformSpecific(iced::event::PlatformSpecific::Wayland(evt)) => {
if let WaylandEvent::Output(OutputEvent::Created(_), output) = evt {
if let Some(backend) = output.backend().upgrade() {
return Some(Message::WaylandConnection(backend));
}
}
None
}
_ => None,
})
});
Subscription::batch(subscriptions)
} }
fn style(&self) -> Option<cosmic::iced::theme::Style> { fn style(&self) -> Option<cosmic::iced::theme::Style> {
@ -293,9 +319,8 @@ impl cosmic::Application for Window {
} }
} }
impl Window { impl Window {
fn update_xkb(&self) -> Vec<ActiveLayout> { fn update_xkb(&self, xkb: &XkbConfig) -> Vec<ActiveLayout> {
let mut active_layouts = Vec::new(); let mut active_layouts = Vec::new();
let xkb = &self.comp_config.xkb_config;
let layouts = xkb.layout.split_terminator(','); let layouts = xkb.layout.split_terminator(',');

View file

@ -0,0 +1,157 @@
use cctk::{
cosmic_protocols::keyboard_layout::v1::client::zcosmic_keyboard_layout_v1::ZcosmicKeyboardLayoutV1,
keyboard_layout::{KeyboardLayoutHandler, KeyboardLayoutState},
sctk::{
self,
registry::{ProvidesRegistryState, RegistryState},
seat::{Capability, SeatHandler, SeatState},
},
wayland_client::{
Connection, QueueHandle, delegate_noop,
globals::registry_queue_init,
protocol::{wl_keyboard, wl_seat},
},
};
use cosmic::iced;
use futures::{SinkExt, channel::mpsc, executor::block_on};
use std::{hash::Hash, thread};
#[derive(Clone, Debug)]
pub enum Event {
KeyboardLayout(ZcosmicKeyboardLayoutV1),
Group(usize),
}
pub fn subscription(connection: Connection) -> iced::Subscription<Event> {
#[derive(Clone)]
struct WaylandSubscription(Connection);
impl Hash for WaylandSubscription {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.backend().display_id().hash(state);
}
}
iced::Subscription::run_with(
WaylandSubscription(connection),
|WaylandSubscription(connection)| {
let connection = connection.clone();
iced::stream::channel(8, move |sender| async move {
thread::spawn(move || thread(connection, sender));
})
},
)
}
struct Keyboard {
seat: wl_seat::WlSeat,
keyboard_layout: ZcosmicKeyboardLayoutV1,
}
impl Drop for Keyboard {
fn drop(&mut self) {
self.keyboard_layout.destroy();
}
}
struct AppData {
seat_state: SeatState,
registry_state: RegistryState,
keyboard_layout_state: KeyboardLayoutState,
keyboard: Option<Keyboard>,
sender: mpsc::Sender<Event>,
}
impl KeyboardLayoutHandler for AppData {
fn group(
&mut self,
_conn: &Connection,
_qh: &QueueHandle<Self>,
_keyboard: &wl_keyboard::WlKeyboard,
_keyboard_layout: &ZcosmicKeyboardLayoutV1,
group: u32,
) {
let _ = block_on(self.sender.send(Event::Group(group as usize)));
}
}
impl ProvidesRegistryState for AppData {
fn registry(&mut self) -> &mut RegistryState {
&mut self.registry_state
}
sctk::registry_handlers![SeatState,];
}
impl SeatHandler for AppData {
fn seat_state(&mut self) -> &mut SeatState {
&mut self.seat_state
}
fn new_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, _: wl_seat::WlSeat) {}
fn new_capability(
&mut self,
_conn: &Connection,
qh: &QueueHandle<Self>,
seat: wl_seat::WlSeat,
capability: Capability,
) {
if capability == Capability::Keyboard && self.keyboard.is_none() {
let keyboard = seat.get_keyboard(qh, ());
let keyboard_layout = self
.keyboard_layout_state
.get_keyboard_layout(&keyboard, qh);
keyboard.release();
if let Some(keyboard_layout) = keyboard_layout {
let _ = block_on(
self.sender
.send(Event::KeyboardLayout(keyboard_layout.clone())),
);
self.keyboard = Some(Keyboard {
seat,
keyboard_layout,
});
} else {
keyboard.release();
}
}
}
fn remove_capability(
&mut self,
_conn: &Connection,
_: &QueueHandle<Self>,
seat: wl_seat::WlSeat,
_capability: Capability,
) {
self.keyboard.take_if(|x| x.seat == seat);
}
fn remove_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, seat: wl_seat::WlSeat) {
self.keyboard.take_if(|x| x.seat == seat);
}
}
fn thread(conn: Connection, sender: mpsc::Sender<Event>) {
let (globals, mut event_queue) = registry_queue_init(&conn).unwrap();
let qh = event_queue.handle();
let registry_state = RegistryState::new(&globals);
let seat_state = SeatState::new(&globals, &qh);
let keyboard_layout_state = KeyboardLayoutState::new(&registry_state, &qh);
let mut app_data = AppData {
seat_state,
registry_state,
keyboard_layout_state,
keyboard: None,
sender,
};
loop {
event_queue.blocking_dispatch(&mut app_data).unwrap();
}
}
sctk::delegate_registry!(AppData);
sctk::delegate_seat!(AppData);
cctk::delegate_keyboard_layout!(AppData);
delegate_noop!(AppData: ignore wl_keyboard::WlKeyboard);

View file

@ -248,17 +248,23 @@ impl cosmic::Application for Minimize {
} }
Message::OpenOverflowPopup => { Message::OpenOverflowPopup => {
if let Some(id) = self.overflow_popup.take() { if let Some(id) = self.overflow_popup.take() {
return destroy_popup(id); return cosmic::surface::surface_task(cosmic::surface::action::destroy_popup(
id,
));
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
let pos = self.max_icon_count().unwrap_or_default(); let pos = app.max_icon_count().unwrap_or_default();
self.overflow_popup = Some(new_id); app.overflow_popup = Some(new_id);
let icon_size = self.core.applet.suggested_size(true).0 as u32 let icon_size = app.core.applet.suggested_size(true).0 as u32
+ 2 * self.core.applet.suggested_padding(true).1 as u32; + 2 * app.core.applet.suggested_padding(true).1 as u32;
let spacing = self.core.system_theme().cosmic().space_xxs() as u32; let spacing = app.core.system_theme().cosmic().space_xxs() as u32;
let major_axis_len = (icon_size + spacing) * (pos.saturating_sub(1) as u32); let major_axis_len =
let rectangle = match self.core.applet.anchor { (icon_size + spacing) * (pos.saturating_sub(1) as u32);
let rectangle = match app.core.applet.anchor {
PanelAnchor::Top | PanelAnchor::Bottom => iced::Rectangle { PanelAnchor::Top | PanelAnchor::Bottom => iced::Rectangle {
x: major_axis_len as i32, x: major_axis_len as i32,
y: 0, y: 0,
@ -272,16 +278,18 @@ impl cosmic::Application for Minimize {
height: icon_size as i32, height: icon_size as i32,
}, },
}; };
let mut popup_settings = self.core.applet.get_popup_settings( let mut popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
popup_settings.positioner.anchor_rect = rectangle; popup_settings.positioner.anchor_rect = rectangle;
popup_settings
return get_popup(popup_settings); },
None,
));
} }
} }
Message::CloseOverflowPopup => todo!(), Message::CloseOverflowPopup => todo!(),

View file

@ -0,0 +1,6 @@
cancel = Annuller
connected = Forbundet
connect = Opret forbindelse
wifi = Wi-Fi
identity = Identitet
network = Netværk

View file

@ -0,0 +1,2 @@
cancel = Cancel
connected = Connected

View file

@ -9,7 +9,7 @@ mac = MAC
megabits-per-second = Mbps megabits-per-second = Mbps
connected = Connecté connected = Connecté
connecting = Connexion connecting = Connexion
connect = Connecter connect = Se connecter
cancel = Annuler cancel = Annuler
settings = Paramètres réseaux... settings = Paramètres réseaux...
visible-wireless-networks = Réseaux Wi-Fi disponibles visible-wireless-networks = Réseaux Wi-Fi disponibles

View file

@ -0,0 +1,24 @@
cancel = Cancelar
connected = Conectado
connect = Conectar
identity = Identidade
wifi = Wi-Fi
network = Rede
airplane-mode = Modo avión
airplane-mode-on = O modo avión está activo
turn-off-airplane-mode = Desactívao para activar a wifi, o Bluetooth e a banda larga móbil.
ipv4 = Dirección IPv4
ipv6 = Dirección IPv6
mac = MAC
megabits-per-second = Mbps
gigabits-per-second = Gbps
terabits-per-second = Tbps
connecting = Conectando
settings = Axustes da rede...
visible-wireless-networks = Redes sen fíos visibles
vpn-connections = Conexións VPN
enter-password = Introduce o contrasinal ou a chave de cifrado
router-wps-button = Tamén podes conectarte premendo o botón "WPS" do router
unable-to-connect = Non se puido conectar á rede
check-wifi-connection = Asegúrate de que a wifi está conectada a Internet e de que o contrasinal é correcto
reset = Restablecer

View file

@ -0,0 +1 @@
cancel = ᱵᱟᱹᱛᱤᱞ

View file

@ -8,7 +8,7 @@ ipv4 = IPv4 位址
ipv6 = IPv6 位址 ipv6 = IPv6 位址
mac = MAC mac = MAC
megabits-per-second = Mbps megabits-per-second = Mbps
connected = 已經連線 connected = 已連線
connecting = 連線中 connecting = 連線中
connect = 連線 connect = 連線
cancel = 取消 cancel = 取消

View file

@ -0,0 +1,19 @@
hours-ago =
{ $duration ->
[0] Xusto agora
[one] Hai 1 hora
*[other] Hai { $duration } horas
}
minutes-ago =
{ $duration ->
[0] Xusto agora
[one] Hai 1 minuto
*[other] Hai { $duration } minutos
}
show-less = Mostrar menos
show-more = Mostrar { $more } máis
clear-group = Limpar grupo
clear-all = Limpar todas as notificacións
do-not-disturb = Non Molestar
notification-settings = Configuración das notificacións...
no-notifications = Sen notificacións

View file

@ -157,18 +157,23 @@ impl cosmic::Application for Notifications {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
return destroy_popup(p); return destroy_popup(p);
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
let popup_settings = self.core.applet.get_popup_settings( let popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
popup_settings
return get_popup(popup_settings); },
None,
));
} }
} }
Message::DoNotDisturb(b) => { Message::DoNotDisturb(b) => {

View file

@ -2,3 +2,35 @@ cancel = Cancel·lar
confirm = Confirmar confirm = Confirmar
restart = Reinicia restart = Reinicia
suspend = Suspèn suspend = Suspèn
confirm-button =
{ $action ->
[restart] { restart }
[suspend] { suspend }
[shutdown] Apaga
[log-out] { log-out }
*[other] { confirm }
}
power = Energia
confirm-body =
{ $action ->
[restart] L'ordinador es reiniciarà
[suspend] L'ordinador se suspendrà
[shutdown] L'ordinador s'apagarà
[lock-screen] La pantalla es bloquejarà
[log-out] La sessió es tancarà
*[other] L'acció seleccionada es durà a terme
} automàticament d'aquí a { $countdown } segons.
lock-screen = Bloqueja la pantalla
shutdown = Apaga
log-out = Tanca la sessió
log-out-shortcut = Súper + Majús + Esc
settings = Configuració...
lock-screen-shortcut = Súper + Esc
confirm-title =
¿{ $action ->
[restart] { restart }
[suspend] { suspend }
[shutdown] { shutdown }
[log-out] Voleu tancar totes les aplicacions i tancar la sessió
*[other] Voleu dur a terme l'acció seleccionada
}?

View file

@ -0,0 +1,36 @@
power = Enerxía
settings = Axustes...
lock-screen = Pantalla de Bloqueo
lock-screen-shortcut = Super + Esc
log-out = Pechar Sesión
log-out-shortcut = Super + Maiús + Esc
suspend = Suspender
restart = Reiniciar
shutdown = Apagar
confirm = Confirmar
cancel = Cancelar
confirm-button =
{ $action ->
[restart] { restart }
[suspend] { suspend }
[shutdown] Apagar
[log-out] { log-out }
*[other] { confirm }
}
confirm-title =
{ $action ->
[restart] { restart } agora?
[suspend] { suspend } agora?
[shutdown] { shutdown } agora?
[log-out] Pechar todas as aplicacións e pechar a sesión agora?
*[other] Aplicar a acción seleccionada agora
}
confirm-body =
O sistema { $action ->
[restart] reiniciarase
[suspend] suspenderase
[shutdown] apagarase
[lock-screen] bloqueará a pantalla
[log-out] pechará a sesión
*[other] aplicará a acción seleccionada
} automaticamente en { $countdown } segundos.

View file

@ -115,20 +115,27 @@ impl cosmic::Application for Power {
match message { match message {
Message::TogglePopup => { Message::TogglePopup => {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
return destroy_popup(p); return cosmic::surface::surface_task(cosmic::surface::action::destroy_popup(
p,
));
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Power| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
let popup_settings = self.core.applet.get_popup_settings( let popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
popup_settings
return get_popup(popup_settings); },
None,
));
} }
} }
Message::OpenSettings => { Message::OpenSettings => {

View file

@ -246,38 +246,49 @@ impl cosmic::Application for App {
if let Some(popup_id) = self.popup.take() { if let Some(popup_id) = self.popup.take() {
cmds.push(destroy_popup(popup_id)); cmds.push(destroy_popup(popup_id));
} }
let popup_id = self.next_popup_id();
let i = self.menus.keys().position(|&i| i == id).unwrap(); let popup_task =
let (i, parent) = self cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let popup_id = app.next_popup_id();
let i = app.menus.keys().position(|&i| i == id).unwrap();
let (i, parent) = app
.overflow_index() .overflow_index()
.and_then(|overflow_i| { .and_then(|overflow_i| {
if overflow_i <= i { if overflow_i <= i {
Some(i - overflow_i).zip(self.overflow_popup) Some(i - overflow_i).zip(app.overflow_popup)
} else { } else {
Some((i, self.core.main_window_id().unwrap())) Some((i, app.core.main_window_id().unwrap()))
} }
}) })
.unwrap_or((i, self.core.main_window_id().unwrap())); .unwrap_or((i, app.core.main_window_id().unwrap()));
let mut popup_settings = self let mut popup_settings = app
.core .core
.applet .applet
.get_popup_settings(parent, popup_id, None, None, None); .get_popup_settings(parent, popup_id, None, None, None);
self.popup = Some(popup_id); app.popup = Some(popup_id);
if matches!( if matches!(
self.core.applet.anchor, app.core.applet.anchor,
PanelAnchor::Left | PanelAnchor::Right PanelAnchor::Left | PanelAnchor::Right
) { ) {
let suggested_size = self.core.applet.suggested_size(false).1 let suggested_size = app.core.applet.suggested_size(false).1
+ 2 * self.core.applet.suggested_padding(false).1; + 2 * app.core.applet.suggested_padding(false).1;
popup_settings.positioner.anchor_rect.y = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.y =
i as i32 * suggested_size as i32;
} else { } else {
let suggested_size = self.core.applet.suggested_size(false).0 let suggested_size = app.core.applet.suggested_size(false).0
+ 2 * self.core.applet.suggested_padding(false).1; + 2 * app.core.applet.suggested_padding(false).1;
popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.x =
i as i32 * suggested_size as i32;
} }
cmds.push(get_popup(popup_settings)); popup_settings
},
None,
));
cmds.push(popup_task);
return app::Task::batch(cmds); return app::Task::batch(cmds);
} else if let Some(popup_id) = self.popup { } else if let Some(popup_id) = self.popup {
self.menus[&id].closed(); self.menus[&id].closed();
@ -339,39 +350,49 @@ impl cosmic::Application for App {
} else { } else {
return Task::none(); return Task::none();
} }
let popup_id = self.next_popup_id(); let popup_task = cosmic::surface::surface_task(cosmic::surface::action::app_popup(
let i = self.menus.keys().position(|&i| i == id).unwrap(); |_| Default::default(),
move |app: &mut Self| {
let popup_id = app.next_popup_id();
let i = app.menus.keys().position(|&i| i == id).unwrap();
let (i, parent) = self let (i, parent) = app
.overflow_index() .overflow_index()
.and_then(|overflow_i| { .and_then(|overflow_i| {
if overflow_i <= i { if overflow_i <= i {
Some(i - overflow_i).zip(self.overflow_popup) Some(i - overflow_i).zip(app.overflow_popup)
} else { } else {
Some((i, self.core.main_window_id().unwrap())) Some((i, app.core.main_window_id().unwrap()))
} }
}) })
.unwrap_or((i, self.core.main_window_id().unwrap())); .unwrap_or((i, app.core.main_window_id().unwrap()));
let mut popup_settings = self let mut popup_settings = app
.core .core
.applet .applet
.get_popup_settings(parent, popup_id, None, None, None); .get_popup_settings(parent, popup_id, None, None, None);
self.popup = Some(popup_id); app.popup = Some(popup_id);
if matches!( if matches!(
self.core.applet.anchor, app.core.applet.anchor,
PanelAnchor::Left | PanelAnchor::Right PanelAnchor::Left | PanelAnchor::Right
) { ) {
let suggested_size = self.core.applet.suggested_size(true).1 let suggested_size = app.core.applet.suggested_size(true).1
+ 2 * self.core.applet.suggested_padding(true).1; + 2 * app.core.applet.suggested_padding(true).1;
popup_settings.positioner.anchor_rect.y = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.y =
i as i32 * suggested_size as i32;
} else { } else {
let suggested_size = self.core.applet.suggested_size(true).0 let suggested_size = app.core.applet.suggested_size(true).0
+ 2 * self.core.applet.suggested_padding(true).0; + 2 * app.core.applet.suggested_padding(true).0;
popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.x =
i as i32 * suggested_size as i32;
} }
cmds.push(get_popup(popup_settings)); popup_settings
},
None,
));
cmds.push(popup_task);
Task::batch(cmds) Task::batch(cmds)
} }
Msg::WheelScrolled(delta) => { Msg::WheelScrolled(delta) => {
@ -399,9 +420,13 @@ impl cosmic::Application for App {
return destroy_popup(popup_id); return destroy_popup(popup_id);
} else if let Some(overflow_index) = self.overflow_index() { } else if let Some(overflow_index) = self.overflow_index() {
// If we don't have an overflow, create it // If we don't have an overflow, create it
let popup_id = self.next_popup_id(); let popup_task =
let mut popup_settings = self.core.applet.get_popup_settings( cosmic::surface::surface_task(cosmic::surface::action::app_popup(
self.core.main_window_id().unwrap(), |_| Default::default(),
move |app: &mut Self| {
let popup_id = app.next_popup_id();
let mut popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
popup_id, popup_id,
None, None,
None, None,
@ -410,22 +435,26 @@ impl cosmic::Application for App {
popup_settings.close_with_children = false; popup_settings.close_with_children = false;
if matches!( if matches!(
self.core.applet.anchor, app.core.applet.anchor,
PanelAnchor::Left | PanelAnchor::Right PanelAnchor::Left | PanelAnchor::Right
) { ) {
let suggested_size = self.core.applet.suggested_size(true).1 let suggested_size = app.core.applet.suggested_size(true).1
+ 2 * self.core.applet.suggested_padding(true).1; + 2 * app.core.applet.suggested_padding(true).1;
popup_settings.positioner.anchor_rect.y = popup_settings.positioner.anchor_rect.y =
overflow_index as i32 * suggested_size as i32; overflow_index as i32 * suggested_size as i32;
} else { } else {
let suggested_size = self.core.applet.suggested_size(true).0 let suggested_size = app.core.applet.suggested_size(true).0
+ 2 * self.core.applet.suggested_padding(true).0; + 2 * app.core.applet.suggested_padding(true).0;
popup_settings.positioner.anchor_rect.x = popup_settings.positioner.anchor_rect.x =
overflow_index as i32 * suggested_size as i32; overflow_index as i32 * suggested_size as i32;
} }
self.overflow_popup = Some(popup_id); app.overflow_popup = Some(popup_id);
return get_popup(popup_settings); popup_settings
},
None,
));
return popup_task;
} else { } else {
return Task::none(); return Task::none();
} }
@ -444,34 +473,41 @@ impl cosmic::Application for App {
} else { } else {
return Task::none(); return Task::none();
} }
let Some(i) = self.overflow_index() else {
let popup_id = self.next_popup_id(); return Task::batch(cmds);
let mut popup_settings = self.core.applet.get_popup_settings( };
self.core.main_window_id().unwrap(), let popup_task = cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let popup_id = app.next_popup_id();
let mut popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
popup_id, popup_id,
None, None,
None, None,
None, None,
); );
self.popup = Some(popup_id); app.popup = Some(popup_id);
let Some(i) = self.overflow_index() else {
return Task::batch(cmds);
};
if matches!( if matches!(
self.core.applet.anchor, app.core.applet.anchor,
PanelAnchor::Left | PanelAnchor::Right PanelAnchor::Left | PanelAnchor::Right
) { ) {
let suggested_size = self.core.applet.suggested_size(false).1 let suggested_size = app.core.applet.suggested_size(false).1
+ 2 * self.core.applet.suggested_padding(false).1; + 2 * app.core.applet.suggested_padding(false).1;
popup_settings.positioner.anchor_rect.y = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.y =
i as i32 * suggested_size as i32;
} else { } else {
let suggested_size = self.core.applet.suggested_size(false).0 let suggested_size = app.core.applet.suggested_size(false).0
+ 2 * self.core.applet.suggested_padding(false).1; + 2 * app.core.applet.suggested_padding(false).1;
popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.x =
i as i32 * suggested_size as i32;
} }
cmds.push(get_popup(popup_settings)); popup_settings
},
None,
));
cmds.push(popup_task);
Task::batch(cmds) Task::batch(cmds)
} }
} }
@ -656,7 +692,7 @@ fn menu_icon_button<'a>(
.class(if symbolic { .class(if symbolic {
cosmic::theme::Svg::Custom(std::rc::Rc::new(|theme| { cosmic::theme::Svg::Custom(std::rc::Rc::new(|theme| {
cosmic::iced::widget::svg::Style { cosmic::iced::widget::svg::Style {
color: Some(theme.cosmic().background(false).on.into()), color: Some(theme.cosmic().background(theme.transparent).on.into()),
} }
})) }))
} else { } else {

View file

@ -232,7 +232,11 @@ fn layout_view(layout: &Layout, expanded: Option<i32>) -> cosmic::Element<'_, Ms
} }
if let Some(icon_data) = i.icon_data() { if let Some(icon_data) = i.icon_data() {
let handle = iced::widget::image::Handle::from_bytes(icon_data.to_vec()); let handle = iced::widget::image::Handle::from_bytes(icon_data.to_vec());
children.insert(0, iced::widget::Image::new(handle).into()); let icon = iced::widget::Image::new(handle)
.width(iced::Length::Fixed(14.0))
.height(iced::Length::Fixed(14.0))
.content_fit(iced::core::ContentFit::Contain);
children.insert(0, icon.into());
} else if let Some(icon_name) = i.icon_name() { } else if let Some(icon_name) = i.icon_name() {
let icon = cosmic::widget::icon::from_name(icon_name) let icon = cosmic::widget::icon::from_name(icon_name)
.size(14) .size(14)

View file

@ -0,0 +1,2 @@
tile-windows = Organitza les finestres en mosaic automàticament
shortcuts = Dreceres

View file

@ -0,0 +1,20 @@
tile-windows = Dispoñer as xanelas en mosaico automaticamente
tile-current = Dispoñer en mosaico o espazo de traballo actual
shortcuts = Atallos
navigate-windows = Navergar polas xanelas
move-window = Mover a xanela
toggle-floating-window = Alternar xanela flotante
view-all-shortcuts = Ver todos os atallos...
active-hint = Indicador de foco activo
gaps = Espazos
floating-window-exceptions = Excepcións de xanelas flotantes...
window-management-settings = Axustes da xestión de xanelas...
all-workspaces = Todos os espazos de traballo
per-workspace = Por espazo de traballo
super = Super
shift = Maiús
arrow-keys = frechas
tiled = En mosaico
floating = Flotante
autotile-behavior = Organizar as xanelas en mosaico nos espazos de traballo
new-workspace = Comportamento dos novos espazos de traballo

View file

@ -3,9 +3,9 @@ tile-current = Huidig werkblad tegelen
shortcuts = Sneltoetsen shortcuts = Sneltoetsen
navigate-windows = Tussen vensters schakelen navigate-windows = Tussen vensters schakelen
move-window = Venster verplaatsen move-window = Venster verplaatsen
toggle-floating-window = Zet zwevende vensters aan/uit toggle-floating-window = Zweven aan- of uitzetten voor venster
view-all-shortcuts = Alle sneltoetsen bekijken… view-all-shortcuts = Alle sneltoetsen bekijken…
active-hint = Visuele hint actief venster active-hint = Vensterfocus-aanduiding
gaps = Ruimte rond getegelde vensters gaps = Ruimte rond getegelde vensters
floating-window-exceptions = Uitzonderingen voor zwevende vensters… floating-window-exceptions = Uitzonderingen voor zwevende vensters…
window-management-settings = Instellingen voor vensterbeheer… window-management-settings = Instellingen voor vensterbeheer…

View file

@ -147,17 +147,22 @@ impl cosmic::Application for Window {
return if let Some(p) = self.popup.take() { return if let Some(p) = self.popup.take() {
destroy_popup(p) destroy_popup(p)
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = Id::unique(); let new_id = Id::unique();
self.popup = Some(new_id); app.popup = Some(new_id);
let popup_settings = self.core.applet.get_popup_settings( let popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
Some((1, 1)), Some((1, 1)),
None, None,
None, None,
); );
popup_settings
get_popup(popup_settings) },
None,
));
}; };
} }
Message::PopupClosed(id) => { Message::PopupClosed(id) => {

View file

@ -0,0 +1 @@
datetime-settings = Configuració de data, hora i calendari...

View file

@ -0,0 +1 @@
datetime-settings = Axustes de data, hora e calendario...

View file

@ -521,14 +521,17 @@ impl cosmic::Application for Window {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
destroy_popup(p) destroy_popup(p)
} else { } else {
self.date_today = self.now.date(); return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
self.date_selected = self.date_today; |_| Default::default(),
|app: &mut Self| {
app.date_today = app.now.date();
app.date_selected = app.date_today;
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup = Some(new_id); app.popup = Some(new_id);
let mut popup_settings = self.core.applet.get_popup_settings( let mut popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
@ -539,7 +542,7 @@ impl cosmic::Application for Window {
y, y,
width, width,
height, height,
} = self.rectangle; } = app.rectangle;
popup_settings.positioner.anchor_rect = Rectangle::<i32> { popup_settings.positioner.anchor_rect = Rectangle::<i32> {
x: x.max(1.) as i32, x: x.max(1.) as i32,
y: y.max(1.) as i32, y: y.max(1.) as i32,
@ -548,8 +551,10 @@ impl cosmic::Application for Window {
}; };
popup_settings.positioner.size = None; popup_settings.positioner.size = None;
popup_settings
get_popup(popup_settings) },
None,
));
} }
} }
Message::Tick => { Message::Tick => {

View file

@ -0,0 +1 @@
cosmic-applet-workspaces = Espais de treball del COSMIC

View file

@ -0,0 +1 @@
cosmic-applet-workspaces = Espazos de traballo de COSMIC

View file

@ -203,11 +203,7 @@ impl cosmic::Application for IcedWorkspacesApplet {
let content = column!(content, space::horizontal().width(Length::Fixed(width))) let content = column!(content, space::horizontal().width(Length::Fixed(width)))
.align_x(Alignment::Center); .align_x(Alignment::Center);
let btn = button( let btn = button(content)
container(content)
.align_x(Alignment::Center)
.align_y(Alignment::Center),
)
.padding(if horizontal { .padding(if horizontal {
[0, self.core.applet.suggested_padding(true).1] [0, self.core.applet.suggested_padding(true).1]
} else { } else {

View file

@ -66,7 +66,7 @@ impl Button {
.class(if symbolic { .class(if symbolic {
cosmic::theme::Svg::Custom(std::rc::Rc::new(|theme| { cosmic::theme::Svg::Custom(std::rc::Rc::new(|theme| {
cosmic::iced::widget::svg::Style { cosmic::iced::widget::svg::Style {
color: Some(theme.cosmic().background(false).on.into()), color: Some(theme.cosmic().background(theme.transparent).on.into()),
} }
})) }))
} else { } else {

View file

@ -1 +1,2 @@
cosmic-app-list = Safata d'Aplicacions cosmic-app-list = Safata d'Aplicacions
cosmic-app-list-comment = Inicieu aplicacions ancorades i gestioneu les finestres obertes

View file

@ -1,4 +1,4 @@
cosmic-app-list = Panel aplikací cosmic-app-list = Oblast aplikací
cosmic-applet-a11y = Přístupnost cosmic-applet-a11y = Přístupnost
cosmic-applet-audio = Zvuk cosmic-applet-audio = Zvuk
cosmic-applet-battery = Napájení a baterie cosmic-applet-battery = Napájení a baterie
@ -8,7 +8,7 @@ cosmic-applet-minimize = Minimalizovaná okna
cosmic-applet-network = Síť cosmic-applet-network = Síť
cosmic-applet-notifications = Centrum oznámení cosmic-applet-notifications = Centrum oznámení
cosmic-applet-power = Uživatelská relace cosmic-applet-power = Uživatelská relace
cosmic-applet-status-area = Panel oznámení cosmic-applet-status-area = Oznamovací oblast
cosmic-applet-tiling = Dlaždicový režim oken cosmic-applet-tiling = Dlaždicový režim oken
cosmic-applet-time = Datum, čas a kalendář cosmic-applet-time = Datum, čas a kalendář
cosmic-applet-workspaces = Číslované pracovní plochy cosmic-applet-workspaces = Číslované pracovní plochy
@ -26,9 +26,9 @@ cosmic-applet-network-comment = Správa síťových připojení
cosmic-applet-network-keywords = COSMIC;Applet;Síť; cosmic-applet-network-keywords = COSMIC;Applet;Síť;
cosmic-applet-notifications-comment = Správa oznámení a režimu Nerušit cosmic-applet-notifications-comment = Správa oznámení a režimu Nerušit
cosmic-applet-notifications-keywords = COSMIC;Applet;Oznámení; cosmic-applet-notifications-keywords = COSMIC;Applet;Oznámení;
cosmic-applet-status-area-keywords = COSMIC;Applet;Aplikace;Indikátory;Oznámení;Notifikace;Panel;Status;Stav; cosmic-applet-status-area-keywords = COSMIC;Applet;Aplikace;Indikátory;Oznámení;Notifikace;Oblast;Status;Stav;
cosmic-app-list-comment = Správa otevřených oken a spouštění připnutých aplikací cosmic-app-list-comment = Správa otevřených oken a spouštění připnutých aplikací
cosmic-app-list-keywords = COSMIC;Applet;Aplikace;Panel;Seznam;Úloha;Úlohy;Lišta; cosmic-app-list-keywords = COSMIC;Applet;Aplikace;Oblast;Seznam;Úloha;Úlohy;Lišta;
cosmic-applet-a11y-comment = Konfigurace nastavení přístupnosti z panelu cosmic-applet-a11y-comment = Konfigurace nastavení přístupnosti z panelu
cosmic-applet-a11y-keywords = COSMIC;Applet;Přístupnost;A11y;Obrazovka;Obrazovky;Čtečka;Lupa;Kontrast;Barva;Barvy; cosmic-applet-a11y-keywords = COSMIC;Applet;Přístupnost;A11y;Obrazovka;Obrazovky;Čtečka;Lupa;Kontrast;Barva;Barvy;
cosmic-applet-audio-comment = Výběr zvukového zařízení, ovládání hlasitosti a ovládání médií MPRIS cosmic-applet-audio-comment = Výběr zvukového zařízení, ovládání hlasitosti a ovládání médií MPRIS
@ -43,9 +43,9 @@ cosmic-applet-time-keywords = COSMIC;Applet;Datumy;Časy;Kalendář;Hodiny;
cosmic-applet-workspaces-comment = Přepínání mezi číslovanými pracovními plochami v panelu cosmic-applet-workspaces-comment = Přepínání mezi číslovanými pracovními plochami v panelu
cosmic-applet-workspaces-keywords = COSMIC;Applet;Pracovní;Plocha;Plochy; cosmic-applet-workspaces-keywords = COSMIC;Applet;Pracovní;Plocha;Plochy;
cosmic-panel-app-button-comment = Přístup ke knihovně pro spouštění nainstalovaných aplikací cosmic-panel-app-button-comment = Přístup ke knihovně pro spouštění nainstalovaných aplikací
cosmic-panel-app-button-keywords = COSMIC;Applet;Aplikace;Knihovna;Panel;Spuštění;Spouštění; cosmic-panel-app-button-keywords = COSMIC;Applet;Aplikace;Knihovna;Oblast;Spuštění;Spouštění;
cosmic-panel-launcher-button-comment = Přístup ke spouštěči pro vyhledávání aplikací a spouštění příkazů cosmic-panel-launcher-button-comment = Přístup ke spouštěči pro vyhledávání aplikací a spouštění příkazů
cosmic-panel-launcher-button-keywords = COSMIC;Applet;Spouštěč;Vyhledávání;Příkazy; cosmic-panel-launcher-button-keywords = COSMIC;Applet;Spouštěč;Vyhledávání;Příkazy;
cosmic-panel-workspaces-button-comment = Přístup k přehledu pracovních ploch pro jejich správu a přepínání cosmic-panel-workspaces-button-comment = Přístup k přehledu pracovních ploch pro jejich správu a přepínání
cosmic-panel-workspaces-button-keywords = COSMIC;Applet;Pracovní;Plocha;Plochy;Přehled; cosmic-panel-workspaces-button-keywords = COSMIC;Applet;Pracovní;Plocha;Plochy;Přehled;
cosmic-applet-status-area-comment = Indikátory aplikací, které mohou exportovat menu do panelu cosmic-applet-status-area-comment = Ikony aplikací, které mohou zobrazovat nabídky na panelu

View file

@ -0,0 +1,51 @@
cosmic-app-list = Programbakke
cosmic-app-list-comment = Start fastgjorte apps og håndter åbne vinduer
cosmic-app-list-keywords = COSMIC;Applet;App;Statusområde;Liste;Opgave;Bjælke;
cosmic-applet-a11y = Tilgængelighed
cosmic-applet-a11y-comment = Konfigurer tilgængelighedsindstillinger fra panelet
cosmic-applet-a11y-keywords = COSMIC;Applet;Tilgængelighed;A11y;Skærm;Skærmlæser;Forstørrelsesglas;Kontrast;Farve;
cosmic-applet-audio = Lyd
cosmic-applet-audio-comment = Valg af lydenhed, lydstyrkekontrol og MPRIS-mediekontrol
cosmic-applet-audio-keywords = COSMIC;Applet;Lyd;Lyd;MPRIS;
cosmic-applet-battery = Strøm og batteri
cosmic-applet-battery-comment = Strømtilstande og strømspareindstillinger
cosmic-applet-battery-keywords = COSMIC;Applet;Strøm;Batteri;
cosmic-applet-bluetooth = Bluetooth
cosmic-applet-bluetooth-comment = Administrer Bluetooth-enheder
cosmic-applet-bluetooth-keywords = COSMIC;Applet;Bluetooth;
cosmic-applet-input-sources = Inputkilder
cosmic-applet-input-sources-comment = Skift mellem inputkilder
cosmic-applet-input-sources-keywords = COSMIC;Applet;Input;Kilde;
cosmic-applet-minimize = Minimerede vinduer
cosmic-applet-minimize-comment = Administrer minimerede vinduer
cosmic-applet-minimize-keywords = COSMIC;Applet;Minimer;
cosmic-applet-network = Netværk
cosmic-applet-network-comment = Administrer netværksforbindelser
cosmic-applet-network-keywords = COSMIC;Applet;Netværk;
cosmic-applet-notifications = Notifikationscenter
cosmic-applet-notifications-comment = Administrer notifikationer og Forstyr ikke
cosmic-applet-notifications-keywords = COSMIC;Applet;Notifikation;
cosmic-applet-power = Brugersession
cosmic-applet-power-comment = Låseskærm, log ud, dvale, genstart og luk ned
cosmic-applet-power-keywords = COSMIC;Applet;Bruger;Session;Lås;Log;Genstart;Luk ned;Dvale;
cosmic-applet-status-area = Notifikationsområde
cosmic-applet-status-area-comment = Programindikatorer, som kan eksportere menuer til panelet
cosmic-applet-status-area-keywords = COSMIC;Applet;App;Indikator;Notifikation;Statusområde;Status;
cosmic-applet-tiling = Opdeling
cosmic-applet-tiling-comment = Administrer aktiv hint samt automatisk opdeling for aktuelt og pr. arbejdsområde
cosmic-applet-tiling-keywords = COSMIC;Applet;Opdeling;Hint;Arbejdsområde;
cosmic-applet-time = Dato, tid og kalender
cosmic-applet-time-comment = Vis den aktuelle tid i panelet med en kalenderpopup
cosmic-applet-time-keywords = COSMIC;Applet;Dato;Tid;Kalender;
cosmic-applet-workspaces = Nummererede arbejdsområder
cosmic-applet-workspaces-comment = Skift mellem nummererede arbejdsområder i panelet
cosmic-applet-workspaces-keywords = COSMIC;Applet;Arbejdsområde;
cosmic-panel-app-button = Appbibliotek-knap
cosmic-panel-app-button-comment = Åbn applikationsbiblioteket for at starte installerede programmer
cosmic-panel-app-button-keywords = COSMIC;Applet;App;Bibliotek;Statusområde;
cosmic-panel-launcher-button = Starterknap
cosmic-panel-launcher-button-keywords = COSMIC;Applet;Starter;Kører;
cosmic-panel-workspaces-button = Arbejdsområdeknap
cosmic-panel-workspaces-button-comment = Åbn oversigten over arbejdsområder for at administrere og skifte mellem arbejdsområder
cosmic-panel-workspaces-button-keywords = COSMIC;Applet;Arbejdsområde;Oversigt;
cosmic-panel-launcher-button-comment = Åbn starteren for at søge efter programmer og køre kommandoer

View file

@ -37,7 +37,7 @@ cosmic-app-list-comment = Angeheftete Apps starten und geöffnete Fenster verwal
cosmic-applet-a11y-comment = Einstellungen für Barrierefreiheit über das Panel konfigurieren cosmic-applet-a11y-comment = Einstellungen für Barrierefreiheit über das Panel konfigurieren
cosmic-applet-power-comment = Bildschirm sperren, abmelden, anhalten, neu starten und herunterfahren cosmic-applet-power-comment = Bildschirm sperren, abmelden, anhalten, neu starten und herunterfahren
cosmic-applet-status-area = Benachrichtigungsübersicht cosmic-applet-status-area = Benachrichtigungsübersicht
cosmic-applet-time-comment = Aktuelle Uhrzeit im Fenster mit einem Kalender-Popup anzeigen cosmic-applet-time-comment = Aktuelle Uhrzeit im Panel mit einem Kalender-Popup anzeigen
cosmic-panel-app-button-comment = Öffne die Anwendungsbibliothek, um installierte Anwendungen zu starten cosmic-panel-app-button-comment = Öffne die Anwendungsbibliothek, um installierte Anwendungen zu starten
cosmic-panel-launcher-button-comment = Öffne den Starter, um nach Anwendungen zu suchen und Befehle auszuführen cosmic-panel-launcher-button-comment = Öffne den Starter, um nach Anwendungen zu suchen und Befehle auszuführen
cosmic-panel-workspaces-button-comment = Öffne die Arbeitsflächenübersicht, um Arbeitsflächen zu verwalten und zwischen ihnen zu wechseln cosmic-panel-workspaces-button-comment = Öffne die Arbeitsflächenübersicht, um Arbeitsflächen zu verwalten und zwischen ihnen zu wechseln

View file

@ -0,0 +1,51 @@
cosmic-app-list = App Tray
cosmic-app-list-comment = Launch pinned apps and manage open windows
cosmic-app-list-keywords = COSMIC;Applet;App;Tray;List;Task;Bar;
cosmic-applet-a11y = Accessibility
cosmic-applet-a11y-comment = Configure accessibility settings from the panel
cosmic-applet-a11y-keywords = COSMIC;Applet;Accessibility;A11y;Screen;Reader;Magnifier;Contrast;Colour;
cosmic-applet-audio = Sound
cosmic-applet-audio-comment = Audio device selection, volume control, and MPRIS media controls
cosmic-applet-audio-keywords = COSMIC;Applet;Sound;Audio;MPRIS;
cosmic-applet-battery = Power & Battery
cosmic-applet-battery-comment = Power modes and power saving options
cosmic-applet-battery-keywords = COSMIC;Applet;Power;Battery;
cosmic-applet-bluetooth = Bluetooth
cosmic-applet-bluetooth-comment = Manage Bluetooth devices
cosmic-applet-bluetooth-keywords = COSMIC;Applet;Bluetooth;
cosmic-applet-input-sources = Input Sources
cosmic-applet-input-sources-comment = Switch between input sources
cosmic-applet-input-sources-keywords = COSMIC;Applet;Input;Source;
cosmic-applet-minimize = Minimised Windows
cosmic-applet-minimize-comment = Manage minimised windows
cosmic-applet-minimize-keywords = COSMIC;Applet;Minimise;
cosmic-applet-network = Network
cosmic-applet-network-comment = Manage network connections
cosmic-applet-network-keywords = COSMIC;Applet;Network;
cosmic-applet-notifications = Notifications Centre
cosmic-applet-notifications-comment = Manage notifications and Do Not Disturb
cosmic-applet-notifications-keywords = COSMIC;Applet;Notification;
cosmic-applet-power = User Session
cosmic-applet-power-comment = Lock screen, log out, suspend, reboot, and shutdown
cosmic-applet-power-keywords = COSMIC;Applet;User;Session;Lock;Log out;Reboot;Shutdown;Suspend;
cosmic-applet-status-area = Notifications Tray
cosmic-applet-status-area-comment = Application indicators which may export menus to the panel
cosmic-applet-status-area-keywords = COSMIC;Applet;App;Indicator;Notification;Tray;Status;
cosmic-applet-tiling = Tiling
cosmic-applet-tiling-comment = Manage the active hint, current & per-workspace auto-tiling
cosmic-applet-tiling-keywords = COSMIC;Applet;Tiling;Hint;Workspace;
cosmic-applet-time = Date, Time & Calendar
cosmic-applet-time-comment = Display the current time in the panel with a calendar popup
cosmic-applet-time-keywords = COSMIC;Applet;Date;Time;Calendar;
cosmic-applet-workspaces = Numbered Workspaces
cosmic-applet-workspaces-comment = Switch between numbered workspaces in the panel
cosmic-applet-workspaces-keywords = COSMIC;Applet;Workspace;
cosmic-panel-app-button = App Library Button
cosmic-panel-app-button-comment = Open the application library for launching installed applications
cosmic-panel-app-button-keywords = COSMIC;Applet;App;Library;Tray;
cosmic-panel-launcher-button = Launcher Button
cosmic-panel-launcher-button-comment = Open the launcher to search applications and run commands
cosmic-panel-launcher-button-keywords = COSMIC;Applet;Launcher;Runner;
cosmic-panel-workspaces-button = Workspaces Button
cosmic-panel-workspaces-button-comment = Open the workspaces overview to manage and switch workspaces
cosmic-panel-workspaces-button-keywords = COSMIC;Applet;Workspace;Overview;

View file

@ -0,0 +1,5 @@
cosmic-app-list = نوار برنامه‌ها
cosmic-applet-a11y = دسترسی‌پذیری
cosmic-applet-audio = صدا
cosmic-applet-bluetooth = بلوتوث
cosmic-applet-bluetooth-comment = مدیریت دستگاه‌های بلوتوث

View file

@ -0,0 +1,51 @@
cosmic-app-list = Bandexa de aplicacións
cosmic-app-list-comment = Inicia as aplicacións fixadas e xestiona as xanelas abertas
cosmic-app-list-keywords = COSMIC;Miniaplicación;Aplicación;Bandexa;Lista;Tarefa;Barra;
cosmic-applet-a11y = Accesibilidade
cosmic-applet-a11y-comment = Configurar os axustes de accesibilidade dende o panel
cosmic-applet-a11y-keywords = COSMIC;Miniaplicación;Accesibilidade;A11y;Pantalla;Lector;Lupa;Contraste;Cor;
cosmic-applet-audio = Son
cosmic-applet-audio-comment = Selección do dispositivo de son, control do volume e controis multimedia MPRIS
cosmic-applet-audio-keywords = COSMIC;Miniaplicación;Son;Audio;MPRIS;
cosmic-applet-battery = Enerxía e Batería
cosmic-applet-battery-comment = Modos de enerxía e opcións de aforro enerxético
cosmic-applet-battery-keywords = COSMIC;Miniaplicación;Enerxía;Batería;
cosmic-applet-bluetooth = Bluetooth
cosmic-applet-bluetooth-comment = Xestionar dispositivos Bluetooth
cosmic-applet-bluetooth-keywords = COSMIC;Miniaplicación;Bluetooth;
cosmic-applet-input-sources = Fontes de Entrada
cosmic-applet-input-sources-comment = Cambiar entre fontes de entrada
cosmic-applet-input-sources-keywords = COSMIC;Miniaplicación;Entrada;Fonte;
cosmic-applet-minimize = Xanelas minimizadas
cosmic-applet-minimize-comment = Xestionar xanelas minimizadas
cosmic-applet-minimize-keywords = COSMIC;Miniaplicación;Minimizar;
cosmic-applet-network = Rede
cosmic-applet-network-comment = Xestionar as conexións de rede
cosmic-applet-network-keywords = COSMIC;Miniaplicación;Rede;
cosmic-applet-notifications = Centro de notificacións
cosmic-applet-notifications-comment = Xestionar as notificacións e o modo Non molestar
cosmic-applet-notifications-keywords = COSMIC;Miniaplicación;Notificación;
cosmic-applet-power = Sesión de usuario
cosmic-applet-power-comment = Bloquear a pantalla, pechar a sesión, suspender, reiniciar e apagar
cosmic-applet-power-keywords = COSMIC;Miniaplicación;Usuario;Sesión;Bloquear;Pechar sesión;Reiniciar;Apagar;Suspender;
cosmic-applet-status-area = Bandexa de Notificacións
cosmic-applet-status-area-comment = Indicadores de aplicación que poden exportar menús ao panel
cosmic-applet-status-area-keywords = COSMIC;Miniaplicación;Aplicación;Indicador;Notificación;Bandexa;Estado;
cosmic-applet-tiling = Mosaico
cosmic-applet-tiling-comment = Xestiona a indicación activa e o mosaico automático actual e por espazo de traballo
cosmic-applet-tiling-keywords = COSMIC;Miniaplicación;Mosaico;Indicación;Espazo de traballo;
cosmic-applet-time = Data, hora e calendario
cosmic-applet-time-comment = Mostra a hora actual no panel cun calendario emerxente
cosmic-applet-time-keywords = COSMIC;Miniaplicación;Data;Hora;Calendario;
cosmic-applet-workspaces = Espazos de traballo numerados
cosmic-applet-workspaces-comment = Cambia entre os espazos de traballo numerados desde o panel
cosmic-applet-workspaces-keywords = COSMIC;Miniaplicación;Espazo de traballo;
cosmic-panel-app-button = Botón da biblioteca de aplicacións
cosmic-panel-app-button-comment = Abre a biblioteca de aplicacións para iniciar as aplicacións instaladas
cosmic-panel-app-button-keywords = COSMIC;Miniaplicación;Aplicación;Biblioteca;Bandexa;
cosmic-panel-launcher-button = Botón do lanzador
cosmic-panel-launcher-button-comment = Abre o lanzador para buscar aplicacións e executar ordes
cosmic-panel-launcher-button-keywords = COSMIC;Miniaplicación;Lanzador;Executor de ordes;
cosmic-panel-workspaces-button = Botón dos espazos de traballo
cosmic-panel-workspaces-button-comment = Abre a vista xeral dos espazos de traballo para xestionalos e cambiar entre eles
cosmic-panel-workspaces-button-keywords = COSMIC;Miniaplicación;Espazo de traballo;Vista xeral;

View file

@ -0,0 +1,34 @@
cosmic-applet-a11y = अभिगम्यता
cosmic-applet-a11y-comment = पैनल से अभिगम्यता सेटिंग्स विन्यस्त करें
cosmic-applet-audio = ध्वनि
cosmic-applet-audio-comment = ऑडियो उपकरण चयन, ध्वनि स्तर नियंत्रण और MPRIS मीडिया नियंत्रण
cosmic-applet-battery = पावर और बैटरी
cosmic-applet-battery-comment = पावर मोड और ऊर्जा बचत विकल्प
cosmic-applet-battery-keywords = COSMIC;ऐपलेट;पावर;बैटरी
cosmic-applet-bluetooth = ब्लूटूथ
cosmic-applet-bluetooth-comment = ब्लूटूथ डिवाइस प्रबंधित करें
cosmic-applet-input-sources = इनपुट स्रोत
cosmic-applet-input-sources-comment = इनपुट स्रोतों के बीच स्विच करें
cosmic-applet-input-sources-keywords = COSMIC; Applet; इनपुट; स्रोत;
cosmic-applet-minimize = न्यूनतम की गई विंडोज़
cosmic-applet-minimize-comment = न्यूनतम की गई विंडोज़ प्रबंधित करें
cosmic-applet-network = नेटवर्क
cosmic-applet-network-comment = नेटवर्क कनेक्शन प्रबंधित करें
cosmic-applet-notifications = नोटिफ़िकेशन सेंटर
cosmic-applet-notifications-comment = नोटिफ़िकेशन और डु नॉट डिस्टर्ब प्रबंधित करें
cosmic-applet-power = यूज़र सेशन
cosmic-applet-power-comment = स्क्रीन लॉक करें, लॉग आउट करें, सस्पेंड करें, रीबूट करें और शटडाउन करें
cosmic-applet-status-area = नोटिफ़िकेशन ट्रे
cosmic-applet-status-area-comment = एप्लिकेशन इंडिकेटर जो पैनल में मेनू एक्सपोर्ट कर सकते हैं
cosmic-applet-tiling = टाइलिंग
cosmic-applet-tiling-comment = सक्रिय हिंट, वर्तमान और प्रति-वर्कस्पेस ऑटो-टाइलिंग प्रबंधित करें
cosmic-applet-time = दिनांक, समय और कैलेंडर
cosmic-applet-time-comment = पैनल में कैलेंडर पॉपअप के साथ वर्तमान समय प्रदर्शित करें
cosmic-applet-workspaces = क्रमांकित वर्कस्पेस
cosmic-applet-workspaces-comment = पैनल में क्रमांकित वर्कस्पेस के बीच स्विच करें
cosmic-panel-app-button = ऐप लाइब्रेरी बटन
cosmic-panel-app-button-comment = इंस्टॉल किए गए एप्लिकेशन लॉन्च करने के लिए ऐप लाइब्रेरी खोलें
cosmic-panel-launcher-button = लॉन्चर बटन
cosmic-panel-launcher-button-comment = एप्लिकेशन खोजने और कमांड चलाने के लिए लॉन्चर खोलें
cosmic-panel-workspaces-button = वर्कस्पेस बटन
cosmic-panel-workspaces-button-comment = वर्कस्पेस प्रबंधित करने और उनके बीच स्विच करने के लिए वर्कस्पेस ओवरव्यू खोलें

View file

@ -1,16 +1,16 @@
cosmic-app-list = Alkalmazástálca cosmic-app-list = Alkalmazástálca
cosmic-applet-a11y = Akadálymentesség cosmic-applet-a11y = Akadálymentesség
cosmic-applet-audio = Hang cosmic-applet-audio = Hang
cosmic-applet-battery = Energia és Akkumulátor cosmic-applet-battery = Energia és akkumulátor
cosmic-applet-bluetooth = Bluetooth cosmic-applet-bluetooth = Bluetooth
cosmic-applet-input-sources = Beviteli Források cosmic-applet-input-sources = Beviteli források
cosmic-applet-minimize = Minimalizált ablakok cosmic-applet-minimize = Minimalizált ablakok
cosmic-applet-network = Hálózat cosmic-applet-network = Hálózat
cosmic-applet-notifications = Értesítési központ cosmic-applet-notifications = Értesítési központ
cosmic-applet-power = Felhasználói Munkamenet cosmic-applet-power = Felhasználói munkamenet
cosmic-applet-status-area = Értesítési terület cosmic-applet-status-area = Értesítési terület
cosmic-applet-tiling = Csempézés cosmic-applet-tiling = Csempézés
cosmic-applet-time = Dátum, Idő és Naptár cosmic-applet-time = Dátum, idő és naptár
cosmic-applet-workspaces = Számozott Munkaterületek cosmic-applet-workspaces = Számozott Munkaterületek
cosmic-panel-app-button = Alkalmazáskönyvtár gomb cosmic-panel-app-button = Alkalmazáskönyvtár gomb
cosmic-panel-launcher-button = Indító gomb cosmic-panel-launcher-button = Indító gomb
@ -21,7 +21,7 @@ cosmic-applet-audio-keywords = COSMIC;kisalkalmazás;hang;MPRIS;
cosmic-applet-battery-keywords = COSMIC;kisalkalmazás;energia;akkumulátor; cosmic-applet-battery-keywords = COSMIC;kisalkalmazás;energia;akkumulátor;
cosmic-applet-bluetooth-comment = Bluetooth-eszközök kezelése cosmic-applet-bluetooth-comment = Bluetooth-eszközök kezelése
cosmic-applet-bluetooth-keywords = COSMIC;kisalkalmazás;bluetooth; cosmic-applet-bluetooth-keywords = COSMIC;kisalkalmazás;bluetooth;
cosmic-applet-input-sources-keywords = COSMIC;kisalkalmazás;beviteli forrás; cosmic-applet-input-sources-keywords = COSMIC;kisalkalmazás;beviteli;forrás;
cosmic-applet-minimize-keywords = COSMIC;kisalkalmazás;minimizálás; cosmic-applet-minimize-keywords = COSMIC;kisalkalmazás;minimizálás;
cosmic-applet-network-keywords = COSMIC;kisalkalmazás;hálózat;internet; cosmic-applet-network-keywords = COSMIC;kisalkalmazás;hálózat;internet;
cosmic-applet-notifications-keywords = COSMIC;kisalkalmazás;értesítések; cosmic-applet-notifications-keywords = COSMIC;kisalkalmazás;értesítések;

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