Option to enable desktop notifications while AFK

This commit is contained in:
Natsumi
2023-11-13 21:29:13 +13:00
parent 928422e5b9
commit 25f47f9a1e
6 changed files with 130 additions and 93 deletions

View File

@@ -34,9 +34,11 @@ namespace VRCX
isSteamVRRunning = true;
}
var isHmdAfk = VRCXVR.Instance.IsHmdAfk;
// TODO: fix this throwing an exception for being called before the browser is ready. somehow it gets past the checks
if (MainForm.Instance?.Browser != null && !MainForm.Instance.Browser.IsLoading && MainForm.Instance.Browser.CanExecuteJavascriptInMainFrame)
MainForm.Instance.Browser.ExecuteScriptAsync("$app.updateIsGameRunning", isGameRunning, isSteamVRRunning);
MainForm.Instance.Browser.ExecuteScriptAsync("$app.updateIsGameRunning", isGameRunning, isSteamVRRunning, isHmdAfk);
}
/// <summary>

View File

@@ -42,6 +42,7 @@ namespace VRCX
private Texture2D _texture2;
private Thread _thread;
private bool _wristOverlayActive;
public bool IsHmdAfk { get; private set; }
static VRCXVR()
{
@@ -190,6 +191,7 @@ namespace VRCX
if (type == EVREventType.VREvent_Quit)
{
active = false;
IsHmdAfk = false;
OpenVR.Shutdown();
nextInit = DateTime.UtcNow.AddSeconds(10);
system = null;
@@ -247,6 +249,7 @@ namespace VRCX
else if (active)
{
active = false;
IsHmdAfk = false;
OpenVR.Shutdown();
_deviceListLock.EnterWriteLock();
try
@@ -314,102 +317,120 @@ namespace VRCX
for (var i = 0u; i < OpenVR.k_unMaxTrackedDeviceCount; ++i)
{
var devClass = system.GetTrackedDeviceClass(i);
if (devClass == ETrackedDeviceClass.Controller ||
devClass == ETrackedDeviceClass.GenericTracker ||
devClass == ETrackedDeviceClass.TrackingReference)
switch (devClass)
{
var err = ETrackedPropertyError.TrackedProp_Success;
var batteryPercentage = system.GetFloatTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_DeviceBatteryPercentage_Float, ref err);
if (err != ETrackedPropertyError.TrackedProp_Success)
{
batteryPercentage = 1f;
}
err = ETrackedPropertyError.TrackedProp_Success;
var isCharging = system.GetBoolTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_DeviceIsCharging_Bool, ref err);
if (err != ETrackedPropertyError.TrackedProp_Success)
{
isCharging = false;
}
sb.Clear();
system.GetStringTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_TrackingSystemName_String, sb, (uint)sb.Capacity, ref err);
var isOculus = sb.ToString().IndexOf("oculus", StringComparison.OrdinalIgnoreCase) >= 0;
// Oculus : B/Y, Bit 1, Mask 2
// Oculus : A/X, Bit 7, Mask 128
// Vive : Menu, Bit 1, Mask 2,
// Vive : Grip, Bit 2, Mask 4
var role = system.GetControllerRoleForTrackedDeviceIndex(i);
if (role == ETrackedControllerRole.LeftHand || role == ETrackedControllerRole.RightHand)
{
if (_overlayHand == 0 ||
(_overlayHand == 1 && role == ETrackedControllerRole.LeftHand) ||
(_overlayHand == 2 && role == ETrackedControllerRole.RightHand))
case ETrackedDeviceClass.HMD:
var success = system.GetControllerState(i, ref state, (uint)Marshal.SizeOf(state));
if (!success)
break; // this fails while SteamVR overlay is open
var prox = state.ulButtonPressed & (1UL << ((int)EVRButtonId.k_EButton_ProximitySensor));
var isHmdAfk = prox == 0;
if (isHmdAfk != IsHmdAfk)
{
if (system.GetControllerState(i, ref state, (uint)Marshal.SizeOf(state)) &&
(state.ulButtonPressed & (_menuButton ? 2u : isOculus ? 128u : 4u)) != 0)
{
if (role == ETrackedControllerRole.LeftHand)
{
Array.Copy(_translationLeft, _translation, 3);
Array.Copy(_rotationLeft, _rotation, 3);
}
else
{
Array.Copy(_translationRight, _translation, 3);
Array.Copy(_rotationRight, _rotation, 3);
}
IsHmdAfk = isHmdAfk;
AppApi.Instance.CheckGameRunning();
}
break;
case ETrackedDeviceClass.Controller:
case ETrackedDeviceClass.GenericTracker:
case ETrackedDeviceClass.TrackingReference:
{
var err = ETrackedPropertyError.TrackedProp_Success;
var batteryPercentage = system.GetFloatTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_DeviceBatteryPercentage_Float, ref err);
if (err != ETrackedPropertyError.TrackedProp_Success)
{
batteryPercentage = 1f;
}
overlayIndex = i;
err = ETrackedPropertyError.TrackedProp_Success;
var isCharging = system.GetBoolTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_DeviceIsCharging_Bool, ref err);
if (err != ETrackedPropertyError.TrackedProp_Success)
{
isCharging = false;
}
sb.Clear();
system.GetStringTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_TrackingSystemName_String, sb, (uint)sb.Capacity, ref err);
var isOculus = sb.ToString().IndexOf("oculus", StringComparison.OrdinalIgnoreCase) >= 0;
// Oculus : B/Y, Bit 1, Mask 2
// Oculus : A/X, Bit 7, Mask 128
// Vive : Menu, Bit 1, Mask 2,
// Vive : Grip, Bit 2, Mask 4
var role = system.GetControllerRoleForTrackedDeviceIndex(i);
if (role == ETrackedControllerRole.LeftHand || role == ETrackedControllerRole.RightHand)
{
if (_overlayHand == 0 ||
(_overlayHand == 1 && role == ETrackedControllerRole.LeftHand) ||
(_overlayHand == 2 && role == ETrackedControllerRole.RightHand))
{
if (system.GetControllerState(i, ref state, (uint)Marshal.SizeOf(state)) &&
(state.ulButtonPressed & (_menuButton ? 2u : isOculus ? 128u : 4u)) != 0)
{
if (role == ETrackedControllerRole.LeftHand)
{
Array.Copy(_translationLeft, _translation, 3);
Array.Copy(_rotationLeft, _rotation, 3);
}
else
{
Array.Copy(_translationRight, _translation, 3);
Array.Copy(_rotationRight, _rotation, 3);
}
overlayIndex = i;
}
}
}
}
var type = string.Empty;
if (devClass == ETrackedDeviceClass.Controller)
{
if (role == ETrackedControllerRole.LeftHand)
var type = string.Empty;
if (devClass == ETrackedDeviceClass.Controller)
{
type = "leftController";
if (role == ETrackedControllerRole.LeftHand)
{
type = "leftController";
}
else if (role == ETrackedControllerRole.RightHand)
{
type = "rightController";
}
else
{
type = "controller";
}
}
else if (role == ETrackedControllerRole.RightHand)
else if (devClass == ETrackedDeviceClass.GenericTracker)
{
type = "rightController";
type = "tracker";
}
else
else if (devClass == ETrackedDeviceClass.TrackingReference)
{
type = "controller";
type = "base";
}
}
else if (devClass == ETrackedDeviceClass.GenericTracker)
{
type = "tracker";
}
else if (devClass == ETrackedDeviceClass.TrackingReference)
{
type = "base";
}
var item = new[]
{
type,
system.IsTrackedDeviceConnected(i)
? "connected"
: "disconnected",
isCharging
? "charging"
: "discharging",
(batteryPercentage * 100).ToString(),
poses[i].eTrackingResult.ToString()
};
_deviceListLock.EnterWriteLock();
try
{
_deviceList.Add(item);
}
finally
{
_deviceListLock.ExitWriteLock();
var item = new[]
{
type,
system.IsTrackedDeviceConnected(i)
? "connected"
: "disconnected",
isCharging
? "charging"
: "discharging",
(batteryPercentage * 100).ToString(),
poses[i].eTrackingResult.ToString()
};
_deviceListLock.EnterWriteLock();
try
{
_deviceList.Add(item);
}
finally
{
_deviceListLock.ExitWriteLock();
}
break;
}
}
}

View File

@@ -5231,6 +5231,7 @@ speechSynthesis.getVoices();
isGameRunning: false,
isGameNoVR: configRepository.getBool('isGameNoVR'),
isSteamVRRunning: false,
isHmdAfk: false,
appVersion: '',
latestAppVersion: '',
ossDialog: false
@@ -5455,7 +5456,8 @@ speechSynthesis.getVoices();
$app.methods.updateIsGameRunning = function (
isGameRunning,
isSteamVRRunning
isSteamVRRunning,
isHmdAfk
) {
if (isGameRunning !== this.isGameRunning) {
this.isGameRunning = isGameRunning;
@@ -5485,6 +5487,10 @@ speechSynthesis.getVoices();
this.isSteamVRRunning = isSteamVRRunning;
console.log('isSteamVRRunning:', isSteamVRRunning);
}
if (isHmdAfk !== this.isHmdAfk) {
this.isHmdAfk = isHmdAfk;
console.log('isHmdAfk:', isHmdAfk);
}
this.updateOpenVR();
};
@@ -6227,8 +6233,13 @@ speechSynthesis.getVoices();
(this.desktopToast === 'Game Running' && this.isGameRunning) ||
(this.desktopToast === 'Desktop Mode' &&
this.isGameNoVR &&
this.isGameRunning)
this.isGameRunning) ||
(this.afkDesktopToast &&
this.isHmdAfk &&
this.isGameRunning &&
!this.isGameNoVR)
) {
// this if statement looks like it has seen better days
playDesktopToast = true;
}
var playXSNotification = this.xsNotifications;
@@ -14212,6 +14223,10 @@ speechSynthesis.getVoices();
'VRCX_desktopToast',
'Never'
);
$app.data.afkDesktopToast = configRepository.getBool(
'VRCX_afkDesktopToast',
false
);
$app.data.minimalFeed = configRepository.getBool('VRCX_minimalFeed', false);
$app.data.displayVRCPlusIconsAsAvatar = configRepository.getBool(
'displayVRCPlusIconsAsAvatar',
@@ -14366,6 +14381,7 @@ speechSynthesis.getVoices();
this.imageNotifications
);
configRepository.setString('VRCX_desktopToast', this.desktopToast);
configRepository.setBool('VRCX_afkDesktopToast', this.afkDesktopToast);
configRepository.setBool('VRCX_minimalFeed', this.minimalFeed);
configRepository.setBool(
'displayVRCPlusIconsAsAvatar',

View File

@@ -322,7 +322,8 @@
"when_to_display_outside_vr": "Outside VR",
"when_to_display_game_closed": "Game Closed",
"when_to_display_game_running": "Game Running",
"when_to_display_always": "Always"
"when_to_display_always": "Always",
"desktop_notification_while_afk": "Desktop Notification While AFK"
},
"text_to_speech": {
"header": "Text-To-Speech Options",

View File

@@ -273,6 +273,9 @@ mixin settingsTab()
el-radio-button(label="Game Closed") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_game_closed') }}
el-radio-button(label="Game Running") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_game_running') }}
el-radio-button(label="Always") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_always') }}
div.options-container-item
span.name(style="min-width:225px") {{ $t('view.settings.notifications.notifications.desktop_notifications.desktop_notification_while_afk') }}
el-switch(v-model="afkDesktopToast" @change="saveOpenVROption")
//- Notifications | Notifications | Text-to-Speech Options
div.options-container
span.sub-header {{ $t('view.settings.notifications.notifications.text_to_speech.header') }}

View File

@@ -462,12 +462,6 @@ html
img(v-if="device[1] !== 'connected'" src="images/base_status_off.png")
img(v-else src="images/base_status_ready.png")
span(v-if="device[3] !== 100") {{ device[3] }}x
div(v-else class="tracker-device" :class="trackingResultToClass(device[4])")
img(v-if="device[1] !== 'connected'" src="images/other_status_off.png")
img(v-else-if="device[2] === 'charging'" src="images/other_status_ready_charging.png")
img(v-else-if="device[3] < 20" src="images/other_status_ready_low.png")
img(v-else src="images/other_status_ready.png")
span {{ device[3] }}%
.x-containerbottom
template(v-if="nowPlaying.playing")
span(style="float:right;padding-left:10px") {{ nowPlaying.remainingText }}