Tray notification icon dot

This commit is contained in:
Natsumi
2025-10-30 01:16:17 +11:00
parent 814a66abea
commit 3836b9b4ce
15 changed files with 90 additions and 35 deletions

View File

@@ -216,5 +216,10 @@ namespace VRCX
using var client = MainForm.Instance.Browser.GetDevToolsClient();
_ = client.Network.SetUserAgentOverrideAsync(Program.Version);
}
public override void SetTrayIconNotification(bool notify)
{
MainForm.Instance.BeginInvoke(new MethodInvoker(() => { MainForm.Instance.SetTrayIconNotification(notify); }));
}
}
}

View File

@@ -14,6 +14,7 @@ namespace VRCX
public abstract void SetZoom(double zoomLevel);
public abstract Task<double> GetZoom();
public abstract void DesktopNotification(string BoldText, string Text = "", string Image = "");
public abstract void SetTrayIconNotification(bool notify);
public abstract void RestartApplication(bool isUpgrade);
public abstract bool CheckForUpdateExe();

View File

@@ -143,5 +143,9 @@ namespace VRCX
public override void SetUserAgent()
{
}
public override void SetTrayIconNotification(bool notify)
{
}
}
}

View File

@@ -7,7 +7,7 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Reflection;
using System.IO;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
@@ -22,6 +22,8 @@ namespace VRCX
public static NativeWindow nativeWindow;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public ChromiumWebBrowser Browser;
private readonly Icon _appIcon;
private readonly Icon _appIconNoty;
private readonly Timer _saveTimer;
private int LastLocationX;
private int LastLocationY;
@@ -41,10 +43,11 @@ namespace VRCX
_saveTimer.Tick += SaveTimer_Tick;
try
{
var location = Assembly.GetExecutingAssembly().Location;
var icon = Icon.ExtractAssociatedIcon(location);
Icon = icon;
TrayIcon.Icon = icon;
var path = Path.GetDirectoryName(Environment.ProcessPath) ?? string.Empty;
_appIcon = new Icon(Path.Combine(path, "VRCX.ico"));
_appIconNoty = new Icon(Path.Combine(path, "VRCX_notify.ico"));
Icon = _appIcon;
TrayIcon.Icon = _appIcon;
}
catch (Exception ex)
{
@@ -246,5 +249,10 @@ namespace VRCX
SaveWindowState();
Application.Exit();
}
public void SetTrayIconNotification(bool notify)
{
TrayIcon.Icon = notify ? _appIconNoty : _appIcon;
}
}
}

View File

@@ -85,6 +85,9 @@
<Content Include="..\images\VRCX.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\images\VRCX_notify.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\images\VRCX.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -100,7 +103,7 @@
<PackageReference Include="Silk.NET.Direct3D11" Version="2.22.0" />
<PackageReference Include="Silk.NET.DXGI" Version="2.22.0" />
<PackageReference Include="Silk.NET.Windowing" Version="2.22.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
<PackageReference Include="SourceGear.sqlite3" Version="3.50.4.2" />
<PackageReference Include="System.Data.SQLite" Version="2.0.2" />

View File

@@ -64,6 +64,9 @@
<Content Include="..\images\VRCX.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\images\VRCX_notify.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\images\VRCX.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -74,7 +77,7 @@
<PackageReference Include="DiscordRichPresence" Version="1.6.1.70" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="NLog" Version="6.0.5" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
<PackageReference Include="SourceGear.sqlite3" Version="3.50.4.2" />
<PackageReference Include="System.Data.SQLite" Version="2.0.2" />

View File

@@ -69,6 +69,9 @@
<Content Include="..\images\VRCX.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\images\VRCX_notify.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\images\VRCX.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -79,7 +82,7 @@
<PackageReference Include="DiscordRichPresence" Version="1.6.1.70" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="NLog" Version="6.0.5" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
<PackageReference Include="SourceGear.sqlite3" Version="3.50.4.2" />
<PackageReference Include="System.Data.SQLite" Version="1.0.119" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 KiB

After

Width:  |  Height:  |  Size: 106 KiB

BIN
images/VRCX_notify.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
images/VRCX_notify.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -83,6 +83,8 @@
"src-electron/*",
"images/VRCX.png",
"images/VRCX.ico",
"images/VRCX_notify.png",
"images/VRCX_notify.ico",
"Version",
"src-electron/libs/linux/libopenvr_api.so"
],

View File

@@ -161,28 +161,6 @@ if (!gotTheLock) {
});
}
ipcMain.handle('getArch', () => {
return process.arch.toString();
});
ipcMain.handle('applyWindowSettings', (event, position, size, state) => {
if (position) {
mainWindow.setPosition(parseInt(position.x), parseInt(position.y));
}
if (size) {
mainWindow.setSize(parseInt(size.width), parseInt(size.height));
}
if (state) {
if (state === '0') {
mainWindow.restore();
} else if (state === '1') {
mainWindow.restore();
} else if (state === '2') {
mainWindow.maximize();
}
}
});
ipcMain.handle('dialog:openFile', async () => {
const result = await dialog.showOpenDialog(mainWindow, {
properties: ['openFile'],
@@ -278,6 +256,14 @@ ipcMain.handle(
}
);
ipcMain.handle('app:getArch', () => {
return process.arch.toString();
});
ipcMain.handle('app:setTrayIconNotification', (event, notify) => {
setTrayIconNotification(notify);
});
function tryRelaunchWithArgs(args) {
if (
process.platform !== 'linux' ||
@@ -536,21 +522,35 @@ function destroyHmdOverlayWindow() {
hmdOverlayWindow = undefined;
}
let tray = null;
let trayIcon = null;
let trayIconNotify = null;
function createTray() {
let tray = null;
if (process.platform === 'darwin') {
const image = nativeImage.createFromPath(
path.join(rootDir, 'images/VRCX.png')
);
tray = new Tray(image.resize({ width: 16, height: 16 }));
trayIcon = image.resize({ width: 16, height: 16 });
const imageNotify = nativeImage.createFromPath(
path.join(rootDir, 'images/VRCX_notify.png')
);
trayIconNotify = imageNotify.resize({ width: 16, height: 16 });
} else if (process.platform === 'linux') {
const image = nativeImage.createFromPath(
path.join(rootDir, 'images/VRCX.png')
);
tray = new Tray(image.resize({ width: 64, height: 64 }));
trayIcon = image.resize({ width: 64, height: 64 });
const imageNotify = nativeImage.createFromPath(
path.join(rootDir, 'images/VRCX_notify.png')
);
trayIconNotify = imageNotify.resize({ width: 64, height: 64 });
} else {
tray = new Tray(path.join(rootDir, 'images/VRCX.ico'));
trayIcon = path.join(rootDir, 'images/VRCX.ico');
trayIconNotify = path.join(rootDir, 'images/VRCX_notify.ico');
}
tray = new Tray(trayIcon);
const contextMenu = Menu.buildFromTemplate([
{
label: 'Open',
@@ -583,6 +583,10 @@ function createTray() {
});
}
function setTrayIconNotification(notify) {
tray.setImage(notify ? trayIconNotify : trayIcon);
}
async function installVRCX() {
console.log('Home path:', homePath);
console.log('AppImage path:', appImagePath);

View File

@@ -22,7 +22,9 @@ contextBridge.exposeInMainWorld('interopApi', {
const validChannels = ['launch-command'];
contextBridge.exposeInMainWorld('electron', {
getArch: () => ipcRenderer.invoke('getArch'),
getArch: () => ipcRenderer.invoke('app:getArch'),
setTrayIconNotification: (notify) =>
ipcRenderer.invoke('app:setTrayIconNotification', notify),
openFileDialog: () => ipcRenderer.invoke('dialog:openFile'),
openDirectoryDialog: () => ipcRenderer.invoke('dialog:openDirectory'),
onWindowPositionChanged: (callback) =>

View File

@@ -23,6 +23,7 @@ export const useUiStore = defineStore('Ui', () => {
const notifiedMenus = ref([]);
const shiftHeld = ref(false);
const trayIconNotify = ref(false);
watch(
() => watchState.isLoggedIn,
@@ -41,6 +42,7 @@ export const useUiStore = defineStore('Ui', () => {
!notifiedMenus.value.includes(index)
) {
notifiedMenus.value.push(index);
updateTrayIconNotify();
}
}
@@ -58,6 +60,22 @@ export const useUiStore = defineStore('Ui', () => {
function removeNotify(index) {
notifiedMenus.value = notifiedMenus.value.filter((i) => i !== index);
updateTrayIconNotify();
}
function updateTrayIconNotify() {
const newState =
notifiedMenus.value.includes('notification') ||
notifiedMenus.value.includes('friendLog');
if (trayIconNotify.value !== newState) {
trayIconNotify.value = newState;
if (LINUX) {
window.electron.setTrayIconNotification(trayIconNotify.value);
return;
}
AppApi.SetTrayIconNotification(trayIconNotify.value);
}
}
return {

View File

@@ -36,6 +36,7 @@ declare global {
};
electron: {
getArch: () => Promise<string>;
setTrayIconNotification: (notify: boolean) => Promise<void>;
openFileDialog: () => Promise<string>;
openDirectoryDialog: () => Promise<string>;
desktopNotification: (
@@ -187,6 +188,7 @@ declare global {
CopyImageToClipboard(path: string): Promise<void>;
FlashWindow(): Promise<void>;
SetUserAgent(): Promise<void>;
SetTrayIconNotification(notify: boolean): Promise<void>;
// Common Functions
GetColourFromUserID(userId: string): Promise<number>;