email-client

A gtk4 Email Client
git clone git://archive.git.mtrnord.blog/erooster-mail/email-client.git
Log | Files | Refs | LICENSE

commit 59623e9bbebfab9b9741cfdcab422fc30a72bf06
parent 3211ad425ddf4b1e47023b462c77ea2ace9c1375
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sun, 19 Feb 2023 21:48:09 +0100

Use resources better and add missing icons

Diffstat:
MCargo.lock | 1-
MCargo.toml | 4++++
Mbuild-aux/de.nordgedanken.Email.Devel.yaml | 5+++--
Dbuild.rs | 7-------
Adata/dev.nordgedanken.Email.gresource.xml | 12++++++++++++
Rresources/shortcuts.ui -> data/gtk/shortcuts.ui | 0
Adata/gtk/style.css | 22++++++++++++++++++++++
Adata/icons/inbox-symbolic.svg | 6++++++
Adata/icons/mail-symbolic.svg | 6++++++
Adata/icons/meson.build | 10++++++++++
Mdata/meson.build | 14+++++++++++++-
Mmeson.build | 8+++++++-
Dresources/resources.gresource.xml | 7-------
Asrc/config.rs | 8++++++++
Asrc/config.rs.in | 8++++++++
Msrc/folder_view.rs | 27++++++++-------------------
Msrc/main.rs | 36+++++++++++++++++++++++-------------
Msrc/meson.build | 23+++++++++++++++++++++++
Dsrc/style.css | 43-------------------------------------------
19 files changed, 153 insertions(+), 94 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -1408,7 +1408,6 @@ dependencies = [ "image", "lazy_static", "mac-notification-sys", - "serde", "tauri-winrt-notification", ] diff --git a/Cargo.toml b/Cargo.toml @@ -22,3 +22,7 @@ default-features = false [build-dependencies] glib-build-tools = "0.17" + +[profile.release] +lto = true +opt-level = 3 diff --git a/build-aux/de.nordgedanken.Email.Devel.yaml b/build-aux/de.nordgedanken.Email.Devel.yaml @@ -12,8 +12,9 @@ finish-args: - --device=dri - --share=network - --socket=session-bus - - --env=RUST_LOG=mail_client=debug - - --env=G_MESSAGES_DEBUG=none + - --env=RUST_LOG=debug + #- --env=RUST_LOG=mail_client=debug + #- --env=G_MESSAGES_DEBUG=none - --env=RUST_BACKTRACE=1 build-options: append-path: /usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm14/bin diff --git a/build.rs b/build.rs @@ -1,7 +0,0 @@ -fn main() { - glib_build_tools::compile_resources( - &["resources"], - "resources/resources.gresource.xml", - "resources.gresource", - ); -} diff --git a/data/dev.nordgedanken.Email.gresource.xml b/data/dev.nordgedanken.Email.gresource.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<gresources> + <gresource prefix="/dev/nordgedanken/Email/"> + <file compressed="true" alias="style.css">gtk/style.css</file> + <file compressed="true" preprocess="xml-stripblanks" alias="gtk/help-overlay.ui">gtk/shortcuts.ui</file> + </gresource> + <gresource prefix="/dev/nordgedanken/Email/icons"> + <file compressed="true" preprocess="xml-stripblanks" alias="mail-symbolic.svg">icons/mail-symbolic.svg</file> + <file compressed="true" preprocess="xml-stripblanks" alias="inbox-symbolic.svg">icons/inbox-symbolic.svg</file> + </gresource> +</gresources> +\ No newline at end of file diff --git a/resources/shortcuts.ui b/data/gtk/shortcuts.ui diff --git a/data/gtk/style.css b/data/gtk/style.css @@ -0,0 +1,21 @@ +.sidebar { + background-color: grey; +} + +.main { + background-color: green; +} + +.expander title { + border-radius: 0px; + padding: 4px; +} + +.expander title:hover { + background-color: #ececec; +} + +.tree-item { + border-radius: 0px; + padding: 4px; +} +\ No newline at end of file diff --git a/data/icons/inbox-symbolic.svg b/data/icons/inbox-symbolic.svg @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"> + <path fill="none" d="M0 0h24v24H0z"/> + <path d="M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm17 11h-3.416a5.001 5.001 0 0 1-9.168 0H4v5h16v-5zm0-2V5H4v7h5a3 3 0 0 0 6 0h5z"/> +</svg> +\ No newline at end of file diff --git a/data/icons/mail-symbolic.svg b/data/icons/mail-symbolic.svg @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"> + <path fill="none" d="M0 0h24v24H0z"/> + <path d="M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm17 4.238l-7.928 7.1L4 7.216V19h16V7.238zM4.511 5l7.55 6.662L19.502 5H4.511z"/> +</svg> +\ No newline at end of file diff --git a/data/icons/meson.build b/data/icons/meson.build @@ -0,0 +1,9 @@ +# install_data( +# 'mail-symbolic.svg', +# install_dir: iconsdir / 'hicolor' / 'symbolic' / 'actions', +# ) + +# install_data( +# 'inbox-symbolic.svg', +# install_dir: iconsdir / 'hicolor' / 'symbolic' / 'actions', +# ) +\ No newline at end of file diff --git a/data/meson.build b/data/meson.build @@ -1,4 +1,6 @@ -application_id = 'dev.nordgedanken.Email' +# Icons # +subdir('icons') + metainfo_file = '@0@.metainfo.xml'.format(application_id) desktop_file = '@0@.desktop'.format(application_id) @@ -41,3 +43,13 @@ endif # '@0@.svg'.format(application_id), # install_dir: datadir / 'icons' / 'hicolor' / 'scalable' / 'apps' #) + +gnome.compile_resources( + application_id, + '@0@.gresource.xml'.format(application_id), + gresource_bundle: true, + source_dir: meson.current_build_dir(), + install: true, + install_dir: pkgdatadir +) + diff --git a/meson.build b/meson.build @@ -9,11 +9,17 @@ gnome = import('gnome') cargo = find_program('cargo', required: true) +name = 'Email Client' +application_id = 'dev.nordgedanken.Email' version = meson.project_version() prefix = get_option('prefix') bindir = prefix / get_option('bindir') - +path_id = '/dev/nordgedanken/Email' +profile = get_option('profile') datadir = prefix / get_option('datadir') +iconsdir = datadir / 'icons' +pkgdatadir = datadir / meson.project_name() + dependency('glib-2.0', version: '>= 2.66') diff --git a/resources/resources.gresource.xml b/resources/resources.gresource.xml @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<gresources> - <gresource prefix="/dev/nordgedanken/email/"> - <file compressed="true" preprocess="xml-stripblanks" alias="gtk/help-overlay.ui">shortcuts.ui</file> - </gresource> -</gresources> -\ No newline at end of file diff --git a/src/config.rs b/src/config.rs @@ -0,0 +1,7 @@ +pub static NAME: &str = "Email Client"; +pub static PKGNAME: &str = "mail-client"; +pub static APP_ID: &str = "dev.nordgedanken.Email"; +pub static PATH_ID: &str = "/dev/nordgedanken/Email"; +pub static VERSION: &str = "0.1.0"; +pub static PROFILE: &str = "development"; +pub static DATADIR: &str = "/app/share"; +\ No newline at end of file diff --git a/src/config.rs.in b/src/config.rs.in @@ -0,0 +1,7 @@ +pub static NAME: &str = @NAME@; +pub static PKGNAME: &str = @PKGNAME@; +pub static APP_ID: &str = @APP_ID@; +pub static PATH_ID: &str = @PATH_ID@; +pub static VERSION: &str = @VERSION@; +pub static PROFILE: &str = @PROFILE@; +pub static DATADIR: &str = @DATADIR@; +\ No newline at end of file diff --git a/src/folder_view.rs b/src/folder_view.rs @@ -1,4 +1,4 @@ -use gtk::{prelude::*, Align, Orientation}; +use gtk::{prelude::*, Align}; use relm4::{factory::FactoryVecDeque, prelude::*}; pub struct MailboxesView { @@ -25,16 +25,10 @@ impl SimpleComponent for MailboxesView { view! { gtk::ScrolledWindow { set_propagate_natural_width: true, + set_hscrollbar_policy: gtk::PolicyType::Never, - // This should be a ListBox with ListBoxRow children #[local_ref] - mailbox_list_box -> gtk::Box { - set_orientation: Orientation::Vertical, - set_halign: Align::Fill, - set_valign: Align::Fill, - set_hexpand: true, - set_homogeneous: true, - } + mailbox_list_box -> gtk::Box {} } } @@ -95,7 +89,6 @@ impl FactoryComponent for Mailbox { view! { root = gtk::Expander { set_expanded: true, - add_css_class: "expander", set_halign: Align::Fill, set_hexpand: true, #[wrap(Some)] @@ -103,7 +96,7 @@ impl FactoryComponent for Mailbox { gtk::Image { set_margin_end: 8, #[watch] - set_icon_name: Some(&self.icon_name) + set_from_icon_name: Some(&self.icon_name) }, gtk::Label { #[watch] @@ -117,8 +110,7 @@ impl FactoryComponent for Mailbox { } fn init_model(value: Self::Init, _index: &DynamicIndex, sender: FactorySender<Self>) -> Self { - let box_parent = gtk::Box::default(); - box_parent.set_homogeneous(true); + let box_parent = gtk::ListBox::default(); box_parent.set_halign(Align::Fill); let mut model = Self { icon_name: value.icon_name, @@ -171,12 +163,10 @@ impl FactoryComponent for Folder { type Output = (); type CommandOutput = (); type ParentInput = MailboxInput; - type ParentWidget = gtk::Box; + type ParentWidget = gtk::ListBox; view! { - root = gtk::Button { - add_css_class: "tree-item", - set_has_frame: false, + root = gtk::ListBoxRow { set_halign: Align::Fill, gtk::Box { @@ -185,14 +175,13 @@ impl FactoryComponent for Folder { gtk::Image { set_margin_end: 8, #[watch] - set_icon_name: Some(&self.icon_name) + set_from_icon_name: Some(&self.icon_name) }, gtk::Label { #[watch] set_label: &self.folder_name, } } - } } diff --git a/src/main.rs b/src/main.rs @@ -1,10 +1,13 @@ use folder_view::MailboxesView; -use gtk::{gdk::Display, gio, prelude::*, Application, CssProvider, StyleContext}; +use gtk::{gdk::Display, gio, prelude::*, Application}; use relm4::prelude::*; use std::convert::identity; use crate::folder_view::{FolderInit, MailboxInit, MailboxesInit}; +#[rustfmt::skip] +mod config; + mod folder_view; struct App { @@ -72,6 +75,7 @@ impl Component for App { #[wrap(Some)] set_start_child = &gtk::ScrolledWindow { + set_hscrollbar_policy: gtk::PolicyType::Never, }, #[wrap(Some)] @@ -126,8 +130,15 @@ fn main() { .init(); tracing::info!("Starting application!"); - // Register and include resources - gio::resources_register_include!("resources.gresource").expect("Failed to register resources."); + // Load app resources + let path = &format!( + "{}/{}/{}.gresource", + config::DATADIR, + config::PKGNAME, + config::APP_ID + ); + let res = gio::Resource::load(path).expect("Could not load resources"); + gio::resources_register(&res); let app = Application::builder() .application_id("dev.nordgedanken.Email") @@ -139,14 +150,13 @@ fn main() { } fn load_css() { - // Load the CSS file and add it to the provider - let provider = CssProvider::new(); - provider.load_from_data(include_bytes!("style.css")); - - // Add the provider to the default screen - StyleContext::add_provider_for_display( - &Display::default().expect("Could not connect to a display."), - &provider, - gtk::STYLE_PROVIDER_PRIORITY_APPLICATION, - ); + let provider = gtk::CssProvider::new(); + provider.load_from_resource(&format!("{}/style.css", config::PATH_ID)); + if let Some(display) = Display::default() { + gtk::StyleContext::add_provider_for_display( + &display, + &provider, + gtk::STYLE_PROVIDER_PRIORITY_APPLICATION, + ); + } } diff --git a/src/meson.build b/src/meson.build @@ -1,3 +1,26 @@ +# Configuration file +conf = configuration_data() +conf.set_quoted('NAME', name) +conf.set_quoted('PKGNAME', meson.project_name()) +conf.set_quoted('APP_ID', application_id) +conf.set_quoted('PATH_ID', path_id) +conf.set_quoted('VERSION', meson.project_version()) +conf.set_quoted('PROFILE', profile) +conf.set_quoted('DATADIR', datadir) + +configure_file( + input: 'config.rs.in', + output: 'config.rs', + configuration: conf +) + +run_command( + 'cp', + join_paths(meson.project_build_root(), 'src', 'config.rs'), + join_paths(meson.project_source_root(), 'src', 'config.rs'), + check: true +) + cargo_options = [ '--manifest-path', meson.project_source_root() / 'Cargo.toml' ] cargo_options += [ '--target-dir', meson.project_build_root() / 'src' ] diff --git a/src/style.css b/src/style.css @@ -1,42 +0,0 @@ -.sidebar { - background-color: grey; -} - -.main { - background-color: green; -} - -.expander title { - border-radius: 0px; - padding: 4px; -} - -.expander title:hover { - background-color: #ececec; -} - -/* -In reality we apply this in code when expanded since gtk doesn't allow this inside of css - - -.expander title { - background-color: #3584e4; - color: white; -} -*/ -.tree-item { - background-color: transparent; - border-radius: 0px; - padding: 4px; - color: black; -} - -.tree-item:hover { - background-color: #ececec; -} - -/* -.tree-item { - background-color: #3584e4; - color: white; -}*/ -\ No newline at end of file