Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ use crate::workspaces::user_profiles::UserProfiles;
use anyhow::Context;
use anyhow::{anyhow, Result};
use appearance::{Appearance, AppearanceManager};
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
use channel::Channel;
use channel::ChannelState;
use interval_timer::IntervalTimer;
use itertools::Itertools;
Expand Down Expand Up @@ -985,6 +987,10 @@ fn run_internal(mut launch_mode: LaunchMode) -> Result<()> {
use warpui::platform::linux::{self, AppBuilderExt};

app_builder.set_window_class(ChannelState::app_id().to_string());
match linux_window_icon() {
Ok(icon) => app_builder.set_window_icon(icon),
Err(err) => log::warn!("Failed to load Linux window icon: {err:#}"),
}

let force_x11 = ForceX11::read_from_preferences(prefs_for_public_settings)
.unwrap_or(ForceX11::default_value());
Expand Down Expand Up @@ -1079,6 +1085,32 @@ fn run_internal(mut launch_mode: LaunchMode) -> Result<()> {
})
}

#[cfg(any(target_os = "linux", target_os = "freebsd"))]
fn linux_window_icon() -> Result<winit::window::Icon> {
use anyhow::Context as _;

let image = image::load_from_memory(linux_window_icon_png())
.context("Failed to decode Linux window icon asset")?
.into_rgba8();
let (width, height) = image.dimensions();

winit::window::Icon::from_rgba(image.into_raw(), width, height)
.context("Failed to create Linux window icon")
}

#[cfg(any(target_os = "linux", target_os = "freebsd"))]
fn linux_window_icon_png() -> &'static [u8] {
match ChannelState::channel() {
Channel::Stable => include_bytes!("../channels/stable/icon/no-padding/512x512.png"),
Channel::Preview => include_bytes!("../channels/preview/icon/no-padding/512x512.png"),
Channel::Dev => include_bytes!("../channels/dev/icon/no-padding/512x512.png"),
Channel::Local | Channel::Integration => {
include_bytes!("../channels/local/icon/no-padding/512x512.png")
}
Channel::Oss => include_bytes!("../channels/oss/icon/no-padding/512x512.png"),
}
}

pub struct UpdateQuakeModeEventArg {
active_window_id: Option<WindowId>,
}
Expand Down
8 changes: 8 additions & 0 deletions crates/warpui/src/platform/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub trait AppBuilderExt {
/// This is used to identify the application and link it properly to its
/// .desktop file and associated resources (like app icons).
fn set_window_class(&mut self, window_class: String);
/// Sets the icon to apply to newly-created native windows.
fn set_window_icon(&mut self, icon: winit::window::Icon);

/// Whether or not to force the use of XWayland for users running Wayland.
fn force_x11(&mut self, force_x11: bool);
Expand All @@ -30,6 +32,12 @@ impl AppBuilderExt for super::AppBuilder {
AppBackend::Headless(_) => (),
}
}
fn set_window_icon(&mut self, icon: winit::window::Icon) {
match self.as_inner_mut() {
AppBackend::CurrentPlatform(app) => app.set_window_icon(icon),
AppBackend::Headless(_) => (),
}
}

fn force_x11(&mut self, force_x11: bool) {
match self.as_inner_mut() {
Expand Down
12 changes: 12 additions & 0 deletions crates/warpui/src/windowing/winit/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ pub struct App {
is_integration_test: bool,
window_class: Option<String>,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
window_icon: Option<winit::window::Icon>,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
force_x11: bool,
}

Expand All @@ -143,6 +145,8 @@ impl App {
is_integration_test: test_driver.is_some(),
window_class: None,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
window_icon: None,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
force_x11: false,
}
}
Expand All @@ -153,6 +157,10 @@ impl App {
pub(crate) fn set_window_class(&mut self, window_class: String) {
self.window_class = Some(window_class);
}
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
pub(crate) fn set_window_icon(&mut self, icon: winit::window::Icon) {
self.window_icon = Some(icon);
}

#[cfg(any(target_os = "linux", target_os = "freebsd"))]
pub(crate) fn force_x11(&mut self, force_x11: bool) {
Expand All @@ -169,6 +177,8 @@ impl App {
is_integration_test,
window_class,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
window_icon,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
force_x11,
} = self;

Expand Down Expand Up @@ -211,6 +221,8 @@ impl App {
callbacks,
init_fn,
window_class,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
window_icon,
event_loop.create_proxy(),
);

Expand Down
9 changes: 9 additions & 0 deletions crates/warpui/src/windowing/winit/event_loop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,8 @@ pub(super) struct EventLoop {
callbacks: AppCallbackDispatcher,
init_fn: Option<platform::app::AppInitCallbackFn>,
window_class: Option<String>,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
window_icon: Option<winit::window::Icon>,
state: State,
proxy: EventLoopProxy<CustomEvent>,
ime_enabled: bool,
Expand All @@ -522,13 +524,18 @@ impl EventLoop {
callbacks: platform::AppCallbacks,
init_fn: impl FnOnce(&mut AppContext, LocalBoxFuture<'static, crate::App>) + 'static,
window_class: Option<String>,
#[cfg(any(target_os = "linux", target_os = "freebsd"))] window_icon: Option<
winit::window::Icon,
>,
proxy: EventLoopProxy<CustomEvent>,
) -> Self {
Self {
ui_app: ui_app.clone(),
callbacks: AppCallbackDispatcher::new(callbacks, ui_app),
init_fn: Some(Box::new(init_fn)),
window_class,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
window_icon,
state: Default::default(),
proxy,
ime_enabled: false,
Expand Down Expand Up @@ -615,6 +622,8 @@ impl EventLoop {
window_target,
window_options,
&self.window_class,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
self.window_icon.as_ref(),
is_tiling_window_manager,
self.downrank_non_nvidia_vulkan_adapters,
) {
Expand Down
13 changes: 13 additions & 0 deletions crates/warpui/src/windowing/winit/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,13 +756,18 @@ impl Window {
window_target: &ActiveEventLoop,
window_options: WindowOptions,
window_class: &Option<String>,
#[cfg(any(target_os = "linux", target_os = "freebsd"))] window_icon: Option<
&winit::window::Icon,
>,
tiling_window_manager: bool,
downrank_non_nvidia_vulkan_adapters: bool,
) -> Result<winit::window::WindowId> {
let window = create_window(
window_target,
&window_options,
window_class,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
window_icon,
tiling_window_manager,
)?;

Expand Down Expand Up @@ -1296,6 +1301,9 @@ fn create_window(
window_target: &ActiveEventLoop,
window_options: &WindowOptions,
_window_class: &Option<String>,
#[cfg(any(target_os = "linux", target_os = "freebsd"))] window_icon: Option<
&winit::window::Icon,
>,
tiling_window_manager: bool,
) -> Result<winit::window::Window> {
let decorations = !window_options.hide_title_bar;
Expand Down Expand Up @@ -1415,6 +1423,11 @@ fn create_window(
FullscreenState::Normal => {}
}

#[cfg(any(target_os = "linux", target_os = "freebsd"))]
{
window_attributes.window_icon = window_icon.cloned();
}

#[cfg(any(target_os = "linux", target_os = "freebsd"))]
if let Some(window_class) = _window_class.as_deref() {
use winit::platform::x11::{WindowAttributesExtX11, WindowType};
Expand Down