1
0
Fork 0
mirror of https://github.com/Zedfrigg/ironbar.git synced 2025-07-01 10:41:03 +02:00

feat: global icon theme setting

BREAKING CHANGE: This removes the `icon_theme` option from `launcher` and `focused`. You will need to set this at the top of your config instead.
This commit is contained in:
Jake Stanger 2023-01-29 18:38:57 +00:00
parent 393800aaa2
commit 3cf9be89fd
No known key found for this signature in database
GPG key ID: C51FC8F9CB0BEA61
12 changed files with 75 additions and 40 deletions

View file

@ -8,7 +8,7 @@ use crate::{await_sync, read_lock, send, write_lock, Config};
use color_eyre::Result;
use gtk::gdk::{EventMask, Monitor, ScrollDirection};
use gtk::prelude::*;
use gtk::{Application, ApplicationWindow, EventBox, Orientation, Widget};
use gtk::{Application, ApplicationWindow, EventBox, IconTheme, Orientation, Widget};
use std::sync::{Arc, RwLock};
use tokio::spawn;
use tokio::sync::mpsc;
@ -140,6 +140,11 @@ fn load_modules(
monitor: &Monitor,
output_name: &str,
) -> Result<()> {
let icon_theme = IconTheme::new();
if let Some(ref theme) = config.icon_theme {
icon_theme.set_custom_theme(Some(theme));
}
macro_rules! info {
($location:expr) => {
ModuleInfo {
@ -148,6 +153,7 @@ fn load_modules(
monitor,
output_name,
location: $location,
icon_theme: &icon_theme,
}
};
}

View file

@ -73,6 +73,9 @@ pub struct Config {
#[serde(default = "default_bar_height")]
pub height: i32,
/// GTK icon theme to use.
pub icon_theme: Option<String>,
pub start: Option<Vec<ModuleConfig>>,
pub center: Option<Vec<ModuleConfig>>,
pub end: Option<Vec<ModuleConfig>>,

View file

@ -35,6 +35,16 @@ impl<'a> ImageProvider<'a> {
Ok(Self { location, size })
}
/// Returns true if the input starts with a prefix
/// that is supported by the parser
/// (ie the parser would not fallback to checking the input).
pub fn is_definitely_image_input(input: &str) -> bool {
input.starts_with("icon:")
|| input.starts_with("file://")
|| input.starts_with("http://")
|| input.starts_with("https://")
}
fn get_location(input: String, theme: &'a IconTheme, size: i32) -> Result<ImageLocation> {
let (input_type, input_name) = input
.split_once(':')

View file

@ -82,7 +82,7 @@ impl Module<Button> for ClockModule {
});
}
let popup = self.into_popup(context.controller_tx, context.popup_rx);
let popup = self.into_popup(context.controller_tx, context.popup_rx, info);
Ok(ModuleWidget {
widget: button,
@ -94,6 +94,7 @@ impl Module<Button> for ClockModule {
self,
_tx: mpsc::Sender<Self::ReceiveMessage>,
rx: glib::Receiver<Self::SendMessage>,
_info: &ModuleInfo,
) -> Option<gtk::Box> {
let container = gtk::Box::builder()
.orientation(Orientation::Vertical)

View file

@ -63,17 +63,28 @@ pub enum WidgetType {
impl Widget {
/// Creates this widget and adds it to the parent container
fn add_to(self, parent: &gtk::Box, tx: Sender<ExecEvent>, bar_orientation: Orientation) {
fn add_to(
self,
parent: &gtk::Box,
tx: Sender<ExecEvent>,
bar_orientation: Orientation,
icon_theme: &IconTheme,
) {
match self.widget_type {
WidgetType::Box => parent.add(&self.into_box(&tx, bar_orientation)),
WidgetType::Box => parent.add(&self.into_box(&tx, bar_orientation, icon_theme)),
WidgetType::Label => parent.add(&self.into_label()),
WidgetType::Button => parent.add(&self.into_button(tx, bar_orientation)),
WidgetType::Image => parent.add(&self.into_image()),
WidgetType::Image => parent.add(&self.into_image(icon_theme)),
}
}
/// Creates a `gtk::Box` from this widget
fn into_box(self, tx: &Sender<ExecEvent>, bar_orientation: Orientation) -> gtk::Box {
fn into_box(
self,
tx: &Sender<ExecEvent>,
bar_orientation: Orientation,
icon_theme: &IconTheme,
) -> gtk::Box {
let mut builder = gtk::Box::builder();
if let Some(name) = self.name {
@ -92,9 +103,9 @@ impl Widget {
}
if let Some(widgets) = self.widgets {
widgets
.into_iter()
.for_each(|widget| widget.add_to(&container, tx.clone(), bar_orientation));
widgets.into_iter().for_each(|widget| {
widget.add_to(&container, tx.clone(), bar_orientation, icon_theme)
});
}
container
@ -163,7 +174,7 @@ impl Widget {
button
}
fn into_image(self) -> gtk::Image {
fn into_image(self, icon_theme: &IconTheme) -> gtk::Image {
let mut builder = gtk::Image::builder();
if let Some(name) = self.name {
@ -173,9 +184,8 @@ impl Widget {
let gtk_image = builder.build();
if let Some(src) = self.src {
let theme = IconTheme::new();
let size = self.size.unwrap_or(32);
if let Err(err) = ImageProvider::parse(src, &theme, size)
if let Err(err) = ImageProvider::parse(src, icon_theme, size)
.and_then(|image| image.load_into_image(gtk_image.clone()))
{
error!("{err:?}");
@ -248,10 +258,15 @@ impl Module<gtk::Box> for CustomModule {
}
self.bar.clone().into_iter().for_each(|widget| {
widget.add_to(&container, context.controller_tx.clone(), orientation);
widget.add_to(
&container,
context.controller_tx.clone(),
orientation,
info.icon_theme,
);
});
let popup = self.into_popup(context.controller_tx, context.popup_rx);
let popup = self.into_popup(context.controller_tx, context.popup_rx, info);
Ok(ModuleWidget {
widget: container,
@ -263,6 +278,7 @@ impl Module<gtk::Box> for CustomModule {
self,
tx: Sender<Self::ReceiveMessage>,
_rx: glib::Receiver<Self::SendMessage>,
info: &ModuleInfo,
) -> Option<gtk::Box>
where
Self: Sized,
@ -276,9 +292,14 @@ impl Module<gtk::Box> for CustomModule {
}
if let Some(popup) = self.popup {
popup
.into_iter()
.for_each(|widget| widget.add_to(&container, tx.clone(), Orientation::Horizontal));
popup.into_iter().for_each(|widget| {
widget.add_to(
&container,
tx.clone(),
Orientation::Horizontal,
info.icon_theme,
)
});
}
Some(container)

View file

@ -6,7 +6,7 @@ use crate::{await_sync, read_lock, send_async};
use color_eyre::Result;
use glib::Continue;
use gtk::prelude::*;
use gtk::{IconTheme, Label};
use gtk::Label;
use serde::Deserialize;
use tokio::spawn;
use tokio::sync::mpsc::{Receiver, Sender};
@ -24,8 +24,6 @@ pub struct FocusedModule {
/// Icon size in pixels.
#[serde(default = "default_icon_size")]
icon_size: i32,
/// GTK icon theme to use.
icon_theme: Option<String>,
truncate: Option<TruncateMode>,
@ -95,11 +93,7 @@ impl Module<gtk::Box> for FocusedModule {
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
info: &ModuleInfo,
) -> Result<ModuleWidget<gtk::Box>> {
let icon_theme = IconTheme::new();
if let Some(theme) = self.icon_theme {
icon_theme.set_custom_theme(Some(&theme));
}
let icon_theme = info.icon_theme;
let container = gtk::Box::new(info.bar_position.get_orientation(), 5);
@ -114,6 +108,7 @@ impl Module<gtk::Box> for FocusedModule {
container.add(&label);
{
let icon_theme = icon_theme.clone();
context.widget_rx.attach(None, move |(name, id)| {
if self.show_icon {
if let Err(err) = ImageProvider::parse(id, &icon_theme, self.icon_size)

View file

@ -11,7 +11,7 @@ use crate::{lock, read_lock, try_send, write_lock};
use color_eyre::{Help, Report};
use glib::Continue;
use gtk::prelude::*;
use gtk::{Button, IconTheme, Orientation};
use gtk::{Button, Orientation};
use indexmap::IndexMap;
use serde::Deserialize;
use std::process::{Command, Stdio};
@ -33,9 +33,6 @@ pub struct LauncherModule {
#[serde(default = "crate::config::default_true")]
show_icons: bool,
/// Name of the GTK icon theme to use.
icon_theme: Option<String>,
#[serde(flatten)]
pub common: Option<CommonConfig>,
}
@ -309,15 +306,15 @@ impl Module<gtk::Box> for LauncherModule {
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
info: &ModuleInfo,
) -> crate::Result<ModuleWidget<gtk::Box>> {
let icon_theme = IconTheme::new();
if let Some(ref theme) = self.icon_theme {
icon_theme.set_custom_theme(Some(theme));
}
let icon_theme = info.icon_theme;
let container = gtk::Box::new(info.bar_position.get_orientation(), 0);
{
let container = container.clone();
let icon_theme = icon_theme.clone();
let controller_tx = context.controller_tx.clone();
let show_names = self.show_names;
let show_icons = self.show_icons;
@ -325,7 +322,6 @@ impl Module<gtk::Box> for LauncherModule {
let mut buttons = IndexMap::<String, ItemButton>::new();
let controller_tx2 = context.controller_tx.clone();
context.widget_rx.attach(None, move |event| {
match event {
LauncherUpdate::AddItem(item) => {
@ -341,7 +337,7 @@ impl Module<gtk::Box> for LauncherModule {
orientation,
&icon_theme,
&context.tx,
&controller_tx2,
&controller_tx,
);
container.add(&button.button);
@ -400,7 +396,7 @@ impl Module<gtk::Box> for LauncherModule {
});
}
let popup = self.into_popup(context.controller_tx, context.popup_rx);
let popup = self.into_popup(context.controller_tx, context.popup_rx, info);
Ok(ModuleWidget {
widget: container,
popup,
@ -411,6 +407,7 @@ impl Module<gtk::Box> for LauncherModule {
self,
controller_tx: Sender<Self::ReceiveMessage>,
rx: glib::Receiver<Self::SendMessage>,
_info: &ModuleInfo,
) -> Option<gtk::Box> {
const MAX_WIDTH: i32 = 250;

View file

@ -19,7 +19,7 @@ use crate::popup::ButtonGeometry;
use color_eyre::Result;
use glib::IsA;
use gtk::gdk::Monitor;
use gtk::{Application, Widget};
use gtk::{Application, IconTheme, Widget};
use tokio::sync::mpsc;
#[derive(Clone)]
@ -34,6 +34,7 @@ pub struct ModuleInfo<'a> {
pub bar_position: BarPosition,
pub monitor: &'a Monitor,
pub output_name: &'a str,
pub icon_theme: &'a IconTheme,
}
#[derive(Debug)]
@ -88,6 +89,7 @@ where
self,
_tx: mpsc::Sender<Self::ReceiveMessage>,
_rx: glib::Receiver<Self::SendMessage>,
_info: &ModuleInfo,
) -> Option<gtk::Box>
where
Self: Sized,

View file

@ -200,7 +200,7 @@ impl Module<Button> for MusicModule {
});
};
let popup = self.into_popup(context.controller_tx, context.popup_rx);
let popup = self.into_popup(context.controller_tx, context.popup_rx, info);
Ok(ModuleWidget {
widget: button,
@ -212,6 +212,7 @@ impl Module<Button> for MusicModule {
self,
tx: Sender<Self::ReceiveMessage>,
rx: glib::Receiver<Self::SendMessage>,
_info: &ModuleInfo,
) -> Option<gtk::Box> {
let icon_theme = IconTheme::new();