mirror of https://github.com/wayvr-org/wayvr.git
wvr_server: scale windows based on resolution
This commit is contained in:
parent
2d820f1d1b
commit
b2037feacf
|
|
@ -424,12 +424,12 @@ impl WayVRClient {
|
||||||
|
|
||||||
pub async fn fn_wlx_handsfree(
|
pub async fn fn_wlx_handsfree(
|
||||||
client: WayVRClientMutex,
|
client: WayVRClientMutex,
|
||||||
params: HandsfreeParams
|
params: HandsfreeParams,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
send_only!(client, &PacketClient::WlxHandsfree(params));
|
send_only!(client, &PacketClient::WlxHandsfree(params));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fn_wlx_modify_panel(
|
pub async fn fn_wlx_modify_panel(
|
||||||
client: WayVRClientMutex,
|
client: WayVRClientMutex,
|
||||||
params: packet_client::WlxModifyPanelParams,
|
params: packet_client::WlxModifyPanelParams,
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ impl Application {
|
||||||
self.redraw_requests.remove(surface_id)
|
self.redraw_requests.remove(surface_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_logical_size(&self) -> Size<i32, Logical> {
|
pub fn output_logical_size(&self) -> Size<i32, Logical> {
|
||||||
self.output
|
self.output
|
||||||
.current_mode()
|
.current_mode()
|
||||||
.map(|mode| Size::new(mode.size.w, mode.size.h))
|
.map(|mode| Size::new(mode.size.w, mode.size.h))
|
||||||
|
|
@ -520,36 +520,60 @@ impl XdgShellHandler for Application {
|
||||||
surface.send_repositioned(token);
|
surface.send_repositioned(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the app wants to be fullscreen, make it think that it's fullscreen.
|
// If the app requests fullscreen, make it fill the virtual output
|
||||||
fn fullscreen_request(
|
fn fullscreen_request(
|
||||||
&mut self,
|
&mut self,
|
||||||
surface: ToplevelSurface,
|
surface: ToplevelSurface,
|
||||||
_output: Option<wl_output::WlOutput>,
|
_output: Option<wl_output::WlOutput>,
|
||||||
) {
|
) {
|
||||||
|
let size = self.output_logical_size();
|
||||||
|
|
||||||
surface.with_pending_state(|state| {
|
surface.with_pending_state(|state| {
|
||||||
|
state.bounds = Some(size);
|
||||||
|
state.size = Some(size);
|
||||||
state.states.set(xdg_toplevel::State::Fullscreen);
|
state.states.set(xdg_toplevel::State::Fullscreen);
|
||||||
});
|
});
|
||||||
|
|
||||||
surface.send_configure();
|
surface.send_configure();
|
||||||
}
|
}
|
||||||
fn unfullscreen_request(&mut self, surface: ToplevelSurface) {
|
|
||||||
surface.with_pending_state(|state| {
|
// If the app requests maximize, make it fill the virtual output
|
||||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
|
||||||
});
|
|
||||||
surface.send_configure();
|
|
||||||
}
|
|
||||||
// If the app wants to be maximized, make it think that it's maximized.
|
|
||||||
fn maximize_request(&mut self, surface: ToplevelSurface) {
|
fn maximize_request(&mut self, surface: ToplevelSurface) {
|
||||||
|
let size = self.output_logical_size();
|
||||||
|
|
||||||
surface.with_pending_state(|state| {
|
surface.with_pending_state(|state| {
|
||||||
|
state.bounds = Some(size);
|
||||||
|
state.size = Some(size);
|
||||||
state.states.set(xdg_toplevel::State::Maximized);
|
state.states.set(xdg_toplevel::State::Maximized);
|
||||||
});
|
});
|
||||||
|
|
||||||
surface.send_configure();
|
surface.send_configure();
|
||||||
}
|
}
|
||||||
fn unmaximize_request(&mut self, surface: ToplevelSurface) {
|
|
||||||
|
fn unfullscreen_request(&mut self, surface: ToplevelSurface) {
|
||||||
|
let bounds = self.output_logical_size();
|
||||||
|
|
||||||
surface.with_pending_state(|state| {
|
surface.with_pending_state(|state| {
|
||||||
|
state.bounds = Some(bounds);
|
||||||
|
state.size = None;
|
||||||
|
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||||
|
});
|
||||||
|
|
||||||
|
surface.send_configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unmaximize_request(&mut self, surface: ToplevelSurface) {
|
||||||
|
let bounds = self.output_logical_size();
|
||||||
|
|
||||||
|
surface.with_pending_state(|state| {
|
||||||
|
state.bounds = Some(bounds);
|
||||||
|
state.size = None;
|
||||||
state.states.unset(xdg_toplevel::State::Maximized);
|
state.states.unset(xdg_toplevel::State::Maximized);
|
||||||
});
|
});
|
||||||
|
|
||||||
surface.send_configure();
|
surface.send_configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the app requests minimize, hide its window
|
// If the app requests minimize, hide its window
|
||||||
fn minimize_request(&mut self, surface: ToplevelSurface) {
|
fn minimize_request(&mut self, surface: ToplevelSurface) {
|
||||||
if let Some(client) = surface.wl_surface().client() {
|
if let Some(client) = surface.wl_surface().client() {
|
||||||
|
|
|
||||||
|
|
@ -343,28 +343,35 @@ impl WvrServerState {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let output_bounds = wvr_server.manager.state.output_logical_size();
|
||||||
|
|
||||||
let (min_size, max_size) = with_states(toplevel.wl_surface(), |state| {
|
let (min_size, max_size) = with_states(toplevel.wl_surface(), |state| {
|
||||||
let mut guard = state.cached_state.get::<SurfaceCachedState>();
|
let mut guard = state.cached_state.get::<SurfaceCachedState>();
|
||||||
let (mut min_size, mut max_size) =
|
let current = guard.current();
|
||||||
{ (guard.current().min_size, guard.current().max_size) };
|
|
||||||
|
let mut min_size = current.min_size;
|
||||||
|
let mut max_size = current.max_size;
|
||||||
|
|
||||||
if min_size.is_empty() {
|
if min_size.is_empty() {
|
||||||
min_size = Size::new(1, 1);
|
min_size = Size::new(1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if max_size.is_empty() {
|
if max_size.is_empty() {
|
||||||
max_size = Size::new(4096, 4096);
|
max_size = output_bounds;
|
||||||
|
} else {
|
||||||
|
max_size = max_size.clamp(Size::new(1, 1), output_bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
(min_size, max_size)
|
(min_size, max_size)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Size, icon & fallback title comes from process
|
// Size, icon & fallback title comes from process
|
||||||
let (size, pos, fallback_title, icon, is_cage) =
|
let (fallback_size, pos, fallback_title, icon, is_cage) =
|
||||||
match wvr_server.processes.get(&process_handle) {
|
match wvr_server.processes.get(&process_handle) {
|
||||||
Some(Process::Managed(p)) => {
|
Some(Process::Managed(p)) => {
|
||||||
let size: Size<i32, Logical> =
|
let size: Size<i32, Logical> =
|
||||||
Size::new(p.resolution[0] as _, p.resolution[1] as _);
|
Size::new(p.resolution[0] as _, p.resolution[1] as _);
|
||||||
|
|
||||||
(
|
(
|
||||||
size.clamp(min_size, max_size),
|
size.clamp(min_size, max_size),
|
||||||
p.pos_mode,
|
p.pos_mode,
|
||||||
|
|
@ -382,6 +389,21 @@ impl WvrServerState {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let window_handle = wvr_server.wm.create_window(
|
||||||
|
toplevel.clone(),
|
||||||
|
process_handle,
|
||||||
|
fallback_size.w as _,
|
||||||
|
fallback_size.h as _,
|
||||||
|
);
|
||||||
|
|
||||||
|
toplevel.with_pending_state(|state| {
|
||||||
|
state.bounds = Some(output_bounds);
|
||||||
|
// suggest an initial size but let the app request a different one
|
||||||
|
state.size = Some(fallback_size);
|
||||||
|
state.states.set(xdg_toplevel::State::Activated);
|
||||||
|
});
|
||||||
|
toplevel.send_configure();
|
||||||
|
|
||||||
let mut title: Arc<str> = fallback_title
|
let mut title: Arc<str> = fallback_title
|
||||||
.unwrap_or_else(|| format!("P{}", client.pid))
|
.unwrap_or_else(|| format!("P{}", client.pid))
|
||||||
.into();
|
.into();
|
||||||
|
|
@ -392,19 +414,6 @@ impl WvrServerState {
|
||||||
SpawnPos::Parent(OverlaySelector::Id(oid))
|
SpawnPos::Parent(OverlaySelector::Id(oid))
|
||||||
});
|
});
|
||||||
|
|
||||||
let window_handle = wvr_server.wm.create_window(
|
|
||||||
toplevel.clone(),
|
|
||||||
process_handle,
|
|
||||||
size.w as _,
|
|
||||||
size.h as _,
|
|
||||||
);
|
|
||||||
toplevel.with_pending_state(|state| {
|
|
||||||
state.size = Some(size);
|
|
||||||
state.states.set(xdg_toplevel::State::Activated);
|
|
||||||
state.states.set(xdg_toplevel::State::Maximized);
|
|
||||||
});
|
|
||||||
toplevel.send_configure();
|
|
||||||
|
|
||||||
let mut icon = icon;
|
let mut icon = icon;
|
||||||
|
|
||||||
// Try to get title from xdg_toplevel, unless it's running in cage
|
// Try to get title from xdg_toplevel, unless it's running in cage
|
||||||
|
|
@ -456,7 +465,7 @@ impl WvrServerState {
|
||||||
app,
|
app,
|
||||||
window_handle,
|
window_handle,
|
||||||
icon,
|
icon,
|
||||||
[size.w as _, size.h as _],
|
[fallback_size.w as _, fallback_size.h as _],
|
||||||
pos,
|
pos,
|
||||||
)
|
)
|
||||||
.context("Could not create WvrWindow overlay")
|
.context("Could not create WvrWindow overlay")
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use smithay::utils::{Logical, Size};
|
||||||
use smithay::wayland::shell::xdg::ToplevelSurface;
|
use smithay::wayland::shell::xdg::ToplevelSurface;
|
||||||
use wayvr_ipc::packet_server;
|
use wayvr_ipc::packet_server;
|
||||||
|
|
||||||
|
|
@ -25,15 +26,33 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_size(&mut self, size_x: u32, size_y: u32) {
|
pub fn configure_size(&mut self, size: Option<Size<i32, Logical>>, bounds: Size<i32, Logical>) {
|
||||||
self.toplevel.with_pending_state(|state| {
|
self.toplevel.with_pending_state(|state| {
|
||||||
//state.bounds = Some((size_x as i32, size_y as i32).into());
|
state.bounds = Some(bounds);
|
||||||
state.size = Some((size_x as i32, size_y as i32).into());
|
state.size = size;
|
||||||
});
|
});
|
||||||
self.toplevel.send_configure();
|
self.toplevel.send_configure();
|
||||||
|
|
||||||
|
if let Some(size) = size {
|
||||||
|
self.remember_committed_size(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn request_size(&mut self, size: Size<i32, Logical>, bounds: Size<i32, Logical>) {
|
||||||
|
let size = size.clamp(Size::new(1, 1), bounds);
|
||||||
|
self.configure_size(Some(size), bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remember_committed_size(&mut self, size: Size<i32, Logical>) -> bool {
|
||||||
|
let size_x = size.w.max(1) as u32;
|
||||||
|
let size_y = size.h.max(1) as u32;
|
||||||
|
|
||||||
|
let changed = self.size_x != size_x || self.size_y != size_y;
|
||||||
|
|
||||||
self.size_x = size_x;
|
self.size_x = size_x;
|
||||||
self.size_y = size_y;
|
self.size_y = size_y;
|
||||||
|
|
||||||
|
changed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +97,7 @@ impl WindowManager {
|
||||||
size_y: u32,
|
size_y: u32,
|
||||||
) -> WindowHandle {
|
) -> WindowHandle {
|
||||||
let mut window = Window::new(toplevel, process);
|
let mut window = Window::new(toplevel, process);
|
||||||
window.set_size(size_x, size_y);
|
window.remember_committed_size(Size::new(size_x as i32, size_y as i32));
|
||||||
self.windows.add(window)
|
self.windows.add(window)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
use glam::{Affine2, Affine3A, Quat, Vec2, Vec3, vec2, vec3};
|
use glam::{Affine2, Affine3A, Quat, Vec2, Vec3, vec2, vec3};
|
||||||
|
use slotmap::Key;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
desktop::PopupManager,
|
desktop::PopupManager,
|
||||||
reexports::wayland_server::{Resource, backend::ObjectId, protocol::wl_surface::WlSurface},
|
reexports::wayland_server::{Resource, backend::ObjectId, protocol::wl_surface::WlSurface},
|
||||||
utils::{Logical, Point},
|
utils::{Logical, Point, Size},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::{
|
compositor::{
|
||||||
SUBSURFACE_ROLE, SubsurfaceCachedState, SurfaceAttributes, TraversalAction,
|
SUBSURFACE_ROLE, SubsurfaceCachedState, SurfaceAttributes, TraversalAction,
|
||||||
|
|
@ -37,6 +38,7 @@ use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
XrBackend,
|
XrBackend,
|
||||||
input::{self, HoverResult},
|
input::{self, HoverResult},
|
||||||
|
task::{OverlayTask, TaskType},
|
||||||
wayvr::{
|
wayvr::{
|
||||||
self, PointerFocusTarget, SurfaceBufWithImage, process::KillSignal,
|
self, PointerFocusTarget, SurfaceBufWithImage, process::KillSignal,
|
||||||
window::WindowHandle,
|
window::WindowHandle,
|
||||||
|
|
@ -51,6 +53,7 @@ use crate::{
|
||||||
state::{self, AppState},
|
state::{self, AppState},
|
||||||
subsystem::{hid::WheelDelta, input::KeyboardFocus},
|
subsystem::{hid::WheelDelta, input::KeyboardFocus},
|
||||||
windowing::{
|
windowing::{
|
||||||
|
OverlayID, OverlaySelector,
|
||||||
backend::{
|
backend::{
|
||||||
FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender,
|
FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender,
|
||||||
ui_transform,
|
ui_transform,
|
||||||
|
|
@ -75,8 +78,7 @@ pub fn create_wl_window_overlay(
|
||||||
size: [u32; 2],
|
size: [u32; 2],
|
||||||
pos_mode: PositionMode,
|
pos_mode: PositionMode,
|
||||||
) -> anyhow::Result<OverlayWindowConfig> {
|
) -> anyhow::Result<OverlayWindowConfig> {
|
||||||
let scale = size[0].max(size[1]) as f32 / 1920.0;
|
let (scale, curve_scale) = overlay_scale_from_extent(size);
|
||||||
let curve_scale = size[0] as f32 / 1920.0;
|
|
||||||
|
|
||||||
let z_dist = if matches!(pos_mode, PositionMode::Anchor) {
|
let z_dist = if matches!(pos_mode, PositionMode::Anchor) {
|
||||||
0.0
|
0.0
|
||||||
|
|
@ -106,7 +108,11 @@ pub fn create_wl_window_overlay(
|
||||||
category: OverlayCategory::WayVR,
|
category: OverlayCategory::WayVR,
|
||||||
show_on_spawn: true,
|
show_on_spawn: true,
|
||||||
..OverlayWindowConfig::from_backend(Box::new(WvrWindowBackend::new(
|
..OverlayWindowConfig::from_backend(Box::new(WvrWindowBackend::new(
|
||||||
name, app, window, icon,
|
name,
|
||||||
|
app,
|
||||||
|
window,
|
||||||
|
icon,
|
||||||
|
(scale, curve_scale),
|
||||||
)?))
|
)?))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -167,6 +173,8 @@ pub struct WvrWindowBackend {
|
||||||
uv_range: RangeInclusive<f32>,
|
uv_range: RangeInclusive<f32>,
|
||||||
panel_hovered: bool,
|
panel_hovered: bool,
|
||||||
scrolling: bool,
|
scrolling: bool,
|
||||||
|
overlay_id: OverlayID,
|
||||||
|
scale: (f32, f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WvrWindowBackend {
|
impl WvrWindowBackend {
|
||||||
|
|
@ -175,6 +183,7 @@ impl WvrWindowBackend {
|
||||||
app: &mut AppState,
|
app: &mut AppState,
|
||||||
window: wayvr::window::WindowHandle,
|
window: wayvr::window::WindowHandle,
|
||||||
icon: Arc<str>,
|
icon: Arc<str>,
|
||||||
|
scale: (f32, f32),
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
let subsurface_pipeline = app.gfx.create_pipeline(
|
let subsurface_pipeline = app.gfx.create_pipeline(
|
||||||
app.gfx_extras.shaders.get("vert_quad").unwrap(), // want panic
|
app.gfx_extras.shaders.get("vert_quad").unwrap(), // want panic
|
||||||
|
|
@ -274,10 +283,43 @@ impl WvrWindowBackend {
|
||||||
uv_range: 0.0..=1.0,
|
uv_range: 0.0..=1.0,
|
||||||
panel_hovered: false,
|
panel_hovered: false,
|
||||||
scrolling: false,
|
scrolling: false,
|
||||||
|
overlay_id: OverlayID::null(),
|
||||||
|
scale,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_extent(&mut self, app: &mut AppState, meta: &FrameMeta) -> anyhow::Result<()> {
|
fn apply_extent(&mut self, app: &mut AppState, meta: &FrameMeta) -> anyhow::Result<()> {
|
||||||
|
let (old_scale, old_curve_scale) = self.scale;
|
||||||
|
let (new_scale, curve_scale) = overlay_scale_from_extent(meta.extent);
|
||||||
|
self.scale = (new_scale, curve_scale);
|
||||||
|
|
||||||
|
if new_scale.abs() > f32::EPSILON {
|
||||||
|
let scale_delta = new_scale / old_scale;
|
||||||
|
let curve_scale_delta = curve_scale / old_curve_scale;
|
||||||
|
|
||||||
|
if (scale_delta - 1.0).abs() > f32::EPSILON
|
||||||
|
|| (curve_scale_delta - 1.0).abs() > f32::EPSILON
|
||||||
|
{
|
||||||
|
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
|
||||||
|
OverlaySelector::Id(self.overlay_id),
|
||||||
|
Box::new(move |_app, owc| {
|
||||||
|
if let Some(state) = owc.active_state.as_mut() {
|
||||||
|
if let Some(curvature) = state.curvature.as_mut() {
|
||||||
|
*curvature = (curve_scale_delta * *curvature).clamp(0.0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(saved) = state.saved_transform.as_mut() {
|
||||||
|
saved.matrix3 = saved.matrix3.mul_scalar(scale_delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.transform.matrix3 =
|
||||||
|
state.transform.matrix3.mul_scalar(scale_delta);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.interaction_transform = Some(ui_transform(meta.extent));
|
self.interaction_transform = Some(ui_transform(meta.extent));
|
||||||
|
|
||||||
let mut scale = vec2(
|
let mut scale = vec2(
|
||||||
|
|
@ -441,6 +483,35 @@ impl WvrWindowBackend {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sync_committed_toplevel_size(
|
||||||
|
&mut self,
|
||||||
|
app: &mut AppState,
|
||||||
|
inner_extent: [u32; 2],
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let Some(wvr_server) = app.wvr_server.as_mut() else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
let bounds = wvr_server.manager.state.output_logical_size();
|
||||||
|
let requested = Size::new(inner_extent[0].max(1) as i32, inner_extent[1].max(1) as i32);
|
||||||
|
let clamped = requested.clamp(Size::new(1, 1), bounds);
|
||||||
|
|
||||||
|
let Some(window) = wvr_server.wm.windows.get_mut(&self.window) else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
if requested == clamped {
|
||||||
|
// client picked a new size that fits
|
||||||
|
window.remember_committed_size(requested);
|
||||||
|
} else {
|
||||||
|
// client committed something outside the output bounds
|
||||||
|
if window.size_x != clamped.w as u32 || window.size_y != clamped.h as u32 {
|
||||||
|
window.request_size(clamped, bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OverlayBackend for WvrWindowBackend {
|
impl OverlayBackend for WvrWindowBackend {
|
||||||
|
|
@ -556,6 +627,8 @@ impl OverlayBackend for WvrWindowBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
let inner_extent = meta.extent;
|
let inner_extent = meta.extent;
|
||||||
|
self.sync_committed_toplevel_size(app, inner_extent)?;
|
||||||
|
|
||||||
meta.extent[0] += BORDER_SIZE * 2;
|
meta.extent[0] += BORDER_SIZE * 2;
|
||||||
meta.extent[1] += BORDER_SIZE * 2 + BAR_SIZE;
|
meta.extent[1] += BORDER_SIZE * 2 + BAR_SIZE;
|
||||||
|
|
||||||
|
|
@ -695,6 +768,7 @@ impl OverlayBackend for WvrWindowBackend {
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
match event_data {
|
match event_data {
|
||||||
OverlayEventData::IdAssigned(oid) => {
|
OverlayEventData::IdAssigned(oid) => {
|
||||||
|
self.overlay_id = oid;
|
||||||
let wvr_server = app.wvr_server.as_mut().unwrap(); //never None
|
let wvr_server = app.wvr_server.as_mut().unwrap(); //never None
|
||||||
wvr_server.overlay_added(oid, self.window);
|
wvr_server.overlay_added(oid, self.window);
|
||||||
}
|
}
|
||||||
|
|
@ -1093,3 +1167,12 @@ fn surface_tree_input_hit_test(
|
||||||
|
|
||||||
hit
|
hit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn overlay_scale_from_extent(size: [u32; 2]) -> (f32, f32) {
|
||||||
|
const RELATIVE_SIZE: f32 = 1440.0; // sqrt(1920 * 1080)
|
||||||
|
|
||||||
|
let w = size[0].max(1) as f32;
|
||||||
|
let h = size[1].max(1) as f32;
|
||||||
|
|
||||||
|
((w * h).sqrt() / RELATIVE_SIZE, w / 1920.0)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue