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
+3 -1
View File
@@ -34,9 +34,11 @@ namespace VRCX
isSteamVRRunning = true; 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 // 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) 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> /// <summary>
+103 -82
View File
@@ -42,6 +42,7 @@ namespace VRCX
private Texture2D _texture2; private Texture2D _texture2;
private Thread _thread; private Thread _thread;
private bool _wristOverlayActive; private bool _wristOverlayActive;
public bool IsHmdAfk { get; private set; }
static VRCXVR() static VRCXVR()
{ {
@@ -190,6 +191,7 @@ namespace VRCX
if (type == EVREventType.VREvent_Quit) if (type == EVREventType.VREvent_Quit)
{ {
active = false; active = false;
IsHmdAfk = false;
OpenVR.Shutdown(); OpenVR.Shutdown();
nextInit = DateTime.UtcNow.AddSeconds(10); nextInit = DateTime.UtcNow.AddSeconds(10);
system = null; system = null;
@@ -247,6 +249,7 @@ namespace VRCX
else if (active) else if (active)
{ {
active = false; active = false;
IsHmdAfk = false;
OpenVR.Shutdown(); OpenVR.Shutdown();
_deviceListLock.EnterWriteLock(); _deviceListLock.EnterWriteLock();
try try
@@ -314,102 +317,120 @@ namespace VRCX
for (var i = 0u; i < OpenVR.k_unMaxTrackedDeviceCount; ++i) for (var i = 0u; i < OpenVR.k_unMaxTrackedDeviceCount; ++i)
{ {
var devClass = system.GetTrackedDeviceClass(i); var devClass = system.GetTrackedDeviceClass(i);
if (devClass == ETrackedDeviceClass.Controller || switch (devClass)
devClass == ETrackedDeviceClass.GenericTracker ||
devClass == ETrackedDeviceClass.TrackingReference)
{ {
var err = ETrackedPropertyError.TrackedProp_Success; case ETrackedDeviceClass.HMD:
var batteryPercentage = system.GetFloatTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_DeviceBatteryPercentage_Float, ref err); var success = system.GetControllerState(i, ref state, (uint)Marshal.SizeOf(state));
if (err != ETrackedPropertyError.TrackedProp_Success) if (!success)
{ break; // this fails while SteamVR overlay is open
batteryPercentage = 1f;
}
err = ETrackedPropertyError.TrackedProp_Success; var prox = state.ulButtonPressed & (1UL << ((int)EVRButtonId.k_EButton_ProximitySensor));
var isCharging = system.GetBoolTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_DeviceIsCharging_Bool, ref err); var isHmdAfk = prox == 0;
if (err != ETrackedPropertyError.TrackedProp_Success) if (isHmdAfk != IsHmdAfk)
{
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)) && IsHmdAfk = isHmdAfk;
(state.ulButtonPressed & (_menuButton ? 2u : isOculus ? 128u : 4u)) != 0) AppApi.Instance.CheckGameRunning();
{ }
if (role == ETrackedControllerRole.LeftHand) break;
{ case ETrackedDeviceClass.Controller:
Array.Copy(_translationLeft, _translation, 3); case ETrackedDeviceClass.GenericTracker:
Array.Copy(_rotationLeft, _rotation, 3); case ETrackedDeviceClass.TrackingReference:
} {
else var err = ETrackedPropertyError.TrackedProp_Success;
{ var batteryPercentage = system.GetFloatTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_DeviceBatteryPercentage_Float, ref err);
Array.Copy(_translationRight, _translation, 3); if (err != ETrackedPropertyError.TrackedProp_Success)
Array.Copy(_rotationRight, _rotation, 3); {
} 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; var type = string.Empty;
if (devClass == ETrackedDeviceClass.Controller) if (devClass == ETrackedDeviceClass.Controller)
{
if (role == ETrackedControllerRole.LeftHand)
{ {
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[] var item = new[]
{ {
type, type,
system.IsTrackedDeviceConnected(i) system.IsTrackedDeviceConnected(i)
? "connected" ? "connected"
: "disconnected", : "disconnected",
isCharging isCharging
? "charging" ? "charging"
: "discharging", : "discharging",
(batteryPercentage * 100).ToString(), (batteryPercentage * 100).ToString(),
poses[i].eTrackingResult.ToString() poses[i].eTrackingResult.ToString()
}; };
_deviceListLock.EnterWriteLock(); _deviceListLock.EnterWriteLock();
try try
{ {
_deviceList.Add(item); _deviceList.Add(item);
} }
finally finally
{ {
_deviceListLock.ExitWriteLock(); _deviceListLock.ExitWriteLock();
}
break;
} }
} }
} }
+18 -2
View File
@@ -5231,6 +5231,7 @@ speechSynthesis.getVoices();
isGameRunning: false, isGameRunning: false,
isGameNoVR: configRepository.getBool('isGameNoVR'), isGameNoVR: configRepository.getBool('isGameNoVR'),
isSteamVRRunning: false, isSteamVRRunning: false,
isHmdAfk: false,
appVersion: '', appVersion: '',
latestAppVersion: '', latestAppVersion: '',
ossDialog: false ossDialog: false
@@ -5455,7 +5456,8 @@ speechSynthesis.getVoices();
$app.methods.updateIsGameRunning = function ( $app.methods.updateIsGameRunning = function (
isGameRunning, isGameRunning,
isSteamVRRunning isSteamVRRunning,
isHmdAfk
) { ) {
if (isGameRunning !== this.isGameRunning) { if (isGameRunning !== this.isGameRunning) {
this.isGameRunning = isGameRunning; this.isGameRunning = isGameRunning;
@@ -5485,6 +5487,10 @@ speechSynthesis.getVoices();
this.isSteamVRRunning = isSteamVRRunning; this.isSteamVRRunning = isSteamVRRunning;
console.log('isSteamVRRunning:', isSteamVRRunning); console.log('isSteamVRRunning:', isSteamVRRunning);
} }
if (isHmdAfk !== this.isHmdAfk) {
this.isHmdAfk = isHmdAfk;
console.log('isHmdAfk:', isHmdAfk);
}
this.updateOpenVR(); this.updateOpenVR();
}; };
@@ -6227,8 +6233,13 @@ speechSynthesis.getVoices();
(this.desktopToast === 'Game Running' && this.isGameRunning) || (this.desktopToast === 'Game Running' && this.isGameRunning) ||
(this.desktopToast === 'Desktop Mode' && (this.desktopToast === 'Desktop Mode' &&
this.isGameNoVR && 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; playDesktopToast = true;
} }
var playXSNotification = this.xsNotifications; var playXSNotification = this.xsNotifications;
@@ -14212,6 +14223,10 @@ speechSynthesis.getVoices();
'VRCX_desktopToast', 'VRCX_desktopToast',
'Never' 'Never'
); );
$app.data.afkDesktopToast = configRepository.getBool(
'VRCX_afkDesktopToast',
false
);
$app.data.minimalFeed = configRepository.getBool('VRCX_minimalFeed', false); $app.data.minimalFeed = configRepository.getBool('VRCX_minimalFeed', false);
$app.data.displayVRCPlusIconsAsAvatar = configRepository.getBool( $app.data.displayVRCPlusIconsAsAvatar = configRepository.getBool(
'displayVRCPlusIconsAsAvatar', 'displayVRCPlusIconsAsAvatar',
@@ -14366,6 +14381,7 @@ speechSynthesis.getVoices();
this.imageNotifications this.imageNotifications
); );
configRepository.setString('VRCX_desktopToast', this.desktopToast); configRepository.setString('VRCX_desktopToast', this.desktopToast);
configRepository.setBool('VRCX_afkDesktopToast', this.afkDesktopToast);
configRepository.setBool('VRCX_minimalFeed', this.minimalFeed); configRepository.setBool('VRCX_minimalFeed', this.minimalFeed);
configRepository.setBool( configRepository.setBool(
'displayVRCPlusIconsAsAvatar', 'displayVRCPlusIconsAsAvatar',
+2 -1
View File
@@ -322,7 +322,8 @@
"when_to_display_outside_vr": "Outside VR", "when_to_display_outside_vr": "Outside VR",
"when_to_display_game_closed": "Game Closed", "when_to_display_game_closed": "Game Closed",
"when_to_display_game_running": "Game Running", "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": { "text_to_speech": {
"header": "Text-To-Speech Options", "header": "Text-To-Speech Options",
+3
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 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="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') }} 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 //- Notifications | Notifications | Text-to-Speech Options
div.options-container div.options-container
span.sub-header {{ $t('view.settings.notifications.notifications.text_to_speech.header') }} span.sub-header {{ $t('view.settings.notifications.notifications.text_to_speech.header') }}
-6
View File
@@ -462,12 +462,6 @@ html
img(v-if="device[1] !== 'connected'" src="images/base_status_off.png") img(v-if="device[1] !== 'connected'" src="images/base_status_off.png")
img(v-else src="images/base_status_ready.png") img(v-else src="images/base_status_ready.png")
span(v-if="device[3] !== 100") {{ device[3] }}x 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 .x-containerbottom
template(v-if="nowPlaying.playing") template(v-if="nowPlaying.playing")
span(style="float:right;padding-left:10px") {{ nowPlaying.remainingText }} span(style="float:right;padding-left:10px") {{ nowPlaying.remainingText }}