This commit is contained in:
Aleksander 2026-08-07 19:58:58 +02:00 committed by galister
parent 6631c004c9
commit cae2d7c7e2
69 changed files with 725 additions and 734 deletions

View File

@ -638,7 +638,7 @@ pub fn horiz_cell(layout: &mut Layout, parent: WidgetID) -> anyhow::Result<Widge
taffy::Style {
flex_direction: taffy::FlexDirection::Row,
align_items: Some(taffy::AlignItems::CENTER),
gap: length(8.0),
gap: length(8.0_f32),
..Default::default()
},
)?;

View File

@ -57,15 +57,14 @@ impl SettingsTab for State {
for task in self.tasks.drain() {
match task {
Task::WhisperDownloadClosed => {
if let Some(model) = self.pending_download.take() {
if !whisper_model_path(model.file_name).exists() {
if let Some(model) = self.pending_download.take()
&& !whisper_model_path(model.file_name).exists() {
// download failed, set to selection to none
par.general_config.whisper_model = "".into();
par.config_change_kind.replace(ConfigChangeKind::Other);
// reload the tab
self.parent_tasks.push(ParentTask::SetTab(TabNameEnum::Features));
}
}
}
Task::WhisperRemoveUnused => {
let _ = whisper_delete_all_models().log_err("could not remove whisper models");
@ -303,8 +302,8 @@ fn whisper_models_dropdown(mp: &mut MacroParams, parent: WidgetID) -> anyhow::Re
let mut params = TemplateParams::new();
params.insert("id", &id);
params.insert("translation", "APP_SETTINGS.WHISPER_MODEL".into());
params.insert("tooltip", "APP_SETTINGS.WHISPER_MODEL_HELP".into());
params.insert("translation", "APP_SETTINGS.WHISPER_MODEL");
params.insert("tooltip", "APP_SETTINGS.WHISPER_MODEL_HELP");
mp.parser_state
.instantiate_template(mp.doc_params, "DropdownButton", mp.layout, parent, params)?;

View File

@ -285,8 +285,8 @@ impl PopupManager {
let id_content = state.get_widget_id("content")?;
let padding = match popup_padding {
PopupPadding::Normal => 16.0,
PopupPadding::None => 0.0,
PopupPadding::Normal => 16.0_f32,
PopupPadding::None => 0.0_f32,
};
layout.tasks.push(LayoutTask::SetWidgetStyle(

View File

@ -65,8 +65,8 @@ impl ToastManager {
taffy::Style {
position: taffy::Position::Absolute,
size: taffy::Size {
width: percent(1.0),
height: percent(0.8),
width: percent(1.0_f32),
height: percent(0.8_f32),
},
align_items: Some(taffy::AlignItems::END),
justify_content: Some(taffy::JustifyContent::CENTER),
@ -85,15 +85,15 @@ impl ToastManager {
}),
taffy::Style {
position: taffy::Position::Relative,
gap: length(4.0),
gap: length(4.0_f32),
padding: taffy::Rect {
left: length(16.0),
right: length(16.0),
top: length(8.0),
bottom: length(8.0),
left: length(16.0_f32),
right: length(16.0_f32),
top: length(8.0_f32),
bottom: length(8.0_f32),
},
max_size: taffy::Size {
width: length(400.0),
width: length(400.0_f32),
height: auto(),
},
..Default::default()

View File

@ -384,13 +384,15 @@ fn input_controls_for_action(
input_controls_for_hand(
mp,
parent,
current_left,
XrInputSide::Left,
action.clone(),
click_type,
profile,
current.threshold_left,
InputControlsForHandParams {
parent,
current: current_left,
side: XrInputSide::Left,
action: &action,
click_type,
profile,
threshold: current.threshold_left,
},
)?;
let current_right = current.right.as_ref().map(|x| match x {
@ -400,33 +402,40 @@ fn input_controls_for_action(
input_controls_for_hand(
mp,
parent,
current_right,
XrInputSide::Right,
action,
click_type,
profile,
current.threshold_right,
)
InputControlsForHandParams {
parent,
current: current_right,
side: XrInputSide::Right,
action: &action,
click_type,
profile,
threshold: current.threshold_right,
},
)?;
Ok(())
}
fn input_controls_for_hand(
mp: &mut MacroParams,
struct InputControlsForHandParams<'a> {
parent: WidgetID,
current: Option<&str>,
current: Option<&'a str>,
side: XrInputSide,
action: Rc<str>,
action: &'a Rc<str>,
click_type: ClickType,
profile: &XrControllerProfile,
profile: &'a XrControllerProfile,
threshold: Option<[f32; 2]>,
) -> anyhow::Result<()> {
let Some(user_path) = profile.find_userpath(side) else {
}
fn input_controls_for_hand(mp: &mut MacroParams, par: InputControlsForHandParams) -> anyhow::Result<()> {
let Some(user_path) = par.profile.find_userpath(par.side) else {
return Ok(()); // this hand is not available
};
let current = current.and_then(|cur| ParsedOpenXrInputPath::try_from(cur).log_warn(cur).ok());
let current = par
.current
.and_then(|cur| ParsedOpenXrInputPath::try_from(cur).log_warn(cur).ok());
let parent = horiz_cell(mp.layout, parent)?;
let parent = horiz_cell(mp.layout, par.parent)?;
let available_components: Rc<[XrInputComponent]> = current
.as_ref()
@ -445,8 +454,8 @@ fn input_controls_for_hand(
subpath_dropdown(
mp,
parent,
action.clone(),
side,
par.action.clone(),
par.side,
available_subpaths,
current.as_ref().map(|x| x.subpath),
)?;
@ -454,22 +463,22 @@ fn input_controls_for_hand(
if !component_dropdown(
mp,
parent,
action.clone(),
side,
par.action.clone(),
par.side,
available_components,
current.as_ref().map(|x| x.component),
)? {
return Ok(());
}
clicks_dropdown(mp, parent, action.clone(), click_type)?;
clicks_dropdown(mp, parent, par.action.clone(), par.click_type)?;
if let Some(component) = current.as_ref().map(|x| x.component)
&& component.is_analog()
&& &*action != "scroll"
&& &**par.action != "scroll"
// hax
{
threshold_slider(mp, parent, action, side, threshold)?;
threshold_slider(mp, parent, par.action.clone(), par.side, par.threshold)?;
}
Ok(())

View File

@ -85,8 +85,8 @@ impl View {
image,
taffy::Style {
size: taffy::Size {
width: percent(1.0),
height: percent(1.0),
width: percent(1.0_f32),
height: percent(1.0_f32),
},
..Default::default()
},
@ -125,7 +125,7 @@ impl View {
align_self: Some(AlignSelf::BASELINE),
justify_self: Some(JustifySelf::CENTER),
margin: taffy::Rect {
top: length(32.0),
top: length(32.0_f32),
bottom: auto(),
left: auto(),
right: auto(),
@ -199,10 +199,10 @@ impl View {
taffy::Style {
position: taffy::Position::Absolute,
size: taffy::Size {
width: percent(1.0),
height: percent(1.0),
width: percent(1.0_f32),
height: percent(1.0_f32),
},
padding: taffy::Rect::length(2.0),
padding: taffy::Rect::length(2.0_f32),
align_items: Some(AlignItems::CENTER),
justify_content: Some(JustifyContent::CENTER),
..Default::default()
@ -223,7 +223,7 @@ impl View {
position: taffy::Position::Absolute,
align_self: Some(align_self),
size: taffy::Size {
width: percent(1.0),
width: percent(1.0_f32),
height: percent(height),
},
..Default::default()

View File

@ -237,8 +237,8 @@ impl TestbedGeneric {
WidgetDiv::create(),
taffy::Style {
size: taffy::Size {
width: length(128.0),
height: length(64.0),
width: length(128.0_f32),
height: length(64.0_f32),
},
..Default::default()
},

View File

@ -31,7 +31,7 @@ pub fn init_window(
let event_loop = EventLoop::new().unwrap(); // want panic
let mut vk_instance_extensions = Surface::required_extensions(&event_loop).unwrap();
vk_instance_extensions.khr_get_physical_device_properties2 = true;
log::debug!("Instance exts for runtime: {:?}", &vk_instance_extensions);
log::debug!("Instance exts for runtime: {:?}", vk_instance_extensions);
let instance = Instance::new(
get_vulkan_library().clone(),
@ -57,7 +57,7 @@ pub fn init_window(
let mut device_extensions = DeviceExtensions::empty();
device_extensions.khr_swapchain = true;
log::debug!("Device exts for app: {:?}", &device_extensions);
log::debug!("Device exts for app: {:?}", device_extensions);
let (physical_device, mut my_extensions, queue_families) = instance
.enumerate_physical_devices()?

View File

@ -6,14 +6,14 @@ fn main() {
match std::env::var("GITHUB_JOB").as_deref() {
Ok("make_release") => {
wlx_build = format!("{} (Release)", &wlx_build);
wlx_build = format!("{} (Release)", wlx_build);
}
Ok("build_appimage") => {
wlx_build = format!("{} (AppImage)", &wlx_build);
wlx_build = format!("{} (AppImage)", wlx_build);
}
_ => {}
}
println!("cargo:rustc-env=WLX_BUILD={}", &wlx_build);
println!("cargo:rustc-env=WLX_BUILD={}", wlx_build);
}
fn get_version() -> Result<String, Box<dyn std::error::Error>> {

View File

@ -103,13 +103,13 @@ impl InputState {
}
pub fn apply_handsfree_action(&mut self, params: HandsfreeParams) {
fn set_true(v: &mut bool) {
const fn set_true(v: &mut bool) {
*v = true;
}
fn set_false(v: &mut bool) {
const fn set_false(v: &mut bool) {
*v = false;
}
fn toggle(v: &mut bool) {
const fn toggle(v: &mut bool) {
*v = !*v;
}
@ -130,10 +130,10 @@ impl InputState {
HandsfreeAction::Click => apply(&mut self.handsfree_state.click),
HandsfreeAction::RightModifier => apply(&mut self.handsfree_state.click_modifier_right),
HandsfreeAction::MiddleModifier => {
apply(&mut self.handsfree_state.click_modifier_middle)
apply(&mut self.handsfree_state.click_modifier_middle);
}
HandsfreeAction::Grab => apply(&mut self.handsfree_state.grab),
};
}
}
pub fn handle_task(&mut self, task: InputTask) {
@ -574,16 +574,16 @@ where
// grab
if grab_start && hovered_state.grabbable {
update_focus(app, hovered.config.input_focus);
start_grab(
start_grab(StartGrabParams {
idx,
hit.overlay,
hovered.config.name.clone(),
hovered.config.editing,
hovered_state,
id: hit.overlay,
name: hovered.config.name.clone(),
editing: hovered.config.editing,
state: hovered_state,
app,
edit_mode,
grab_float,
);
});
log::debug!("Hand {}: grabbed {}", hit.pointer, hovered.config.name);
return (
Some((hit, raw_hit)),
@ -772,10 +772,8 @@ where
continue;
};
if uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0 {
if !overlay.config.resizing {
continue;
}
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) && !overlay.config.resizing {
continue;
}
let pointer_hit = PointerHit {
@ -795,25 +793,29 @@ where
(None, None)
}
fn start_grab(
struct StartGrabParams<'a> {
idx: usize,
id: OverlayID,
name: Arc<str>,
editing: bool,
state: &mut OverlayWindowState,
app: &mut AppState,
state: &'a mut OverlayWindowState,
app: &'a mut AppState,
edit_mode: bool,
grab_float: bool,
) {
let pointer = &mut app.input_state.pointers[idx];
}
fn start_grab(par: StartGrabParams) {
let (app, id, state) = (par.app, par.id, par.state);
let pointer = &mut app.input_state.pointers[par.idx];
// Grab anchor if:
// - grabbed overlay is Anchored
// - not in editmode
// - not using grab_float
// - grabbing with one hand. (grabbing with the 2nd hand will grab the individual overlay instead)
let grab_anchor = !edit_mode
&& !grab_float
let grab_anchor = !par.edit_mode
&& !par.grab_float
&& !app.anchor_grabbed
&& matches!(state.positioning, Positioning::Anchored);
@ -837,11 +839,18 @@ fn start_grab(
OverlaySelector::Id(id),
Box::new({
let pos = state.positioning;
let name = name.clone();
let name = par.name.clone();
move |app, o| {
let _ = o
.backend
.notify(app, OverlayEventData::OverlayGrabbed { name, pos, editing })
.notify(
app,
OverlayEventData::OverlayGrabbed {
name,
pos,
editing: par.editing,
},
)
.inspect_err(|e| log::warn!("Error during Notify OverlayGrabbed: {e:?}"));
}
}),
@ -865,7 +874,14 @@ fn start_grab(
Box::new(move |app, o| {
let _ = o
.backend
.notify(app, OverlayEventData::OverlayGrabbed { name, pos, editing })
.notify(
app,
OverlayEventData::OverlayGrabbed {
name: par.name,
pos,
editing: par.editing,
},
)
.inspect_err(|e| log::warn!("Error during Notify OverlayGrabbed: {e:?}"));
o.default_state.positioning = Positioning::FollowHand { hand, lerp: 0.1 };

View File

@ -35,7 +35,7 @@ impl OverlayWindowData<OpenVrOverlayData> {
app: &mut AppState,
) -> anyhow::Result<OverlayHandle> {
let key = format!("wlx-{}", self.config.name);
log::debug!("Create overlay with key: {}", &key);
log::debug!("Create overlay with key: {key}");
let handle = match overlay.create_overlay(&key, &key) {
Ok(handle) => handle,
Err(e) => {

View File

@ -51,7 +51,7 @@ pub struct MultiClickHandler<const COUNT: usize> {
impl<const COUNT: usize> MultiClickHandler<COUNT> {
fn new(action_set: &xr::ActionSet, action_name: &str, side: &str) -> anyhow::Result<Self> {
let name = format!("{side}_{COUNT}-{action_name}");
let name_f32 = format!("{}_value", &name);
let name_f32 = format!("{name}_value");
let action_bool = action_set.create_action::<bool>(&name, &name, &[])?;
let action_f32 = action_set.create_action::<f32>(&name_f32, &name_f32, &[])?;
@ -135,7 +135,7 @@ impl CustomClickAction {
})
}
pub fn set_threshold(&mut self, threshold: [f32; 2]) {
pub const fn set_threshold(&mut self, threshold: [f32; 2]) {
self.threshold = threshold;
}
@ -238,7 +238,14 @@ impl OpenXrInputSource {
let mut any_tracked = false;
let old_handsfree = app.session.config.handsfree_pointer;
if !app.input_state.picking_focus.is_none() {
if app.input_state.picking_focus.is_none() {
let should_disable_lerp = app.input_state.should_disable_lerp();
for i in 0..2 {
let pointer = &mut app.input_state.pointers[i];
self.pointers[i].update(pointer, xr, &app.session, !should_disable_lerp)?;
any_tracked |= pointer.tracked;
}
} else {
app.session.config.handsfree_pointer = app.session.config.handsfree_alt_tab.into();
app.input_state.handsfree_state.scroll_x =
@ -250,13 +257,6 @@ impl OpenXrInputSource {
ptr1.before = ptr1.now;
ptr1.now = PointerState::default();
ptr1.tracked = false;
} else {
let should_disable_lerp = app.input_state.should_disable_lerp();
for i in 0..2 {
let pointer = &mut app.input_state.pointers[i];
self.pointers[i].update(pointer, xr, &app.session, !should_disable_lerp)?;
any_tracked |= pointer.tracked;
}
}
if !any_tracked {
@ -709,7 +709,7 @@ fn suggest_bindings(instance: &xr::Instance, hands: &mut [&mut OpenXrHandSource;
let profiles = load_xr_input_profiles();
for profile in profiles {
log::debug!("Loading profile {}", &profile.profile);
log::debug!("Loading profile {}", profile.profile);
let Ok(profile_path) = instance.string_to_path(&profile.profile) else {
log::warn!("Profile not supported: {}", profile.profile);

View File

@ -99,9 +99,7 @@ pub fn openxr_run(args: &Args) -> Result<(), BackendError> {
app.late_init();
let mut playspace_mover = playspace::PlayspaceMover::new()
.map_err(|e| log::warn!("Will not use Monado playspace mover: {e}"))
.ok();
let mut playspace_mover = playspace::PlayspaceMover::new();
let mut blocker = app
.monado_state
@ -303,9 +301,7 @@ pub fn openxr_run(args: &Args) -> Result<(), BackendError> {
.enqueue(TaskType::Overlay(OverlayTask::ToggleDashboard));
}
if let Some(ref mut playspace_mover) = playspace_mover {
playspace_mover.update(&mut overlays, &mut app);
}
playspace_mover.update(&mut overlays, &mut app);
for o in overlays.values_mut() {
o.after_input(&mut app)?;
@ -492,9 +488,7 @@ pub fn openxr_run(args: &Args) -> Result<(), BackendError> {
overlays.handle_task(&mut app, task)?;
}
TaskType::Playspace(task) => {
if let Some(playspace_mover) = playspace_mover.as_mut() {
playspace_mover.handle_task(&mut app, &mut overlays, task);
}
playspace_mover.handle_task(&mut app, &mut overlays, task);
}
TaskType::OpenXR(task) => {
if matches!(task, OpenXrTask::EnvironmentChanged) {

View File

@ -27,15 +27,15 @@ pub(super) struct PlayspaceMover {
}
impl PlayspaceMover {
pub fn new() -> anyhow::Result<Self> {
pub fn new() -> Self {
log::info!("Monado: using space offset API");
Ok(Self {
Self {
drag: None,
rotate: None,
gravity: SpaceGravity::new(),
playspace_state: load_playspace_state().unwrap_or_default(),
})
}
}
pub fn handle_task(

View File

@ -276,7 +276,7 @@ impl WayVRCompositor {
delta: DVec2,
delta_unaccel: DVec2,
) {
let location: Point<f64, Logical> = (global_pos.x as f64, global_pos.y as f64).into();
let location: Point<f64, Logical> = (global_pos.x, global_pos.y).into();
let delta: Point<f64, Logical> = (delta.x, delta.y).into();
let delta_unaccel: Point<f64, Logical> = (delta_unaccel.x, delta_unaccel.y).into();
@ -337,6 +337,9 @@ impl WayVRCompositor {
}
pub fn send_pointer_axis_wheel_raw(&mut self, delta: super::WheelDelta) {
// 15 logical axis units for one wheel detent of 120 v120 units
const AXIS_VALUE_PER_DETENT: f64 = 15.0;
let time = super::time::get_millis() as u32;
let v120_x = delta.x as i32;
@ -346,9 +349,6 @@ impl WayVRCompositor {
return;
}
// 15 logical axis units for one wheel detent of 120 v120 units
const AXIS_VALUE_PER_DETENT: f64 = 15.0;
let mut frame = AxisFrame::new(time).source(AxisSource::Wheel);
if v120_x != 0 {

View File

@ -173,10 +173,10 @@ impl Application {
}
pub fn output_logical_size(&self) -> Size<i32, Logical> {
self.output
.current_mode()
.map(|mode| Size::new(mode.size.w, mode.size.h))
.unwrap_or_else(|| Size::new(WAYVR_SCREEN_RES[0], WAYVR_SCREEN_RES[1]))
self.output.current_mode().map_or_else(
|| Size::new(WAYVR_SCREEN_RES[0], WAYVR_SCREEN_RES[1]),
|mode| Size::new(mode.size.w, mode.size.h),
)
}
fn surface_logical_size(surface: &WlSurface) -> Option<Size<i32, Logical>> {
@ -458,7 +458,7 @@ impl XdgShellHandler for Application {
serial
);
let popup = PopupKind::Xdg(surface.clone());
let popup = PopupKind::Xdg(surface);
let Ok(root_surface) = find_popup_root_surface(&popup) else {
log::warn!("xdg_popup.grab: could not find popup root surface");

View File

@ -237,6 +237,7 @@ fn surface_accepts_input(surface: &RenderedSurface, global_pos: Vec2) -> bool {
return false;
}
#[allow(clippy::significant_drop_tightening)]
with_states(&surface.surface, |states| {
let mut guard = states.cached_state.get::<SurfaceAttributes>();
let attrs = guard.current();
@ -252,6 +253,7 @@ fn surface_accepts_input(surface: &RenderedSurface, global_pos: Vec2) -> bool {
})
}
#[allow(clippy::significant_drop_tightening)]
fn surface_accepts_input_states(
states: &smithay::wayland::compositor::SurfaceData,
local: Vec2,
@ -357,14 +359,13 @@ pub fn build_hit_context(
toplevel: &WlSurface,
_popup_manager: &PopupManager,
inner_extent: [u32; 2],
) -> Option<WvrHitContext> {
) -> WvrHitContext {
let (mouse_transform, uv_range) = compute_transforms(inner_extent);
let panel_height = BORDER_SIZE * 2 + BAR_SIZE;
let surfaces = collect_rendered_surface_tree(toplevel);
let mut popup_roots = Vec::new();
let mut popups = Vec::new();
for (popup, point) in PopupManager::popups_for_surface(toplevel) {
let configured = with_states(popup.wl_surface(), |states| {
@ -387,20 +388,14 @@ pub fn build_hit_context(
surface: popup.wl_surface().clone(),
surface_origin: Vec2::new(popup_origin.x as f32, popup_origin.y as f32),
});
popups.extend(collect_rendered_surface_tree_at(
popup.wl_surface(),
popup_origin,
true,
));
}
Some(WvrHitContext {
WvrHitContext {
surfaces,
popup_roots: popup_roots.into(),
mouse_transform,
uv_range,
inner_extent,
panel_height,
})
}
}

View File

@ -27,7 +27,7 @@ use std::{
use crate::subsystem::dbus::DbusConnector;
const IGNORE_PREFIX: &str = "WayVR";
const WATCHDOG_TIMEOUT: Duration = Duration::from_millis(5000);
const WATCHDOG_TIMEOUT: Duration = Duration::from_secs(5);
const POLL_TIMEOUT_MS: i32 = 20;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -295,6 +295,7 @@ enum ProcessResult {
ReceiverGone,
}
#[allow(clippy::match_same_arms)]
fn worker_main(
command_rx: Receiver<Command>,
event_tx: Sender<CapturedEvent>,
@ -307,10 +308,7 @@ fn worker_main(
let mut libinput = Libinput::new_with_udev(interface);
if libinput.udev_assign_seat("seat0").is_err() {
let _ = init_tx.send(Err(io::Error::new(
io::ErrorKind::Other,
format!("failed to assign libinput seat"),
)));
let _ = init_tx.send(Err(io::Error::other("failed to assign libinput seat")));
return;
}
@ -421,7 +419,7 @@ fn worker_main(
};
// SAFETY: poll_fd is valid for the duration of this call
let poll_result = unsafe { libc::poll(&mut poll_fd, 1, POLL_TIMEOUT_MS) };
let poll_result = unsafe { libc::poll(&raw mut poll_fd, 1, POLL_TIMEOUT_MS) };
if poll_result < 0 {
let error = io::Error::last_os_error();
@ -453,16 +451,16 @@ fn worker_main(
}
for event in &mut libinput {
match process_libinput_event(
match process_libinput_event(ProcessLibinputEventParams {
event,
grabbed,
true,
&mut pending_grab,
&event_tx,
&mut runtime_devices,
&mut pointer_devices,
allow_deferred_grab: true,
pending_grab: &mut pending_grab,
event_tx: &event_tx,
runtime_devices: &mut runtime_devices,
pointer_devices: &mut pointer_devices,
pointer_accel,
) {
}) {
ProcessResult::Continue => {}
ProcessResult::ForceUngrab => {
emergency_ungrab = true;
@ -521,19 +519,27 @@ fn worker_main(
}
}
fn process_libinput_event(
struct ProcessLibinputEventParams<'a> {
event: Event,
grabbed: bool,
allow_deferred_grab: bool,
pending_grab: &mut bool,
event_tx: &Sender<CapturedEvent>,
runtime_devices: &mut HashMap<LibinputDevice, RuntimeDeviceState>,
pointer_devices: &mut HashSet<LibinputDevice>,
pending_grab: &'a mut bool,
event_tx: &'a Sender<CapturedEvent>,
runtime_devices: &'a mut HashMap<LibinputDevice, RuntimeDeviceState>,
pointer_devices: &'a mut HashSet<LibinputDevice>,
pointer_accel: PointerAccelConfig,
) -> ProcessResult {
match event {
}
#[allow(clippy::similar_names)]
fn process_libinput_event(par: ProcessLibinputEventParams) -> ProcessResult {
match par.event {
Event::Device(event) => {
handle_device_event(event, runtime_devices, pointer_devices, pointer_accel);
handle_device_event(
event,
par.runtime_devices,
par.pointer_devices,
par.pointer_accel,
);
}
Event::Keyboard(KeyboardEvent::Key(event)) => {
let code_u32 = event.key();
@ -544,7 +550,7 @@ fn process_libinput_event(
let pressed = event.key_state() == KeyState::Pressed;
let device = event.device();
let state = runtime_devices.entry(device).or_default();
let state = par.runtime_devices.entry(device).or_default();
if pressed {
state.pressed_keys.insert(code);
@ -552,12 +558,12 @@ fn process_libinput_event(
state.pressed_keys.remove(&code);
}
if !grabbed {
if !par.grabbed {
// while ungrabbed, arm an automatic grab that triggers after release
if allow_deferred_grab
if par.allow_deferred_grab
&& key_combo_is_pressed(KeyCombo::GrabRelease, &state.pressed_keys)
{
*pending_grab = true;
*par.pending_grab = true;
}
return ProcessResult::Continue;
@ -589,7 +595,8 @@ fn process_libinput_event(
state.active_combos.remove(&combo);
}
if event_tx
if par
.event_tx
.send(CapturedEvent::KeyCombo {
combo,
pressed: combo_pressed,
@ -600,17 +607,22 @@ fn process_libinput_event(
}
}
if event_tx.send(CapturedEvent::Key { code, pressed }).is_err() {
if par
.event_tx
.send(CapturedEvent::Key { code, pressed })
.is_err()
{
return ProcessResult::ReceiverGone;
}
}
Event::Pointer(PointerEvent::Motion(event)) if grabbed => {
Event::Pointer(PointerEvent::Motion(event)) if par.grabbed => {
let dx = event.dx();
let dy = event.dy();
let dx_raw = event.dx_unaccelerated();
let dy_raw = event.dy_unaccelerated();
if (dx != 0.0 || dy != 0.0)
&& event_tx
&& par
.event_tx
.send(CapturedEvent::PointerMotion {
dx,
dy,
@ -622,9 +634,10 @@ fn process_libinput_event(
return ProcessResult::ReceiverGone;
}
}
Event::Pointer(PointerEvent::Button(event)) if grabbed => {
Event::Pointer(PointerEvent::Button(event)) if par.grabbed => {
let pressed = event.button_state() == ButtonState::Pressed;
if event_tx
if par
.event_tx
.send(CapturedEvent::PointerButton {
button: event.button(),
pressed,
@ -634,7 +647,7 @@ fn process_libinput_event(
return ProcessResult::ReceiverGone;
}
}
Event::Pointer(PointerEvent::ScrollWheel(event)) if grabbed => {
Event::Pointer(PointerEvent::ScrollWheel(event)) if par.grabbed => {
let horizontal = if event.has_axis(Axis::Horizontal) {
event.scroll_value_v120(Axis::Horizontal)
} else {
@ -646,13 +659,14 @@ fn process_libinput_event(
0.0
};
let state = runtime_devices.entry(event.device()).or_default();
let state = par.runtime_devices.entry(event.device()).or_default();
let horizontal_v120 = accumulate_v120(&mut state.horizontal_v120_remainder, horizontal);
let vertical_v120 = accumulate_v120(&mut state.vertical_v120_remainder, vertical);
// libinput already provides correct values unlike REL_WHEEL
if (horizontal_v120 != 0 || vertical_v120 != 0)
&& event_tx
&& par
.event_tx
.send(CapturedEvent::PointerAxis {
horizontal_v120,
vertical_v120,
@ -723,16 +737,16 @@ fn drain_pending_libinput_events(
let mut ignored = false;
for event in libinput {
let _ = process_libinput_event(
let _ = process_libinput_event(ProcessLibinputEventParams {
event,
false,
false,
&mut ignored,
grabbed: false,
allow_deferred_grab: false,
pending_grab: &mut ignored,
event_tx,
runtime_devices,
pointer_devices,
pointer_accel,
);
});
}
}
@ -754,7 +768,7 @@ fn force_reopen_ungrabbed(
libinput
.resume()
.map_err(|()| io::Error::new(io::ErrorKind::Other, "failed to resume libinput context"))?;
.map_err(|()| io::Error::other("failed to resume libinput context"))?;
drain_pending_libinput_events(
libinput,
@ -797,6 +811,7 @@ fn clear_transient_state(runtime_devices: &mut HashMap<LibinputDevice, RuntimeDe
}
}
#[allow(clippy::float_cmp)]
fn accumulate_v120(remainder: &mut f64, value: f64) -> i32 {
if !value.is_finite() {
return 0;
@ -858,7 +873,7 @@ fn looks_like_mouse(device: &EvdevDevice, keys: &AttributeSetRef<KeyCode>) -> bo
.any(|button| keys.contains(button))
}
fn mouse_buttons() -> [KeyCode; 8] {
const fn mouse_buttons() -> [KeyCode; 8] {
[
KeyCode::BTN_LEFT,
KeyCode::BTN_RIGHT,

View File

@ -71,6 +71,7 @@ use crate::{
image_importer::ImageImporter,
input_capture::InputCapture,
process::{KillSignal, Process},
window::CreateWindowParams,
},
},
graphics::{ExtentExt, WGfxExtras},
@ -150,7 +151,7 @@ pub struct WvrServerState {
grab_toast_sent: bool,
}
#[derive(Clone, Copy, PartialEq)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum MouseIndex {
Left,
Center,
@ -310,6 +311,7 @@ impl WvrServerState {
}
#[allow(clippy::too_many_lines)]
#[allow(clippy::significant_drop_tightening)]
pub fn tick_events(app: &mut AppState) -> anyhow::Result<Vec<TickTask>> {
let mut tasks: Vec<TickTask> = Vec::new();
@ -328,7 +330,7 @@ impl WvrServerState {
// Tick all child processes
let mut to_remove: SmallVec<[process::ProcessHandle; 2]> = SmallVec::new();
for (handle, process) in wvr_server.processes.iter_mut() {
for (handle, process) in &mut wvr_server.processes {
if !process.is_running() {
to_remove.push(handle);
}
@ -413,15 +415,15 @@ impl WvrServerState {
),
};
let window_handle = wvr_server.wm.create_window(
toplevel.clone(),
process_handle,
output_bounds,
let window_handle = wvr_server.wm.create_window(CreateWindowParams {
toplevel: toplevel.clone(),
process: process_handle,
bounds: output_bounds,
min_size,
max_size,
fallback_size.w as _,
fallback_size.h as _,
);
size_x: fallback_size.w as _,
size_y: fallback_size.h as _,
});
toplevel.with_pending_state(|state| {
state.bounds = Some(output_bounds);
@ -527,13 +529,14 @@ impl WvrServerState {
wvr_server.overlay_to_window.remove(oid);
if let Some(process_handle) = process_handle.as_ref() {
let mut empty = false;
if let Some(overlays) =
let empty = if let Some(overlays) =
wvr_server.process_overlays.get_mut(process_handle)
{
overlays.retain(|other| *other != oid);
empty = overlays.is_empty();
}
overlays.is_empty()
} else {
false
};
if empty {
wvr_server.process_overlays.remove(process_handle);
@ -612,7 +615,7 @@ impl WvrServerState {
continue;
}
for (h, w) in wvr_server.wm.windows.iter() {
for (h, w) in &wvr_server.wm.windows {
if w.process != process_handle {
continue;
}
@ -702,7 +705,7 @@ impl WvrServerState {
pub fn process_removed(&mut self, tasks: &mut TaskContainer, process: process::ProcessHandle) {
let mut to_remove = vec![];
for (hnd, win) in self.wm.windows.iter() {
for (hnd, win) in &self.wm.windows {
if win.process != process {
continue;
}
@ -730,6 +733,7 @@ impl WvrServerState {
self.window_to_overlay.get(&window).copied()
}
#[allow(clippy::match_same_arms)]
pub fn hit_target_to_focus(
&self,
target: WvrHitTarget,
@ -738,18 +742,18 @@ impl WvrServerState {
) -> PointerFocusTarget {
match target {
WvrHitTarget::Panel(_) => PointerFocusTarget::None,
WvrHitTarget::Toplevel { .. } => self
.wm
.windows
.get(hover_window)
.map(|w| {
let surface = w.toplevel.wl_surface().clone();
PointerFocusTarget::Surface {
surface,
origin: glam::Vec2::ZERO,
}
})
.unwrap_or(PointerFocusTarget::Toplevel),
WvrHitTarget::Toplevel { .. } => {
self.wm
.windows
.get(hover_window)
.map_or(PointerFocusTarget::Toplevel, |w| {
let surface = w.toplevel.wl_surface().clone();
PointerFocusTarget::Surface {
surface,
origin: glam::Vec2::ZERO,
}
})
}
WvrHitTarget::Surface {
surface, origin, ..
} => PointerFocusTarget::Surface { surface, origin },
@ -836,32 +840,32 @@ impl WvrServerState {
|| (hid::VirtualKey::KP_1 as u32) == vk)
&& pressed
{
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(0)))
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(0)));
} else if ((hid::VirtualKey::N2 as u32) == vk
|| (hid::VirtualKey::KP_2 as u32) == vk)
&& pressed
{
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(1)))
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(1)));
} else if ((hid::VirtualKey::N3 as u32) == vk
|| (hid::VirtualKey::KP_3 as u32) == vk)
&& pressed
{
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(2)))
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(2)));
} else if ((hid::VirtualKey::N4 as u32) == vk
|| (hid::VirtualKey::KP_4 as u32) == vk)
&& pressed
{
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(3)))
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(3)));
} else if ((hid::VirtualKey::N5 as u32) == vk
|| (hid::VirtualKey::KP_5 as u32) == vk)
&& pressed
{
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(4)))
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(4)));
} else if ((hid::VirtualKey::N6 as u32) == vk
|| (hid::VirtualKey::KP_6 as u32) == vk)
&& pressed
{
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(5)))
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(5)));
}
} else if self.has_input_focus {
self.manager.send_key(vk, pressed);
@ -996,16 +1000,14 @@ impl WvrServerState {
let toplevel = window.toplevel.wl_surface().clone();
let inner_extent = with_states(&toplevel, |states| {
SurfaceBufWithImage::get_from_surface(states)
.map(|s| s.image.extent_u32arr())
.unwrap_or([1, 1])
.map_or([1, 1], |s| s.image.extent_u32arr())
});
let Some(hit_ctx) = build_hit_context(
let hit_ctx = build_hit_context(
&toplevel,
&self.manager.state.popup_manager,
inner_extent,
) else {
break 'mouse_update;
};
);
let new_x = (hover.pos.x + mouse_delta.x).clamp(0., inner_extent[0] as f64);
let new_y = (hover.pos.y + mouse_delta.y).clamp(0., inner_extent[1] as f64);
@ -1033,7 +1035,7 @@ impl WvrServerState {
}
}
fn button_to_mouse_index(button: u32) -> Option<MouseIndex> {
const fn button_to_mouse_index(button: u32) -> Option<MouseIndex> {
match button {
272 => Some(MouseIndex::Left),
273 => Some(MouseIndex::Right),
@ -1043,18 +1045,18 @@ impl WvrServerState {
}
/// Use HidWrapper::set_input_focus instead!!!
pub fn set_input_focus(&mut self, has_focus: bool) {
pub const fn set_input_focus(&mut self, has_focus: bool) {
self.has_input_focus = has_focus;
if !has_focus {
self.wm.mouse = None;
}
}
pub fn get_focused_window(&self) -> Option<window::WindowHandle> {
pub const fn get_focused_window(&self) -> Option<window::WindowHandle> {
if !self.has_input_focus {
return None;
}
self.wm.keyboard_focus.clone()
self.wm.keyboard_focus
}
fn get_mouse_focus(

View File

@ -221,7 +221,7 @@ impl ProcessHandle {
Self::from(slotmap::KeyData::from_ffi(handle.user))
}
pub fn as_packet(&self) -> packet_server::WvrProcessHandle {
pub fn as_packet(self) -> packet_server::WvrProcessHandle {
packet_server::WvrProcessHandle {
user: self.0.as_ffi(),
}

View File

@ -119,6 +119,16 @@ pub struct WindowManager {
pub keyboard_focus: Option<WindowHandle>,
}
pub struct CreateWindowParams {
pub toplevel: Rc<ToplevelSurface>,
pub process: process::ProcessHandle,
pub bounds: Size<i32, Logical>,
pub min_size: Size<i32, Logical>,
pub max_size: Size<i32, Logical>,
pub size_x: u32,
pub size_y: u32,
}
impl WindowManager {
pub fn new() -> Self {
Self {
@ -137,18 +147,15 @@ impl WindowManager {
None
}
pub fn create_window(
&mut self,
toplevel: Rc<ToplevelSurface>,
process: process::ProcessHandle,
bounds: Size<i32, Logical>,
min_size: Size<i32, Logical>,
max_size: Size<i32, Logical>,
size_x: u32,
size_y: u32,
) -> WindowHandle {
let mut window = Window::new(toplevel, process, bounds, min_size, max_size);
window.remember_committed_size(Size::new(size_x as i32, size_y as i32));
pub fn create_window(&mut self, par: CreateWindowParams) -> WindowHandle {
let mut window = Window::new(
par.toplevel,
par.process,
par.bounds,
par.min_size,
par.max_size,
);
window.remember_committed_size(Size::new(par.size_x as i32, par.size_y as i32));
self.windows.insert(window)
}
@ -166,7 +173,7 @@ impl WindowHandle {
Self::from(slotmap::KeyData::from_ffi(handle.user))
}
pub fn as_packet(&self) -> packet_server::WvrWindowHandle {
pub fn as_packet(self) -> packet_server::WvrWindowHandle {
packet_server::WvrWindowHandle {
user: self.0.as_ffi(),
}

View File

@ -400,7 +400,7 @@ pub fn init_openvr_graphics(
let layers = vec![];
log::debug!("Instance exts for runtime: {:?}", &vk_instance_extensions);
log::debug!("Instance exts for runtime: {vk_instance_extensions:?}");
vk_instance_extensions.khr_get_physical_device_properties2 = true;
@ -452,7 +452,7 @@ pub fn init_openvr_graphics(
log::debug!(
"Device exts for {}: {:?}",
p.properties().device_name,
&my_extensions
my_extensions
);
Some((p, my_extensions))
})

View File

@ -833,7 +833,7 @@ fn shell_on_action(state: &ShellButtonState) -> anyhow::Result<()> {
.arg(&state.exec)
.stdout(Stdio::piped())
.spawn()
.with_context(|| format!("Failed to run shell script: '{}'", &state.exec))?;
.with_context(|| format!("Failed to run shell script: '{}'", state.exec))?;
mut_state.child = Some(child);

View File

@ -360,7 +360,7 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
}
fn notify(&mut self, app: &mut AppState, data: OverlayEventData) -> anyhow::Result<()> {
if let OverlayEventData::ColorPaletteRefresh = data {
if matches!(data, OverlayEventData::ColorPaletteRefresh) {
self.layout.tasks.push(LayoutTask::RefreshPalette);
}
let Some(on_notify) = self.on_notify.take() else {

View File

@ -1,3 +1,4 @@
use crate::backend::wayvr::process::ProcessHandle;
use crate::backend::wayvr::{self, WvrServerState};
use crate::subsystem::input::{HidWrapper, InputFocus};
@ -208,8 +209,8 @@ impl Connection {
.windows
.iter()
.map(|(handle, win)| packet_server::WvrWindow {
handle: wayvr::window::WindowHandle::as_packet(&handle),
process_handle: wayvr::process::ProcessHandle::as_packet(&win.process),
handle: wayvr::window::WindowHandle::as_packet(handle),
process_handle: wayvr::process::ProcessHandle::as_packet(win.process),
size_x: win.size_x,
size_y: win.size_y,
visible: win.visible,
@ -228,7 +229,7 @@ impl Connection {
window.visible = visible;
params
.signals
.send(WayVRSignal::WindowVisibilityChanged(window_handle, visible))
.send(WayVRSignal::WindowVisibilityChanged(window_handle, visible));
}
}
@ -253,7 +254,7 @@ impl Connection {
packet_params.userdata,
);
let res = res.map(|r| r.as_packet()).map_err(|e| e.to_string());
let res = res.map(ProcessHandle::as_packet).map_err(|e| e.to_string());
send_packet(
&mut self.conn,

View File

@ -293,7 +293,7 @@ fn logging_init(args: &mut Args) {
.open(&log_file_path)
{
Ok(file) => {
println!("Logging to {}", &log_file_path);
println!("Logging to {log_file_path}");
Some(file)
}
Err(e) => {

View File

@ -93,7 +93,7 @@ impl DashFrontend {
show_welcome: tutorial,
has_monado: app.feats.xr_backend.is_open_xr(),
theme: app.wgui_theme.clone(),
color_palette: &*app.session.config.color_palette,
color_palette: &app.session.config.color_palette,
executor: app.executor.clone(),
})?;
@ -213,18 +213,18 @@ impl OverlayBackend for DashFrontend {
}
// if we're grabbed, stop following the hmd
if let OverlayEventData::OverlayGrabbed { name, .. } = data {
if &*name == DASH_NAME {
self.tutorial = false;
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Name(name),
Box::new(|_app, owc| {
if let Some(active_state) = owc.active_state.as_mut() {
active_state.positioning = Positioning::Floating;
}
}),
)));
}
if let OverlayEventData::OverlayGrabbed { name, .. } = data
&& &*name == DASH_NAME
{
self.tutorial = false;
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Name(name),
Box::new(|_app, owc| {
if let Some(active_state) = owc.active_state.as_mut() {
active_state.positioning = Positioning::Floating;
}
}),
)));
}
Ok(())
@ -319,7 +319,7 @@ impl OverlayBackend for DashFrontend {
}
}
fn tutorial_spawn_effect(app: &mut AppState) -> anyhow::Result<()> {
fn tutorial_spawn_effect(app: &mut AppState) {
let dash_name: Arc<str> = DASH_NAME.into();
app.tasks.enqueue_at(
@ -360,13 +360,11 @@ fn tutorial_spawn_effect(app: &mut AppState) -> anyhow::Result<()> {
Instant::now().add(Duration::from_millis(500 + 40 * i)),
);
}
Ok(())
}
pub fn create_dash_frontend(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
if !app.session.config.tutorial_graduated {
tutorial_spawn_effect(app)?;
tutorial_spawn_effect(app);
}
Ok(OverlayWindowConfig {
@ -401,8 +399,8 @@ impl DashInterface<AppState> for DashInterfaceLive {
.windows
.iter()
.map(|(handle, win)| WvrWindow {
handle: WindowHandle::as_packet(&handle),
process_handle: ProcessHandle::as_packet(&win.process),
handle: WindowHandle::as_packet(handle),
process_handle: ProcessHandle::as_packet(win.process),
size_x: win.size_x,
size_y: win.size_y,
visible: win.visible,
@ -459,7 +457,7 @@ impl DashInterface<AppState> for DashInterfaceLive {
params.icon.as_deref(),
params.userdata,
)
.map(|x| x.as_packet())
.map(ProcessHandle::as_packet)
}
fn process_list(&mut self, app: &mut AppState) -> anyhow::Result<Vec<WvrProcess>> {

View File

@ -79,16 +79,15 @@ struct EditModeState {
impl EditModeState {
fn resize_end(&mut self, app: &mut AppState) {
match std::mem::replace(&mut self.resize, ResizeState::None) {
ResizeState::Active { overlay_id, .. } => {
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Id(overlay_id),
Box::new(|_app, owc| {
owc.resizing = false;
}),
)));
}
_ => {}
if let ResizeState::Active { overlay_id, .. } =
std::mem::replace(&mut self.resize, ResizeState::None)
{
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Id(overlay_id),
Box::new(|_app, owc| {
owc.resizing = false;
}),
)));
}
}
}
@ -312,25 +311,22 @@ impl OverlayBackend for EditModeBackendWrapper {
) {
self.panel.on_pointer(app, hit, pressed);
match &mut self.panel.state.resize {
ResizeState::Start { overlay_id } => {
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Id(*overlay_id),
Box::new(|_app, owc| {
owc.resizing = true;
}),
)));
if let ResizeState::Start { overlay_id } = &mut self.panel.state.resize {
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Id(*overlay_id),
Box::new(|_app, owc| {
owc.resizing = true;
}),
)));
let last_uv = hit.uv;
self.panel.state.resize = ResizeState::Active {
overlay_id: *overlay_id,
pointer: hit.pointer,
start_uv: last_uv,
last_uv: last_uv,
last_extent: self.extent,
};
}
_ => {}
let last_uv = hit.uv;
self.panel.state.resize = ResizeState::Active {
overlay_id: *overlay_id,
pointer: hit.pointer,
start_uv: last_uv,
last_uv,
last_extent: self.extent,
};
}
}
fn on_scroll(
@ -508,7 +504,7 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
return Ok(EventResult::Pass);
}
state.resize = ResizeState::Start {
overlay_id: state.id.borrow().clone(),
overlay_id: *state.id.borrow(),
};
Ok(EventResult::Consumed)
}),

View File

@ -426,7 +426,7 @@ fn on_enter_anim(
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
set_anim_color(&common.globals().palette, &key_state, rect, data.pos);
for child in key_state.labels.iter() {
for child in &key_state.labels {
let mut widget = common
.state
.widgets
@ -439,7 +439,7 @@ fn on_enter_anim(
widget.set_color(common, color, true);
}
for child in key_state.sprites.iter() {
for child in &key_state.sprites {
let mut widget = common
.state
.widgets
@ -474,7 +474,7 @@ fn on_leave_anim(
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
set_anim_color(&common.globals().palette, &key_state, rect, 1.0 - data.pos);
for child in key_state.labels.iter() {
for child in &key_state.labels {
let color = child.base_color.lerp(
&common.globals().palette,
&HOVER_TEXT_COLOR,
@ -488,7 +488,7 @@ fn on_leave_anim(
widget.set_color(common, color, true);
}
for child in key_state.sprites.iter() {
for child in &key_state.sprites {
let color = child.base_color.lerp(
&common.globals().palette,
&HOVER_TEXT_COLOR,

View File

@ -160,7 +160,7 @@ impl OverlayBackend for PassthruBackend {
color.with_alpha(1.0).as_arr().iter(),
)?;
let set0 = pipeline.buffer(0, buf_color.clone())?;
let set0 = pipeline.buffer(0, buf_color)?;
let extentf32 = [
self.frame_meta.extent[0] as f32,
self.frame_meta.extent[1] as f32,
@ -183,7 +183,7 @@ impl OverlayBackend for PassthruBackend {
[0.0, 0.0, 0.0, 1.0].iter(),
)?;
let set0 = pipeline.buffer(0, buf_color.clone())?;
let set0 = pipeline.buffer(0, buf_color)?;
let pass = pipeline.create_pass(
[extentf32[0] - 8.0, extentf32[1] - 8.0],

View File

@ -100,7 +100,7 @@ impl ScreenPipeline {
self.pass.clear(); // ensure_depth will repopulate
}
pub fn set_stereo_adjust_mouse(&mut self, adjust: bool) {
pub const fn set_stereo_adjust_mouse(&mut self, adjust: bool) {
self.stereo_adjust_mouse = adjust;
}
@ -255,7 +255,7 @@ impl ScreenPipeline {
mouse: &MouseMeta,
rdr: &mut RenderResources,
) -> anyhow::Result<()> {
for cmd_buf in rdr.cmd_bufs.iter_mut() {
for cmd_buf in &mut rdr.cmd_bufs {
let size = CURSOR_SIZE * self.extentf[1];
let half_size = size * 0.5;

View File

@ -86,12 +86,8 @@ pub fn new_mirror(name: Arc<str>, app: &mut AppState) -> anyhow::Result<OverlayW
capture: Box<dyn WlxCapture<WlxCaptureIn, WlxCaptureOut>>,
app: &mut AppState,
) -> Box<dyn OverlayBackend> {
let renderer = ScreenBackend::new_raw(
name.clone(),
app.feats.xr_backend,
CaptureType::PipeWire,
capture,
);
let renderer =
ScreenBackend::new_raw(name, app.feats.xr_backend, CaptureType::PipeWire, capture);
let backend = MirrorBackend(renderer);
@ -117,7 +113,7 @@ pub fn new_mirror(name: Arc<str>, app: &mut AppState) -> anyhow::Result<OverlayW
)?;
Ok(OverlayWindowConfig {
name: name.clone(),
name,
category: OverlayCategory::Mirror,
show_on_spawn: true,
default_state: OverlayWindowState {

View File

@ -68,6 +68,8 @@ pub struct ScreenCreateData {
pub screens: Vec<(ScreenMeta, OverlayWindowConfig)>,
}
// clippy suggests broken code
#[allow(clippy::needless_return)]
pub fn create_screens(app: &mut AppState) -> anyhow::Result<(ScreenCreateData, DesktopBackend)> {
app.screens.clear();

View File

@ -124,7 +124,7 @@ impl ScreenCastBackend {
) -> anyhow::Result<Self> {
if app.screencast_manager.is_none() {
anyhow::bail!("xdg-desktop-portal screencasts not supported");
};
}
let panel_params = NewGuiPanelParams {
extra_vars: HashMap::from([
@ -135,8 +135,8 @@ impl ScreenCastBackend {
};
let state = ScreenCastPanelState {
name: name.clone(),
description: description.clone(),
name,
description,
logical_pos,
logical_size,
params: Some(params),
@ -157,18 +157,20 @@ impl OverlayBackend for ScreenCastBackend {
if let Some(params) = self.panel.state.params.take()
&& let Some(screencast_manager) = app.screencast_manager.as_mut()
{
let request_id = screencast_manager.request(params.clone())?;
let request_id = screencast_manager.request(params)?;
check(
self.panel.state.name.clone(),
self.panel.state.description.clone(),
self.panel.state.logical_pos,
self.panel.state.logical_size,
0,
None,
None,
request_id.clone(),
CheckParams {
name: self.panel.state.name.clone(),
description: self.panel.state.description.clone(),
logical_pos: self.panel.state.logical_pos,
logical_size: self.panel.state.logical_size,
user_wait: 0,
notify_id: None,
request_id,
last_result: None,
app,
},
self.panel.state.finalize_fn,
app,
);
}
@ -247,60 +249,63 @@ impl OverlayBackend for ScreenCastBackend {
}
}
fn check(
struct CheckParams<'a> {
name: Arc<str>,
description: Arc<str>,
logical_pos: Vec2,
logical_size: Vec2,
user_wait: u32,
mut notify_id: Option<u32>,
last_result: Option<ScreenCastResult>,
notify_id: Option<u32>,
request_id: ScreenCastRequestId,
finalize_fn: ScreenCastFinalizeFn,
app: &mut AppState,
) {
last_result: Option<ScreenCastResult>,
app: &'a mut AppState,
}
fn check(mut par: CheckParams, finalize_fn: ScreenCastFinalizeFn) {
const POLL_INTERVAL: Duration = Duration::from_millis(100);
if let Some(screencast_manager) = app.screencast_manager.as_mut() {
let new_result = screencast_manager.check(&request_id);
if let Some(screencast_manager) = par.app.screencast_manager.as_mut() {
let new_result = screencast_manager.check(&par.request_id);
match new_result {
ScreenCastResult::Ok(ref pw_result) => {
log::debug!(
"{}: PipeWire result streams: {:?}",
name,
&pw_result.streams
par.name,
pw_result.streams
);
let node_id = pw_result.streams.first().unwrap().node_id; // streams guaranteed to have at least one element
log::info!("{}: PipeWire node selected: {}", name, node_id);
log::info!("{}: PipeWire node selected: {}", par.name, node_id);
if let Some(id) = notify_id.take() {
if let Some(id) = par.notify_id.take() {
let _ = DbusConnector::notify_close(id);
}
let pw_tokens_copy = app.session.pw_tokens.clone();
let pw_tokens_copy = par.app.session.pw_tokens.clone();
if let Some(restore_token) = pw_result.restore_token.as_ref()
&& app
&& par
.app
.session
.pw_tokens
.arc_set(name.clone(), restore_token.clone())
.arc_set(par.name.clone(), restore_token.clone())
{
log::info!("Adding Pipewire token for {name}");
log::info!("Adding Pipewire token for {}", par.name);
}
if pw_tokens_copy != app.session.pw_tokens {
if pw_tokens_copy != par.app.session.pw_tokens {
// Token list changed, re-create token config file
if let Err(err) = save_pw_token_config(app.session.pw_tokens.clone()) {
if let Err(err) = save_pw_token_config(par.app.session.pw_tokens.clone()) {
log::error!("Failed to save Pipewire token config: {err}");
}
}
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Name(name.clone()),
par.app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Name(par.name.clone()),
Box::new(move |app, owc| {
let capture = new_wlx_capture!(
app.gfx_extras.queue_capture,
PipewireCapture::new(name.clone(), node_id)
PipewireCapture::new(par.name.clone(), node_id)
);
owc.backend = finalize_fn(name, logical_pos, logical_size, capture, app);
owc.backend =
finalize_fn(par.name, par.logical_pos, par.logical_size, capture, app);
let _ = owc
.backend
@ -314,10 +319,10 @@ fn check(
| ScreenCastResult::Pending
| ScreenCastResult::WaitingForUser => {
let user_wait_add = if matches!(new_result, ScreenCastResult::WaitingForUser) {
if user_wait == 2 {
notify_id = DbusConnector::notify_send(
if par.user_wait == 2 {
par.notify_id = DbusConnector::notify_send(
"Select screen cast for:",
format!("{name} {description}").as_str(),
format!("{} {}", par.name, par.description).as_str(),
1,
30000,
0,
@ -330,26 +335,31 @@ fn check(
0
};
if last_result.is_none_or(|last_result| last_result != new_result) {
update_status_hack(&name, &description, &new_result, app);
if par
.last_result
.is_none_or(|last_result| last_result != new_result)
{
update_status_hack(&par.name, &par.description, &new_result, par.app);
}
app.tasks.enqueue_at(
par.app.tasks.enqueue_at(
TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Name(name.clone()),
OverlaySelector::Name(par.name.clone()),
Box::new({
move |app, _owc| {
check(
name.clone(),
description.clone(),
logical_pos,
logical_size,
user_wait + user_wait_add,
notify_id,
Some(new_result),
request_id.clone(),
CheckParams {
name: par.name.clone(),
description: par.description.clone(),
logical_pos: par.logical_pos,
logical_size: par.logical_size,
user_wait: par.user_wait + user_wait_add,
notify_id: par.notify_id,
request_id: par.request_id,
last_result: Some(new_result),
app,
},
finalize_fn,
app,
);
}
}),
@ -358,11 +368,11 @@ fn check(
);
}
ScreenCastResult::Failed(ref e) => {
if let Some(id) = notify_id.take() {
if let Some(id) = par.notify_id.take() {
let _ = DbusConnector::notify_close(id);
}
update_status_hack(&name, &description, &new_result, app);
update_status_hack(&par.name, &par.description, &new_result, par.app);
log::warn!("Failed to create mirror due to PipeWire error: {e:?}");
Toast::new(
@ -370,7 +380,7 @@ fn check(
"TOAST.TITLE_SCREENCAST_FAIL".into(),
format!("{e}"),
)
.submit(app);
.submit(par.app);
}
}
}

View File

@ -45,17 +45,16 @@ pub fn create_screen_renderer_wl(
app.session.config.capture_method,
CaptureMethod::ScreenCopyCpu | CaptureMethod::ScreenCopyGpu | CaptureMethod::Auto
) && has_wlr_screencopy
&& let Some(mut backend) = ScreenBackend::new_wlr_screencopy(output, app)
{
if let Some(mut backend) = ScreenBackend::new_wlr_screencopy(output, app) {
log::info!("{}: Using ScreenCopy capture", &output.name);
backend.logical_pos = vec2(output.logical_pos.0 as f32, output.logical_pos.1 as f32);
backend.logical_size = vec2(output.logical_size.0 as f32, output.logical_size.1 as f32);
backend.apply_mouse_transform_with_override(Transform::Undefined);
return Ok(Box::new(backend));
}
log::info!("{}: Using ScreenCopy capture", output.name);
backend.logical_pos = vec2(output.logical_pos.0 as f32, output.logical_pos.1 as f32);
backend.logical_size = vec2(output.logical_size.0 as f32, output.logical_size.1 as f32);
backend.apply_mouse_transform_with_override(Transform::Undefined);
return Ok(Box::new(backend));
}
log::info!("{}: Using Pipewire capture", &output.name);
log::info!("{}: Using Pipewire capture", output.name);
let display_name = &*output.name;
// Find existing token by display
@ -63,7 +62,7 @@ pub fn create_screen_renderer_wl(
.session
.pw_tokens
.arc_get(display_name)
.map(|x| x.to_string().into());
.map(|x| x.clone().into());
if token.is_some() {
log::info!("Found existing Pipewire token for display {display_name}");

View File

@ -56,7 +56,7 @@ pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result<ScreenCreateDa
.session
.pw_tokens
.arc_get("x11")
.map(|x| x.to_string().into()),
.map(|x| x.clone().into()),
embed_mouse: !app.session.config.double_cursor_fix,
allow_multiple: true,
persist: true,

View File

@ -46,7 +46,7 @@ use crate::{
rendered_surfaces_dirty,
},
process::KillSignal,
window::WindowHandle,
window::{Window, WindowHandle},
},
},
config::none_if_0,
@ -99,8 +99,7 @@ pub fn create_wl_window_overlay(
.wvr_server
.as_mut()
.and_then(|wvr| wvr.wm.windows.get(window))
.map(|w| w.resizable())
.unwrap_or(false);
.is_some_and(Window::resizable);
Ok(OverlayWindowConfig {
name: name.clone(),
@ -287,8 +286,7 @@ impl WvrWindowBackend {
.wvr_server
.as_mut()
.and_then(|wvr| wvr.wm.windows.get(self.window))
.map(|w| w.resizable())
.unwrap_or(false);
.is_some_and(Window::resizable);
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Id(self.overlay_id),
@ -366,6 +364,17 @@ impl WvrWindowBackend {
}
fn update_decor(&mut self, wvr_server: &mut WvrServerState) {
const COLORS: [(WguiColor, WguiColor); 2] = [
(
WguiColorName::Outline.to_wgui_color(),
WguiColorName::OnBackground.to_wgui_color(),
),
(
WguiColorName::Tertiary.to_wgui_color(),
WguiColorName::Tertiary.to_wgui_color(),
),
];
let now_focused = wvr_server
.get_focused_window()
.is_some_and(|w| w == self.window);
@ -381,17 +390,6 @@ impl WvrWindowBackend {
alterables: &mut self.panel.layout.alterables,
};
const COLORS: [(WguiColor, WguiColor); 2] = [
(
WguiColorName::Outline.to_wgui_color(),
WguiColorName::OnBackground.to_wgui_color(),
),
(
WguiColorName::Tertiary.to_wgui_color(),
WguiColorName::Tertiary.to_wgui_color(),
),
];
let (rect_col, label_col) = COLORS[now_focused as usize];
if let Ok(mut rect) = self
@ -411,7 +409,7 @@ impl WvrWindowBackend {
}
}
fn mouse_index_from_mode(mode: input::PointerMode) -> Option<wayvr::MouseIndex> {
const fn mouse_index_from_mode(mode: input::PointerMode) -> Option<wayvr::MouseIndex> {
match mode {
input::PointerMode::Left => Some(wayvr::MouseIndex::Left),
input::PointerMode::Middle => Some(wayvr::MouseIndex::Center),
@ -464,13 +462,9 @@ impl WvrWindowBackend {
Ok(())
}
fn sync_committed_toplevel_size(
&mut self,
app: &mut AppState,
inner_extent: [u32; 2],
) -> anyhow::Result<()> {
fn sync_committed_toplevel_size(&mut self, app: &mut AppState, inner_extent: [u32; 2]) {
let Some(wvr_server) = app.wvr_server.as_mut() else {
return Ok(());
return;
};
let bounds = wvr_server.manager.state.output_logical_size();
@ -478,7 +472,7 @@ impl WvrWindowBackend {
let committed = Size::new(inner_extent[0].max(1) as i32, inner_extent[1].max(1) as i32);
let Some(window) = wvr_server.wm.windows.get_mut(self.window) else {
return Ok(());
return;
};
let clamped = window.clamp_configure_size(committed, bounds);
@ -494,8 +488,6 @@ impl WvrWindowBackend {
window.pending_configure_size,
);
}
Ok(())
}
}
@ -575,7 +567,7 @@ impl OverlayBackend for WvrWindowBackend {
tree_dirty |= state.take_redraw_request(&surface.surface_id);
tree_dirty |= state.has_pending_frame_callbacks(&surface.surface_id);
}
for popup in popups.iter() {
for popup in &popups {
tree_dirty |= state.take_redraw_request(&popup.surface_id);
tree_dirty |= state.has_pending_frame_callbacks(&popup.surface_id);
}
@ -617,7 +609,7 @@ impl OverlayBackend for WvrWindowBackend {
}
let inner_extent = meta.extent;
self.sync_committed_toplevel_size(app, inner_extent)?;
self.sync_committed_toplevel_size(app, inner_extent);
let hit_context = WvrHitContext {
surfaces: hit_surfaces,
@ -713,7 +705,6 @@ impl OverlayBackend for WvrWindowBackend {
}
let image = self.cur_image.as_ref().unwrap().clone();
let mut callback_surfaces = Vec::with_capacity(self.surfaces.len() + self.popups.len());
self.pipeline
.as_mut()
@ -722,12 +713,10 @@ impl OverlayBackend for WvrWindowBackend {
for surface in self.surfaces.iter() {
self.render_subsurface(app, rdr, surface)?;
callback_surfaces.push(&surface.surface_id);
}
for popup in self.popups.iter() {
self.render_subsurface(app, rdr, popup)?;
callback_surfaces.push(&popup.surface_id);
}
// frame callbacks for toplevel + subsurf + popup
@ -832,16 +821,18 @@ impl OverlayBackend for WvrWindowBackend {
self.panel_hovered = true;
self.panel.on_hover(app, &hit2)
}
Some(WvrHitTarget::Popup {
surface,
global_pos,
origin,
})
| Some(WvrHitTarget::Surface {
surface,
global_pos,
origin,
}) => {
Some(
WvrHitTarget::Popup {
surface,
global_pos,
origin,
}
| WvrHitTarget::Surface {
surface,
global_pos,
origin,
},
) => {
if self.panel_hovered {
self.panel.on_left(app, hit.pointer);
self.panel_hovered = false;
@ -930,7 +921,7 @@ impl OverlayBackend for WvrWindowBackend {
&& app
.wvr_server
.as_ref()
.is_some_and(|server| server.pointer_is_grabbed());
.is_some_and(WvrServerState::pointer_is_grabbed);
let outside_grabbed_popup =
popup_grab_active && !matches!(&target, Some(WvrHitTarget::Popup { .. }));
@ -958,16 +949,18 @@ impl OverlayBackend for WvrWindowBackend {
self.panel.on_pointer(app, &hit2, pressed);
}
Some(WvrHitTarget::Popup {
surface,
global_pos,
origin,
})
| Some(WvrHitTarget::Surface {
surface,
global_pos,
origin,
}) => {
Some(
WvrHitTarget::Popup {
surface,
global_pos,
origin,
}
| WvrHitTarget::Surface {
surface,
global_pos,
origin,
},
) => {
let wvr_server = app.wvr_server.as_mut().unwrap();
wvr_server.send_mouse_button(
@ -1011,9 +1004,9 @@ impl OverlayBackend for WvrWindowBackend {
self.panel.on_scroll(app, &hit2, delta);
let _ = hit2;
}
Some(WvrHitTarget::Popup { global_pos, .. })
| Some(WvrHitTarget::Surface { global_pos, .. }) => {
Some(
WvrHitTarget::Popup { global_pos, .. } | WvrHitTarget::Surface { global_pos, .. },
) => {
let wvr_server = app.wvr_server.as_mut().unwrap();
wvr_server.send_mouse_scroll(self.window, global_pos, delta);
}
@ -1050,7 +1043,7 @@ impl OverlayBackend for WvrWindowBackend {
if let Some(stereo) = self.stereo.as_mut() {
log::debug!("{}: stereo: {stereo:?} → {new:?}", self.name);
*stereo = new;
if let Some(meta) = self.meta.clone() {
if let Some(meta) = self.meta {
let _ = self.apply_extent(app, &meta);
}
if let Some(pipeline) = self.pipeline.as_mut() {

View File

@ -67,7 +67,7 @@ impl WhisperState {
}
}
}
return false;
false
}
}
@ -119,42 +119,41 @@ pub fn create_whisper(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig>
return Ok(EventResult::Pass);
}
let whisper = match app.whisper_sst.as_mut() {
Some(x) => x,
None => {
let model_path = data_dir::get_path("whisper")
.join(app.session.config.whisper_model.as_ref());
if model_path.is_file() {
app.whisper_sst = match WhisperStt::new(model_path)
.log_err("Error while starting Whisper engine")
{
Ok(x) => Some(x),
Err(e) => {
Toast::new(
ToastTopic::System,
"WHISPER.INIT_ERROR".into(),
e.to_string(),
)
.with_timeout(5.)
.with_sound(true)
.submit(app);
return Ok(EventResult::Consumed);
}
let whisper = if let Some(x) = app.whisper_sst.as_mut() {
x
} else {
let model_path = data_dir::get_path("whisper")
.join(app.session.config.whisper_model.as_ref());
if model_path.is_file() {
app.whisper_sst = match WhisperStt::new(model_path)
.log_err("Error while starting Whisper engine")
{
Ok(x) => Some(x),
Err(e) => {
Toast::new(
ToastTopic::System,
"WHISPER.INIT_ERROR".into(),
e.to_string(),
)
.with_timeout(5.)
.with_sound(true)
.submit(app);
return Ok(EventResult::Consumed);
}
} else {
Toast::new(
ToastTopic::System,
"WHISPER.MODEL_NOT_DOWNLOADED".into(),
"WHISPER.DOWNLOAD_GUIDANCE".into(),
)
.with_timeout(5.)
.with_sound(true)
.submit(app);
return Ok(EventResult::Consumed);
}
app.whisper_sst.as_mut().unwrap()
} else {
Toast::new(
ToastTopic::System,
"WHISPER.MODEL_NOT_DOWNLOADED".into(),
"WHISPER.DOWNLOAD_GUIDANCE".into(),
)
.with_timeout(5.)
.with_sound(true)
.submit(app);
return Ok(EventResult::Consumed);
}
app.whisper_sst.as_mut().unwrap()
};
let _ = whisper
@ -294,13 +293,13 @@ pub fn create_whisper(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig>
let on_label_tick: EventCallback<AppState, WhisperState> =
Box::new(move |common, data, app, state| {
if let Some(whisper_stt) = app.whisper_sst.as_mut() {
if let Some(text) = whisper_stt.take_transcription() {
let text: Rc<str> = text.into();
state.last_transcription = Some(text.clone());
let label = data.obj.get_as_mut::<WidgetLabel>().unwrap();
label.set_text(common, Translation::from_raw_text_rc(text));
}
if let Some(whisper_stt) = app.whisper_sst.as_mut()
&& let Some(text) = whisper_stt.take_transcription()
{
let text: Rc<str> = text.into();
state.last_transcription = Some(text.clone());
let label = data.obj.get_as_mut::<WidgetLabel>().unwrap();
label.set_text(common, Translation::from_raw_text_rc(text));
}
Ok(EventResult::Pass)
});
@ -313,6 +312,7 @@ pub fn create_whisper(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig>
panel.update_layout(app)?;
#[allow(clippy::unreadable_literal)]
let transform = Affine3A::from_cols_array_2d(&[
[0.49993715, -0.00020921684, -0.008030709],
[-0.0021463279, 0.47818363, -0.14607349],

View File

@ -170,10 +170,11 @@ impl AppState {
let mut assets = Box::new(gui::asset::GuiAsset {});
audio_sample_player.register_wgui_samples(assets.as_mut())?;
let mut theme = WguiTheme::default();
theme.animation_mult = 1. / session.config.ui_animation_speed;
theme.rounding_mult = session.config.ui_round_multiplier;
let mut theme = WguiTheme {
animation_mult: 1. / session.config.ui_animation_speed,
rounding_mult: session.config.ui_round_multiplier,
..Default::default()
};
let dbus = DbusConnector::default();
@ -284,7 +285,11 @@ impl AppState {
#[cfg(feature = "whisper")]
{
if self.whisper_sst.as_ref().is_some_and(|x| x.should_unload()) {
if self
.whisper_sst
.as_ref()
.is_some_and(WhisperStt::should_unload)
{
log::info!("Unloading Whisper model due to timeout");
self.whisper_sst = None;
}

View File

@ -80,7 +80,7 @@ impl Provider {
tx,
_thread: thread,
}),
Err(err) => anyhow::bail!("{}", err),
Err(err) => anyhow::bail!("{err}"),
}
}
}

View File

@ -192,12 +192,13 @@ impl ClipboardRuntime {
let _ = self.conn.flush();
}
#[allow(clippy::match_same_arms)]
fn drain_x_events(&mut self) {
loop {
match self.conn.poll_for_event() {
Ok(Some(event)) => self.handle_x_event(event),
Ok(None) => break,
Err(xcb::Error::Protocol(_)) => continue,
Err(xcb::Error::Protocol(_)) => { /* continue */ }
Err(xcb::Error::Connection(_)) => break,
}
}
@ -208,10 +209,10 @@ impl ClipboardRuntime {
xcb::Event::X(x::Event::SelectionRequest(req)) => {
self.handle_selection_request(&req);
}
xcb::Event::X(x::Event::SelectionClear(ev)) => {
if ev.selection() == self.atoms.clipboard {
self.owns_clipboard = false;
}
xcb::Event::X(x::Event::SelectionClear(ev))
if ev.selection() == self.atoms.clipboard =>
{
self.owns_clipboard = false;
}
_ => {}
}
@ -263,9 +264,7 @@ impl ClipboardRuntime {
if target == self.atoms.utf8_string
|| target == self.atoms.text_plain_utf8
|| target == self.atoms.text_plain
{
Some(target)
} else if self.content.is_ascii() && (target == self.atoms.text || target == x::ATOM_STRING)
|| (self.content.is_ascii() && (target == self.atoms.text || target == x::ATOM_STRING))
{
Some(target)
} else {

View File

@ -1,4 +1,3 @@
use crate::overlays::toast::Toast;
use crate::subsystem::hid::provider::HidProvider;
use crate::subsystem::hid::{VirtualKey, WheelDelta, XkbKeymap};
use glam::DVec2;
@ -20,6 +19,6 @@ impl HidProvider for DummyProvider {
fn commit(&mut self) {}
}
pub fn initialize_dummy() -> anyhow::Result<Box<dyn HidProvider>, Toast> {
Ok(Box::new(DummyProvider {}))
pub fn initialize_dummy() -> Box<dyn HidProvider> {
Box::new(DummyProvider {})
}

View File

@ -3,7 +3,7 @@ use std::os::fd::AsFd;
use std::time::{SystemTime, UNIX_EPOCH};
use anyhow::Context as _;
use glam::{Vec2, DVec2};
use input_linux::sys::{*};
use input_linux::sys::{BTN_LEFT, BTN_MIDDLE, BTN_RIGHT};
use smithay::reexports::rustix::fs::{memfd_create, MemfdFlags};
use smithay::reexports::wayland_protocols_wlr::virtual_pointer::v1::client::zwlr_virtual_pointer_manager_v1::ZwlrVirtualPointerManagerV1;
use smithay::reexports::wayland_protocols_wlr::virtual_pointer::v1::client::zwlr_virtual_pointer_v1::ZwlrVirtualPointerV1;
@ -19,12 +19,12 @@ use xkbcommon::xkb::{KEYMAP_FORMAT_TEXT_V1};
use wlx_common::overlays::ToastTopic;
use crate::overlays::toast::Toast;
use crate::subsystem::hid::provider::HidProvider;
use crate::subsystem::hid::{VirtualKey, WheelDelta, *};
use crate::subsystem::hid::{self, VirtualKey, WheelDelta};
const LOCKED: u8 = CAPS_LOCK | NUM_LOCK;
const LOCKED: u8 = hid::CAPS_LOCK | hid::NUM_LOCK;
pub struct WlVirtualProvider {
_connection: wayland_client::Connection,
connection: wayland_client::Connection,
queue: wayland_client::EventQueue<KbState>,
state: KbState,
@ -74,14 +74,15 @@ impl HidProvider for WlVirtualProvider {
self.virtual_pointer.button(
Self::now_ms(),
match button {
i if i == MOUSE_LEFT => BTN_LEFT as u32,
i if i == MOUSE_RIGHT => BTN_RIGHT as u32,
i if i == MOUSE_MIDDLE => BTN_MIDDLE as u32,
i if i == hid::MOUSE_LEFT => BTN_LEFT as u32,
i if i == hid::MOUSE_RIGHT => BTN_RIGHT as u32,
i if i == hid::MOUSE_MIDDLE => BTN_MIDDLE as u32,
_ => panic!("Invalid mouse button: {button}"),
},
match down {
true => ButtonState::Pressed,
false => ButtonState::Released,
if down {
ButtonState::Pressed
} else {
ButtonState::Released
},
);
self.virtual_pointer.frame();
@ -128,10 +129,10 @@ impl HidProvider for WlVirtualProvider {
fn set_modifiers(&mut self, mods: u8) {
let changed = (self.keyboard_mods_state ^ mods) & !LOCKED;
for bit in [SHIFT, CTRL, ALT, SUPER] {
for bit in [hid::SHIFT, hid::CTRL, hid::ALT, hid::SUPER] {
if changed & bit != 0 {
let down = mods & bit != 0;
if let Some(kc) = MODS_TO_KEYS.get(bit) {
if let Some(kc) = hid::MODS_TO_KEYS.get(bit) {
self.virtual_keyboard
.key(Self::now_ms(), kc[0] as u32 - 8, down as u32);
}
@ -143,24 +144,18 @@ impl HidProvider for WlVirtualProvider {
self.virtual_keyboard.modifiers(depressed, 0, locked, 0);
self.keyboard_mods_state = mods;
self._connection.flush().unwrap();
self.connection.flush().unwrap();
}
fn send_key(&mut self, key: VirtualKey, down: bool) {
#[cfg(debug_assertions)]
log::trace!("Keyboard key: {key:?} ({}), down: {down}", key as u16);
self.virtual_keyboard.key(
Self::now_ms(),
key as u32 - 8,
match down {
true => 1,
false => 0,
},
);
self.virtual_keyboard
.key(Self::now_ms(), key as u32 - 8, u32::from(down));
// sending a mod key → also have to update mod state
if let Some(m) = KEYS_TO_MODS.get(key) {
if let Some(m) = hid::KEYS_TO_MODS.get(key) {
match (down, m & LOCKED != 0) {
(true, true) => self.keyboard_mods_state ^= m,
(true, false) => self.keyboard_mods_state |= m,
@ -173,10 +168,10 @@ impl HidProvider for WlVirtualProvider {
self.virtual_keyboard.modifiers(depressed, 0, locked, 0);
}
self._connection.flush().unwrap();
self.connection.flush().unwrap();
}
fn set_keymap(&mut self, keymap: &XkbKeymap) {
fn set_keymap(&mut self, keymap: &hid::XkbKeymap) {
#[cfg(debug_assertions)]
log::trace!(
"Keyboard keymap: {:?}",
@ -228,12 +223,12 @@ impl WlVirtualProvider {
let virtual_keyboard = keyboard_manager.create_virtual_keyboard(&seat, &qh, ());
let keymap =
get_keymap_wl().unwrap_or_else(|_| XkbKeymap::from_layout_variant("us", "").unwrap());
let keymap = hid::get_keymap_wl()
.unwrap_or_else(|_| hid::XkbKeymap::from_layout_variant("us", "").unwrap());
let mut result = Self {
keymap_file: None,
_connection: connection,
connection,
queue,
state,
virtual_pointer,

View File

@ -18,12 +18,13 @@ pub struct HidWrapper {
pub keymap: Option<XkbKeymap>,
}
#[allow(clippy::map_unwrap_or)]
impl HidWrapper {
pub fn new(method: InputEmulationMethod) -> (Self, Option<Toast>) {
let maybe_provider = match method {
InputEmulationMethod::Uinput => hid::provider::uinput::initialize_uinput(),
InputEmulationMethod::WlVirtual => hid::provider::wl_virtual::initialize_wl_virtual(),
InputEmulationMethod::None => hid::provider::dummy::initialize_dummy(),
InputEmulationMethod::None => Ok(hid::provider::dummy::initialize_dummy()),
};
let (provider, toast) = maybe_provider
@ -45,7 +46,9 @@ impl HidWrapper {
wvr_server: Option<&mut WvrServerState>,
value: InputFocus,
) -> bool {
if self.input_focus != value {
if self.input_focus == value {
false
} else {
self.input_focus = value;
if let Some(wvr_server) = wvr_server {
@ -53,12 +56,10 @@ impl HidWrapper {
}
true
} else {
false
}
}
pub fn get_input_focus(&self) -> InputFocus {
pub const fn get_input_focus(&self) -> InputFocus {
self.input_focus
}
@ -85,7 +86,7 @@ impl HidWrapper {
.inspect_err(|e| log::error!("Could not set WayVR keymap: {e:?}"));
} else {
self.keymap = Some(keymap.clone());
self.inner.set_keymap(&keymap);
self.inner.set_keymap(keymap);
}
log::info!(

View File

@ -40,9 +40,7 @@ pub struct WhisperSttConfig {
impl WhisperSttConfig {
pub fn new(model_path: impl AsRef<Path>) -> Self {
let n_threads = std::thread::available_parallelism()
.map(|n| n.get().min(4) as i32)
.unwrap_or(4);
let n_threads = std::thread::available_parallelism().map_or(4, |n| n.get().min(4) as i32);
Self {
model_path: model_path.as_ref().to_path_buf(),
@ -117,10 +115,12 @@ impl WhisperStt {
}
pub fn init(config: WhisperSttConfig) -> Result<Self, WhisperSttError> {
let mut ctx_params = WhisperContextParameters::default();
ctx_params.use_gpu = config.use_gpu;
ctx_params.gpu_device = config.gpu_device;
ctx_params.flash_attn = config.flash_attn;
let ctx_params = WhisperContextParameters {
use_gpu: config.use_gpu,
gpu_device: config.gpu_device,
flash_attn: config.flash_attn,
..Default::default()
};
let ctx = WhisperContext::new_with_params(&config.model_path, ctx_params)
.map_err(|e| WhisperSttError::ModelLoad(e.to_string()))?;
@ -260,10 +260,9 @@ impl WhisperStt {
.active
.as_ref()
.is_some_and(|session| Instant::now() >= session.deadline)
&& let Err(e) = self.stop_active_capture()
{
if let Err(e) = self.stop_active_capture() {
self.last_error = Some(e.to_string());
}
self.last_error = Some(e.to_string());
}
None
@ -338,15 +337,12 @@ fn recognizer_thread(
audio.len().saturating_sub(last_decoded_len) >= partial_stride_samples;
if audio.len() >= min_samples && enough_new_audio {
match transcribe_audio(&ctx, &config, &audio) {
Ok(text) => {
latest_partial = text;
last_decoded_len = audio.len();
}
Err(_) => {
// do not fail the session on a speculative decode
// the final decode after PTT end gets reported
}
if let Ok(text) = transcribe_audio(&ctx, &config, &audio) {
latest_partial = text;
last_decoded_len = audio.len();
} else {
// do not fail the session on a speculative decode
// the final decode after PTT end gets reported
}
}
}
@ -401,8 +397,7 @@ fn transcribe_audio(
let text = state
.as_iter()
.map(|segment| segment.to_string())
.collect::<Vec<_>>()
.join("");
.collect::<String>();
Ok(normalize_transcript(text))
}
@ -417,10 +412,10 @@ fn rodio_capture_thread(
let result = run_rodio_capture(audio_tx, stop_rx, input_device_name, &mut ready_tx);
if let Err(e) = result {
if let Some(ready_tx) = ready_tx.take() {
let _ = ready_tx.send(Err(e.to_string()));
}
if let Err(e) = result
&& let Some(ready_tx) = ready_tx.take()
{
let _ = ready_tx.send(Err(e.to_string()));
}
}
@ -510,12 +505,12 @@ fn run_rodio_capture(
// Rodio's default sample type is f32. This cast also keeps the code
// compiling if the crate is built with rodio's `64bit` feature.
interleaved.push(sample as f32);
interleaved.push(sample);
}
let resampled = resampler.push_interleaved_mono_16k(&interleaved, channels, input_rate);
let resampled_vec = resampler.push_interleaved_mono_16k(&interleaved, channels, input_rate);
if !resampled.is_empty() && audio_tx.send(resampled).is_err() {
if !resampled_vec.is_empty() && audio_tx.send(resampled_vec).is_err() {
break;
}
}
@ -572,6 +567,7 @@ impl StreamingResampler {
((self.pending.len() as f64 - self.position) / step).max(0.0) as usize,
);
#[allow(clippy::while_float)]
while self.position + 1.0 < self.pending.len() as f64 {
let i = self.position.floor() as usize;
let frac = (self.position - i as f64) as f32;
@ -594,7 +590,7 @@ impl StreamingResampler {
}
}
fn ms_to_samples(ms: u64) -> usize {
const fn ms_to_samples(ms: u64) -> usize {
((ms as usize) * WHISPER_SAMPLE_RATE) / 1000
}

View File

@ -173,7 +173,7 @@ where
for name in saved_passthrus {
if me.lookup(&name).is_none() {
let mut config = new_passthru(name.clone(), app);
config.show_on_spawn = !me.global_set.hidden_overlays.arc_get(&*name).is_some();
config.show_on_spawn = me.global_set.hidden_overlays.arc_get(&name).is_none();
me.add_with_spawn_pos(
OverlayWindowData::from_config(config),
@ -397,7 +397,7 @@ where
}
}
OverlayTask::Spawn(sel, spawn_pos, f) => {
self.spawn_overlay(app, sel, spawn_pos, f)?;
self.spawn_overlay(app, sel, spawn_pos, f);
}
OverlayTask::Drop(sel) => {
let (id, name) = match &sel {
@ -436,7 +436,7 @@ where
) {
log::warn!(
"Received command for '{}', but this overlay does not support commands",
&task.overlay
task.overlay
);
return Ok(());
}
@ -460,15 +460,15 @@ where
sel: OverlaySelector,
spawn_pos: SpawnPos,
f: Box<CreateOverlayTask>,
) -> anyhow::Result<()> {
) {
let None = self.mut_by_selector(&sel) else {
log::debug!("Could not spawn {sel:?}: exists");
return Ok(());
return;
};
let Some(overlay_config) = f(app) else {
log::debug!("Could not spawn {sel:?}: empty config");
return Ok(());
return;
};
self.add_with_spawn_pos(
@ -479,8 +479,6 @@ where
app,
spawn_pos,
);
Ok(())
}
}
@ -566,10 +564,10 @@ impl<T> OverlayWindowManager<T> {
let mut global_overlays: HashMap<_, _> =
self.global_set.inactive_overlays.iter().cloned().collect();
for o in self.overlays.values() {
if o.config.global {
if let Some(state) = &o.config.active_state {
global_overlays.insert(o.config.name.clone(), state.clone());
}
if o.config.global
&& let Some(state) = &o.config.active_state
{
global_overlays.insert(o.config.name.clone(), state.clone());
}
}
let global_hidden: HashMap<_, _> = self

View File

@ -131,7 +131,7 @@ impl WguiColor {
/// Gets a matching foreground color from a background color
pub fn fg_color(&self) -> Option<Self> {
if let Self::Named(name) = self {
name.name.fg_color().map(|x| x.into())
name.name.fg_color().map(Into::into)
} else {
None
}
@ -140,7 +140,7 @@ impl WguiColor {
/// Gets a matching background color from a foreground color
pub fn bg_color(&self) -> Option<Self> {
if let Self::Named(name) = self {
name.name.bg_color().map(|x| x.into())
name.name.bg_color().map(Into::into)
} else {
None
}
@ -148,7 +148,7 @@ impl WguiColor {
}
impl WguiColorName {
pub fn fg_color(&self) -> Option<Self> {
pub const fn fg_color(&self) -> Option<Self> {
match self {
Self::Primary => Some(Self::OnPrimary),
Self::Secondary => Some(Self::OnSecondary),
@ -161,7 +161,7 @@ impl WguiColorName {
}
}
pub fn bg_color(&self) -> Option<Self> {
pub const fn bg_color(&self) -> Option<Self> {
match self {
Self::OnPrimary => Some(Self::Primary),
Self::OnSecondary => Some(Self::Secondary),

View File

@ -111,7 +111,7 @@ pub fn construct(
mut params: Params,
) -> anyhow::Result<(WidgetPair, Rc<ComponentBarGraph>)> {
params.style.flex_direction = FlexDirection::Row;
params.style.gap = length(4.0);
params.style.gap = length(4.0_f32);
// override style
let (root, _) = ess.layout.add_child(ess.parent, WidgetDiv::create(), params.style)?;
@ -124,7 +124,7 @@ pub fn construct(
flex_direction: FlexDirection::Column,
size: taffy::Size {
width: auto(),
height: percent(1.0),
height: percent(1.0_f32),
},
..Default::default()
},
@ -143,8 +143,8 @@ pub fn construct(
taffy::Style {
position: taffy::Position::Relative,
size: taffy::Size {
width: percent(1.0),
height: percent(1.0),
width: percent(1.0_f32),
height: percent(1.0_f32),
},
..Default::default()
},
@ -194,8 +194,8 @@ pub fn construct(
}),
taffy::Style {
size: taffy::Size {
width: percent(1.0),
height: percent(1.0),
width: percent(1.0_f32),
height: percent(1.0_f32),
},
..Default::default()
},

View File

@ -603,16 +603,20 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
let id_rect = root.id;
let default_margin = taffy::Rect {
top: length(4.0),
bottom: length(4.0),
left: length(4.0),
right: length(4.0),
top: length(4.0_f32),
bottom: length(4.0_f32),
left: length(4.0_f32),
right: length(4.0_f32),
};
let id_sprite = if let Some(sprite_path) = params.sprite_src {
let sprite = WidgetSprite::create(WidgetSpriteParams {
glyph_data: Some(CustomGlyphData::from_assets(&ess.layout.state.globals, sprite_path)?),
color: Some(params.sprite_color.unwrap_or(WguiColorName::OnBackground.into())),
color: Some(
params
.sprite_color
.unwrap_or_else(|| WguiColorName::OnBackground.into()),
),
..Default::default()
});
@ -621,8 +625,8 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
sprite,
taffy::Style {
min_size: taffy::Size {
width: length(20.0),
height: length(20.0),
width: length(20.0_f32),
height: length(20.0_f32),
},
margin: default_margin,
..Default::default()
@ -715,7 +719,7 @@ fn color_to_apply(parent_color: ParentColor, bg_color: WguiColor) -> Option<Wgui
}
}
fn color_to_apply2(parent_color: ParentColor, bg_color: WguiColor, fg_color: WguiColor) -> Option<WguiColor> {
const fn color_to_apply2(parent_color: ParentColor, bg_color: WguiColor, fg_color: WguiColor) -> Option<WguiColor> {
match parent_color {
ParentColor::Foreground => Some(fg_color),
ParentColor::Background => Some(bg_color),

View File

@ -123,13 +123,9 @@ impl ComponentTrait for ComponentCheckbox {
fn set_box_checked(widgets: &layout::WidgetMap, data: &Data, checked: bool, hovered: bool) {
widgets.call(data.id_inner_box, |rect: &mut WidgetRectangle| {
rect.params.color = if checked {
if hovered {
COLOR_HOVERED.into()
} else {
data.color_checked
}
if hovered { COLOR_HOVERED } else { data.color_checked }
} else {
COLOR_UNCHECKED.into()
COLOR_UNCHECKED
}
});
}
@ -180,13 +176,13 @@ fn anim_hover(anim_data: &mut crate::animation::CallbackData<'_>, pos: f32, _pre
let rect = anim_data.obj.as_any_mut().downcast_mut::<WidgetRectangle>().unwrap();
rect.params.border = 2.0;
rect.params.border_color = if pos > 0.0 {
COLOR_HOVERED.into()
COLOR_HOVERED
} else {
WguiColorName::OnBackground.into()
};
}
fn anim_hover_in(state: Rc<RefCell<State>>, data: Rc<Data>, anim_mult: f32) -> Animation {
fn anim_hover_in(state: &Rc<RefCell<State>>, data: &Rc<Data>, anim_mult: f32) -> Animation {
let down = state.borrow().down;
Animation::new(
data.id_outer_box,
@ -199,7 +195,7 @@ fn anim_hover_in(state: Rc<RefCell<State>>, data: Rc<Data>, anim_mult: f32) -> A
)
}
fn anim_hover_out(state: Rc<RefCell<State>>, data: Rc<Data>, anim_mult: f32) -> Animation {
fn anim_hover_out(state: &Rc<RefCell<State>>, data: &Rc<Data>, anim_mult: f32) -> Animation {
let down = state.borrow().down;
Animation::new(
data.id_outer_box,
@ -223,9 +219,7 @@ fn register_event_mouse_enter(
EventListenerKind::MouseEnter,
Box::new(move |common, _event_data, (), ()| {
common.alterables.trigger_haptics();
common
.alterables
.animate(anim_hover_in(state.clone(), data.clone(), anim_mult));
common.alterables.animate(anim_hover_in(&state, &data, anim_mult));
ComponentTooltip::register_hover_in(common, &tooltip_info, data.id_container, state.clone());
@ -240,7 +234,7 @@ fn register_event_mouse_enter(
.state
.widgets
.call(data.id_inner_box, |rect: &mut WidgetRectangle| {
rect.params.color = COLOR_HOVERED.into();
rect.params.color = COLOR_HOVERED;
});
}
@ -259,9 +253,7 @@ fn register_event_mouse_leave(
EventListenerKind::MouseLeave,
Box::new(move |common, _event_data, (), ()| {
common.alterables.trigger_haptics();
common
.alterables
.animate(anim_hover_out(state.clone(), data.clone(), anim_mult));
common.alterables.animate(anim_hover_out(&state, &data, anim_mult));
let checked = {
let mut state = state.borrow_mut();
@ -312,7 +304,7 @@ fn register_event_mouse_press(
.call(data.id_outer_box, |rect: &mut WidgetRectangle| {
rect.params.border = 2.0;
rect.params.border_color = if pressed_hovered {
COLOR_HOVERED.into()
COLOR_HOVERED
} else {
WguiColorName::OnBackground.into()
};
@ -350,7 +342,7 @@ fn register_event_mouse_release(
.call(data.id_outer_box, |rect: &mut WidgetRectangle| {
rect.params.border = 2.0;
rect.params.border_color = if released_hovered {
COLOR_HOVERED.into()
COLOR_HOVERED
} else {
WguiColorName::OnBackground.into()
};
@ -406,20 +398,20 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
// make checkbox interaction box larger by setting padding and negative margin
style.padding = taffy::Rect {
left: length(4.0),
right: length(8.0),
top: length(4.0),
bottom: length(4.0),
left: length(4.0_f32),
right: length(8.0_f32),
top: length(4.0_f32),
bottom: length(4.0_f32),
};
style.margin = taffy::Rect {
left: length(-4.0),
right: length(-8.0),
top: length(-4.0),
bottom: length(-4.0),
left: length(-4.0_f32),
right: length(-8.0_f32),
top: length(-4.0_f32),
bottom: length(-4.0_f32),
};
//style.align_self = Some(taffy::AlignSelf::Start); // do not stretch self to the parent
style.gap = length(4.0);
style.gap = length(4.0_f32);
let (round_5, round_8) = if params.radio_group.is_some() {
(WLength::Percent(1.0), WLength::Percent(1.0))
@ -427,7 +419,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
(WLength::Units(5.0), WLength::Units(8.0))
};
let color_checked = params.color_checked.unwrap_or(WguiColorName::Primary.into());
let color_checked = params.color_checked.unwrap_or_else(|| WguiColorName::Primary.into());
let (root, _) = ess.layout.add_child(
ess.parent,
@ -457,7 +449,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
}),
taffy::Style {
size: box_size,
padding: taffy::Rect::length(4.0),
padding: taffy::Rect::length(4.0_f32),
min_size: box_size,
max_size: box_size,
..Default::default()
@ -468,17 +460,13 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
outer_box.id,
WidgetRectangle::create(WidgetRectangleParams {
round: round_5,
color: if params.checked {
color_checked
} else {
COLOR_UNCHECKED.into()
},
color: if params.checked { color_checked } else { COLOR_UNCHECKED },
..Default::default()
}),
taffy::Style {
size: taffy::Size {
width: percent(1.0),
height: percent(1.0),
width: percent(1.0_f32),
height: percent(1.0_f32),
},
..Default::default()
},

View File

@ -276,11 +276,11 @@ pub fn construct(
let text_color = WguiColor::from(WguiColorName::OnBackgroundVariant);
if params.style.size.width.is_auto() {
params.style.size.width = length(128.0);
params.style.size.width = length(128.0_f32);
}
if params.style.size.height.is_auto() {
params.style.size.height = length(32.0);
params.style.size.height = length(32.0_f32);
}
// override style
@ -312,8 +312,8 @@ pub fn construct(
align_content: Some(taffy::AlignContent::CENTER),
align_items: Some(taffy::AlignItems::CENTER),
size: taffy::Size {
width: percent(1.0),
height: percent(1.0),
width: percent(1.0_f32),
height: percent(1.0_f32),
},
..Default::default()
},
@ -331,7 +331,7 @@ pub fn construct(
root.id,
WidgetDiv::create(),
taffy::Style {
padding: taffy::Rect::length(8.0),
padding: taffy::Rect::length(8.0_f32),
..Default::default()
},
)?;
@ -370,8 +370,8 @@ pub fn construct(
align_self: Some(taffy::AlignSelf::CENTER),
justify_self: Some(taffy::JustifySelf::END),
min_size: taffy::Size {
width: length(2.0),
height: length(16.0),
width: length(2.0_f32),
height: length(16.0_f32),
},
..Default::default()
},

View File

@ -649,8 +649,8 @@ fn mount_slider_handle(
) -> anyhow::Result<SliderHandleData> {
let slider_handle_style = taffy::Style {
size: taffy::Size {
width: length(0.0),
height: percent(1.0),
width: length(0.0_f32),
height: percent(1.0_f32),
},
position: taffy::Position::Absolute,
align_items: Some(taffy::AlignItems::CENTER),
@ -728,7 +728,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
}),
taffy::Style {
size: taffy::Size {
width: percent(1.0),
width: percent(1.0_f32),
height: percent(PAD_PERCENT),
},
position: taffy::Position::Absolute,

View File

@ -121,7 +121,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
style.flex_direction = taffy::FlexDirection::Column;
style.flex_wrap = taffy::FlexWrap::NoWrap;
style.align_items = Some(AlignItems::CENTER);
style.gap = length(4.0);
style.gap = length(4.0_f32);
let (root, _) = ess.layout.add_child(ess.parent, WidgetDiv::create(), style)?;
@ -141,8 +141,8 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
sprite_src,
style: taffy::Style {
min_size: taffy::Size {
width: percent(1.0),
height: length(32.0),
width: percent(1.0_f32),
height: length(32.0_f32),
},
justify_content: Some(taffy::JustifyContent::START),
..Default::default()

View File

@ -216,8 +216,8 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
margin: taffy::Rect {
left: length(pin_left),
top: length(pin_top),
bottom: length(0.0),
right: length(0.0),
bottom: length(0.0_f32),
right: length(0.0_f32),
},
/* important, to make it centered! */
size: taffy::Size {
@ -241,12 +241,12 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
}),
taffy::Style {
position: taffy::Position::Relative,
gap: length(4.0),
gap: length(4.0_f32),
padding: taffy::Rect {
left: length(16.0),
right: length(16.0),
top: length(8.0),
bottom: length(8.0),
left: length(16.0_f32),
right: length(16.0_f32),
top: length(8.0_f32),
bottom: length(8.0_f32),
},
..Default::default()
},

View File

@ -238,8 +238,8 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
WidgetImage::create(Default::default()),
taffy::Style {
size: taffy::Size {
width: percent(1.0),
height: percent(1.0),
width: percent(1.0_f32),
height: percent(1.0_f32),
},
..Default::default()
},

View File

@ -204,16 +204,8 @@ impl Color {
}
const fn hex_byte(high: u8, low: u8) -> Option<u8> {
let high = match hex_nibble(high) {
Some(value) => value,
None => return None,
};
let low = match hex_nibble(low) {
Some(value) => value,
None => return None,
};
let Some(high) = hex_nibble(high) else { return None };
let Some(low) = hex_nibble(low) else { return None };
Some((high << 4) | low)
}
@ -223,19 +215,16 @@ impl Color {
return None;
}
let r = match hex_byte(bytes[1], bytes[2]) {
Some(value) => value,
None => return None,
let Some(r) = hex_byte(bytes[1], bytes[2]) else {
return None;
};
let g = match hex_byte(bytes[3], bytes[4]) {
Some(value) => value,
None => return None,
let Some(g) = hex_byte(bytes[3], bytes[4]) else {
return None;
};
let b = match hex_byte(bytes[5], bytes[6]) {
Some(value) => value,
None => return None,
let Some(b) = hex_byte(bytes[5], bytes[6]) else {
return None;
};
let a = if bytes.len() == 9 {

View File

@ -573,7 +573,7 @@ impl Layout {
};
let size = if params.resize_to_parent {
taffy::Size::percent(1.0)
taffy::Size::percent(1.0_f32)
} else {
taffy::Size::auto()
};

View File

@ -84,7 +84,7 @@ const fn hex(hex: &str) -> drawing::Color {
}
}
pub static PALETTES: &[(&'static str, &WguiColorPalette)] = &[
pub static PALETTES: &[(&str, &WguiColorPalette)] = &[
("Default", DEFAULT),
("Ayu Dusk", AYU),
("Catppuccin", CATPPUCCIN),

View File

@ -44,52 +44,51 @@ pub fn parse_component_tabs<'a>(
let attribs = process_attribs(file, ctx, &child, false);
for attrib in attribs.iter() {
for attrib in &attribs {
match &*attrib.attrib {
"name" => name = Some(attrib.value.clone()),
"text" => text = Some(Translation::from_raw_text(&*attrib.value)),
"translation" => text = Some(Translation::from_translation_key(&*attrib.value)),
"text" => text = Some(Translation::from_raw_text(&attrib.value)),
"translation" => text = Some(Translation::from_translation_key(&attrib.value)),
"sprite_src" | "sprite_src_ext" | "sprite_src_builtin" | "sprite_src_internal" => {
sprite_src = Some(get_asset_path_rc_from_kv(
"sprite_",
&*attrib.attrib,
&attrib.attrib,
attrib.value.clone(),
));
continue;
}
"round" => {
parse_round(
ctx,
tag_name,
&*attrib.attrib,
&*attrib.value,
&attrib.attrib,
&attrib.value,
&mut round,
ctx.layout.state.theme.rounding_mult,
);
}
"color" => {
parse_color_opt(ctx, tag_name, &*attrib.attrib, &*attrib.value, &mut color);
parse_color_opt(ctx, tag_name, &attrib.attrib, &attrib.value, &mut color);
}
"border" => {
ctx.parse_check_f32(tag_name, &*attrib.attrib, &*attrib.value, &mut border);
ctx.parse_check_f32(tag_name, &attrib.attrib, &attrib.value, &mut border);
}
"border_color" => {
parse_color_opt(ctx, tag_name, &*attrib.attrib, &*attrib.value, &mut border_color);
parse_color_opt(ctx, tag_name, &attrib.attrib, &attrib.value, &mut border_color);
}
"hover_color" => {
parse_color_opt(ctx, tag_name, &*attrib.attrib, &*attrib.value, &mut hover_color);
parse_color_opt(ctx, tag_name, &attrib.attrib, &attrib.value, &mut hover_color);
}
"hover_border_color" => {
parse_color_opt(ctx, tag_name, &*attrib.attrib, &*attrib.value, &mut hover_border_color);
parse_color_opt(ctx, tag_name, &attrib.attrib, &attrib.value, &mut hover_border_color);
}
"sticky_color" => {
parse_color_opt(ctx, tag_name, &*attrib.attrib, &*attrib.value, &mut sticky_color);
parse_color_opt(ctx, tag_name, &attrib.attrib, &attrib.value, &mut sticky_color);
}
"sticky_border_color" => {
parse_color_opt(ctx, tag_name, &*attrib.attrib, &*attrib.value, &mut sticky_border_color);
parse_color_opt(ctx, tag_name, &attrib.attrib, &attrib.value, &mut sticky_border_color);
}
other_key => {
ctx.print_invalid_attrib("Tab", other_key, &*attrib.value);
ctx.print_invalid_attrib("Tab", other_key, &attrib.value);
}
}
}

View File

@ -522,7 +522,7 @@ impl ParserContext<'_> {
}
fn populate_extra_variables(&mut self, other: &HashMap<Rc<str>, Rc<str>>) {
for (k, v) in other.iter() {
for (k, v) in other {
self.data_local.var_map.insert(k.clone(), v.clone());
}
}
@ -805,7 +805,7 @@ fn process_attrib(template_parameters: &TemplateParams, ctx: &ParserContext, key
Some(name) => AttribPair::new(key, name),
None => {
log::warn!("{}: undefined variable \"{value}\"", ctx.doc_params.path.get_str());
AttribPair::new(key, format!("undefined_{}", value))
AttribPair::new(key, format!("undefined_{value}"))
}
}
} else {

View File

@ -550,11 +550,10 @@ fn prepare_glyph(par: &mut PrepareGlyphParams) -> Option<GlyphVertex> {
let details = if let Some(details) = par.atlas.mask_atlas.glyph_cache.get(&glyph.cache_key) {
par.atlas.mask_atlas.glyphs_in_use.insert(glyph.cache_key);
details
} else if let Some(details) = par.atlas.color_atlas.glyph_cache.get(&glyph.cache_key) {
} else {
let details = par.atlas.color_atlas.glyph_cache.get(&glyph.cache_key)?;
par.atlas.color_atlas.glyphs_in_use.insert(glyph.cache_key);
details
} else {
return None;
};
let mut x = glyph.x + i32::from(details.left);

View File

@ -563,12 +563,12 @@ impl WidgetState {
}
// this is called before calling children of this widget
pub fn process_event_priority<'a>(
pub fn process_event_priority(
&mut self,
params: &mut EventParams,
widget_id: WidgetID,
event: &Event,
event_result: &'a mut EventResult,
event_result: &mut EventResult,
) -> anyhow::Result<EventResult> {
match &event {
Event::MouseCancel => {

View File

@ -66,7 +66,7 @@ impl WidgetSprite {
self.params.glyph_data.clone()
}
pub fn parent_color(&self) -> ParentColor {
pub const fn parent_color(&self) -> ParentColor {
self.params.parent_color
}
}

View File

@ -119,8 +119,8 @@ impl WguiWindow {
taffy::Rect {
left: length(params.position.x - window_padding),
top: length(params.position.y - header_height - window_padding),
bottom: length(0.0),
right: length(0.0),
bottom: length(0.0_f32),
right: length(0.0_f32),
},
taffy::JustifyContent::START, // x start
taffy::AlignItems::START, // y start
@ -128,18 +128,18 @@ impl WguiWindow {
WguiWindowPlacement::BottomLeft => (
taffy::Rect {
left: length(params.position.x - window_padding),
top: length(0.0),
top: length(0.0_f32),
bottom: length(params.position.y - window_padding),
right: length(0.0),
right: length(0.0_f32),
},
taffy::JustifyContent::START, // x start
taffy::AlignItems::END, // y end
),
WguiWindowPlacement::TopRight => (
taffy::Rect {
left: length(0.0),
left: length(0.0_f32),
top: length(params.position.y - header_height - window_padding),
bottom: length(0.0),
bottom: length(0.0_f32),
right: length(params.position.x - window_padding),
},
taffy::JustifyContent::END, // x end
@ -147,8 +147,8 @@ impl WguiWindow {
),
WguiWindowPlacement::BottomRight => (
taffy::Rect {
left: length(0.0),
top: length(0.0),
left: length(0.0_f32),
top: length(0.0_f32),
bottom: length(params.position.y - window_padding),
right: length(params.position.x - window_padding),
},
@ -175,8 +175,8 @@ impl WguiWindow {
taffy::Style {
position: taffy::Position::Absolute,
size: taffy::Size {
width: percent(1.0),
height: percent(1.0),
width: percent(1.0_f32),
height: percent(1.0_f32),
},
..Default::default()
},
@ -207,8 +207,8 @@ impl WguiWindow {
justify_content: Some(justify_content),
padding,
size: taffy::Size {
width: percent(1.0),
height: percent(1.0),
width: percent(1.0_f32),
height: percent(1.0_f32),
},
..Default::default()
},

View File

@ -147,7 +147,7 @@ where
match data.tx_ctrl.send(PwChangeRequest::Pause) {
Ok(_) => (),
Err(_) => {
log::warn!("{}: disconnected, stopping stream", &self.name);
log::warn!("{}: disconnected, stopping stream", self.name);
}
}
}
@ -158,12 +158,12 @@ where
Ok(_) => {
log::debug!(
"{}: dropped {} old frames before resuming",
&self.name,
self.name,
data.rx_frame.try_iter().count()
);
}
Err(_) => {
log::warn!("{}: disconnected, stopping stream", &self.name);
log::warn!("{}: disconnected, stopping stream", self.name);
}
}
}
@ -184,7 +184,7 @@ where
U: Any,
R: Any,
{
log::debug!("{}: pipewire main_loop start", &name);
log::debug!("{}: pipewire main_loop start", name);
let main_loop = MainLoopRc::new(None)?;
let context = ContextRc::new(&main_loop, None)?;
let core = context.connect_rc(None)?;
@ -212,7 +212,7 @@ where
.state_changed({
let name = name.clone();
move |_, _, old, new| {
log::info!("{}: stream state changed: {:?} -> {:?}", &name, old, new);
log::info!("{}: stream state changed: {:?} -> {:?}", name, old, new);
}
})
.param_changed({
@ -240,16 +240,16 @@ where
"SHM"
};
log::info!("{}: got {} video format:", &name, &kind);
log::info!("{}: got {} video format:", name, kind);
log::info!(" format: {} ({:?})", info.format().as_raw(), info.format());
log::info!(" size: {}x{}", info.size().width, info.size().height);
log::info!(" modifier: {}", info.modifier());
let Ok(params_bytes) = obj_to_bytes(get_buffer_params()) else {
log::warn!("{}: failed to serialize buffer params", &name);
log::warn!("{}: failed to serialize buffer params", name);
return;
};
let Some(params_pod) = Pod::from_bytes(&params_bytes) else {
log::warn!("{}: failed to deserialize buffer params", &name);
log::warn!("{}: failed to deserialize buffer params", name);
return;
};
@ -269,7 +269,7 @@ where
let mut pods = [params_pod, header_pod, xform_pod];
if let Err(e) = stream.update_params(&mut pods) {
log::error!("{}: failed to update params: {}", &name, e);
log::error!("{}: failed to update params: {}", name, e);
}
}
})
@ -287,7 +287,7 @@ where
if let Some(header) = buffer.find_meta::<MetaHeader>()
&& header.flags().contains(MetaHeaderFlags::CORRUPTED)
{
log::warn!("{}: PipeWire buffer is corrupt.", &name);
log::warn!("{}: PipeWire buffer is corrupt.", name);
return;
}
@ -303,7 +303,7 @@ where
MetaVideoTransformValue::FLIPPED270 => Transform::Flipped270,
_ => Transform::Undefined,
};
log::debug!("{}: Transform: {:?}", &name, &format.transform);
log::debug!("{}: Transform: {:?}", name, format.transform);
}
let mouse_meta = buffer
@ -316,7 +316,7 @@ where
let datas = buffer.datas_mut();
if datas.is_empty() {
log::debug!("{}: no data", &name);
log::debug!("{}: no data", name);
return;
}
@ -346,7 +346,7 @@ where
Ok(_) => (),
Err(mpsc::TrySendError::Full(_)) => (),
Err(mpsc::TrySendError::Disconnected(_)) => {
log::warn!("{}: disconnected, stopping stream", &name);
log::warn!("{}: disconnected, stopping stream", name);
let _ = stream.disconnect();
}
}
@ -369,7 +369,7 @@ where
Ok(_) => (),
Err(mpsc::TrySendError::Full(_)) => (),
Err(mpsc::TrySendError::Disconnected(_)) => {
log::warn!("{}: disconnected, stopping stream", &name);
log::warn!("{}: disconnected, stopping stream", name);
let _ = stream.disconnect();
}
}
@ -389,7 +389,7 @@ where
Ok(_) => (),
Err(mpsc::TrySendError::Full(_)) => (),
Err(mpsc::TrySendError::Disconnected(_)) => {
log::warn!("{}: disconnected, stopping stream", &name);
log::warn!("{}: disconnected, stopping stream", name);
let _ = stream.disconnect();
}
}
@ -459,7 +459,7 @@ where
});
main_loop.run();
log::info!("{}: pipewire loop exited", &name);
log::info!("{}: pipewire loop exited", name);
Ok::<(), Error>(())
}

View File

@ -6,7 +6,7 @@ use std::{
pin::Pin,
rc::Rc,
sync::{Arc, Mutex, MutexGuard},
task::{Context, Poll, Wake, Waker},
task::{Context, Poll},
time::Duration,
};
@ -71,17 +71,14 @@ pub enum ScreenCastResult {
impl PartialEq for ScreenCastResult {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Ok(_), Self::Ok(_)) => true,
(Self::Queued, Self::Queued) => true,
(Self::Pending, Self::Pending) => true,
(Self::WaitingForUser, Self::WaitingForUser) => true,
(Self::Failed(_), Self::Failed(_)) => true,
_ => false,
}
}
fn ne(&self, other: &Self) -> bool {
!self.eq(other)
matches!(
(self, other),
(Self::Ok(_), Self::Ok(_))
| (Self::Queued, Self::Queued)
| (Self::Pending, Self::Pending)
| (Self::WaitingForUser, Self::WaitingForUser)
| (Self::Failed(_), Self::Failed(_))
)
}
}
@ -246,6 +243,7 @@ impl ScreenCastManager {
while i < self.cleanup.len() {
match poll_boxed(&mut self.cleanup[i]) {
Poll::Ready(_) => {
#[allow(clippy::let_underscore_future)]
let _ = self.cleanup.swap_remove(i);
}
Poll::Pending => i += 1,
@ -826,28 +824,17 @@ fn poll_unpin<F>(future: &mut F) -> Poll<F::Output>
where
F: Future + Unpin,
{
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);
let waker = std::task::Waker::noop();
let mut cx = Context::from_waker(waker);
Pin::new(future).poll(&mut cx)
}
fn poll_boxed<T>(future: &mut DbusFuture<T>) -> Poll<Result<T, dbus::Error>> {
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);
let waker = std::task::Waker::noop();
let mut cx = Context::from_waker(waker);
future.as_mut().poll(&mut cx)
}
fn noop_waker() -> Waker {
struct NoopWake;
impl Wake for NoopWake {
fn wake(self: Arc<Self>) {}
fn wake_by_ref(self: &Arc<Self>) {}
}
Waker::from(Arc::new(NoopWake))
}
fn sender_path_component(unique_name: &str) -> String {
let name = unique_name.strip_prefix(':').unwrap_or(unique_name);

View File

@ -218,7 +218,7 @@ fn request_dmabuf_frame(
Ok(_) => (),
Err(mpsc::TrySendError::Full(_)) => (),
Err(mpsc::TrySendError::Disconnected(_)) => {
log::warn!("{}: disconnected", &name);
log::warn!("{}: disconnected", name);
}
}
}

View File

@ -117,26 +117,26 @@ where
})
}),
};
log::trace!("{}: captured frame", &monitor.name());
log::trace!("{}: captured frame", monitor.name());
let frame = WlxFrame::MemPtr(memptr_frame);
if let Some(r) = receive_callback(&user_data, frame) {
match tx_frame.try_send(r) {
Ok(_) => (),
Err(mpsc::TrySendError::Full(_)) => {
log::debug!("{}: channel full", &monitor.name());
log::debug!("{}: channel full", monitor.name());
}
Err(mpsc::TrySendError::Disconnected(_)) => {
log::warn!(
"{}: capture thread channel closed (send)",
&monitor.name(),
monitor.name(),
);
break;
}
}
}
} else {
log::debug!("{}: XShmGetImage failed", &monitor.name());
log::debug!("{}: XShmGetImage failed", monitor.name());
}
}
Err(_) => {
@ -166,7 +166,7 @@ where
if let Some(rx) = self.receiver.as_ref() {
log::debug!(
"{}: dropped {} old frames before resuming",
&self.screen.name,
self.screen.name,
rx.try_iter().count()
);
}

View File

@ -128,7 +128,7 @@ struct SerializedWguiColorPalette {
}
impl SerializedWguiColorPalette {
pub fn into_palette(&self) -> WguiColorPalette {
pub fn into_palette(self) -> WguiColorPalette {
// order must stay the same as per WguiColorName
WguiColorPalette::from_inner([
self.primary,