Compare commits

..
19 Commits
Author SHA1 Message Date
galister 3f425820d7 release 0.5.0 2024-09-19 05:29:27 +09:00
galister 6a2d8b9f90 fresh watch style 2024-09-19 03:09:09 +09:00
galister 583a5f7fe0 openxr: toggle for space rotate axis lock 2024-09-18 04:06:37 +09:00
galister 03f2eaf97f fps-stabilize openxr smoothing 2024-09-16 07:05:26 +09:00
galister 21331b5c42 fps-aware openxr pointer smoothing 2024-09-16 05:09:10 +09:00
galister 72a82530ae fix openxr space rotate 2024-09-16 05:01:15 +09:00
galister 13d9284bb8 move mouse move-scroll exclusivity to hid module 2024-09-11 06:03:22 +09:00
galister b0a33a1181 openxr: laser pointer smoothing 2024-09-09 07:54:19 +09:00
galister 4f38d1ad44 make pipewire default on wlroots 2024-08-24 02:21:43 +09:00
galister c6bc880bc3 add logging for screen pipeline 2024-08-20 16:49:35 +09:00
galister 0a2be76150 change some version stuff 2024-08-20 16:40:08 +09:00
galister 1a87823847 rename github action 2024-08-20 14:04:44 +09:00
galister e763e15bdc build dev appimages 2024-08-20 14:02:12 +09:00
galister 6a3b60f298 feat: screen_render_down 2024-08-20 13:54:18 +09:00
Adalyn Black 397b3eedd1 Use git hash if no tags can be found 2024-08-19 17:35:58 +02:00
hypevhs 9d18628354 feat: XR binding for playspace reset 2024-08-15 21:30:39 +02:00
galister dc985f6da6 docs: update known issues 2024-08-13 07:43:37 +00:00
raku-cat 850601b3b9 Update wlx-capture 2024-08-12 12:16:10 +00:00
galister 8a4c7a400f dirty versions 2024-08-11 06:41:17 +09:00
16 changed files with 227 additions and 63 deletions

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
name: Build AppImage
on:
push:
branches:
- 'main'
env:
APPDIR: WlxOverlay-S.AppDir
CARGO_TERM_COLOR: always
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"
jobs:
build_appimage:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.3
- name: Prepare Environment
run: |
sudo add-apt-repository -syn universe
sudo add-apt-repository -syn ppa:pipewire-debian/pipewire-upstream || sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 25088A0359807596
sudo apt-get update
sudo apt-get install -y fuse cmake pkg-config fontconfig libasound2-dev libxkbcommon-dev libxkbcommon-x11-0 libxkbcommon-x11-dev libopenxr-dev libfontconfig-dev libdbus-1-dev libpipewire-0.3-0 libpipewire-0.3-dev libspa-0.2-dev libx11-6 libxext6 libxrandr2 libx11-dev libxext-dev libxrandr-dev libopenvr-dev libopenvr-api1
rustup update
test -f linuxdeploy-x86_64.AppImage || wget -q "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
chmod +x linuxdeploy-x86_64.AppImage
test -d ${APPDIR} && rm -rf ${APPDIR}
mkdir -p ${APPDIR}/usr/bin
- name: Cargo Build
run: |
cargo build --release
mv target/release/wlx-overlay-s ${APPDIR}/usr/bin
chmod +x ${APPDIR}/usr/bin/wlx-overlay-s
- name: Package AppImage
run: |
export VERSION=$GITHUB_REF_NAME
./linuxdeploy-x86_64.AppImage -dwlx-overlay-s.desktop -iwlx-overlay-s.png --appdir=${APPDIR} --output appimage --exclude-library '*libpipewire*'
mv WlxOverlay-S-$VERSION-x86_64.AppImage WlxOverlay-S-x86_64.AppImage
- name: Upload AppImage
uses: actions/upload-artifact@v4
with:
name: WlxOverlay-S-${{ github.ref_name }}-x86_64.AppImage
path: ./WlxOverlay-S-x86_64.AppImage
+1 -1
View File
@@ -2,7 +2,7 @@ name: Check Full
on:
pull_request:
#branches: [ "main" ]
branches: [ "!main" ]
env:
CARGO_TERM_COLOR: always
Generated
+2 -2
View File
@@ -4556,7 +4556,7 @@ dependencies = [
[[package]]
name = "wlx-capture"
version = "0.3.12"
source = "git+https://github.com/galister/wlx-capture?tag=v0.3.12#14d2b8a13dad62849973fe90bed7be262aa07143"
source = "git+https://github.com/galister/wlx-capture?tag=v0.3.13#c375a7c1d4b57741655a052ebe8af9fb4774f92d"
dependencies = [
"ashpd",
"drm-fourcc",
@@ -4574,7 +4574,7 @@ dependencies = [
[[package]]
name = "wlx-overlay-s"
version = "0.4.4"
version = "0.5.0"
dependencies = [
"anyhow",
"ash",
+2 -2
View File
@@ -4,7 +4,7 @@ debug = true
[package]
name = "wlx-overlay-s"
version = "0.4.4"
version = "0.5.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -55,7 +55,7 @@ sysinfo = { version = "0.31.2" }
thiserror = "1.0.61"
vulkano = { git = "https://github.com/vulkano-rs/vulkano", rev = "b9f3e89" }
vulkano-shaders = { git = "https://github.com/vulkano-rs/vulkano", rev = "b9f3e89" }
wlx-capture = { git = "https://github.com/galister/wlx-capture", tag = "v0.3.12", default-features = false }
wlx-capture = { git = "https://github.com/galister/wlx-capture", tag = "v0.3.13", default-features = false }
libmonado-rs = { git = "https://github.com/technobaboo/libmonado-rs", rev = "a495f6d", optional = true }
winit = { version = "0.30.0", optional = true }
xdg = "2.5.2"
+1 -5
View File
@@ -128,12 +128,8 @@ This has been idenfitied as an issue with SteamVR versions 2.5.5 and above (late
This is a rare issue that can make your desktop not react to click or keys due to a modifier being stuck somewhere. Restarting the overlay fixes this.
## Scroll wheel doesn't work
This seems to be an issue specific to Electron apps (Discord, Element, Slack, Spotify) on Wayland. Scrolling will work when using these in your web browser.
## X11 limitations
- X11 capture can generally seem slow. This is because zero-copy GPU capture is not supported on the general X11 desktop. Consider trying Wayland or Picom.
- DPI scaling is not supported and may cause the mouse to not follow the laser properly.
- Upright screens are not supported and can cause the mouse to act weirdly.
- Screen changes (connecting / disconnecting a display, resolution changes, etc) are not handled at runtime. Restart the overlay for these to take effect.
+23 -6
View File
@@ -2,22 +2,39 @@ use regex::Regex;
use std::process::Command;
fn main() {
let mut wlx_build = get_version().unwrap_or(format!("{} (Cargo)", env!("CARGO_PKG_VERSION")));
let mut wlx_build = get_version().unwrap_or(format!("{}-unknown", env!("CARGO_PKG_VERSION")));
if std::env::var("GITHUB_ACTIONS").is_ok() {
wlx_build = format!("{} (AppImage)", &wlx_build)
match std::env::var("GITHUB_JOB").as_deref() {
Ok("make_release") => {
wlx_build = format!("{} (Release)", &wlx_build);
}
Ok("build_appimage") => {
wlx_build = format!("{} (AppImage)", &wlx_build);
}
_ => {}
}
println!("cargo:rustc-env=WLX_BUILD={}", &wlx_build);
}
fn get_version() -> Result<String, Box<dyn std::error::Error>> {
let re = Regex::new(r"v([0-9.]+)-([0-9]+)-g([a-f0-9]+)").unwrap(); // safe
let output = Command::new("git")
.args(["describe", "--tags", "--abbrev=7"])
.args(["describe", "--tags", "--abbrev=7", "--dirty"])
.output()?;
let output_str = String::from_utf8(output.stdout)?;
let mut output_str = String::from_utf8(output.stdout)?;
if output_str.is_empty() {
let output = Command::new("git")
.args(["describe", "--tags", "--abbrev=7", "--dirty", "--always"])
.output()?;
output_str = format!(
"{}-{}",
env!("CARGO_PKG_VERSION"),
String::from_utf8(output.stdout)?
);
}
Ok(re.replace_all(&output_str, "${1}.r${2}.${3}").into_owned())
}
+6 -7
View File
@@ -73,6 +73,9 @@ impl InputState {
if hand.now.space_rotate != hand.before.space_rotate {
log::debug!("Hand {}: space_rotate {}", hand.idx, hand.now.space_rotate);
}
if hand.now.space_reset != hand.before.space_reset {
log::debug!("Hand {}: space_reset {}", hand.idx, hand.now.space_reset);
}
if hand.now.click_modifier_right != hand.before.click_modifier_right {
log::debug!(
"Hand {}: click_modifier_right {}",
@@ -192,6 +195,7 @@ pub struct PointerState {
pub show_hide: bool,
pub space_drag: bool,
pub space_rotate: bool,
pub space_reset: bool,
pub click_modifier_right: bool,
pub click_modifier_middle: bool,
pub move_mouse: bool,
@@ -366,18 +370,13 @@ where
);
}
let scroll_threshold = 0.1;
let mut haptics: Option<Haptics> = None;
// Pass mouse motion events only if not scrolling
// (allows scrolling on all Chromium-based applications)
if app.input_state.pointers[idx].now.scroll.abs() <= scroll_threshold {
haptics = hovered.backend.on_hover(app, &hit);
}
let haptics = hovered.backend.on_hover(app, &hit);
pointer = &mut app.input_state.pointers[idx];
if pointer.now.scroll.abs() > scroll_threshold {
if pointer.now.scroll.abs() > 0.1 {
let scroll = pointer.now.scroll;
if app.input_state.pointers[1 - idx]
.interaction
+26 -2
View File
@@ -156,6 +156,7 @@ pub(super) struct OpenXrHandSource {
action_show_hide: CustomClickAction,
action_space_drag: CustomClickAction,
action_space_rotate: CustomClickAction,
action_space_reset: CustomClickAction,
action_modifier_right: CustomClickAction,
action_modifier_middle: CustomClickAction,
action_move_mouse: CustomClickAction,
@@ -315,13 +316,21 @@ impl OpenXrHand {
.location_flags
.contains(xr::SpaceLocationFlags::ORIENTATION_VALID)
{
let (quat, pos) = unsafe {
let (cur_quat, cur_pos) = (Quat::from_affine3(&pointer.pose), pointer.pose.translation);
let (new_quat, new_pos) = unsafe {
(
transmute::<Quaternionf, Quat>(location.pose.orientation),
transmute::<Vector3f, Vec3>(location.pose.position),
)
};
pointer.pose = Affine3A::from_rotation_translation(quat, pos);
let lerp_factor =
(1.0 / (xr.fps / 100.0) * session.config.pointer_lerp_factor).clamp(0.1, 1.0);
pointer.raw_pose = Affine3A::from_rotation_translation(new_quat, new_pos);
pointer.pose = Affine3A::from_rotation_translation(
cur_quat.lerp(new_quat, lerp_factor),
cur_pos.lerp(new_pos.into(), lerp_factor).into(),
);
}
pointer.now.click = self
@@ -377,6 +386,11 @@ impl OpenXrHand {
.action_space_rotate
.state(pointer.before.space_rotate, xr, session)?;
pointer.now.space_reset =
self.source
.action_space_reset
.state(pointer.before.space_reset, xr, session)?;
Ok(())
}
}
@@ -410,6 +424,7 @@ impl OpenXrHandSource {
action_show_hide: CustomClickAction::new(action_set, "show_hide", side)?,
action_space_drag: CustomClickAction::new(action_set, "space_drag", side)?,
action_space_rotate: CustomClickAction::new(action_set, "space_rotate", side)?,
action_space_reset: CustomClickAction::new(action_set, "space_reset", side)?,
action_modifier_right: CustomClickAction::new(
action_set,
"click_modifier_right",
@@ -579,6 +594,14 @@ fn suggest_bindings(instance: &xr::Instance, hands: &[&OpenXrHandSource; 2]) ->
instance
);
add_custom!(
profile.space_reset,
&hands[0].action_space_reset,
&hands[1].action_space_reset,
bindings,
instance
);
add_custom!(
profile.click_modifier_right,
&hands[0].action_modifier_right,
@@ -634,6 +657,7 @@ struct OpenXrActionConfProfile {
show_hide: Option<OpenXrActionConfAction>,
space_drag: Option<OpenXrActionConfAction>,
space_rotate: Option<OpenXrActionConfAction>,
space_reset: Option<OpenXrActionConfAction>,
click_modifier_right: Option<OpenXrActionConfAction>,
click_modifier_middle: Option<OpenXrActionConfAction>,
move_mouse: Option<OpenXrActionConfAction>,
+22
View File
@@ -48,6 +48,7 @@ struct XrState {
system: xr::SystemId,
session: xr::Session<xr::Vulkan>,
predicted_display_time: xr::Time,
fps: f32,
stage: Arc<xr::Space>,
view: Arc<xr::Space>,
stage_offset: Affine3A,
@@ -131,6 +132,7 @@ pub fn openxr_run(running: Arc<AtomicBool>, show_by_default: bool) -> Result<(),
system,
session,
predicted_display_time: xr::Time::from_nanos(0),
fps: 30.0,
stage: Arc::new(stage),
view: Arc::new(view),
stage_offset: Affine3A::IDENTITY,
@@ -153,6 +155,8 @@ pub fn openxr_run(running: Arc<AtomicBool>, show_by_default: bool) -> Result<(),
let mut next_device_update = Instant::now();
let mut due_tasks = VecDeque::with_capacity(4);
let mut fps_counter: VecDeque<Instant> = VecDeque::new();
let mut main_session_visible = false;
'main_loop: loop {
@@ -231,6 +235,24 @@ pub fn openxr_run(running: Arc<AtomicBool>, show_by_default: bool) -> Result<(),
frame_stream.begin()?;
xr_state.predicted_display_time = xr_frame_state.predicted_display_time;
xr_state.fps = {
fps_counter.push_back(Instant::now());
while let Some(time) = fps_counter.front() {
if time.elapsed().as_secs_f32() > 1. {
fps_counter.pop_front();
} else {
break;
}
}
let total_elapsed = fps_counter
.front()
.map(|time| time.elapsed().as_secs_f32())
.unwrap_or(0f32);
fps_counter.len() as f32 / total_elapsed
};
if !xr_frame_state.should_render {
frame_stream.end(
+7
View File
@@ -15,6 +15,9 @@
// -- space_rotate --
// rotate your stage (playspace rotate, WIP)
//
// -- space_reset --
// reset your stage (reset the offset from playspace drag)
//
// -- click_modifier_right --
// while this is held, your pointer will turn ORANGE and your mouse clicks will be RIGHT clicks
//
@@ -132,6 +135,10 @@
left: "/user/hand/left/input/trackpad/force",
// right trackpad is alt_click
},
space_reset: {
double_click: true,
left: "/user/hand/left/input/trackpad/force",
},
click_modifier_right: {
left: "/user/hand/left/input/b/touch",
right: "/user/hand/right/input/b/touch"
+25 -22
View File
@@ -55,6 +55,16 @@ impl PlayspaceMover {
state: &AppState,
monado: &mut Monado,
) {
for pointer in state.input_state.pointers.iter() {
if pointer.now.space_reset {
if !pointer.before.space_reset {
log::info!("Space reset");
self.reset_offset(monado);
}
return;
}
}
if let Some(mut data) = self.rotate.take() {
let pointer = &state.input_state.pointers[data.hand];
if !pointer.now.space_rotate {
@@ -64,32 +74,25 @@ impl PlayspaceMover {
}
let new_hand =
Quat::from_affine3(&(data.pose * state.input_state.pointers[data.hand].pose));
Quat::from_affine3(&(data.pose * state.input_state.pointers[data.hand].raw_pose));
let dq = new_hand * data.hand_pose.conjugate();
let rel_y = f32::atan2(
2.0 * (dq.y * dq.w + dq.x * dq.z),
(2.0 * (dq.w * dq.w + dq.x * dq.x)) - 1.0,
);
let mut space_transform = if state.session.config.space_rotate_unlocked {
Affine3A::from_quat(dq)
} else {
let rel_y = f32::atan2(
2.0 * (dq.y * dq.w + dq.x * dq.z),
(2.0 * (dq.w * dq.w + dq.x * dq.x)) - 1.0,
);
//let mut space_transform = Affine3A::from_rotation_translation(dq, Vec3::ZERO);
let mut space_transform = Affine3A::from_rotation_y(rel_y);
Affine3A::from_rotation_y(rel_y)
};
let offset = (space_transform.transform_vector3a(state.input_state.hmd.translation)
- state.input_state.hmd.translation)
* -1.0;
let mut overlay_transform = Affine3A::from_rotation_y(-rel_y);
overlay_transform.translation = offset;
space_transform.translation = offset;
overlays.iter_mut().for_each(|overlay| {
if overlay.state.grabbable {
overlay.state.dirty = true;
overlay.state.transform.translation =
overlay_transform.transform_point3a(overlay.state.transform.translation);
}
});
data.pose *= space_transform;
data.hand_pose = new_hand;
@@ -98,7 +101,7 @@ impl PlayspaceMover {
} else {
for (i, pointer) in state.input_state.pointers.iter().enumerate() {
if pointer.now.space_rotate {
let hand_pose = Quat::from_affine3(&self.last_transform);
let hand_pose = Quat::from_affine3(&(self.last_transform * pointer.raw_pose));
self.rotate = Some(MoverData {
pose: self.last_transform,
hand: i,
@@ -121,7 +124,7 @@ impl PlayspaceMover {
let new_hand = data
.pose
.transform_point3a(state.input_state.pointers[data.hand].pose.translation);
.transform_point3a(state.input_state.pointers[data.hand].raw_pose.translation);
let relative_pos =
(new_hand - data.hand_pose) * state.session.config.space_drag_multiplier;
@@ -149,7 +152,7 @@ impl PlayspaceMover {
if pointer.now.space_drag {
let hand_pos = self
.last_transform
.transform_point3a(pointer.pose.translation);
.transform_point3a(pointer.raw_pose.translation);
self.drag = Some(MoverData {
pose: self.last_transform,
hand: i,
@@ -186,8 +189,8 @@ impl PlayspaceMover {
self.rotate = None;
}
let y1 = input.pointers[0].pose.translation.y;
let y2 = input.pointers[1].pose.translation.y;
let y1 = input.pointers[0].raw_pose.translation.y;
let y2 = input.pointers[1].raw_pose.translation.y;
let delta = y1.min(y2) - 0.03;
self.last_transform.translation.y += delta;
self.apply_offset(self.last_transform, monado);
+13
View File
@@ -121,6 +121,10 @@ pub fn def_point7() -> f32 {
0.7
}
pub fn def_point3() -> f32 {
0.3
}
fn def_osc_port() -> u16 {
9000
}
@@ -260,6 +264,15 @@ pub struct GeneralConfig {
#[serde(default = "def_max_height")]
pub screen_max_height: u16,
#[serde(default = "def_false")]
pub screen_render_down: bool,
#[serde(default = "def_point3")]
pub pointer_lerp_factor: f32,
#[serde(default = "def_false")]
pub space_rotate_unlocked: bool,
}
impl GeneralConfig {
+16
View File
@@ -47,6 +47,7 @@ pub enum HighlightTest {
AutoRealign,
NotificationSounds,
Notifications,
RorateLock,
}
#[derive(Deserialize, Clone)]
@@ -55,6 +56,7 @@ pub enum SystemAction {
ToggleAutoRealign,
ToggleNotificationSounds,
ToggleNotifications,
ToggleRotateLock,
PlayspaceResetOffset,
PlayspaceFixFloor,
RecalculateExtent,
@@ -298,6 +300,7 @@ fn modular_button_highlight(
HighlightTest::AutoRealign => app.session.config.realign_on_showhide,
HighlightTest::NotificationSounds => app.session.config.notifications_sound_enabled,
HighlightTest::Notifications => app.session.config.notifications_enabled,
HighlightTest::RorateLock => !app.session.config.space_rotate_unlocked,
};
if lit {
@@ -369,6 +372,19 @@ fn run_system(action: &SystemAction, app: &mut AppState) {
)
.submit(app);
}
SystemAction::ToggleRotateLock => {
app.session.config.space_rotate_unlocked = !app.session.config.space_rotate_unlocked;
Toast::new(
ToastTopic::System,
format!(
"Space rotate axis lock now {}.",
ENABLED_DISABLED[!app.session.config.space_rotate_unlocked as usize]
)
.into(),
"".into(),
)
.submit(app);
}
SystemAction::PlayspaceResetOffset => {
app.tasks
.enqueue(TaskType::System(SystemTask::ResetPlayspace));
+4 -1
View File
@@ -242,7 +242,7 @@ impl HidProvider for UInputProvider {
self.desktop_origin = origin;
}
fn mouse_move(&mut self, pos: Vec2) {
if self.current_action.pos.is_none() {
if self.current_action.pos.is_none() && self.current_action.scroll.is_none() {
self.current_action.pos = Some(pos);
}
self.current_action.last_requested_pos = Some(pos);
@@ -256,6 +256,9 @@ impl HidProvider for UInputProvider {
fn wheel(&mut self, delta: i32) {
if self.current_action.scroll.is_none() {
self.current_action.scroll = Some(delta);
// Pass mouse motion events only if not scrolling
// (allows scrolling on all Chromium-based applications)
self.current_action.pos = None;
}
}
fn commit(&mut self) {
+19 -6
View File
@@ -471,9 +471,23 @@ impl OverlayRenderer for ScreenRenderer {
});
match app.graphics.dmabuf_texture(frame) {
Ok(new) => {
let view = ImageView::new_default(new.clone())?;
self.last_view = Some(view);
let pipeline = match self.pipeline {
Some(ref mut p) => Some(p),
None if app.session.config.screen_render_down => {
log::info!("{}: Using render-down pass.", self.name);
let pipeline = ScreenPipeline::new(&self.extent.unwrap(), app)?; // safe
self.last_view = Some(pipeline.view.clone());
self.pipeline = Some(pipeline);
self.pipeline.as_mut()
}
None => None,
};
if let Some(pipeline) = pipeline {
pipeline.render(new.clone(), None, app)?;
} else {
let view = ImageView::new_default(new.clone())?;
self.last_view = Some(view);
}
}
Err(e) => {
log::error!(
@@ -549,6 +563,7 @@ impl OverlayRenderer for ScreenRenderer {
let pipeline = Some(match self.pipeline {
Some(ref mut p) => p,
_ => {
log::info!("{}: Using render-down pass.", self.name);
let extent = extent_from_format(frame.format, &app.session.config);
let mut pipeline = ScreenPipeline::new(&extent, app)?;
self.last_view = Some(pipeline.view.clone());
@@ -598,9 +613,7 @@ pub fn create_screen_renderer_wl(
session: &AppSession,
) -> Option<ScreenRenderer> {
let mut capture: Option<ScreenRenderer> = None;
if (&*session.config.capture_method == "auto" || &*session.config.capture_method == "dmabuf")
&& has_wlr_dmabuf
{
if (&*session.config.capture_method == "wlr-dmabuf") && has_wlr_dmabuf {
log::info!("{}: Using Wlr DMA-Buf", &output.name);
capture = ScreenRenderer::new_wlr_dmabuf(output);
}
+9 -9
View File
@@ -9,14 +9,14 @@ size: [400, 200]
elements:
# background panel
- type: Panel
rect: [0, 0, 400, 200]
corner_radius: 4
rect: [0, 30, 400, 130]
corner_radius: 20
bg_color: "#24273a"
- type: Button
rect: [2, 162, 26, 36]
corner_radius: 4
font_size: 14
font_size: 15
bg_color: "#c6a0f6"
fg_color: "#24273a"
text: "C"
@@ -32,7 +32,7 @@ elements:
- type: Button
rect: [32, 162, 60, 36]
corner_radius: 4
font_size: 14
font_size: 15
fg_color: "#24273a"
bg_color: "#a6da95"
text: Kbd
@@ -67,7 +67,7 @@ elements:
- type: OverlayList
rect: [94, 160, 306, 40]
corner_radius: 4
font_size: 14
font_size: 15
fg_color: "#cad3f5"
bg_color: "#1e2030"
layout: Horizontal
@@ -147,9 +147,9 @@ elements:
# batteries
- type: BatteryList
rect: [0, 0, 400, 30]
rect: [0, 5, 400, 30]
corner_radius: 4
font_size: 14
font_size: 16
fg_color: "#8bd5ca"
fg_color_low: "#B06060"
fg_color_charging: "#6080A0"
@@ -161,7 +161,7 @@ elements:
- type: Button
rect: [315, 52, 70, 32]
corner_radius: 4
font_size: 14
font_size: 13
fg_color: "#cad3f5"
bg_color: "#5b6078"
text: "Vol +"
@@ -171,7 +171,7 @@ elements:
- type: Button
rect: [315, 116, 70, 32]
corner_radius: 4
font_size: 14
font_size: 13
fg_color: "#cad3f5"
bg_color: "#5b6078"
text: "Vol -"