mirror of
https://github.com/ByteAtATime/raycast-linux.git
synced 2025-12-23 10:11:57 +00:00
feat: add toggle for layer shell/window api
This commit is contained in:
parent
1c058b46d3
commit
c11337923d
6 changed files with 159 additions and 34 deletions
49
src/main.rs
49
src/main.rs
|
|
@ -72,8 +72,12 @@ fn dev_boot() -> (State, iced::Task<Message>) {
|
|||
|
||||
fn daemon_view<'a>(state: &'a State, window: window::Id) -> iced::Element<'a, Message> {
|
||||
if state.settings_window_id == Some(window) {
|
||||
return screens::settings::settings_view(&state.extensions, &state.preferences)
|
||||
.map(Message::Settings);
|
||||
return screens::settings::settings_view(
|
||||
&state.extensions,
|
||||
&state.preferences,
|
||||
&state.flare_settings,
|
||||
)
|
||||
.map(Message::Settings);
|
||||
}
|
||||
view(state)
|
||||
}
|
||||
|
|
@ -229,20 +233,33 @@ fn run_daemon() -> Result<(), Box<dyn std::error::Error>> {
|
|||
eprintln!("Failed to register deep links: {}", e);
|
||||
}
|
||||
|
||||
let result = iced_layershell::daemon(boot, namespace, update, daemon_view)
|
||||
.subscription(subscription)
|
||||
.title(|_state, _window| Some(String::from("Flare")))
|
||||
.font(include_bytes!("./assets/Inter.ttf").as_slice())
|
||||
.font(include_bytes!("./assets/icons.ttf").as_slice())
|
||||
.default_font(iced::Font::DEFAULT)
|
||||
.layer_settings(LayerShellSettings {
|
||||
start_mode: StartMode::Background,
|
||||
keyboard_interactivity: KeyboardInteractivity::Exclusive,
|
||||
layer: Layer::Overlay,
|
||||
..Default::default()
|
||||
})
|
||||
.run()
|
||||
.map_err(|e| e.to_string());
|
||||
let flare_settings = preferences::FlareSettings::load();
|
||||
|
||||
let result = if flare_settings.use_layer_shell {
|
||||
iced_layershell::daemon(boot, namespace, update, daemon_view)
|
||||
.subscription(subscription)
|
||||
.title(|_state, _window| Some(String::from("Flare")))
|
||||
.font(include_bytes!("./assets/Inter.ttf").as_slice())
|
||||
.font(include_bytes!("./assets/icons.ttf").as_slice())
|
||||
.default_font(iced::Font::DEFAULT)
|
||||
.layer_settings(LayerShellSettings {
|
||||
start_mode: StartMode::Background,
|
||||
keyboard_interactivity: KeyboardInteractivity::Exclusive,
|
||||
layer: Layer::Overlay,
|
||||
..Default::default()
|
||||
})
|
||||
.run()
|
||||
.map_err(|e| e.to_string())
|
||||
} else {
|
||||
iced::daemon(boot, update, daemon_view)
|
||||
.subscription(subscription)
|
||||
.title("Flare")
|
||||
.font(include_bytes!("./assets/Inter.ttf").as_slice())
|
||||
.font(include_bytes!("./assets/icons.ttf").as_slice())
|
||||
.default_font(iced::Font::DEFAULT)
|
||||
.run()
|
||||
.map_err(|e| e.to_string())
|
||||
};
|
||||
|
||||
ipc::cleanup();
|
||||
result?;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,45 @@ use crate::extensions::Extension;
|
|||
|
||||
pub type ExtensionPreferences = HashMap<String, Value>;
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct FlareSettings {
|
||||
#[serde(default = "default_use_layer_shell")]
|
||||
pub use_layer_shell: bool,
|
||||
}
|
||||
|
||||
fn default_use_layer_shell() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
impl FlareSettings {
|
||||
pub fn load() -> Self {
|
||||
let path = get_flare_settings_path();
|
||||
fs::read_to_string(&path)
|
||||
.ok()
|
||||
.and_then(|content| serde_json::from_str(&content).ok())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn save(&self) -> Result<(), String> {
|
||||
let path = get_flare_settings_path();
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent).map_err(|e| e.to_string())?;
|
||||
}
|
||||
let content = serde_json::to_string_pretty(self).map_err(|e| e.to_string())?;
|
||||
fs::write(path, content).map_err(|e| e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn get_flare_settings_path() -> PathBuf {
|
||||
if let Some(config_dir) = dirs::config_dir() {
|
||||
return config_dir.join("flare").join("settings.json");
|
||||
}
|
||||
if let Some(home_dir) = dirs::home_dir() {
|
||||
return home_dir.join(".flare").join("settings.json");
|
||||
}
|
||||
PathBuf::from(".flare").join("settings.json")
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct PreferenceStore {
|
||||
extensions: HashMap<String, ExtensionPreferences>,
|
||||
|
|
|
|||
|
|
@ -11,4 +11,7 @@ pub enum SettingsMessage {
|
|||
key: String,
|
||||
value: Value,
|
||||
},
|
||||
FlareSettingChanged {
|
||||
use_layer_shell: bool,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,68 @@
|
|||
use iced::Element;
|
||||
use iced::widget::{checkbox, column, pick_list, row, scrollable, text, text_input};
|
||||
use iced::widget::{checkbox, column, pick_list, radio, row, scrollable, text, text_input};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::extensions::{Extension, Preference, PreferenceType};
|
||||
use crate::preferences::PreferenceStore;
|
||||
use crate::preferences::{FlareSettings, PreferenceStore};
|
||||
|
||||
use super::SettingsMessage;
|
||||
|
||||
pub fn settings_view<'a>(
|
||||
extensions: &'a [Extension],
|
||||
preferences: &'a PreferenceStore,
|
||||
flare_settings: &'a FlareSettings,
|
||||
) -> Element<'a, SettingsMessage> {
|
||||
let mut content = column![].spacing(10).padding(20);
|
||||
let mut content = column![].spacing(20).padding(20);
|
||||
|
||||
content = content.push(text("Settings").size(24));
|
||||
|
||||
content = content.push(render_flare_settings(flare_settings));
|
||||
|
||||
content = content.push(render_extension_settings(extensions, preferences));
|
||||
|
||||
scrollable(content).into()
|
||||
}
|
||||
|
||||
fn render_flare_settings(settings: &FlareSettings) -> Element<'_, SettingsMessage> {
|
||||
let mut content = column![].spacing(10);
|
||||
|
||||
content = content.push(text("Flare Settings").size(18));
|
||||
|
||||
let layer_shell_row = row![
|
||||
text("Window Mode").width(150),
|
||||
radio(
|
||||
"Layer Shell (Wayland)",
|
||||
true,
|
||||
Some(settings.use_layer_shell),
|
||||
|v| SettingsMessage::FlareSettingChanged { use_layer_shell: v }
|
||||
),
|
||||
radio(
|
||||
"Regular Window",
|
||||
false,
|
||||
Some(settings.use_layer_shell),
|
||||
|v| SettingsMessage::FlareSettingChanged { use_layer_shell: v }
|
||||
),
|
||||
]
|
||||
.spacing(10)
|
||||
.align_y(iced::Alignment::Center);
|
||||
|
||||
content = content.push(layer_shell_row);
|
||||
content =
|
||||
content.push(text("After changing this setting, please restart the application.").size(12));
|
||||
|
||||
content.into()
|
||||
}
|
||||
|
||||
fn render_extension_settings<'a>(
|
||||
extensions: &'a [Extension],
|
||||
preferences: &'a PreferenceStore,
|
||||
) -> Element<'a, SettingsMessage> {
|
||||
let mut content = column![].spacing(10);
|
||||
|
||||
content = content.push(text("Extension Settings").size(18));
|
||||
|
||||
for ext in extensions {
|
||||
content = content.push(text(format!("Extension: {}", ext.manifest.title)).size(18));
|
||||
content = content.push(text(format!("Extension: {}", ext.manifest.title)).size(16));
|
||||
|
||||
if let Some(prefs) = &ext.manifest.preferences {
|
||||
for pref in prefs {
|
||||
|
|
@ -32,7 +78,7 @@ pub fn settings_view<'a>(
|
|||
for cmd in &ext.manifest.commands {
|
||||
if let Some(prefs) = &cmd.preferences {
|
||||
if !prefs.is_empty() {
|
||||
content = content.push(text(format!("Command: {}", cmd.title)).size(16));
|
||||
content = content.push(text(format!("Command: {}", cmd.title)).size(14));
|
||||
for pref in prefs {
|
||||
content = content.push(render_preference(
|
||||
&ext.manifest.name,
|
||||
|
|
@ -46,7 +92,7 @@ pub fn settings_view<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
scrollable(content).into()
|
||||
content.into()
|
||||
}
|
||||
|
||||
fn render_preference<'a>(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use crate::components::action_panel;
|
|||
use crate::components::actions::ActionPanelItem;
|
||||
use crate::extensions;
|
||||
use crate::frecency::FrecencyStore;
|
||||
use crate::preferences::PreferenceStore;
|
||||
use crate::preferences::{FlareSettings, PreferenceStore};
|
||||
use crate::screens::{Screen, Shell};
|
||||
use crate::theme::Theme;
|
||||
use crate::transport::{SidecarReader, SidecarWriter};
|
||||
|
|
@ -19,6 +19,7 @@ pub struct State {
|
|||
pub extensions: Vec<extensions::Extension>,
|
||||
pub apps: Vec<apps::AppEntry>,
|
||||
pub preferences: PreferenceStore,
|
||||
pub flare_settings: FlareSettings,
|
||||
pub frecency: FrecencyStore,
|
||||
pub theme: Theme,
|
||||
pub search_text: String,
|
||||
|
|
@ -51,6 +52,7 @@ impl State {
|
|||
let commands = extensions::get_launchable_commands(&extensions);
|
||||
let apps = apps::scan_applications();
|
||||
let preferences = PreferenceStore::load();
|
||||
let flare_settings = FlareSettings::load();
|
||||
let frecency = FrecencyStore::new(get_frecency_path());
|
||||
let theme = Theme::default();
|
||||
|
||||
|
|
@ -67,6 +69,7 @@ impl State {
|
|||
extensions,
|
||||
apps,
|
||||
preferences,
|
||||
flare_settings,
|
||||
frecency,
|
||||
theme,
|
||||
search_text,
|
||||
|
|
|
|||
|
|
@ -51,18 +51,29 @@ pub fn update(state: &mut State, message: Message) -> Task<Message> {
|
|||
} else {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let id = window::Id::unique();
|
||||
state.window_id = Some(id);
|
||||
return Task::done(Message::NewLayerShell {
|
||||
settings: NewLayerShellSettings {
|
||||
size: Some((774, 474)),
|
||||
anchor: Anchor::empty(),
|
||||
layer: Layer::Overlay,
|
||||
keyboard_interactivity: KeyboardInteractivity::Exclusive,
|
||||
if state.flare_settings.use_layer_shell {
|
||||
let id = window::Id::unique();
|
||||
state.window_id = Some(id);
|
||||
return Task::done(Message::NewLayerShell {
|
||||
settings: NewLayerShellSettings {
|
||||
size: Some((774, 474)),
|
||||
anchor: Anchor::empty(),
|
||||
layer: Layer::Overlay,
|
||||
keyboard_interactivity: KeyboardInteractivity::Exclusive,
|
||||
..Default::default()
|
||||
},
|
||||
id,
|
||||
});
|
||||
} else {
|
||||
let (id, open) = window::open(window::Settings {
|
||||
decorations: false,
|
||||
level: window::Level::AlwaysOnTop,
|
||||
resizable: false,
|
||||
size: iced::Size::new(774.0, 474.0),
|
||||
..Default::default()
|
||||
},
|
||||
id,
|
||||
});
|
||||
});
|
||||
return open.map(move |_| Message::WindowOpened(id));
|
||||
}
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
{
|
||||
|
|
@ -254,6 +265,12 @@ pub fn update(state: &mut State, message: Message) -> Task<Message> {
|
|||
eprintln!("Failed to save preferences: {}", e);
|
||||
}
|
||||
}
|
||||
SettingsMessage::FlareSettingChanged { use_layer_shell } => {
|
||||
state.flare_settings.use_layer_shell = use_layer_shell;
|
||||
if let Err(e) = state.flare_settings.save() {
|
||||
eprintln!("Failed to save Flare settings: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::OpenUrl(url) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue