WayVR: Display auto-hide support (Fixes #98), keyboard settings in config
This commit is contained in:
@@ -15,11 +15,14 @@ use smithay::{
|
|||||||
wayland::shell::xdg::ToplevelSurface,
|
wayland::shell::xdg::ToplevelSurface,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{backend::overlay::OverlayID, gen_id};
|
use crate::{
|
||||||
|
backend::{overlay::OverlayID, wayvr::time::get_millis},
|
||||||
|
gen_id,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
client::WayVRManager, comp::send_frames_surface_tree, egl_data, event_queue::SyncEventQueue,
|
client::WayVRManager, comp::send_frames_surface_tree, egl_data, event_queue::SyncEventQueue,
|
||||||
process, smithay_wrapper, time, window,
|
process, smithay_wrapper, time, window, WayVRSignal,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn generate_auth_key() -> String {
|
fn generate_auth_key() -> String {
|
||||||
@@ -55,6 +58,7 @@ pub struct Display {
|
|||||||
pub displayed_windows: Vec<DisplayWindow>,
|
pub displayed_windows: Vec<DisplayWindow>,
|
||||||
wayland_env: super::WaylandEnv,
|
wayland_env: super::WaylandEnv,
|
||||||
last_pressed_time_ms: u64,
|
last_pressed_time_ms: u64,
|
||||||
|
pub no_windows_since: Option<u64>,
|
||||||
|
|
||||||
// Render data stuff
|
// Render data stuff
|
||||||
gles_texture: GlesTexture, // TODO: drop texture
|
gles_texture: GlesTexture, // TODO: drop texture
|
||||||
@@ -123,6 +127,7 @@ impl Display {
|
|||||||
overlay_id: None,
|
overlay_id: None,
|
||||||
tasks: SyncEventQueue::new(),
|
tasks: SyncEventQueue::new(),
|
||||||
last_pressed_time_ms: 0,
|
last_pressed_time_ms: 0,
|
||||||
|
no_windows_since: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +163,24 @@ impl Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self) {
|
pub fn tick(
|
||||||
|
&mut self,
|
||||||
|
config: &super::Config,
|
||||||
|
handle: &DisplayHandle,
|
||||||
|
signals: &mut SyncEventQueue<WayVRSignal>,
|
||||||
|
) {
|
||||||
|
if self.visible {
|
||||||
|
if !self.displayed_windows.is_empty() {
|
||||||
|
self.no_windows_since = None;
|
||||||
|
} else if let Some(auto_hide_delay) = config.auto_hide_delay {
|
||||||
|
if let Some(s) = self.no_windows_since {
|
||||||
|
if s + (auto_hide_delay as u64) < get_millis() {
|
||||||
|
signals.send(WayVRSignal::DisplayHideRequest(*handle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while let Some(task) = self.tasks.read() {
|
while let Some(task) = self.tasks.read() {
|
||||||
match task {
|
match task {
|
||||||
DisplayTask::ProcessCleanup(process_handle) => {
|
DisplayTask::ProcessCleanup(process_handle) => {
|
||||||
@@ -169,6 +191,7 @@ impl Display {
|
|||||||
self.name,
|
self.name,
|
||||||
self.displayed_windows.len()
|
self.displayed_windows.len()
|
||||||
);
|
);
|
||||||
|
self.no_windows_since = Some(get_millis());
|
||||||
|
|
||||||
self.reposition_windows();
|
self.reposition_windows();
|
||||||
}
|
}
|
||||||
@@ -248,6 +271,7 @@ impl Display {
|
|||||||
self.visible = visible;
|
self.visible = visible;
|
||||||
if visible {
|
if visible {
|
||||||
self.wants_redraw = true;
|
self.wants_redraw = true;
|
||||||
|
self.no_windows_since = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,10 +65,16 @@ pub enum WayVRTask {
|
|||||||
ProcessTerminationRequest(process::ProcessHandle),
|
ProcessTerminationRequest(process::ProcessHandle),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum WayVRSignal {
|
||||||
|
DisplayHideRequest(display::DisplayHandle),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub click_freeze_time_ms: u32,
|
pub click_freeze_time_ms: u32,
|
||||||
pub keyboard_repeat_delay_ms: u32,
|
pub keyboard_repeat_delay_ms: u32,
|
||||||
pub keyboard_repeat_rate: u32,
|
pub keyboard_repeat_rate: u32,
|
||||||
|
pub auto_hide_delay: Option<u32>, // if None, auto-hide is disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -83,6 +89,7 @@ pub struct WayVR {
|
|||||||
config: Config,
|
config: Config,
|
||||||
|
|
||||||
tasks: SyncEventQueue<WayVRTask>,
|
tasks: SyncEventQueue<WayVRTask>,
|
||||||
|
pub signals: SyncEventQueue<WayVRSignal>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum MouseIndex {
|
pub enum MouseIndex {
|
||||||
@@ -140,6 +147,7 @@ impl WayVR {
|
|||||||
processes: ProcessVec::new(),
|
processes: ProcessVec::new(),
|
||||||
egl_data: Rc::new(egl_data),
|
egl_data: Rc::new(egl_data),
|
||||||
wm: Rc::new(RefCell::new(window::WindowManager::new())),
|
wm: Rc::new(RefCell::new(window::WindowManager::new())),
|
||||||
|
signals: SyncEventQueue::new(),
|
||||||
tasks,
|
tasks,
|
||||||
config,
|
config,
|
||||||
})
|
})
|
||||||
@@ -206,9 +214,9 @@ impl WayVR {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for display in self.displays.vec.iter_mut().flatten() {
|
self.displays.iter_mut(&mut |handle, display| {
|
||||||
display.obj.tick();
|
display.tick(&self.config, &handle, &mut self.signals);
|
||||||
}
|
});
|
||||||
|
|
||||||
while let Some(task) = self.tasks.read() {
|
while let Some(task) = self.tasks.read() {
|
||||||
match task {
|
match task {
|
||||||
|
|||||||
@@ -80,12 +80,40 @@ impl WayVRCatalog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn def_true() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn def_autohide_delay() -> u32 {
|
||||||
|
750
|
||||||
|
}
|
||||||
|
|
||||||
|
fn def_keyboard_repeat_delay() -> u32 {
|
||||||
|
200
|
||||||
|
}
|
||||||
|
|
||||||
|
fn def_keyboard_repeat_rate() -> u32 {
|
||||||
|
50
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct WayVRConfig {
|
pub struct WayVRConfig {
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
pub run_compositor_at_start: bool,
|
pub run_compositor_at_start: bool,
|
||||||
pub catalogs: HashMap<String, WayVRCatalog>,
|
pub catalogs: HashMap<String, WayVRCatalog>,
|
||||||
pub displays: BTreeMap<String, WayVRDisplay>, // sorted alphabetically
|
pub displays: BTreeMap<String, WayVRDisplay>, // sorted alphabetically
|
||||||
|
|
||||||
|
#[serde(default = "def_true")]
|
||||||
|
pub auto_hide: bool,
|
||||||
|
|
||||||
|
#[serde(default = "def_autohide_delay")]
|
||||||
|
pub auto_hide_delay: u32,
|
||||||
|
|
||||||
|
#[serde(default = "def_keyboard_repeat_delay")]
|
||||||
|
pub keyboard_repeat_delay: u32,
|
||||||
|
|
||||||
|
#[serde(default = "def_keyboard_repeat_rate")]
|
||||||
|
pub keyboard_repeat_rate: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WayVRConfig {
|
impl WayVRConfig {
|
||||||
@@ -106,11 +134,19 @@ impl WayVRConfig {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_wayvr_config(config: &crate::config::GeneralConfig) -> wayvr::Config {
|
pub fn get_wayvr_config(
|
||||||
|
config_general: &crate::config::GeneralConfig,
|
||||||
|
config_wayvr: &crate::config_wayvr::WayVRConfig,
|
||||||
|
) -> wayvr::Config {
|
||||||
wayvr::Config {
|
wayvr::Config {
|
||||||
click_freeze_time_ms: config.click_freeze_time_ms,
|
click_freeze_time_ms: config_general.click_freeze_time_ms,
|
||||||
keyboard_repeat_delay_ms: 200,
|
keyboard_repeat_delay_ms: config_wayvr.keyboard_repeat_delay,
|
||||||
keyboard_repeat_rate: 50,
|
keyboard_repeat_rate: config_wayvr.keyboard_repeat_rate,
|
||||||
|
auto_hide_delay: if config_wayvr.auto_hide {
|
||||||
|
Some(config_wayvr.auto_hide_delay)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +183,7 @@ impl WayVRConfig {
|
|||||||
if self.run_compositor_at_start {
|
if self.run_compositor_at_start {
|
||||||
// Start Wayland server instantly
|
// Start Wayland server instantly
|
||||||
Ok(Some(Rc::new(RefCell::new(WayVRState::new(
|
Ok(Some(Rc::new(RefCell::new(WayVRState::new(
|
||||||
Self::get_wayvr_config(config),
|
Self::get_wayvr_config(config, &self),
|
||||||
)?))))
|
)?))))
|
||||||
} else {
|
} else {
|
||||||
// Lazy-init WayVR later if the user requested
|
// Lazy-init WayVR later if the user requested
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ use wlx_capture::frame::{DmabufFrame, FourCC, FrameFormat, FramePlane};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
common::OverlayContainer,
|
common::{OverlayContainer, OverlaySelector},
|
||||||
input::{self, InteractionHandler},
|
input::{self, InteractionHandler},
|
||||||
overlay::{
|
overlay::{
|
||||||
ui_transform, OverlayData, OverlayID, OverlayRenderer, OverlayState,
|
ui_transform, OverlayData, OverlayID, OverlayRenderer, OverlayState,
|
||||||
SplitOverlayBackend,
|
SplitOverlayBackend,
|
||||||
},
|
},
|
||||||
|
task::TaskType,
|
||||||
wayvr::{self, display, WayVR},
|
wayvr::{self, display, WayVR},
|
||||||
},
|
},
|
||||||
graphics::WlxGraphics,
|
graphics::WlxGraphics,
|
||||||
@@ -213,8 +214,27 @@ pub fn tick_events<O>(app: &mut AppState, overlays: &mut OverlayContainer<O>) ->
|
|||||||
where
|
where
|
||||||
O: Default,
|
O: Default,
|
||||||
{
|
{
|
||||||
if let Some(wayvr) = app.wayvr.clone() {
|
if let Some(r_wayvr) = app.wayvr.clone() {
|
||||||
let res = wayvr.borrow_mut().state.tick_events()?;
|
let mut wayvr = r_wayvr.borrow_mut();
|
||||||
|
while let Some(signal) = wayvr.state.signals.read() {
|
||||||
|
match signal {
|
||||||
|
wayvr::WayVRSignal::DisplayHideRequest(display_handle) => {
|
||||||
|
if let Some(overlay_id) = wayvr.display_handle_map.get(&display_handle) {
|
||||||
|
let overlay_id = *overlay_id;
|
||||||
|
wayvr.state.set_display_visible(display_handle, false);
|
||||||
|
app.tasks.enqueue(TaskType::Overlay(
|
||||||
|
OverlaySelector::Id(overlay_id),
|
||||||
|
Box::new(move |_app, o| {
|
||||||
|
o.want_visible = false;
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = wayvr.state.tick_events()?;
|
||||||
|
drop(wayvr);
|
||||||
|
|
||||||
for result in res {
|
for result in res {
|
||||||
match result {
|
match result {
|
||||||
@@ -232,7 +252,7 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(disp_name) = disp_name {
|
if let Some(disp_name) = disp_name {
|
||||||
let mut wayvr = wayvr.borrow_mut();
|
let mut wayvr = r_wayvr.borrow_mut();
|
||||||
|
|
||||||
log::info!("Registering external process with PID {}", req.pid);
|
log::info!("Registering external process with PID {}", req.pid);
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,19 @@ version: 1
|
|||||||
# (used for remote starting external processes)
|
# (used for remote starting external processes)
|
||||||
run_compositor_at_start: false
|
run_compositor_at_start: false
|
||||||
|
|
||||||
|
# Automatically close overlays with zero window count?
|
||||||
|
auto_hide: true
|
||||||
|
|
||||||
|
# For how long an overlay should be visible in case if there are no windows present? (in milliseconds, auto_hide needs to be enabled)
|
||||||
|
# This value shouldn't be set at 0, because some programs could re-initialize a window during startup (splash screens for example)
|
||||||
|
auto_hide_delay: 750
|
||||||
|
|
||||||
|
# In milliseconds
|
||||||
|
keyboard_repeat_delay: 200
|
||||||
|
|
||||||
|
# Chars per second
|
||||||
|
keyboard_repeat_rate: 50
|
||||||
|
|
||||||
displays:
|
displays:
|
||||||
Watch:
|
Watch:
|
||||||
width: 400
|
width: 400
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ impl AppState {
|
|||||||
Ok(wvr.clone())
|
Ok(wvr.clone())
|
||||||
} else {
|
} else {
|
||||||
let wayvr = Rc::new(RefCell::new(WayVRState::new(
|
let wayvr = Rc::new(RefCell::new(WayVRState::new(
|
||||||
WayVRConfig::get_wayvr_config(&self.session.config),
|
WayVRConfig::get_wayvr_config(&self.session.config, &self.session.wayvr_config),
|
||||||
)?));
|
)?));
|
||||||
self.wayvr = Some(wayvr.clone());
|
self.wayvr = Some(wayvr.clone());
|
||||||
Ok(wayvr)
|
Ok(wayvr)
|
||||||
|
|||||||
Reference in New Issue
Block a user