feat(ux): change themes at runtime (#3559)
This commit is contained in:
parent
45501793d1
commit
e96491a3cf
12 changed files with 81 additions and 31 deletions
|
|
@ -215,7 +215,7 @@ pub fn start_client(
|
|||
config.env.set_vars();
|
||||
|
||||
let palette = config
|
||||
.theme_config(&config_options)
|
||||
.theme_config(config_options.theme.as_ref())
|
||||
.unwrap_or_else(|| os_input.load_palette());
|
||||
|
||||
let full_screen_ws = os_input.get_terminal_size_using_fd(0);
|
||||
|
|
@ -615,7 +615,7 @@ pub fn start_server_detached(
|
|||
config.env.set_vars();
|
||||
|
||||
let palette = config
|
||||
.theme_config(&config_options)
|
||||
.theme_config(config_options.theme.as_ref())
|
||||
.unwrap_or_else(|| os_input.load_palette());
|
||||
|
||||
let client_attributes = ClientAttributes {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ use zellij_utils::{
|
|||
plugins::PluginAliases,
|
||||
},
|
||||
ipc::{ClientAttributes, ExitReason, ServerToClientMsg},
|
||||
shared::default_palette,
|
||||
};
|
||||
|
||||
pub type ClientId = u16;
|
||||
|
|
@ -267,6 +268,9 @@ impl SessionMetaData {
|
|||
client_id,
|
||||
keybinds: Some(new_config.keybinds.clone()),
|
||||
default_mode: new_config.options.default_mode,
|
||||
theme: new_config
|
||||
.theme_config(new_config.options.theme.as_ref())
|
||||
.or_else(|| Some(default_palette())),
|
||||
})
|
||||
.unwrap();
|
||||
self.senders
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
|
|||
use std::rc::Rc;
|
||||
use std::time::Instant;
|
||||
use zellij_utils::{
|
||||
data::{ModeInfo, Style},
|
||||
data::{ModeInfo, Palette, Style},
|
||||
errors::prelude::*,
|
||||
input::command::RunCommand,
|
||||
input::layout::{FloatingPaneLayout, Run, RunPluginOrAlias},
|
||||
|
|
@ -913,4 +913,10 @@ impl FloatingPanes {
|
|||
},
|
||||
}
|
||||
}
|
||||
pub fn update_pane_themes(&mut self, theme: Palette) {
|
||||
self.style.colors = theme;
|
||||
for pane in self.panes.values_mut() {
|
||||
pane.update_theme(theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2155,6 +2155,9 @@ impl Grid {
|
|||
pub fn unlock_renders(&mut self) {
|
||||
self.lock_renders = false;
|
||||
}
|
||||
pub fn update_theme(&mut self, theme: Palette) {
|
||||
self.style.colors = theme.clone();
|
||||
}
|
||||
}
|
||||
|
||||
impl Perform for Grid {
|
||||
|
|
|
|||
|
|
@ -675,6 +675,12 @@ impl Pane for PluginPane {
|
|||
self.pane_name = String::from_utf8_lossy(&buf).to_string();
|
||||
self.set_should_render(true);
|
||||
}
|
||||
fn update_theme(&mut self, theme: Palette) {
|
||||
self.style.colors = theme.clone();
|
||||
for grid in self.grids.values_mut() {
|
||||
grid.update_theme(theme.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PluginPane {
|
||||
|
|
|
|||
|
|
@ -790,6 +790,14 @@ impl Pane for TerminalPane {
|
|||
run_command.clone()
|
||||
})
|
||||
}
|
||||
fn update_theme(&mut self, theme: Palette) {
|
||||
self.style.colors = theme.clone();
|
||||
self.grid.update_theme(theme);
|
||||
if self.banner.is_some() {
|
||||
// we do this so that the banner will be updated with the new theme colors
|
||||
self.render_first_run_banner();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TerminalPane {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use crate::{
|
|||
};
|
||||
use stacked_panes::StackedPanes;
|
||||
use zellij_utils::{
|
||||
data::{Direction, ModeInfo, PaneInfo, ResizeStrategy, Style},
|
||||
data::{Direction, ModeInfo, Palette, PaneInfo, ResizeStrategy, Style},
|
||||
errors::prelude::*,
|
||||
input::{
|
||||
command::RunCommand,
|
||||
|
|
@ -1766,6 +1766,12 @@ impl TiledPanes {
|
|||
}
|
||||
pane_infos
|
||||
}
|
||||
pub fn update_pane_themes(&mut self, theme: Palette) {
|
||||
self.style.colors = theme;
|
||||
for pane in self.panes.values_mut() {
|
||||
pane.update_theme(theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::borrowed_box)]
|
||||
|
|
|
|||
|
|
@ -93,23 +93,6 @@ pub(crate) fn route_action(
|
|||
},
|
||||
Action::SwitchToMode(mode) => {
|
||||
let attrs = &client_attributes;
|
||||
// TODO: use the palette from the client and remove it from the server os api
|
||||
// this is left here as a stop gap measure until we shift some code around
|
||||
// to allow for this
|
||||
// TODO: Need access to `ClientAttributes` here
|
||||
senders
|
||||
.send_to_plugin(PluginInstruction::Update(vec![(
|
||||
None,
|
||||
Some(client_id),
|
||||
Event::ModeUpdate(get_mode_info(
|
||||
mode,
|
||||
attrs,
|
||||
capabilities,
|
||||
&client_keybinds,
|
||||
Some(default_mode),
|
||||
)),
|
||||
)]))
|
||||
.with_context(err_context)?;
|
||||
senders
|
||||
.send_to_server(ServerInstruction::ChangeMode(client_id, mode))
|
||||
.with_context(err_context)?;
|
||||
|
|
|
|||
|
|
@ -368,6 +368,7 @@ pub enum ScreenInstruction {
|
|||
client_id: ClientId,
|
||||
keybinds: Option<Keybinds>,
|
||||
default_mode: Option<InputMode>,
|
||||
theme: Option<Palette>,
|
||||
},
|
||||
RerunCommandPane(u32), // u32 - terminal pane id
|
||||
}
|
||||
|
|
@ -1735,11 +1736,13 @@ impl Screen {
|
|||
if mode_info.session_name.as_ref() != Some(&self.session_name) {
|
||||
mode_info.session_name = Some(self.session_name.clone());
|
||||
}
|
||||
let previous_mode = self
|
||||
|
||||
let previous_mode_info = self
|
||||
.mode_info
|
||||
.get(&client_id)
|
||||
.unwrap_or(&self.default_mode_info)
|
||||
.mode;
|
||||
.unwrap_or(&self.default_mode_info);
|
||||
let previous_mode = previous_mode_info.mode;
|
||||
mode_info.style = previous_mode_info.style;
|
||||
|
||||
let err_context = || {
|
||||
format!(
|
||||
|
|
@ -2183,10 +2186,22 @@ impl Screen {
|
|||
&mut self,
|
||||
new_keybinds: Option<Keybinds>,
|
||||
new_default_mode: Option<InputMode>,
|
||||
theme: Option<Palette>,
|
||||
client_id: ClientId,
|
||||
) -> Result<()> {
|
||||
let should_update_mode_info =
|
||||
new_keybinds.is_some() || new_default_mode.is_some() || theme.is_some();
|
||||
|
||||
// themes are currently global and not per-client
|
||||
if let Some(theme) = theme {
|
||||
self.default_mode_info.update_theme(theme);
|
||||
for tab in self.tabs.values_mut() {
|
||||
tab.update_theme(theme);
|
||||
}
|
||||
}
|
||||
|
||||
// client specific configuration
|
||||
if self.connected_clients_contains(&client_id) {
|
||||
let should_update_mode_info = new_keybinds.is_some() || new_default_mode.is_some();
|
||||
let mode_info = self
|
||||
.mode_info
|
||||
.entry(client_id)
|
||||
|
|
@ -2197,15 +2212,21 @@ impl Screen {
|
|||
if let Some(new_default_mode) = new_default_mode {
|
||||
mode_info.update_default_mode(new_default_mode);
|
||||
}
|
||||
if let Some(theme) = theme {
|
||||
mode_info.update_theme(theme);
|
||||
}
|
||||
if should_update_mode_info {
|
||||
for tab in self.tabs.values_mut() {
|
||||
tab.change_mode_info(mode_info.clone(), client_id);
|
||||
tab.mark_active_pane_for_rerender(client_id);
|
||||
tab.update_input_modes()?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::error!("Could not find client_id {client_id} to rebind keys");
|
||||
}
|
||||
|
||||
if should_update_mode_info {
|
||||
for tab in self.tabs.values_mut() {
|
||||
tab.update_input_modes()?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -4082,9 +4103,10 @@ pub(crate) fn screen_thread_main(
|
|||
client_id,
|
||||
keybinds,
|
||||
default_mode,
|
||||
theme,
|
||||
} => {
|
||||
screen
|
||||
.reconfigure_mode_info(keybinds, default_mode, client_id)
|
||||
.reconfigure_mode_info(keybinds, default_mode, theme, client_id)
|
||||
.non_fatal();
|
||||
},
|
||||
ScreenInstruction::RerunCommandPane(terminal_pane_id) => {
|
||||
|
|
|
|||
|
|
@ -492,6 +492,7 @@ pub trait Pane {
|
|||
fn rerun(&mut self) -> Option<RunCommand> {
|
||||
None
|
||||
} // only relevant to terminal panes
|
||||
fn update_theme(&mut self, _theme: Palette) {}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
@ -3951,6 +3952,14 @@ impl Tab {
|
|||
},
|
||||
}
|
||||
}
|
||||
pub fn update_theme(&mut self, theme: Palette) {
|
||||
self.style.colors = theme;
|
||||
self.floating_panes.update_pane_themes(theme);
|
||||
self.tiled_panes.update_pane_themes(theme);
|
||||
for (_, pane) in self.suppressed_panes.values_mut() {
|
||||
pane.update_theme(theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pane_info_for_pane(pane_id: &PaneId, pane: &Box<dyn Pane>) -> PaneInfo {
|
||||
|
|
|
|||
|
|
@ -1175,6 +1175,9 @@ impl ModeInfo {
|
|||
pub fn update_default_mode(&mut self, new_default_mode: InputMode) {
|
||||
self.base_mode = Some(new_default_mode);
|
||||
}
|
||||
pub fn update_theme(&mut self, theme: Palette) {
|
||||
self.style.colors = theme;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||
|
|
|
|||
|
|
@ -163,8 +163,8 @@ impl TryFrom<&CliArgs> for Config {
|
|||
}
|
||||
|
||||
impl Config {
|
||||
pub fn theme_config(&self, opts: &Options) -> Option<Palette> {
|
||||
match &opts.theme {
|
||||
pub fn theme_config(&self, theme_name: Option<&String>) -> Option<Palette> {
|
||||
match &theme_name {
|
||||
Some(theme_name) => self.themes.get_theme(theme_name).map(|theme| theme.palette),
|
||||
None => self.themes.get_theme("default").map(|theme| theme.palette),
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue