libcosmic updates

This commit is contained in:
Ashley Wulber 2024-10-16 20:36:46 -04:00 committed by Ashley Wulber
parent 9c62f19e4b
commit 0491c4baaa
91 changed files with 3550 additions and 2300 deletions

View file

@ -9,8 +9,20 @@ edition = "2021"
once_cell = "1"
rust-embed = "8.0.0"
tracing = "0.1"
env_logger = "0.10.0"
log = "0.4.17"
[dependencies.libcosmic]
git = "https://github.com/pop-os/libcosmic"
default-features = false
features = ["applet", "tokio", "wayland"]
features = [
"applet",
"applet-token",
"multi-window",
"tokio",
"wayland",
"winit",
"desktop",
"dbus-config",
"image",
]

View file

@ -3,5 +3,10 @@ use crate::window::Window;
mod window;
fn main() -> cosmic::iced::Result {
cosmic::applet::run::<Window>(true, ())
let env = env_logger::Env::default()
.filter_or("MY_LOG_LEVEL", "warn")
.write_style_or("MY_LOG_STYLE", "always");
env_logger::init_from_env(env);
cosmic::applet::run::<Window>(())
}

View file

@ -1,9 +1,10 @@
use cosmic::app::Core;
use cosmic::iced::wayland::popup::{destroy_popup, get_popup};
use cosmic::iced::application;
use cosmic::iced::platform_specific::shell::commands::popup::{destroy_popup, get_popup};
use cosmic::iced::window::Id;
use cosmic::iced::{Command, Limits};
use cosmic::iced::{Length, Limits, Task};
use cosmic::iced_runtime::core::window;
use cosmic::iced_style::application;
use cosmic::theme::iced;
use cosmic::widget::{list_column, settings, toggler};
use cosmic::{Element, Theme};
@ -37,22 +38,19 @@ impl cosmic::Application for Window {
&mut self.core
}
fn init(
core: Core,
_flags: Self::Flags,
) -> (Self, Command<cosmic::app::Message<Self::Message>>) {
fn init(core: Core, _flags: Self::Flags) -> (Self, Task<cosmic::app::Message<Self::Message>>) {
let window = Window {
core,
..Default::default()
};
(window, Command::none())
(window, Task::none())
}
fn on_close_requested(&self, id: window::Id) -> Option<Message> {
Some(Message::PopupClosed(id))
}
fn update(&mut self, message: Self::Message) -> Command<cosmic::app::Message<Self::Message>> {
fn update(&mut self, message: Self::Message) -> Task<cosmic::app::Message<Self::Message>> {
match message {
Message::TogglePopup => {
return if let Some(p) = self.popup.take() {
@ -60,17 +58,23 @@ impl cosmic::Application for Window {
} else {
let new_id = Id::unique();
self.popup.replace(new_id);
let mut popup_settings =
self.core
.applet
.get_popup_settings(Id::MAIN, new_id, None, None, None);
let mut popup_settings = self.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(),
new_id,
None,
None,
None,
);
popup_settings.positioner.size_limits = Limits::NONE
.max_width(372.0)
.min_width(300.0)
.min_height(200.0)
.max_height(1080.0);
.max_height(1080.0)
.height(500)
.width(500);
popup_settings.positioner.size = Some((500, 500));
get_popup(popup_settings)
}
};
}
Message::PopupClosed(id) => {
if self.popup.as_ref() == Some(&id) {
@ -79,7 +83,7 @@ impl cosmic::Application for Window {
}
Message::ToggleExampleRow(toggled) => self.example_row = toggled,
}
Command::none()
Task::none()
}
fn view(&self) -> Element<Self::Message> {
@ -93,15 +97,16 @@ impl cosmic::Application for Window {
fn view_window(&self, _id: Id) -> Element<Self::Message> {
let content_list = list_column().padding(5).spacing(0).add(settings::item(
"Example row",
toggler(None, self.example_row, |value| {
cosmic::widget::container(toggler(self.example_row, |value| {
Message::ToggleExampleRow(value)
}),
}))
.height(Length::Fixed(50.)),
));
self.core.applet.popup_container(content_list).into()
}
fn style(&self) -> Option<<Theme as application::StyleSheet>::Style> {
fn style(&self) -> Option<cosmic::iced_runtime::Appearance> {
Some(cosmic::applet::style())
}
}

View file

@ -11,4 +11,15 @@ tracing-log = "0.2.0"
[dependencies.libcosmic]
path = "../../"
default-features = false
features = ["debug", "winit", "tokio", "xdg-portal", "dbus-config", "a11y"]
features = [
"debug",
"winit",
"tokio",
"xdg-portal",
"dbus-config",
"a11y",
"wayland",
"wgpu",
"single-instance",
"multi-window",
]

View file

@ -3,7 +3,8 @@
//! Application API example
use cosmic::app::{Command, Core, Settings};
use cosmic::app::{Core, Settings, Task};
use cosmic::iced::widget::column;
use cosmic::iced_core::Size;
use cosmic::widget::nav_bar;
use cosmic::{executor, iced, ApplicationExt, Element};
@ -50,12 +51,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
/// Messages that are used specifically by our [`App`].
#[derive(Clone, Debug)]
pub enum Message {}
pub enum Message {
Input1(String),
Input2(String),
}
/// The [`App`] stores application-specific state.
pub struct App {
core: Core,
nav_model: nav_bar::Model,
input_1: String,
input_2: String,
}
/// Implement [`cosmic::Application`] to integrate with COSMIC.
@ -81,7 +87,7 @@ impl cosmic::Application for App {
}
/// Creates the application, and optionally emits command on initialize.
fn init(core: Core, input: Self::Flags) -> (Self, Command<Self::Message>) {
fn init(core: Core, input: Self::Flags) -> (Self, Task<Self::Message>) {
let mut nav_model = nav_bar::Model::default();
for (title, content) in input {
@ -90,7 +96,12 @@ impl cosmic::Application for App {
nav_model.activate_position(0);
let mut app = App { core, nav_model };
let mut app = App {
core,
nav_model,
input_1: String::new(),
input_2: String::new(),
};
let command = app.update_title();
@ -103,14 +114,22 @@ impl cosmic::Application for App {
}
/// Called when a navigation item is selected.
fn on_nav_select(&mut self, id: nav_bar::Id) -> Command<Self::Message> {
fn on_nav_select(&mut self, id: nav_bar::Id) -> Task<Self::Message> {
self.nav_model.activate(id);
self.update_title()
}
/// Handle application events here.
fn update(&mut self, _message: Self::Message) -> Command<Self::Message> {
Command::none()
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
match message {
Message::Input1(v) => {
self.input_1 = v;
}
Message::Input2(v) => {
self.input_2 = v;
}
}
Task::none()
}
/// Creates a view after each update.
@ -122,11 +141,20 @@ impl cosmic::Application for App {
let text = cosmic::widget::text(page_content);
let centered = cosmic::widget::container(text)
let centered = cosmic::widget::container(
column![
text,
cosmic::widget::text_input::text_input("", &self.input_1).on_input(Message::Input1),
cosmic::widget::text_input::text_input("", &self.input_2).on_input(Message::Input2),
]
.width(iced::Length::Fill)
.height(iced::Length::Shrink)
.align_x(iced::alignment::Horizontal::Center)
.align_y(iced::alignment::Vertical::Center);
.align_x(iced::alignment::Horizontal::Center),
)
.width(iced::Length::Fill)
.height(iced::Length::Shrink)
.align_x(iced::alignment::Horizontal::Center)
.align_y(iced::alignment::Vertical::Center);
Element::from(centered)
}
@ -142,10 +170,14 @@ where
.unwrap_or("Unknown Page")
}
fn update_title(&mut self) -> Command<Message> {
fn update_title(&mut self) -> Task<Message> {
let header_title = self.active_page_title().to_owned();
let window_title = format!("{header_title} — COSMIC AppDemo");
self.set_header_title(header_title);
self.set_window_title(window_title)
if let Some(id) = self.core.main_window_id() {
self.set_window_title(window_title, id)
} else {
Task::none()
}
}
}

View file

@ -4,7 +4,7 @@
//! Calendar widget example
use chrono::{Local, NaiveDate};
use cosmic::app::{Command, Core, Settings};
use cosmic::app::{Core, Settings, Task};
use cosmic::{executor, iced, ApplicationExt, Element};
/// Runs application with these settings
@ -50,7 +50,7 @@ impl cosmic::Application for App {
}
/// Creates the application, and optionally emits command on initialize.
fn init(core: Core, _input: Self::Flags) -> (Self, Command<Self::Message>) {
fn init(core: Core, _input: Self::Flags) -> (Self, Task<Self::Message>) {
let now = Local::now();
let mut app = App {
@ -64,7 +64,7 @@ impl cosmic::Application for App {
}
/// Handle application events here.
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
match message {
Message::DateSelected(date) => {
self.date_selected = date;
@ -73,7 +73,7 @@ impl cosmic::Application for App {
println!("Date selected: {:?}", self.date_selected);
Command::none()
Task::none()
}
/// Creates a view after each update.
@ -99,7 +99,7 @@ impl App
where
Self: cosmic::Application,
{
fn update_title(&mut self) -> Command<Message> {
fn update_title(&mut self) -> Task<Message> {
self.set_header_title(String::from("Calendar Demo"));
self.set_window_title(String::from("Calendar Demo"))
}

View file

@ -3,7 +3,7 @@
//! Application API example
use cosmic::app::{Command, Core, Settings};
use cosmic::app::{Task, Core, Settings};
use cosmic::iced_core::Size;
use cosmic::widget::{menu, segmented_button};
use cosmic::{executor, iced, ApplicationExt, Element};
@ -65,7 +65,7 @@ impl cosmic::Application for App {
}
/// Creates the application, and optionally emits command on initialize.
fn init(core: Core, _input: Self::Flags) -> (Self, Command<Self::Message>) {
fn init(core: Core, _input: Self::Flags) -> (Self, Task<Self::Message>) {
let mut app = App {
core,
button_label: String::from("Right click me"),
@ -80,10 +80,10 @@ impl cosmic::Application for App {
}
/// Handle application events here.
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
self.button_label = format!("Clicked {message:?}");
Command::none()
Task::none()
}
/// Creates a view after each update.

View file

@ -6,7 +6,7 @@ use cosmic::{
ThemeBuilder,
},
font::load_fonts,
iced::{self, Application, Command, Length, Subscription},
iced::{self, Application, Length, Subscription, Task},
iced::{
subscription,
widget::{self, column, container, horizontal_space, row, text},
@ -324,7 +324,7 @@ impl Application for Window {
type Message = Message;
type Theme = Theme;
fn new(_flags: ()) -> (Self, Command<Self::Message>) {
fn new(_flags: ()) -> (Self, Task<Self::Message>) {
let mut window = Window::default()
.nav_bar_toggled(true)
.show_maximize(true)
@ -389,8 +389,8 @@ impl Application for Window {
])
}
fn update(&mut self, message: Message) -> iced::Command<Self::Message> {
let mut ret = Command::none();
fn update(&mut self, message: Message) -> iced::Task<Self::Message> {
let mut ret = Task::none();
match message {
Message::NavBar(key) => {
if let Some(page) = self.nav_id_to_page.get(key).copied() {
@ -437,10 +437,10 @@ impl Application for Window {
Message::ToggleNavBarCondensed => {
self.nav_bar_toggled_condensed = !self.nav_bar_toggled_condensed
}
Message::Drag => return drag(window::Id::MAIN),
Message::Close => return close(window::Id::MAIN),
Message::Minimize => return minimize(window::Id::MAIN, true),
Message::Maximize => return toggle_maximize(window::Id::MAIN),
Message::Drag => return drag(self.core.main_window_id().unwrap()),
Message::Close => return close(self.core.main_window_id().unwrap()),
Message::Minimize => return minimize(self.core.main_window_id().unwrap(), true),
Message::Maximize => return toggle_maximize(self.core.main_window_id().unwrap()),
Message::InputChanged => {}

View file

@ -482,7 +482,7 @@ impl State {
))
.layer(cosmic::cosmic_theme::Layer::Secondary)
.padding(16)
.style(cosmic::theme::Container::Background)
.class(cosmic::theme::Container::Background)
.into(),
cosmic::widget::text_input::secure_input(
"Type to search apps or type “?” for more options...",

View file

@ -3,7 +3,7 @@
//! Application API example
use cosmic::app::{Command, Core, Settings};
use cosmic::app::{Task, Core, Settings};
use cosmic::{executor, iced, ApplicationExt, Element};
/// Runs application with these settings
@ -51,7 +51,7 @@ impl cosmic::Application for App {
}
/// Creates the application, and optionally emits command on initialize.
fn init(core: Core, _input: Self::Flags) -> (Self, Command<Self::Message>) {
fn init(core: Core, _input: Self::Flags) -> (Self, Task<Self::Message>) {
let mut app = App {
core,
selected: 0,
@ -67,7 +67,7 @@ impl cosmic::Application for App {
}
/// Handle application events here.
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
match message {
Message::Clicked(id) => self.selected = id,
Message::Remove(id) => {
@ -75,7 +75,7 @@ impl cosmic::Application for App {
}
}
Command::none()
Task::none()
}
/// Creates a view after each update.
@ -106,7 +106,7 @@ impl App
where
Self: cosmic::Application,
{
fn update_title(&mut self) -> Command<Message> {
fn update_title(&mut self) -> Task<Message> {
self.set_header_title(String::from("Image Button Demo"));
self.set_window_title(String::from("Image Button Demo"))
}

View file

@ -6,7 +6,7 @@
use std::collections::HashMap;
use std::{env, process};
use cosmic::app::{Command, Core, Settings};
use cosmic::app::{Task, Core, Settings};
use cosmic::iced::window;
use cosmic::iced_core::alignment::{Horizontal, Vertical};
use cosmic::iced_core::keyboard::Key;
@ -97,7 +97,7 @@ impl cosmic::Application for App {
}
/// Creates the application, and optionally emits command on initialize.
fn init(core: Core, _input: Self::Flags) -> (Self, Command<Self::Message>) {
fn init(core: Core, _input: Self::Flags) -> (Self, Task<Self::Message>) {
let app = App {
core,
config: Config {
@ -106,7 +106,7 @@ impl cosmic::Application for App {
key_binds: key_binds(),
};
(app, Command::none())
(app, Task::none())
}
fn header_start(&self) -> Vec<Element<Self::Message>> {
@ -114,13 +114,13 @@ impl cosmic::Application for App {
}
/// Handle application events here.
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
match message {
Message::WindowClose => {
return window::close(window::Id::MAIN);
return window::close(self.core.main_window_id().unwrap());
}
Message::WindowNew => match env::current_exe() {
Ok(exe) => match process::Command::new(&exe).spawn() {
Ok(exe) => match process::Task::new(&exe).spawn() {
Ok(_child) => {}
Err(err) => {
eprintln!("failed to execute {:?}: {}", exe, err);
@ -132,7 +132,7 @@ impl cosmic::Application for App {
},
Message::ToggleHideContent => self.config.hide_content = !self.config.hide_content,
}
Command::none()
Task::none()
}
/// Creates a view after each update.

View file

@ -6,7 +6,7 @@ use cosmic::{
iced_core::{id, Alignment, Length, Point},
iced_widget::{column, container, scrollable, text, text_input},
widget::{button, header_bar},
ApplicationExt, Command,
ApplicationExt, Task,
};
#[derive(Debug, Clone, PartialEq)]
@ -42,10 +42,10 @@ impl cosmic::Application for MultiWindow {
&mut self.core
}
fn init(core: Core, _input: Self::Flags) -> (Self, cosmic::app::Command<Self::Message>) {
fn init(core: Core, _input: Self::Flags) -> (Self, cosmic::app::Task<Self::Message>) {
let windows = MultiWindow {
windows: HashMap::from([(
window::Id::MAIN,
self.core.main_window_id().unwrap(),
Window {
input_id: id::Id::new("main"),
input_value: String::new(),
@ -54,12 +54,12 @@ impl cosmic::Application for MultiWindow {
core,
};
(windows, cosmic::app::Command::none())
(windows, cosmic::app::Task::none())
}
fn subscription(&self) -> cosmic::iced_futures::Subscription<Self::Message> {
event::listen_with(|event, _| {
if let iced::Event::Window(id, window_event) = event {
event::listen_with(|event, _, id| {
if let iced::Event::Window(window_event) = event {
match window_event {
window::Event::CloseRequested => Some(Message::CloseWindow(id)),
window::Event::Opened { position, .. } => {
@ -77,18 +77,18 @@ impl cosmic::Application for MultiWindow {
fn update(
&mut self,
message: Self::Message,
) -> iced::Command<cosmic::app::Message<Self::Message>> {
) -> iced::Task<cosmic::app::Message<Self::Message>> {
match message {
Message::CloseWindow(id) => window::close(id),
Message::WindowClosed(id) => {
self.windows.remove(&id);
Command::none()
Task::none()
}
Message::WindowOpened(id, ..) => {
if let Some(window) = self.windows.get(&id) {
text_input::focus(window.input_id.clone())
} else {
Command::none()
Task::none()
}
}
Message::NewWindow => {
@ -113,13 +113,13 @@ impl cosmic::Application for MultiWindow {
spawn_window
}
Message::Input(id, value) => {
if let Some(w) = self.windows.get_mut(&window::Id::MAIN) {
if let Some(w) = self.windows.get_mut(&self.core.main_window_id().unwrap()) {
if id == w.input_id {
w.input_value = value;
}
}
Command::none()
Task::none()
}
}
}
@ -142,17 +142,15 @@ impl cosmic::Application for MultiWindow {
column![input, new_window_button]
.spacing(50)
.width(Length::Fill)
.align_items(Alignment::Center),
.align_x(Alignment::Center),
);
let window_content = container(container(content).width(200).center_x())
let window_content = container(container(content).center_x(Length::Fixed(200.)))
.style(cosmic::style::Container::Background)
.width(Length::Fill)
.height(Length::Fill)
.center_x()
.center_y();
.center_x(Length::Fill)
.center_y(Length::Fill);
if id == window::Id::MAIN {
if id == self.core.main_window_id().unwrap() {
window_content.into()
} else {
column![header_bar().focused(focused), window_content].into()
@ -160,6 +158,6 @@ impl cosmic::Application for MultiWindow {
}
fn view(&self) -> cosmic::prelude::Element<Self::Message> {
self.view_window(window::Id::MAIN)
self.view_window(self.core.main_window_id().unwrap())
}
}

View file

@ -5,7 +5,7 @@
use std::collections::HashMap;
use cosmic::app::{Command, Core, Settings};
use cosmic::app::{Core, Settings, Task};
use cosmic::iced_core::Size;
use cosmic::widget::{menu, nav_bar};
use cosmic::{executor, iced, ApplicationExt, Element};
@ -106,7 +106,7 @@ impl cosmic::Application for App {
}
/// Creates the application, and optionally emits command on initialize.
fn init(core: Core, input: Self::Flags) -> (Self, Command<Self::Message>) {
fn init(core: Core, input: Self::Flags) -> (Self, Task<Self::Message>) {
let mut nav_model = nav_bar::Model::default();
for (title, content) in input {
@ -143,13 +143,13 @@ impl cosmic::Application for App {
}
/// Called when a navigation item is selected.
fn on_nav_select(&mut self, id: nav_bar::Id) -> Command<Self::Message> {
fn on_nav_select(&mut self, id: nav_bar::Id) -> Task<Self::Message> {
self.nav_model.activate(id);
self.update_title()
}
/// Handle application events here.
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
match message {
Message::NavMenuAction(message) => match message {
NavMenuAction::Delete(id) => self.nav_model.remove(id),
@ -168,7 +168,7 @@ impl cosmic::Application for App {
},
}
Command::none()
Task::none()
}
/// Creates a view after each update.
@ -200,7 +200,7 @@ where
.unwrap_or("Unknown Page")
}
fn update_title(&mut self) -> Command<Message> {
fn update_title(&mut self) -> Task<Message> {
let header_title = self.active_page_title().to_owned();
let window_title = format!("{header_title} — COSMIC AppDemo");
self.set_header_title(header_title);

View file

@ -4,7 +4,7 @@
//! An application which provides an open dialog
use apply::Apply;
use cosmic::app::{Command, Core, Settings};
use cosmic::app::{Task, Core, Settings};
use cosmic::dialog::file_chooser::{self, FileFilter};
use cosmic::iced_core::Length;
use cosmic::widget::button;
@ -66,7 +66,7 @@ impl cosmic::Application for App {
}
/// Creates the application, and optionally emits command on initialize.
fn init(core: Core, _input: Self::Flags) -> (Self, Command<Self::Message>) {
fn init(core: Core, _input: Self::Flags) -> (Self, Task<Self::Message>) {
let mut app = App {
core,
file_contents: String::new(),
@ -77,7 +77,7 @@ impl cosmic::Application for App {
app.set_header_title("Open a file".into());
let cmd = app.set_window_title(
"COSMIC OpenDialog Demo".into(),
cosmic::iced::window::Id::MAIN,
cosmic::iced::self.core.main_window_id().unwrap(),
);
(app, cmd)
@ -88,7 +88,7 @@ impl cosmic::Application for App {
vec![button::suggested("Open").on_press(Message::OpenFile).into()]
}
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
match message {
Message::Cancelled => {
eprintln!("open file dialog cancelled");
@ -198,7 +198,7 @@ impl cosmic::Application for App {
}
}
Command::none()
Task::none()
}
fn view(&self) -> Element<Self::Message> {

View file

@ -3,7 +3,7 @@
//! Application API example
use cosmic::app::{Command, Core, Settings};
use cosmic::app::{Core, Settings, Task};
use cosmic::{executor, iced, ApplicationExt, Element};
/// Runs application with these settings
@ -55,7 +55,7 @@ impl cosmic::Application for App {
}
/// Creates the application, and optionally emits command on initialize.
fn init(core: Core, _input: Self::Flags) -> (Self, Command<Self::Message>) {
fn init(core: Core, _input: Self::Flags) -> (Self, Task<Self::Message>) {
let mut app = App {
core,
editing: false,
@ -63,7 +63,7 @@ impl cosmic::Application for App {
search_id: cosmic::widget::Id::unique(),
};
let commands = Command::batch(vec![
let commands = Task::batch(vec![
cosmic::widget::text_input::focus(app.search_id.clone()),
app.update_title(),
]);
@ -72,7 +72,7 @@ impl cosmic::Application for App {
}
/// Handle application events here.
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
match message {
Message::Input(text) => {
self.input = text;
@ -83,7 +83,7 @@ impl cosmic::Application for App {
}
}
Command::none()
Task::none()
}
/// Creates a view after each update.
@ -115,7 +115,7 @@ impl App
where
Self: cosmic::Application,
{
fn update_title(&mut self) -> Command<Message> {
fn update_title(&mut self) -> Task<Message> {
let window_title = format!("COSMIC TextInputs Demo");
self.set_header_title(window_title.clone());
self.set_window_title(window_title)