Compare commits

..
8 Commits
Author SHA1 Message Date
galister d9287f3250 Release 0.4.4 2024-08-11 06:23:38 +09:00
hypevhs 378ea120c8 Fix mirrors spawning behind head 2024-08-10 20:34:55 +00:00
galister f4cc49ca69 fix keyboard macro regex 2024-08-09 23:25:59 +00:00
galister 57ff3aa1dd clippy 2024-08-09 10:19:57 +00:00
galister 0808383e70 corner_radius is optional 2024-08-09 10:19:57 +00:00
galister c71911998e upright screen fix 2024-08-09 08:38:37 +09:00
galister 50c3f49989 hmd pose from view space 2024-08-09 08:38:37 +09:00
Aleksander b6a07c43a5 Fix scrolling for all Electron-based applications 2024-08-07 18:12:20 +00:00
18 changed files with 181 additions and 116 deletions

No files matched your search

Generated
+3 -1
View File
@@ -2682,6 +2682,7 @@ version = "0.10.0"
source = "git+https://github.com/galister/openxrs?rev=af4a55d#af4a55df60125491c80c61464c824219c6019b76"
dependencies = [
"libc",
"mint",
]
[[package]]
@@ -4573,7 +4574,7 @@ dependencies = [
[[package]]
name = "wlx-overlay-s"
version = "0.4.3"
version = "0.4.4"
dependencies = [
"anyhow",
"ash",
@@ -4599,6 +4600,7 @@ dependencies = [
"libmonado-rs",
"log",
"log-panics",
"mint",
"once_cell",
"openxr",
"ovr_overlay",
+6 -1
View File
@@ -4,7 +4,7 @@ debug = true
[package]
name = "wlx-overlay-s"
version = "0.4.3"
version = "0.4.4"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -34,6 +34,7 @@ log = "0.4.21"
once_cell = "1.19.0"
openxr = { git = "https://github.com/galister/openxrs", rev = "af4a55d", features = [
"linked",
"mint",
], optional = true }
ovr_overlay = { features = [
"ovr_input",
@@ -67,6 +68,10 @@ xcb = { version = "1.4.0", optional = true, features = [
image_dds = { version = "0.6.0", default-features = false, features = [
"ddsfile",
] }
mint = "0.5.9"
[build-dependencies]
regex = { version = "*" }
[features]
default = ["openvr", "openxr", "osc", "x11", "wayland"]
+23
View File
@@ -0,0 +1,23 @@
use regex::Regex;
use std::process::Command;
fn main() {
let mut wlx_build = get_version().unwrap_or(format!("{} (Cargo)", env!("CARGO_PKG_VERSION")));
if std::env::var("GITHUB_ACTIONS").is_ok() {
wlx_build = format!("{} (AppImage)", &wlx_build)
}
println!("cargo:rustc-env=WLX_BUILD={}", &wlx_build);
}
fn get_version() -> Result<String, Box<dyn std::error::Error>> {
let re = Regex::new(r"v([0-9.]+)-([0-9]+)-g([a-f0-9]+)").unwrap(); // safe
let output = Command::new("git")
.args(["describe", "--tags", "--abbrev=7"])
.output()?;
let output_str = String::from_utf8(output.stdout)?;
Ok(re.replace_all(&output_str, "${1}.r${2}.${3}").into_owned())
}
+14 -7
View File
@@ -366,22 +366,27 @@ where
);
}
let haptics = hovered.backend.on_hover(app, &hit);
let scroll_threshold = 0.1;
let mut haptics: Option<Haptics> = None;
// Pass mouse motion events only if not scrolling
// (allows scrolling on all Chromium-based applications)
if app.input_state.pointers[idx].now.scroll.abs() <= scroll_threshold {
haptics = hovered.backend.on_hover(app, &hit);
}
pointer = &mut app.input_state.pointers[idx];
if pointer.now.scroll.abs() > 0.1 {
if pointer.now.scroll.abs() > scroll_threshold {
let scroll = pointer.now.scroll;
if app.input_state.pointers[1 - idx]
.interaction
.grabbed
.is_some_and(|x| x.grabbed_id == hit.overlay)
{
let is_portrait = hovered.view().is_some_and(|v| {
let extent = v.image().extent();
extent[0] >= extent[1]
});
let can_curve = hovered.extent().is_some_and(|e| e[0] >= e[1]);
if is_portrait {
if can_curve {
let cur = hovered.state.curvature.unwrap_or(0.0);
let new = (cur - scroll * 0.01).min(0.35);
if new <= f32::EPSILON {
@@ -389,6 +394,8 @@ where
} else {
hovered.state.curvature = Some(new);
}
} else {
hovered.state.curvature = None;
}
} else {
hovered.backend.on_scroll(app, &hit, scroll);
+13 -14
View File
@@ -132,21 +132,14 @@ pub(super) unsafe fn create_overlay_session(
}
}
pub(super) fn hmd_pose_from_views(views: &[xr::View]) -> (Affine3A, f32) {
let ipd;
let pos = {
let pos0: Vec3 = unsafe { std::mem::transmute(views[0].pose.position) };
let pos1: Vec3 = unsafe { std::mem::transmute(views[1].pose.position) };
ipd = (pos0.distance(pos1) * 1000.0).round() * 0.1;
(pos0 + pos1) * 0.5
};
let rot = {
let rot0: Quat = unsafe { std::mem::transmute(views[0].pose.orientation) };
let rot1: Quat = unsafe { std::mem::transmute(views[1].pose.orientation) };
rot0.lerp(rot1, 0.5)
};
type Vec3M = mint::Vector3<f32>;
type QuatM = mint::Quaternion<f32>;
(Affine3A::from_rotation_translation(rot, pos), ipd)
pub(super) fn ipd_from_views(views: &[xr::View]) -> f32 {
let p0: Vec3 = Vec3M::from(views[0].pose.position).into();
let p1: Vec3 = Vec3M::from(views[1].pose.position).into();
(p0.distance(p1) * 1000.0).round() * 0.1
}
pub(super) fn transform_to_norm_quat(transform: &Affine3A) -> Quat {
@@ -181,3 +174,9 @@ pub(super) fn transform_to_posef(transform: &Affine3A) -> xr::Posef {
let rotation = transform_to_norm_quat(transform);
translation_rotation_to_posef(translation, rotation)
}
pub(super) fn posef_to_transform(pose: &xr::Posef) -> Affine3A {
let rotation = QuatM::from(pose.orientation).into();
let translation = Vec3M::from(pose.position).into();
Affine3A::from_rotation_translation(rotation, translation)
}
+17 -1
View File
@@ -15,7 +15,7 @@ use crate::{
state::{AppSession, AppState},
};
use super::XrState;
use super::{helpers::posef_to_transform, XrState};
type XrSession = xr::Session<xr::Vulkan>;
@@ -204,6 +204,22 @@ impl OpenXrInputSource {
pub fn update(&mut self, xr: &XrState, state: &mut AppState) -> anyhow::Result<()> {
xr.session.sync_actions(&[(&self.action_set).into()])?;
let loc = xr.view.locate(&xr.stage, xr.predicted_display_time)?;
let hmd = posef_to_transform(&loc.pose);
if loc
.location_flags
.contains(xr::SpaceLocationFlags::ORIENTATION_VALID)
{
state.input_state.hmd.matrix3 = hmd.matrix3;
}
if loc
.location_flags
.contains(xr::SpaceLocationFlags::POSITION_VALID)
{
state.input_state.hmd.translation = hmd.translation;
}
for i in 0..2 {
self.hands[i].update(&mut state.input_state.pointers[i], xr, &state.session)?;
}
+5 -2
View File
@@ -49,6 +49,7 @@ struct XrState {
session: xr::Session<xr::Vulkan>,
predicted_display_time: xr::Time,
stage: Arc<xr::Space>,
view: Arc<xr::Space>,
stage_offset: Affine3A,
}
@@ -123,12 +124,15 @@ pub fn openxr_run(running: Arc<AtomicBool>, show_by_default: bool) -> Result<(),
let stage =
session.create_reference_space(xr::ReferenceSpaceType::STAGE, xr::Posef::IDENTITY)?;
let view = session.create_reference_space(xr::ReferenceSpaceType::VIEW, xr::Posef::IDENTITY)?;
let mut xr_state = XrState {
instance: xr_instance,
system,
session,
predicted_display_time: xr::Time::from_nanos(0),
stage: Arc::new(stage),
view: Arc::new(view),
stage_offset: Affine3A::IDENTITY,
};
@@ -274,8 +278,7 @@ pub fn openxr_run(running: Arc<AtomicBool>, show_by_default: bool) -> Result<(),
&xr_state.stage,
)?;
let (hmd, ipd) = helpers::hmd_pose_from_views(&views);
app_state.input_state.hmd = hmd;
let ipd = helpers::ipd_from_views(&views);
if (app_state.input_state.ipd - ipd).abs() > 0.01 {
log::info!("IPD changed: {} -> {}", app_state.input_state.ipd, ipd);
app_state.input_state.ipd = ipd;
-2
View File
@@ -1165,7 +1165,6 @@ pub struct WlxPipelineDynamic {}
pub struct WlxPipelineLegacy {
pub render_pass: Arc<RenderPass>,
pub framebuffer: Arc<Framebuffer>,
pub view: Arc<ImageView>,
}
pub struct WlxPipeline<D> {
@@ -1399,7 +1398,6 @@ impl WlxPipeline<WlxPipelineLegacy> {
data: WlxPipelineLegacy {
render_pass,
framebuffer,
view: render_target,
},
})
}
+22 -16
View File
@@ -120,21 +120,24 @@ impl<D, S> Control<D, S> {
self.rect.h,
)?;
let clamped_radius = self.corner_radius.min(self.rect.w / 2.0).min(self.rect.h / 2.0);
let clamped_radius = self
.corner_radius
.min(self.rect.w / 2.0)
.min(self.rect.h / 2.0);
let skew_radius = vec![
clamped_radius / self.rect.w,
clamped_radius / self.rect.h];
let skew_radius = [clamped_radius / self.rect.w, clamped_radius / self.rect.h];
let set0 = canvas
.pipeline_bg_color
.uniform_buffer(0, vec![
let set0 = canvas.pipeline_bg_color.uniform_buffer(
0,
vec![
self.bg_color.x,
self.bg_color.y,
self.bg_color.z,
self.bg_color.w,
skew_radius[0],
skew_radius[1]])?;
skew_radius[1],
],
)?;
canvas.pipeline_bg_color.create_pass(
[canvas.width as _, canvas.height as _],
@@ -163,21 +166,24 @@ impl<D, S> Control<D, S> {
self.rect.h,
)?;
let clamped_radius = self.corner_radius.min(self.rect.w / 2.0).min(self.rect.h / 2.0);
let clamped_radius = self
.corner_radius
.min(self.rect.w / 2.0)
.min(self.rect.h / 2.0);
let skew_radius = vec![
clamped_radius / self.rect.w,
clamped_radius / self.rect.h];
let skew_radius = [clamped_radius / self.rect.w, clamped_radius / self.rect.h];
let set0 = canvas
.pipeline_bg_color
.uniform_buffer(0, vec![
let set0 = canvas.pipeline_bg_color.uniform_buffer(
0,
vec![
color.x,
color.y,
color.z,
color.w,
skew_radius[0],
skew_radius[1]])?;
skew_radius[1],
],
)?;
let pass = canvas.pipeline_bg_color.create_pass(
[canvas.width as _, canvas.height as _],
+33 -12
View File
@@ -54,12 +54,12 @@ pub struct OverlayListTemplate {
pub enum ModularElement {
Panel {
rect: [f32; 4],
corner_radius: f32,
corner_radius: Option<f32>,
bg_color: Arc<str>,
},
Label {
rect: [f32; 4],
corner_radius: f32,
corner_radius: Option<f32>,
font_size: isize,
fg_color: Arc<str>,
#[serde(flatten)]
@@ -67,7 +67,7 @@ pub enum ModularElement {
},
CenteredLabel {
rect: [f32; 4],
corner_radius: f32,
corner_radius: Option<f32>,
font_size: isize,
fg_color: Arc<str>,
#[serde(flatten)]
@@ -80,7 +80,7 @@ pub enum ModularElement {
},
Button {
rect: [f32; 4],
corner_radius: f32,
corner_radius: Option<f32>,
font_size: isize,
fg_color: Arc<str>,
bg_color: Arc<str>,
@@ -91,7 +91,7 @@ pub enum ModularElement {
/// Convenience type to save you from having to create a bunch of labels
BatteryList {
rect: [f32; 4],
corner_radius: f32,
corner_radius: Option<f32>,
font_size: isize,
fg_color: Arc<str>,
fg_color_low: Arc<str>,
@@ -102,7 +102,7 @@ pub enum ModularElement {
},
OverlayList {
rect: [f32; 4],
corner_radius: f32,
corner_radius: Option<f32>,
font_size: isize,
fg_color: Arc<str>,
bg_color: Arc<str>,
@@ -150,7 +150,7 @@ pub fn modular_canvas(
bg_color,
} => {
canvas.bg_color = color_parse(bg_color).unwrap_or(*FALLBACK_COLOR);
canvas.panel(*x, *y, *w, *h, *corner_radius);
canvas.panel(*x, *y, *w, *h, corner_radius.unwrap_or_default());
}
ModularElement::Label {
rect: [x, y, w, h],
@@ -161,7 +161,14 @@ pub fn modular_canvas(
} => {
canvas.font_size = *font_size;
canvas.fg_color = color_parse(fg_color).unwrap_or(*FALLBACK_COLOR);
let label = canvas.label(*x, *y, *w, *h, *corner_radius, empty_str.clone());
let label = canvas.label(
*x,
*y,
*w,
*h,
corner_radius.unwrap_or_default(),
empty_str.clone(),
);
modular_label_init(label, data);
}
ModularElement::CenteredLabel {
@@ -173,7 +180,14 @@ pub fn modular_canvas(
} => {
canvas.font_size = *font_size;
canvas.fg_color = color_parse(fg_color).unwrap_or(*FALLBACK_COLOR);
let label = canvas.label_centered(*x, *y, *w, *h, *corner_radius, empty_str.clone());
let label = canvas.label_centered(
*x,
*y,
*w,
*h,
corner_radius.unwrap_or_default(),
empty_str.clone(),
);
modular_label_init(label, data);
}
ModularElement::Sprite {
@@ -207,7 +221,14 @@ pub fn modular_canvas(
canvas.bg_color = color_parse(bg_color).unwrap_or(*FALLBACK_COLOR);
canvas.fg_color = color_parse(fg_color).unwrap_or(*FALLBACK_COLOR);
canvas.font_size = *font_size;
let button = canvas.button(*x, *y, *w, *h, *corner_radius, text.clone());
let button = canvas.button(
*x,
*y,
*w,
*h,
corner_radius.unwrap_or_default(),
text.clone(),
);
modular_button_init(button, data);
}
ModularElement::BatteryList {
@@ -240,7 +261,7 @@ pub fn modular_canvas(
button_y + 2.,
button_w - 4.,
button_h - 4.,
*corner_radius,
corner_radius.unwrap_or_default(),
empty_str.clone(),
);
modular_label_init(
@@ -290,7 +311,7 @@ pub fn modular_canvas(
button_y + 2.,
button_w - 4.,
button_h - 4.,
*corner_radius,
corner_radius.unwrap_or_default(),
screen.name.clone(),
);
-1
View File
@@ -533,7 +533,6 @@ pub fn get_key_type(key: VirtualKey) -> KeyType {
}
pub struct XkbKeymap {
pub context: xkb::Context,
pub keymap: xkb::Keymap,
}
+1 -1
View File
@@ -120,7 +120,7 @@ impl Dispatch<WlKeyboard, ()> for WlKeymapHandler {
match maybe_keymap {
Ok(Some(keymap)) => {
state.keymap = Some(XkbKeymap { context, keymap });
state.keymap = Some(XkbKeymap { keymap });
}
Ok(None) => {
log::error!("Could not load keymap: no keymap");
+1 -1
View File
@@ -31,5 +31,5 @@ pub fn get_keymap_x11() -> anyhow::Result<XkbKeymap> {
}
let keymap = keymap_new_from_device(&context, &conn, device_id, xkb::KEYMAP_COMPILE_NO_FLAGS);
Ok(XkbKeymap { context, keymap })
Ok(XkbKeymap { keymap })
}
+1 -1
View File
@@ -79,7 +79,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
log::info!(
"Welcome to {} version {}!",
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION")
env!("WLX_BUILD"),
);
log::info!("It is {}.", chrono::Local::now().format("%c"));
+1 -1
View File
@@ -329,7 +329,7 @@ enum KeyButtonData {
static LAYOUT: Lazy<Layout> = Lazy::new(Layout::load_from_disk);
static MACRO_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^([A-Za-z0-1_-]+)(?: +(UP|DOWN))?$").unwrap()); // want panic
Lazy::new(|| Regex::new(r"^([A-Za-z0-9_-]+)(?: +(UP|DOWN))?$").unwrap()); // want panic
#[derive(Debug, Deserialize, Serialize)]
pub struct Layout {
-2
View File
@@ -4,7 +4,6 @@ use std::{
};
use futures::{Future, FutureExt};
use glam::vec3a;
use wlx_capture::pipewire::{pipewire_select_screen, PipewireCapture, PipewireSelectScreenResult};
use crate::{
@@ -137,7 +136,6 @@ pub fn new_mirror(
show_hide,
want_visible: true,
spawn_scale: 0.5 * session.config.desktop_view_scale,
spawn_point: vec3a(0., 0.5, 0.5),
..Default::default()
};
let backend = Box::new(SplitOverlayBackend {
+39 -24
View File
@@ -15,7 +15,7 @@ use vulkano::{
};
use wlx_capture::{
frame::{
DrmFormat, MouseMeta, WlxFrame, DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR8888,
DrmFormat, FrameFormat, MouseMeta, WlxFrame, DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR8888,
DRM_FORMAT_ARGB8888, DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888,
},
WlxCapture,
@@ -26,9 +26,12 @@ use {
crate::config_io,
std::error::Error,
std::{ops::Deref, path::PathBuf},
wlx_capture::pipewire::{pipewire_select_screen, PipewireCapture, PipewireStream},
wlx_capture::pipewire::{pipewire_select_screen, PipewireCapture},
};
#[cfg(all(feature = "x11", feature = "pipewire"))]
use wlx_capture::pipewire::PipewireStream;
#[cfg(feature = "wayland")]
use {
crate::config::AStrMapExt,
@@ -280,7 +283,7 @@ pub struct ScreenRenderer {
capture: Box<dyn WlxCapture>,
pipeline: Option<ScreenPipeline>,
last_view: Option<Arc<ImageView>>,
extent: [u32; 3],
extent: Option<[u32; 3]>,
}
impl ScreenRenderer {
@@ -291,12 +294,12 @@ impl ScreenRenderer {
capture,
pipeline: None,
last_view: None,
extent: [0; 3],
extent: None,
}
}
#[cfg(feature = "wayland")]
pub fn new_wlr_dmabuf(output: &WlxOutput, config: &GeneralConfig) -> Option<ScreenRenderer> {
pub fn new_wlr_dmabuf(output: &WlxOutput) -> Option<ScreenRenderer> {
let client = WlxClient::new()?;
let capture = WlrDmabufCapture::new(client, output.id);
@@ -305,15 +308,12 @@ impl ScreenRenderer {
capture: Box::new(capture),
pipeline: None,
last_view: None,
extent: extent_from_res(output.size, config),
extent: None,
})
}
#[cfg(feature = "wayland")]
pub fn new_wlr_screencopy(
output: &WlxOutput,
config: &GeneralConfig,
) -> Option<ScreenRenderer> {
pub fn new_wlr_screencopy(output: &WlxOutput) -> Option<ScreenRenderer> {
let client = WlxClient::new()?;
let capture = WlrScreencopyCapture::new(client, output.id);
@@ -322,7 +322,7 @@ impl ScreenRenderer {
capture: Box::new(capture),
pipeline: None,
last_view: None,
extent: extent_from_res(output.size, config),
extent: None,
})
}
@@ -363,14 +363,14 @@ impl ScreenRenderer {
capture: Box::new(capture),
pipeline: None,
last_view: None,
extent: extent_from_res(output.size, &session.config),
extent: None,
},
select_screen_result.restore_token,
))
}
#[cfg(feature = "x11")]
pub fn new_xshm(screen: Arc<XshmScreen>, config: &GeneralConfig) -> ScreenRenderer {
pub fn new_xshm(screen: Arc<XshmScreen>) -> ScreenRenderer {
let capture = XshmCapture::new(screen.clone());
ScreenRenderer {
@@ -378,7 +378,7 @@ impl ScreenRenderer {
capture: Box::new(capture),
pipeline: None,
last_view: None,
extent: extent_from_res((screen.monitor.width(), screen.monitor.height()), config),
extent: None,
}
}
}
@@ -466,6 +466,9 @@ impl OverlayRenderer for ScreenRenderer {
log::error!("Invalid frame");
continue;
}
self.extent.get_or_insert_with(|| {
extent_from_format(frame.format, &app.session.config)
});
match app.graphics.dmabuf_texture(frame) {
Ok(new) => {
let view = ImageView::new_default(new.clone())?;
@@ -491,6 +494,9 @@ impl OverlayRenderer for ScreenRenderer {
log::error!("No fd");
continue;
};
self.extent.get_or_insert_with(|| {
extent_from_format(frame.format, &app.session.config)
});
log::debug!("{}: New MemFd frame", self.name);
let format = fourcc_to_vk(frame.format.fourcc)?;
@@ -543,10 +549,12 @@ impl OverlayRenderer for ScreenRenderer {
let pipeline = Some(match self.pipeline {
Some(ref mut p) => p,
_ => {
let mut pipeline = ScreenPipeline::new(&self.extent, app)?;
let extent = extent_from_format(frame.format, &app.session.config);
let mut pipeline = ScreenPipeline::new(&extent, app)?;
self.last_view = Some(pipeline.view.clone());
pipeline.ensure_mouse_initialized(&mut upload)?;
self.pipeline = Some(pipeline);
self.extent = Some(extent);
self.pipeline.as_mut().unwrap() // safe
}
});
@@ -577,7 +585,7 @@ impl OverlayRenderer for ScreenRenderer {
self.last_view.clone()
}
fn extent(&mut self) -> Option<[u32; 3]> {
Some(self.extent)
self.extent
}
}
@@ -594,12 +602,12 @@ pub fn create_screen_renderer_wl(
&& has_wlr_dmabuf
{
log::info!("{}: Using Wlr DMA-Buf", &output.name);
capture = ScreenRenderer::new_wlr_dmabuf(output, &session.config);
capture = ScreenRenderer::new_wlr_dmabuf(output);
}
if &*session.config.capture_method == "screencopy" && has_wlr_screencopy {
log::info!("{}: Using Wlr Screencopy Wl-SHM", &output.name);
capture = ScreenRenderer::new_wlr_screencopy(output, &session.config);
capture = ScreenRenderer::new_wlr_screencopy(output);
}
if capture.is_none() {
@@ -899,7 +907,11 @@ pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result<ScreenCreateDa
capture: Box::new(PipewireCapture::new(m.name.clone(), s.node_id)),
pipeline: None,
last_view: None,
extent: extent_from_res(size, &app.session.config),
extent: Some(extent_from_res(
size.0 as _,
size.1 as _,
&app.session.config,
)),
};
let backend = Box::new(SplitOverlayBackend {
@@ -937,7 +949,7 @@ pub fn create_screens_xshm(app: &mut AppState) -> anyhow::Result<ScreenCreateDat
let size = (s.monitor.width(), s.monitor.height());
let pos = (s.monitor.x(), s.monitor.y());
let renderer = ScreenRenderer::new_xshm(s.clone(), &app.session.config);
let renderer = ScreenRenderer::new_xshm(s.clone());
log::info!(
"{}: Init X11 screen of res {:?} at {:?}",
@@ -1003,11 +1015,14 @@ impl From<wl_output::Transform> for Transform {
}
}
fn extent_from_res(res: (i32, i32), config: &GeneralConfig) -> [u32; 3] {
// screens above a certain resolution will have severe aliasing
fn extent_from_format(fmt: FrameFormat, config: &GeneralConfig) -> [u32; 3] {
extent_from_res(fmt.width, fmt.height, config)
}
let h = res.1.min(config.screen_max_height as i32) as u32;
let w = (res.0 as f32 / res.1 as f32 * h as f32) as u32;
fn extent_from_res(width: u32, height: u32, config: &GeneralConfig) -> [u32; 3] {
// screens above a certain resolution will have severe aliasing
let h = height.min(config.screen_max_height as u32);
let w = (width as f32 / height as f32 * h as f32) as u32;
[w, h, 1]
}
+2 -29
View File
@@ -1,7 +1,7 @@
use std::{io::Cursor, path::PathBuf, sync::Arc};
use std::{io::Cursor, sync::Arc};
use anyhow::bail;
use glam::{Affine3A, Vec3};
use glam::Affine3A;
use idmap::IdMap;
use rodio::{Decoder, OutputStream, OutputStreamHandle, Source};
use serde::{Deserialize, Serialize};
@@ -89,15 +89,9 @@ impl AppState {
}
pub struct AppSession {
pub config_root_path: PathBuf,
pub config: GeneralConfig,
pub toast_topics: IdMap<ToastTopic, DisplayMethod>,
pub color_norm: Vec3,
pub color_shift: Vec3,
pub color_alt: Vec3,
pub color_grab: Vec3,
}
impl AppSession {
@@ -116,29 +110,8 @@ impl AppSession {
});
AppSession {
config_root_path,
config,
toast_topics,
color_norm: Vec3 {
x: 0.,
y: 1.,
z: 1.,
},
color_shift: Vec3 {
x: 1.,
y: 1.,
z: 0.,
},
color_alt: Vec3 {
x: 1.,
y: 0.,
z: 1.,
},
color_grab: Vec3 {
x: 1.,
y: 0.,
z: 0.,
},
}
}
}