keyboard middle click setting; docs, readme & logs

This commit is contained in:
galister
2026-01-08 20:47:52 +09:00
parent 3611cfc57b
commit 390338c4a5
11 changed files with 256 additions and 152 deletions

View File

@@ -56,8 +56,9 @@ For users specifically running **SteamVR via Steam Flatpak**, follow these steps
**When the screen share pop-up appears, check your notifications or the terminal and select the screens in the order it requests.**
In case screens were selected in the wrong order:
- `rm ~/.config/wlxoverlay/conf.d/pw_tokens.yaml` then restart
- Go to Settings and press `Clear PipeWire tokens` and then `Restart software`
- Pay attention to your notifications, it tells you in which order to pick the screens.
- If notifications don't show, try start Wlx from the terminal and look for instructions in there.
**WiVRn users**: Select WlxOverlay-S from the `Application` drop-down. If there's no such entry, select `Custom` and browse to your WlxOverlay-S executable or AppImage.
@@ -161,29 +162,31 @@ Check [here](https://github.com/galister/wlx-overlay-s/wiki/Troubleshooting) for
### Mouse is not where it should be
X11 users:
If the mouse is moving on a completely different screen, the screens were likely selected in the wrong order:
- Go to Settings and press `Clear PipeWire tokens` and then `Restart software`
- Pay attention to your notifications, it tells you in which order to pick the screens.
- If notifications don't show, try start Wlx from the terminal and look for instructions in there.
COSMIC destkop:
- Due to limitations with COSMIC, the mouse can only move on a single display.
X11 users:
- Might be dealing with a [Phantom Monitor](https://wiki.archlinux.org/title/Xrandr#Disabling_phantom_monitor).
- DPI scaling is not supported and will mess with the mouse.
- Upright screens are not supported and will mess with the mouse.
Other desktops: The screens may have been selected in the wrong order, see [First Start](#first-start).
### Screens are blank or black or frozen on Steam Link
### Crashes, blank screens
As of SteamVR version 2.14.x, PipeWire capture no longer works when using Steam Link.
There are some driver-desktop combinations that don't play nice with DMA-buf capture.
We're unable to completely troubleshoot how and why Steam Link interferes with PipeWire, so consider the following workarounds for the time being:
- Use another streamer, such as WiVRn or ALVR
- If your desktop [supports ScreenCopy](https://wayland.app/protocols/wlr-screencopy-unstable-v1#compositor-support), go to Settings and set `Wayland capture method` to `ScreenCopy`
- If your desktop has an X11 mode, try using that
Disabling DMA-buf capture is a good first step to try when encountering an app crash or gpu driver reset.
### Modifiers get stuck
```bash
echo 'capture_method: pw_fallback' > ~/.config/wlxoverlay/conf.d/pw_fallback.yaml
```
Without DMA-buf capture, capturing screens takes CPU power, so let's try and not show too many screens at the same time.
### Modifiers get stuck, mouse clicks stop working on KDE Plasma
We are not sure what causes this, but it only happens on KDE Plasma. Restarting the overlay fixes this.
Hiding the keyboard will un-press all of its buttons. Alternatively, go to Settings and use the `Restart software` button.
### X11 limitations

View File

@@ -74,6 +74,9 @@
"CAPTURE_METHOD": "Wayland screen capture",
"CAPTURE_METHOD_HELP": "Try changing this if experiencing\nblack or glitchy screens",
"KEYBOARD_MIDDLE_CLICK": "Keyboard middle click",
"KEYBOARD_MIDDLE_CLICK_HELP": "Modifier to use when typing\nwith purple laser",
"OPTION": {
"PIPEWIRE_HELP": "Fast GPU capture. Recommended",
"PW_FALLBACK_HELP": "Slow. Try in case PipeWire GPU doesn't work",

View File

@@ -168,6 +168,7 @@ enum SettingType {
OpaqueBackground,
XwaylandByDefault,
CaptureMethod,
KeyboardMiddleClick,
}
impl SettingType {
@@ -226,6 +227,10 @@ impl SettingType {
Self::CaptureMethod => {
config.capture_method = wlx_common::config::CaptureMethod::from_str(value).expect("Invalid enum value!")
}
Self::KeyboardMiddleClick => {
config.keyboard_middle_click_mode =
wlx_common::config::AltModifier::from_str(value).expect("Invalid enum value!")
}
_ => panic!("Requested enum for non-enum SettingType"),
}
}
@@ -233,6 +238,7 @@ impl SettingType {
fn get_enum_title<'a>(self, config: &'a mut GeneralConfig) -> Translation {
match self {
Self::CaptureMethod => Self::get_enum_title_inner(config.capture_method),
Self::KeyboardMiddleClick => Self::get_enum_title_inner(config.keyboard_middle_click_mode),
_ => panic!("Requested enum for non-enum SettingType"),
}
}
@@ -291,6 +297,7 @@ impl SettingType {
Self::OpaqueBackground => Ok("APP_SETTINGS.OPAQUE_BACKGROUND"),
Self::XwaylandByDefault => Ok("APP_SETTINGS.XWAYLAND_BY_DEFAULT"),
Self::CaptureMethod => Ok("APP_SETTINGS.CAPTURE_METHOD"),
Self::KeyboardMiddleClick => Ok("APP_SETTINGS.KEYBOARD_MIDDLE_CLICK"),
}
}
@@ -308,6 +315,7 @@ impl SettingType {
Self::UsePassthrough => Some("APP_SETTINGS.USE_PASSTHROUGH_HELP"),
Self::ScreenRenderDown => Some("APP_SETTINGS.SCREEN_RENDER_DOWN_HELP"),
Self::CaptureMethod => Some("APP_SETTINGS.CAPTURE_METHOD_HELP"),
Self::KeyboardMiddleClick => Some("APP_SETTINGS.KEYBOARD_MIDDLE_CLICK_HELP"),
_ => None,
}
}
@@ -618,6 +626,12 @@ impl<T> TabSettings<T> {
slider_f32!(mp, c, SettingType::XrClickSensitivity, 0.1, 1.0, 0.1);
slider_f32!(mp, c, SettingType::XrClickSensitivityRelease, 0.1, 1.0, 0.1);
slider_i32!(mp, c, SettingType::ClickFreezeTimeMs, 0, 500, 50);
dropdown!(
mp,
c,
SettingType::KeyboardMiddleClick,
wlx_common::config::AltModifier::VARIANTS
);
let c = category!(mp, root, "APP_SETTINGS.MISC", "dashboard/blocks.svg")?;
checkbox!(mp, c, SettingType::XwaylandByDefault);

View File

@@ -30,6 +30,17 @@ pub enum CaptureMethod {
ScreenCopy,
}
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, AsRefStr, EnumString, EnumProperty, VariantArray)]
pub enum AltModifier {
#[default]
None,
Shift,
Ctrl,
Alt,
Super,
Meta,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct SerializedWindowSet {
pub name: Arc<str>,
@@ -270,4 +281,7 @@ pub struct GeneralConfig {
#[serde(default)]
pub context_menu_hold_and_release: bool,
#[serde(default)]
pub keyboard_middle_click_mode: AltModifier,
}

View File

@@ -4,7 +4,9 @@ use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use wlx_common::{
astr_containers::AStrMap,
config::{CaptureMethod, GeneralConfig, SerializedWindowSet, SerializedWindowStates},
config::{
AltModifier, CaptureMethod, GeneralConfig, SerializedWindowSet, SerializedWindowStates,
},
config_io,
overlays::BackendAttribValue,
};
@@ -139,6 +141,7 @@ pub struct AutoSettings {
pub xwayland_by_default: bool,
pub context_menu_hold_and_release: bool,
pub capture_method: CaptureMethod,
pub keyboard_middle_click_mode: AltModifier,
}
fn get_settings_path() -> PathBuf {
@@ -183,6 +186,7 @@ pub fn save_settings(config: &GeneralConfig) -> anyhow::Result<()> {
xwayland_by_default: config.xwayland_by_default,
context_menu_hold_and_release: config.context_menu_hold_and_release,
capture_method: config.capture_method,
keyboard_middle_click_mode: config.keyboard_middle_click_mode,
};
let json = serde_json::to_string_pretty(&conf).unwrap(); // want panic

View File

@@ -99,10 +99,6 @@ Available argument value types (case insensitive):
- Float: `1f32`, `1.0f32`, etc
- Double: `1f64`, `1.0f64`, etc
##### `::ShutDown`
Gracefully shuts down WlxOverlay-S. Useful when using an auto-restart script.
##### `::SendKey <VirtualKey> <UP|DOWN>`
Sends a key using the virtual keyboard. If WayVR is focused, the key is sent to the WayVR app.
@@ -122,3 +118,88 @@ Recenters the STAGE space position so that the HMD is in the center. Does not mo
Adjusts the level of floor for STAGE and LOCAL_FLOOR spaces.
The user is asked to place one controller on the floor.
##### `::ContextMenuOpen <name>`
Opens the `<context_menu>` of the given name at the location of the click.
##### `::ContextMenuClose`
Closes any active context menus.
##### `::ElementSetDisplay <id> <none|flex|block|grid>`
Sets the visiblitity of the element with `id`.
##### `::SetToggle <index>`
If the given set is visible, it will be hidden.
Otherwise, it will be set visible.
##### `::SetSwitch <index>`
Switch to the given set. If the set is already visible, nothing happens.
##### `::AddSet`
Add a new set and switch to it. The keyboard will be set to visible.
##### `::DeleteSet`
Hides the current set, then deletes it.
##### `::DashToggle`
Toggle the dashboard
##### `::EditToggle`
Toggle edit mode
##### `::NewMirror`
Opens a new PipeWire mirror (Wayland-only)
##### `::CleanupMirrors`
Destroys all mirrors that are not currently visible (including those that are in a different set).
##### `::Restart`
Restarts WlxOverlay-S, reloading all settings.
##### `::ShutDown`
Gracefully shuts down WlxOverlay-S.
##### `::OverlayReset <overlay_name>`
Resets the position of the given overlay and makes it visible.
##### `::OverlayToggle <overlay_name>`
Toggle the visibility of this overlay for the current set
##### `::OverlayDrop <overlay_name>`
Destroys the overlay permanently. Mostly useful for mirrors.
##### `::CustomOverlayReload <overlay_name>`
If this is a custom overlay, reloads its XML from disk.
##### `::WvrOverlayCloseWindow <overlay_name>`
If this is an application, send a close window request to its wl_surface (e.a. X'ing the window)
##### `::WvrOverlayTermProcess <overlay_name>`
If the overlay belongs to an application, sends SIGTERM (graceful exit request) to its process.
##### `::WvrOverlayKillProcess <overlay_name>`
If the overlay belongs to an application, sends SIGKILL (forced exit request) to its process.
Also destroys all overlays belonging to the process.

View File

@@ -6,8 +6,10 @@ use crate::{
panel::{GuiPanel, NewGuiPanelParams},
timer::GuiTimer,
},
overlays::keyboard::alt_modifier_to_key,
state::AppState,
subsystem::hid::XkbKeymap,
windowing::backend::OverlayEventData,
};
use anyhow::Context;
use glam::{FloatExt, Mat4, Vec2, vec2, vec3};
@@ -281,6 +283,11 @@ pub(super) fn create_keyboard_panel(
panel.process_custom_elems(app);
}
if matches!(event_data, OverlayEventData::SettingsChanged) {
panel.state.alt_modifier =
alt_modifier_to_key(app.session.config.keyboard_middle_click_mode);
}
panel.layout.process_alterables(alterables)?;
Ok(())
}));

View File

@@ -2,6 +2,7 @@ use std::{collections::HashMap, str::FromStr, sync::LazyLock};
use regex::Regex;
use serde::{Deserialize, Serialize};
use wlx_common::config::AltModifier;
use crate::{
config::{ConfigType, load_known_yaml},
@@ -232,18 +233,6 @@ pub(super) struct KeyData {
pub(super) cap_type: KeyCapType,
}
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize)]
#[repr(usize)]
pub enum AltModifier {
#[default]
None,
Shift,
Ctrl,
Alt,
Super,
Meta,
}
#[derive(Debug)]
pub enum KeyCapType {
/// Label an SVG

View File

@@ -12,7 +12,7 @@ use crate::{
task::{OverlayTask, TaskType},
},
gui::panel::{GuiPanel, overlay_list::OverlayList, set_list::SetList},
overlays::keyboard::{builder::create_keyboard_panel, layout::AltModifier},
overlays::keyboard::builder::create_keyboard_panel,
state::AppState,
subsystem::{
dbus::DbusConnector,
@@ -34,8 +34,11 @@ use wgui::{
drawing,
event::{InternalStateChangeEvent, MouseButton, MouseButtonIndex},
};
use wlx_common::overlays::{BackendAttrib, BackendAttribValue};
use wlx_common::windowing::{OverlayWindowState, Positioning};
use wlx_common::{
config::AltModifier,
overlays::{BackendAttrib, BackendAttribValue},
};
pub mod builder;
mod layout;
@@ -48,14 +51,7 @@ pub fn create_keyboard(app: &mut AppState, wayland: bool) -> anyhow::Result<Over
let layout = layout::Layout::load_from_disk();
let default_state = KeyboardState {
modifiers: 0,
alt_modifier: match layout.alt_modifier {
AltModifier::Shift => SHIFT,
AltModifier::Ctrl => CTRL,
AltModifier::Alt => ALT,
AltModifier::Super => SUPER,
AltModifier::Meta => META,
_ => 0,
},
alt_modifier: alt_modifier_to_key(app.session.config.keyboard_middle_click_mode),
processes: vec![],
overlay_list: OverlayList::default(),
set_list: SetList::default(),
@@ -122,6 +118,17 @@ pub fn create_keyboard(app: &mut AppState, wayland: bool) -> anyhow::Result<Over
})
}
fn alt_modifier_to_key(m: AltModifier) -> KeyModifier {
match m {
AltModifier::Shift => SHIFT,
AltModifier::Ctrl => CTRL,
AltModifier::Alt => ALT,
AltModifier::Super => SUPER,
AltModifier::Meta => META,
_ => 0,
}
}
new_key_type! {
struct KeyboardPanelKey;
}

View File

@@ -175,10 +175,7 @@ impl OverlayBackend for ScreenBackend {
&Vec::new()
} else {
log::warn!(
"Using DMA-buf capture. If screens are blank for you, switch to SHM using:"
);
log::warn!(
"echo 'capture_method: pw_fallback' > ~/.config/wlxoverlay/conf.d/pw_fallback.yaml"
"Using GPU capture. If you're having issues with screens, go to the Dashboard's Settings tab and switch 'Wayland capture method' to a CPU option!"
);
&app.gfx_extras.drm_formats

View File

@@ -5,7 +5,85 @@
# In case you're not getting the expected result,
# check the logs at /tmp/wlx.log for parsing errors.
################ EXPERIENCE ################
## Only if built with `osc` feature. What port to send OSC messages to.
#osc_out_port: 9000
## Set your preferred watch timezones here.
#timezones:
# - "Europe/Oslo"
# - "America/New_York"
## On most desktops, WlxOverlay-S is able to pick up your keymap via wayland. (Especially when using Fcitx5!)
## However, if this does not happen, you might want to set your keymap by hand.
## When using a simple layout:
#default_keymap: us
#
## When defining a layout-variant pair, separate using a dash:
#default_keymap: us-colemak_dh
## Path to read the custom theme from, relative to `~/.config/wlxoverlay`
#theme_path: "theme"
## These can be used to control the color theme of WlxOverlay-S.
#color_text: "#ffffff"
#color_accent: "#008cff"
#color_danger: "#ff3300"
#color_faded: "#668299"
#color_background: "#010206"
## Path to custom skybox texture, relative to `~/.config/wlxoverlay`
#skybox_texture: ""
## User-defined list of custom overlays that should be created.
## Each entry must correspond to an XML file at: {theme_path}/gui/{entry}.xml
#custom_panels:
# - "test"
## The alt_click binding can be used to execute a program of choice
## These are not default, but example values.
#alt_click_down: ["bash", "-c", "echo x"]
#alt_click_up: ["bash", "-c", "echo y"]
## Example for quick-calibration with `motoc`:
#alt_click_down:
# [
# "motoc",
# "calibrate",
# "--src",
# "WiVRn HMD",
# "--dst",
# "LHR-AABBCCDD",
# "--samples",
# "200",
# ]
## Set what kind of notifications to show and what to hide
#notification_topics:
# System: Center
# DesktopNotification: Center
# XSNotification: Center
# IpdChange: Hide
## Path to a custom notification sound, relative to `~/.config/wlxoverlay`
#notification_sound: ""
## If `screen_render_down` is enabled,
## controls the maximum height of the screen
#screen_max_height: 1440
## Don't move the mouse more often than this value
## helps to avoid unnecessary load when pairing
## a high-refresh screen with a lower-refresh hmd
#mouse_move_interval_ms: 10
################ MANAGED FROM DASHBOARD ################
################ MANAGED FROM DASHBOARD ################
################ MANAGED FROM DASHBOARD ################
################ MANAGED FROM DASHBOARD ################
# ANYTHING BELOW HERE IS MANAGED FROM THE DASHBOARD.
# The settings are here for reference only.
# Probably don't include them in your config file.
## The bottom of the watch will list sets instead of overlays.
#sets_on_watch: false
@@ -51,111 +129,33 @@
## 0.1 → too much smoothing
#pointer_lerp_factor: 0.3
## Only if built with `osc` feature. What port to send OSC messages to.
#osc_out_port: 9000
## If your upright screen is not displaying correctly, try enabling this.
#upright_screen_fix: false
## If you're seeing the cursor twice, try enabling this.
#double_cursor_fix: false
################ TIME ################
## Set your preferred watch timezones here.
#timezones:
# - "Europe/Oslo"
# - "America/New_York"
#
## Use 12h instead of 24h watch.
#clock_12h: false
################ KEYBOARD ################
## On most desktops, WlxOverlay-S is able to pick up your keymap via wayland. (Especially when using Fcitx5!)
## However, if this does not happen, you might want to set your keymap by hand.
## When using a simple layout:
#default_keymap: us
## When defining a layout-variant pair, separate using a dash:
#default_keymap: us-colemak_dh
## Toggle keyboard click sound
#keyboard_sound_enabled: true
################ THEMING & CUSTOMIZATION ################
## Path to read the custom theme from, relative to `~/.config/wlxoverlay`
#theme_path: "theme"
## These can be used to control the color theme of WlxOverlay-S.
#color_text: "#ffffff"
#color_accent: "#008cff"
#color_danger: "#ff3300"
#color_faded: "#668299"
#color_background: "#010206"
## Multiplier for animation speed. 2.0 → double speed, 0.5 → half speed
#animation_speed: 1.0
## Adjust this between 0..1 for a more rectangular feel.
#round_multiplier: 1.0
## Path to custom skybox texture, relative to `~/.config/wlxoverlay`
#skybox_texture: ""
## User-defined list of custom overlays that should be created.
## Each entry must correspond to an XML file at: {theme_path}/gui/{entry}.xml
#custom_panels:
# - "test"
## Alter default scale of various overlays
#keyboard_scale: 1.0
#desktop_view_scale: 1.0
#watch_scale: 1.0
## Control the fade & visibility of the watch
#watch_view_angle_min: 0.5
#watch_view_angle_max: 0.7
## The alt_click binding can be used to execute a program of choice
## These are not default, but example values.
#alt_click_down: ["bash", "-c", "echo x"]
#alt_click_up: ["bash", "-c", "echo y"]
## Example for quick-calibration with `motoc`:
#alt_click_down:
# [
# "motoc",
# "calibrate",
# "--src",
# "WiVRn HMD",
# "--dst",
# "LHR-AABBCCDD",
# "--samples",
# "200",
# ]
################ NOTIFICATIONS ################
## Set whether notifications should be shown at all
#notifications_enabled: true
## Set whether notfications should make a sound
#notifications_sound_enabled: true
## Set what kind of notifications to show and what to hide
#notification_topics:
# System: Center
# DesktopNotification: Center
# XSNotification: Center
# IpdChange: Hide
## Toggle keyboard click sound
#keyboard_sound_enabled: true
## Path to a custom notification sound, relative to `~/.config/wlxoverlay`
#notification_sound: ""
## Multiplier for animation speed. 2.0 → double speed, 0.5 → half speed
#animation_speed: 1.0
################ CONTROL TWEAKS ################
## Adjust this between 0..1 for a more rectangular feel.
#round_multiplier: 1.0
## Render screens & mirrors at a lower resolution.
## Avoids aliasing on 4K+ screens, and also saves VRAM
#screen_render_down: false
## For how much time mouse motion events should be stopped after clicking?
## Prevents accidental dragging various GUI elements or links, making it easier to click
@@ -190,18 +190,3 @@
## allowing for moving both pointers off the screens to the keyboard, while keeping the cursor position
## unchanged, for when the desktop is configured to move the focus with the mouse cursor
#focus_follows_mouse_mode: false
################ PERFORMANCE TWEAKS ################
## Render screens & mirrors at a lower resolution.
## Avoids aliasing on 4K+ screens, and also saves VRAM
#screen_render_down: false
## If `screen_render_down` is enabled,
## controls the maximum height of the screen
#screen_max_height: 1440
## Don't move the mouse more often than this value
## helps to avoid unnecessary load when pairing
## a high-refresh screen with a lower-refresh hmd
#mouse_move_interval_ms: 10