refactor: simplify application trait

This commit is contained in:
Ashley Wulber 2022-11-14 23:51:38 +01:00
parent 9174e42099
commit ee542bd046
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
10 changed files with 9 additions and 544 deletions

View file

@ -1,13 +0,0 @@
[package]
name = "cosmic-applet-graphics"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
zbus = "3.4"
libcosmic = { path = "../..", default-features = false, features = ["debug", "wayland", "applet"] }
cosmic-panel-config = {git = "https://github.com/pop-os/cosmic-panel", default-features = false }
iced_sctk = { git = "https://github.com/pop-os/iced-sctk" }
sctk = { package = "smithay-client-toolkit", git = "https://github.com/Smithay/client-toolkit" }

View file

@ -1,12 +0,0 @@
[Desktop Entry]
Name=Cosmic Applet Graphics
Comment=Write a GTK + Rust application
Type=Application
Exec=cosmic-applet-graphics
Terminal=false
Categories=GNOME;GTK;
Keywords=Gnome;GTK;
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
Icon=com.system76.CosmicAppletGraphics.svg
StartupNotify=true
NoDisplay=true

View file

@ -1,60 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128px" height="128px" viewBox="0 0 128 128" version="1.1">
<defs>
<filter id="alpha" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
<feColorMatrix type="matrix" in="SourceGraphic" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="mask0">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip1">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10632" clip-path="url(#clip1)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 123.503906 236 C 123.503906 268.863281 96.863281 295.503906 64 295.503906 C 31.136719 295.503906 4.496094 268.863281 4.496094 236 C 4.496094 203.136719 31.136719 176.496094 64 176.496094 C 96.863281 176.496094 123.503906 203.136719 123.503906 236 Z M 123.503906 236 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask1">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip2">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10635" clip-path="url(#clip2)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 29.195312 180.496094 L 98.804688 180.496094 C 103.609375 180.496094 107.503906 184.046875 107.503906 188.425781 L 107.503906 283.574219 C 107.503906 287.953125 103.609375 291.503906 98.804688 291.503906 L 29.195312 291.503906 C 24.390625 291.503906 20.496094 287.953125 20.496094 283.574219 L 20.496094 188.425781 C 20.496094 184.046875 24.390625 180.496094 29.195312 180.496094 Z M 29.195312 180.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask2">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip3">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10638" clip-path="url(#clip3)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 20.417969 184.496094 L 107.582031 184.496094 C 111.957031 184.496094 115.503906 188.042969 115.503906 192.417969 L 115.503906 279.582031 C 115.503906 283.957031 111.957031 287.503906 107.582031 287.503906 L 20.417969 287.503906 C 16.042969 287.503906 12.496094 283.957031 12.496094 279.582031 L 12.496094 192.417969 C 12.496094 188.042969 16.042969 184.496094 20.417969 184.496094 Z M 20.417969 184.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask3">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip4">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10641" clip-path="url(#clip4)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 16.425781 200.496094 L 111.574219 200.496094 C 115.953125 200.496094 119.503906 204.390625 119.503906 209.195312 L 119.503906 278.804688 C 119.503906 283.609375 115.953125 287.503906 111.574219 287.503906 L 16.425781 287.503906 C 12.046875 287.503906 8.496094 283.609375 8.496094 278.804688 L 8.496094 209.195312 C 8.496094 204.390625 12.046875 200.496094 16.425781 200.496094 Z M 16.425781 200.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
</defs>
<g id="surface10578">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(94.117647%,94.117647%,94.117647%);fill-opacity:1;stroke:none;"/>
<use xlink:href="#surface10632" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask0)"/>
<use xlink:href="#surface10635" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask1)"/>
<use xlink:href="#surface10638" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask2)"/>
<use xlink:href="#surface10641" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask3)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(38.431373%,62.7451%,91.764706%);stroke-opacity:1;stroke-miterlimit:4;" d="M 0 289 L 128 289 " transform="matrix(1,0,0,1,0,-172)"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.5 KiB

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/com/System76/CosmicDockAppList/">
<!-- see https://gtk-rs.org/gtk4-rs/git/docs/gtk4/struct.Application.html#automatic-resources -->
</gresource>
</gresources>

View file

@ -1,93 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
//! # DBus interface proxy for: `com.system76.PowerDaemon`
//!
//! This code was generated by `zbus-xmlgen` `3.0.0` from DBus introspection data.
//! Source: `Interface '/com/system76/PowerDaemon' from service 'com.system76.PowerDaemon' on system bus`.
//!
//! You may prefer to adapt it, instead of using it verbatim.
//!
//! More information can be found in the
//! [Writing a client proxy](https://dbus.pages.freedesktop.org/zbus/client.html)
//! section of the zbus documentation.
//!
//! This DBus object implements
//! [standard DBus interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
//!
//! * [`zbus::fdo::IntrospectableProxy`]
//!
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
use zbus::{dbus_proxy, Connection};
#[dbus_proxy(
interface = "com.system76.PowerDaemon",
default_path = "/com/system76/PowerDaemon"
)]
trait PowerDaemon {
/// Balanced method
fn balanced(&self) -> zbus::Result<()>;
/// Battery method
fn battery(&self) -> zbus::Result<()>;
/// GetChargeProfiles method
fn get_charge_profiles(
&self,
) -> zbus::Result<Vec<std::collections::HashMap<String, zbus::zvariant::OwnedValue>>>;
/// GetChargeThresholds method
fn get_charge_thresholds(&self) -> zbus::Result<(u8, u8)>;
/// GetDefaultGraphics method
fn get_default_graphics(&self) -> zbus::Result<String>;
/// GetExternalDisplaysRequireDGPU method
fn get_external_displays_require_dgpu(&self) -> zbus::Result<bool>;
/// GetGraphics method
fn get_graphics(&self) -> zbus::Result<String>;
/// GetGraphicsPower method
fn get_graphics_power(&self) -> zbus::Result<bool>;
/// GetProfile method
fn get_profile(&self) -> zbus::Result<String>;
/// GetSwitchable method
fn get_switchable(&self) -> zbus::Result<bool>;
/// Performance method
fn performance(&self) -> zbus::Result<()>;
/// SetChargeThresholds method
fn set_charge_thresholds(&self, thresholds: &(u8, u8)) -> zbus::Result<()>;
/// SetGraphics method
fn set_graphics(&self, vendor: &str) -> zbus::Result<()>;
/// SetGraphicsPower method
fn set_graphics_power(&self, power: bool) -> zbus::Result<()>;
/// HotPlugDetect signal
#[dbus_proxy(signal)]
fn hot_plug_detect(&self, port: u64) -> zbus::Result<()>;
/// PowerProfileSwitch signal
#[dbus_proxy(signal)]
fn power_profile_switch(&self, profile: &str) -> zbus::Result<()>;
}
pub async fn init() -> Option<(Connection, PowerDaemonProxy<'static>)> {
let conn = match Connection::system().await {
Ok(conn) => conn,
_ => return None,
};
let proxy = match PowerDaemonProxy::new(&conn).await {
Ok(p) => p,
_ => return None,
};
Some((conn, proxy))
}

View file

@ -1,32 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
use crate::dbus::PowerDaemonProxy;
use zbus::Result;
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum Graphics {
Integrated,
Hybrid,
Nvidia,
Compute,
}
pub async fn get_current_graphics(daemon: PowerDaemonProxy<'_>) -> Result<Graphics> {
let graphics = daemon.get_graphics().await?;
match graphics.as_str() {
"integrated" => Ok(Graphics::Integrated),
"hybrid" => Ok(Graphics::Hybrid),
"nvidia" => Ok(Graphics::Nvidia),
"compute" => Ok(Graphics::Compute),
_ => panic!("Unknown graphics profile: {}", graphics),
}
}
pub async fn set_graphics(daemon: PowerDaemonProxy<'_>, graphics: Graphics) -> Result<()> {
let graphics_str = match graphics {
Graphics::Integrated => "integrated",
Graphics::Hybrid => "hybrid",
Graphics::Nvidia => "nvidia",
Graphics::Compute => "compute",
};
daemon.set_graphics(graphics_str).await
}

View file

@ -1,37 +0,0 @@
mod dbus;
mod graphics;
mod window;
use cosmic::{
iced::{sctk_settings::InitialSurface, Application},
iced_native::command::platform_specific::wayland::window::SctkWindowSettings,
iced_native::window::Settings,
settings,
};
use cosmic_panel_config::PanelSize;
use window::*;
pub fn main() -> cosmic::iced::Result {
let mut settings = settings();
let pixels = std::env::var("COSMIC_PANEL_SIZE")
.ok()
.and_then(|size| match size.parse::<PanelSize>() {
Ok(PanelSize::XL) => Some(64),
Ok(PanelSize::L) => Some(48),
Ok(PanelSize::M) => Some(36),
Ok(PanelSize::S) => Some(24),
Ok(PanelSize::XS) => Some(18),
Err(_) => Some(36),
})
.unwrap_or(36);
settings.initial_surface = InitialSurface::XdgWindow(SctkWindowSettings {
iced_settings: Settings {
size: (pixels + 32, pixels + 16),
min_size: Some((pixels + 32, pixels + 16)),
max_size: Some((pixels + 32, pixels + 16)),
..Default::default()
},
..Default::default()
});
Window::run(settings)
}

View file

@ -1,270 +0,0 @@
use crate::dbus::{self, PowerDaemonProxy};
use crate::graphics::{get_current_graphics, set_graphics, Graphics};
use cosmic::applet::{get_popup_settings, icon_button, popup_container};
use cosmic::iced_style::application::{self, Appearance};
use cosmic::separator;
use cosmic::theme::Container;
use cosmic::widget::widget::container;
use cosmic::{
iced::widget::{column, radio, text},
iced::{self, Application, Command, Length},
iced_native::window,
theme::{self, Theme},
Element,
};
use cosmic_panel_config::{PanelAnchor, PanelSize};
use iced_sctk::alignment::{Horizontal, Vertical};
use iced_sctk::commands::popup::{destroy_popup, get_popup};
use iced_sctk::Color;
use zbus::Connection;
#[derive(Clone, Copy)]
enum State {
SelectGraphicsMode(bool),
SettingGraphicsMode(Graphics),
}
impl Default for State {
fn default() -> Self {
Self::SelectGraphicsMode(false)
}
}
#[derive(Default)]
pub struct Window {
popup: Option<window::Id>,
graphics_mode: Option<Graphics>,
id_ctr: u32,
icon_size: u16,
anchor: PanelAnchor,
theme: Theme,
dbus: Option<(Connection, PowerDaemonProxy<'static>)>,
state: State,
}
#[allow(dead_code)]
#[derive(Clone, Debug)]
pub enum Message {
CurrentGraphics(Option<Graphics>),
AppliedGraphicsMode(Option<Graphics>),
DBusInit(Option<(Connection, PowerDaemonProxy<'static>)>),
SelectGraphicsMode(Graphics),
TogglePopup,
}
impl Application for Window {
type Executor = iced::executor::Default;
type Flags = ();
type Message = Message;
type Theme = Theme;
fn new(_flags: ()) -> (Self, Command<Self::Message>) {
let mut window = Window::default();
let pixels = std::env::var("COSMIC_PANEL_SIZE")
.ok()
.and_then(|size| match size.parse::<PanelSize>() {
Ok(PanelSize::XL) => Some(64),
Ok(PanelSize::L) => Some(36),
Ok(PanelSize::M) => Some(24),
Ok(PanelSize::S) => Some(16),
Ok(PanelSize::XS) => Some(12),
Err(_) => Some(12),
})
.unwrap_or(16);
window.icon_size = pixels;
window.anchor = std::env::var("COSMIC_PANEL_ANCHOR")
.ok()
.map(|size| match size.parse::<PanelAnchor>() {
Ok(p) => p,
Err(_) => PanelAnchor::Top,
})
.unwrap_or(PanelAnchor::Top);
(
window,
Command::perform(dbus::init(), |dbus_init| Message::DBusInit(dbus_init)),
)
}
fn title(&self) -> String {
String::from("Cosmic Graphics Applet")
}
fn update(&mut self, message: Message) -> iced::Command<Self::Message> {
match message {
Message::SelectGraphicsMode(new_graphics_mode) => {
if let Some((_, proxy)) = self.dbus.as_ref() {
self.state = State::SettingGraphicsMode(new_graphics_mode);
return Command::perform(
set_graphics(proxy.clone(), new_graphics_mode),
move |success| {
Message::AppliedGraphicsMode(success.ok().map(|_| new_graphics_mode))
},
);
}
}
Message::AppliedGraphicsMode(g) => {
if let Some(g) = g {
self.graphics_mode.replace(g);
self.state = State::SelectGraphicsMode(true);
}
}
Message::TogglePopup => {
if let Some(p) = self.popup.take() {
return destroy_popup(p);
} else {
self.id_ctr += 1;
let new_id = window::Id::new(self.id_ctr);
self.popup.replace(new_id);
let mut commands = Vec::new();
if let Some((_, proxy)) = self.dbus.as_ref() {
commands.push(Command::perform(
get_current_graphics(proxy.clone()),
|cur_graphics| Message::CurrentGraphics(cur_graphics.ok()),
));
}
let mut popup_settings =
get_popup_settings(window::Id::new(0), new_id, None, None);
popup_settings.positioner.size = (200, 240);
commands.push(get_popup(popup_settings));
return Command::batch(commands);
}
}
Message::DBusInit(dbus) => {
self.dbus = dbus;
return Command::perform(
get_current_graphics(self.dbus.as_ref().unwrap().1.clone()),
|cur_graphics| {
Message::CurrentGraphics(match cur_graphics {
Ok(g) => Some(g),
Err(err) => {
dbg!(err);
None
}
})
},
);
}
Message::CurrentGraphics(g) => {
if let Some(g) = g {
self.graphics_mode.replace(g);
}
}
}
Command::none()
}
fn view_popup(&self, _: window::Id) -> Element<Message> {
let content = match self.state {
State::SelectGraphicsMode(pending_restart) => {
let mut content_list = vec![
radio(
"Integrated Graphics",
Graphics::Integrated,
self.graphics_mode,
|g| Message::SelectGraphicsMode(g),
)
.into(),
radio(
"Nvidia Graphics",
Graphics::Nvidia,
self.graphics_mode,
|g| Message::SelectGraphicsMode(g),
)
.into(),
radio(
"Hybrid Graphics",
Graphics::Hybrid,
self.graphics_mode,
|g| Message::SelectGraphicsMode(g),
)
.into(),
radio(
"Compute Graphics",
Graphics::Compute,
self.graphics_mode,
|g| Message::SelectGraphicsMode(g),
)
.into(),
];
if pending_restart {
content_list.insert(
0,
text("Restart to apply changes")
.width(Length::Fill)
.horizontal_alignment(Horizontal::Center)
.size(16)
.into(),
)
}
column(content_list).padding([8, 0]).spacing(8).into()
}
State::SettingGraphicsMode(graphics) => {
let graphics_str = match graphics {
Graphics::Integrated => "integrated",
Graphics::Hybrid => "hybrid",
Graphics::Nvidia => "nvidia",
Graphics::Compute => "compute",
};
column(vec![text(format!(
"Setting graphics mode to {graphics_str}..."
))
.width(Length::Fill)
.horizontal_alignment(Horizontal::Center)
.into()])
.into()
}
};
popup_container(
column(vec![
text("Graphics Mode")
.width(Length::Fill)
.horizontal_alignment(Horizontal::Center)
.size(24)
.into(),
separator!(1).into(),
content,
])
.padding(4)
.spacing(4),
)
.into()
}
fn view_layer_surface(
&self,
_: cosmic::iced_native::window::Id,
) -> iced::Element<'_, Self::Message, iced::Renderer<Self::Theme>> {
unimplemented!()
}
fn close_window_requested(&self, _: cosmic::iced_native::window::Id) -> Self::Message {
unimplemented!()
}
fn popup_done(&self, _: cosmic::iced_native::window::Id) -> Self::Message {
unimplemented!()
}
fn layer_surface_done(&self, _: cosmic::iced_native::window::Id) -> Self::Message {
unimplemented!()
}
fn style(&self) -> <Self::Theme as application::StyleSheet>::Style {
<Self::Theme as application::StyleSheet>::Style::Custom(|theme| Appearance {
background_color: Color::from_rgba(0.0, 0.0, 0.0, 0.0),
text_color: theme.cosmic().on_bg_color().into(),
})
}
fn view_window(&self, _: window::Id) -> Element<Message> {
// TODO use panel config crate after resolving version mismatch
let btn = icon_button().on_press(Message::TogglePopup);
btn.into()
}
fn should_exit(&self) -> bool {
false
}
fn theme(&self) -> Theme {
self.theme
}
}

View file

@ -7,3 +7,4 @@ publish = false
[dependencies]
libcosmic = { path = "../..", default-features = false, features = ["debug", "wayland"] }
iced_sctk = { git = "https://github.com/pop-os/iced-sctk" }

View file

@ -7,12 +7,12 @@ use cosmic::{
iced::{self, Alignment, Application, Color, Command, Length},
iced_lazy::responsive,
iced_native::window,
iced_winit::window::{drag, maximize, minimize},
list_view, list_view_item, list_view_row, list_view_section, scrollable,
theme::{self, Theme},
widget::{button, header_bar, list_box, list_row, list_view::*, toggler},
Element,
};
use iced_sctk::application::SurfaceIdWrapper;
use std::collections::BTreeMap;
#[derive(Default)]
@ -99,34 +99,21 @@ impl Application for Window {
Message::PickListSelected(value) => self.pick_list_selected = Some(value),
Message::Close => self.exit = true,
Message::ToggleSidebar => self.sidebar_toggled = !self.sidebar_toggled,
Message::Drag => return drag(window::Id::new(0)),
Message::Minimize => return minimize(window::Id::new(0), true),
Message::Maximize => return maximize(window::Id::new(0), true),
// Message::Drag => return drag(window::Id::new(0)),
// Message::Minimize => return minimize(window::Id::new(0), true),
// Message::Maximize => return maximize(window::Id::new(0), true),
Message::RowSelected(row) => println!("Selected row {row}"),
_ => {}
}
Command::none()
}
fn view_popup(&self, id: window::Id) -> Element<Message> {
unimplemented!()
}
fn view_layer_surface(
&self,
window: cosmic::iced_native::window::Id,
) -> iced::Element<'_, Self::Message, iced::Renderer<Self::Theme>> {
unimplemented!()
}
fn close_window_requested(&self, window: cosmic::iced_native::window::Id) -> Self::Message {
unimplemented!()
}
fn popup_done(&self, window: cosmic::iced_native::window::Id) -> Self::Message {
unimplemented!()
}
fn layer_surface_done(&self, window: cosmic::iced_native::window::Id) -> Self::Message {
fn close_requested(&self, _: SurfaceIdWrapper) -> Self::Message {
unimplemented!()
}
fn view_window(&self, id: window::Id) -> Element<Message> {
fn view(&self, _: SurfaceIdWrapper) -> Element<Message> {
let mut header: Element<Message> = header_bar()
.title(self.title())
.nav_title(String::from("Settings"))