mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-09 10:39:46 -10:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf125a1a69 | ||
|
|
b77e4c4924 | ||
|
|
aa060c5fe1 | ||
|
|
07ff96c50c | ||
|
|
19c23a96c6 | ||
|
|
29d8c49bc2 |
No files matched your search
@@ -9,11 +9,13 @@ description = "The client's input layer: key bindings and their names, mouse, co
|
||||
[dependencies]
|
||||
horizon-client-core = { path = "../horizon-client-core" }
|
||||
winit = "0.30.13"
|
||||
# The window icon.
|
||||
horizon-theme = { path = "../horizon-theme" }
|
||||
png = "0.18"
|
||||
arboard = { version = "3.6.1", default-features = false, features = ["wayland-data-control"] }
|
||||
|
||||
[dev-dependencies]
|
||||
# The window icon test decodes Horizon's icon.
|
||||
horizon-theme = { path = "../horizon-theme" }
|
||||
|
||||
[features]
|
||||
controllers = []
|
||||
|
||||
|
||||
@@ -638,10 +638,30 @@ pub fn fullscreen_request(
|
||||
}
|
||||
}
|
||||
|
||||
/// Horizon's icon for the window's title bar and the task bar (X11 and Windows; Wayland takes
|
||||
/// it from the `horizon.desktop` entry, macOS from the app bundle). `None` if it can't be read.
|
||||
/// The PNG the windows show as their icon, given once at startup by the layer that brands the
|
||||
/// game (the engine has none of its own).
|
||||
static ICON_PNG: std::sync::OnceLock<&'static [u8]> = std::sync::OnceLock::new();
|
||||
|
||||
/// Give the windows their icon, a PNG: call it before the first window opens. A second call
|
||||
/// keeps the first icon.
|
||||
pub fn set_icon_png(png: &'static [u8]) {
|
||||
let _ = ICON_PNG.set(png);
|
||||
}
|
||||
|
||||
/// The icon given to [`set_icon_png`], if any.
|
||||
pub fn icon_png() -> Option<&'static [u8]> {
|
||||
ICON_PNG.get().copied()
|
||||
}
|
||||
|
||||
/// The icon for the window's title bar and the task bar (X11 and Windows; Wayland takes it from
|
||||
/// the `.desktop` entry, macOS from the app bundle). `None` with no icon given, or one that
|
||||
/// can't be read.
|
||||
pub fn icon() -> Option<winit::window::Icon> {
|
||||
let mut decoder = png::Decoder::new(std::io::Cursor::new(horizon_theme::ICON_PNG));
|
||||
decode_icon(icon_png()?)
|
||||
}
|
||||
|
||||
fn decode_icon(png: &[u8]) -> Option<winit::window::Icon> {
|
||||
let mut decoder = png::Decoder::new(std::io::Cursor::new(png));
|
||||
decoder.ignore_checksums(true);
|
||||
decoder.set_transformations(png::Transformations::EXPAND | png::Transformations::STRIP_16);
|
||||
let mut reader = decoder.read_info().ok()?;
|
||||
@@ -654,14 +674,15 @@ pub fn icon() -> Option<winit::window::Icon> {
|
||||
winit::window::Icon::from_rgba(bytes, info.width, info.height).ok()
|
||||
}
|
||||
|
||||
/// Apply Horizon's icon to every window. Windows has a separate taskbar icon slot from the small
|
||||
/// window icon; requiring the decoded icon there prevents a generic taskbar icon from appearing.
|
||||
pub fn with_horizon_icon(
|
||||
attributes: winit::window::WindowAttributes,
|
||||
) -> winit::window::WindowAttributes {
|
||||
/// Apply the icon given to [`set_icon_png`] to a window. Windows has a separate taskbar icon slot
|
||||
/// from the small window icon; requiring a given icon to decode there prevents a generic taskbar
|
||||
/// icon from appearing.
|
||||
pub fn with_icon(attributes: winit::window::WindowAttributes) -> winit::window::WindowAttributes {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let icon = icon();
|
||||
#[cfg(target_os = "windows")]
|
||||
let icon = Some(icon.expect("Horizon's icon must be available on Windows"));
|
||||
let icon =
|
||||
icon_png().map(|png| decode_icon(png).expect("the window icon must decode on Windows"));
|
||||
|
||||
let attributes = attributes.with_window_icon(icon.clone());
|
||||
#[cfg(target_os = "windows")]
|
||||
@@ -706,7 +727,8 @@ mod tests {
|
||||
}
|
||||
#[test]
|
||||
fn the_window_icon_decodes() {
|
||||
assert!(icon().is_some());
|
||||
assert!(decode_icon(horizon_theme::ICON_PNG).is_some());
|
||||
assert!(decode_icon(b"not a png").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -13,6 +13,7 @@ pub fn main_with(mods: crate::mod_api::Mods) {
|
||||
log::warn!("Trait mods already installed; ignoring the second list");
|
||||
}
|
||||
horizon_threads::configure_allocator();
|
||||
crate::horizon_look::give();
|
||||
// OptiFine's and Polytone's pack formats (platform, docs/layers.md), before any pack loads.
|
||||
horizon_client::pack_formats::install();
|
||||
// horizon-extras (docs/forking.md): without the feature, no Horizon Settings or Mods page.
|
||||
|
||||
@@ -98,9 +98,8 @@ impl Loading {
|
||||
.map_or([1280, 720], |o| o.window_size)
|
||||
.map(f64::from);
|
||||
self.fullscreen = horizon_client::window::FullscreenState::new(fullscreen);
|
||||
let attributes = horizon_client::window::with_horizon_icon(
|
||||
Window::default_attributes().with_title("Horizon"),
|
||||
);
|
||||
let attributes =
|
||||
horizon_client::window::with_icon(Window::default_attributes().with_title("Horizon"));
|
||||
// Wayland names the window by its app id, which the horizon.desktop entry matches.
|
||||
#[cfg(target_os = "linux")]
|
||||
let attributes = winit::platform::wayland::WindowAttributesExtWayland::with_name(
|
||||
|
||||
@@ -93,10 +93,9 @@ impl ApplicationHandler for Missing {
|
||||
if self.window.is_some() {
|
||||
return;
|
||||
}
|
||||
let attributes = horizon_client::window::with_horizon_icon(
|
||||
Window::default_attributes().with_title("Horizon"),
|
||||
)
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(1040.0, 700.0));
|
||||
let attributes =
|
||||
horizon_client::window::with_icon(Window::default_attributes().with_title("Horizon"))
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(1040.0, 700.0));
|
||||
let made = event_loop
|
||||
.create_window(attributes)
|
||||
.map_err(Into::into)
|
||||
|
||||
@@ -516,10 +516,9 @@ impl<'a> Split<'a> {
|
||||
continue;
|
||||
}
|
||||
// Opened without the focus: whoever types in the game's window keeps the keyboard.
|
||||
let attributes =
|
||||
horizon_client::window::with_horizon_icon(Window::default_attributes())
|
||||
.with_active(false)
|
||||
.with_visible(window_shown(true, self.offscreen));
|
||||
let attributes = horizon_client::window::with_icon(Window::default_attributes())
|
||||
.with_active(false)
|
||||
.with_visible(window_shown(true, self.offscreen));
|
||||
// A monitor's window covers it, borderless. On macOS not the system's fullscreen, a
|
||||
// Space of its own that hides the other windows as it slides in.
|
||||
let placement = self.placement(*key).cloned();
|
||||
|
||||
@@ -273,9 +273,8 @@ impl ApplicationHandler for Game<'_> {
|
||||
let fullscreen = self.settings.fullscreen || self.options.fullscreen;
|
||||
let size = self.options.window_size.map(f64::from);
|
||||
self.fullscreen = horizon_client::window::FullscreenState::new(fullscreen);
|
||||
let attributes = horizon_client::window::with_horizon_icon(
|
||||
Window::default_attributes().with_title("Horizon"),
|
||||
);
|
||||
let attributes =
|
||||
horizon_client::window::with_icon(Window::default_attributes().with_title("Horizon"));
|
||||
// Wayland names the window by its app id, which the horizon.desktop entry matches.
|
||||
#[cfg(target_os = "linux")]
|
||||
let attributes = winit::platform::wayland::WindowAttributesExtWayland::with_name(
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
//! Horizon's look, given to the engine's extension points at startup (docs/layers.md): the
|
||||
//! windows' icon. Its own module so it can leave the engine crate as a pure file move, for the
|
||||
//! official executable to call.
|
||||
|
||||
/// Give the engine Horizon's look; call it once, before the first window opens.
|
||||
pub(crate) fn give() {
|
||||
horizon_client::window::set_icon_png(horizon_theme::ICON_PNG);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ extern crate self as horizon_client;
|
||||
pub use horizon_client_lib::*;
|
||||
pub mod entry;
|
||||
pub mod game;
|
||||
mod horizon_look;
|
||||
pub mod mod_api;
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -95,7 +95,6 @@
|
||||
"horizon-client -> horizon-shaders",
|
||||
"horizon-client -> horizon-telemetry",
|
||||
"horizon-client -> horizon-theme",
|
||||
"horizon-client-input -> horizon-theme",
|
||||
"horizon-client-lib -> horizon-anticheat",
|
||||
"horizon-client-lib -> horizon-bench",
|
||||
"horizon-client-lib -> horizon-chat-filter",
|
||||
|
||||
Reference in new issue
Block a user