aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-03-15 17:26:13 +0100
committerLibravatar GitHub <noreply@github.com>2023-03-15 17:26:13 +0100
commitf1152d3dbb4c6deefea168d66f15f77b7155a5fe (patch)
tree22c27234b6e3a2dfe47ade037ece47b2533f7039
parent6.2.6-nightly.5 [skip ci] (diff)
downloadferdium-app-f1152d3dbb4c6deefea168d66f15f77b7155a5fe.tar.gz
ferdium-app-f1152d3dbb4c6deefea168d66f15f77b7155a5fe.tar.zst
ferdium-app-f1152d3dbb4c6deefea168d66f15f77b7155a5fe.zip
Basic D-Bus API (#866)
* feat: basic D-Bus API Expose muted state and the number of unread message over D-Bus when running on Linux. This is useful for, e.g., displaying notifications on a window manager status bar. Signed-off-by: Kristóf Marussy <kristof@marussy.com> * docs: create docs directory Move the documentation to a separate directory so that new documentation can be added into one place. We keep the following files still in the repository root by convention: * CHANGELOG.md * CODE_OF_CONDUCT.md * CONTRIBUTING.md * LICENSE.md * README.md * SECURITY.md Signed-off-by: Kristóf Marussy <kristof@marussy.com> * docs: D-Bus usage example Signed-off-by: Kristóf Marussy <kristof@marussy.com> * fix: remove unneeded D-Bus signals Only notify clients that the message counts or the mute status has changed if there actually was a change. Signed-off-by: Kristóf Marussy <kristof@marussy.com> * docs: rewrite sample bar client * docs: better unread --services help * docs: update dbus docs * docs: use ferdium-dbus in dbus bar example * docs: make command argument required in bar example --------- Signed-off-by: Kristóf Marussy <kristof@marussy.com> Co-authored-by: Victor Bonnelle <victor.bonnelle@protonmail.com>
-rw-r--r--README.md2
-rw-r--r--docs/DBUS.md20
-rw-r--r--docs/INTERNAL_SERVER.md (renamed from INTERNAL_SERVER.md)2
-rw-r--r--docs/MIGRATION.md (renamed from MIGRATION.md)0
-rw-r--r--docs/dbus/ferdium_bar.py102
-rw-r--r--docs/dbus/org.ferdium.Ferdium.xml80
-rw-r--r--docs/dbus/requirements.txt1
-rwxr-xr-xscripts/migration/migrate-unix.sh2
-rw-r--r--scripts/migration/migrate-windows.ps12
-rw-r--r--src/lib/DBus.ts69
-rw-r--r--src/lib/dbus/Ferdium.ts88
-rw-r--r--src/stores/ServicesStore.ts52
12 files changed, 393 insertions, 27 deletions
diff --git a/README.md b/README.md
index 692f90943..57428c80d 100644
--- a/README.md
+++ b/README.md
@@ -62,7 +62,7 @@ _Find answers to frequently asked questions on [ferdium.org/faq](https://ferdium
62 62
63## Migrating from Ferdi 63## Migrating from Ferdi
64 64
65If you are a pre-existing user of Ferdi, and are thinking of switching to Ferdium, you might want to run [the following scripts](./scripts/migration) to migrate your existing Ferdi profile such that Ferdium can pick up the configurations. (.ps1 for PowerShell/Windows users and .sh for UNIX (Linux and MacOS users). For a more detailed explanation, please see [MIGRATION.md](MIGRATION.md) 65If you are a pre-existing user of Ferdi, and are thinking of switching to Ferdium, you might want to run [the following scripts](./scripts/migration) to migrate your existing Ferdi profile such that Ferdium can pick up the configurations. (.ps1 for PowerShell/Windows users and .sh for UNIX (Linux and MacOS users). For a more detailed explanation, please see [MIGRATION.md](docs/MIGRATION.md)
66 66
67## Styling 67## Styling
68 68
diff --git a/docs/DBUS.md b/docs/DBUS.md
new file mode 100644
index 000000000..ffbd61f4b
--- /dev/null
+++ b/docs/DBUS.md
@@ -0,0 +1,20 @@
1# D-Bus interface
2
3Ferdium exposes an inter-process communication on Linux systems via [D-Bus](https://www.freedesktop.org/wiki/Software/dbus/).
4This allows integrating Ferdium with your desktop environment by displaying the number of unread notifications in a status area and muting or unmuting notations.
5
6## Desktop integration
7
8As an example integration, the [`docs/dbus`](dbus) folder contains a module for status bars written in Python.
9To run the example, you'll need Python 3.11 and the [`dbus-next`](https://pypi.org/project/dbus-next/) PyPI package.
10
11The integration uses the [`FerdiumClient`](dbus/ferdium_client.py) client library, which is an asynchronous wrapper over the D-Bus interface.
12It illustrates multiple advanced concepts, such as asynchronous communication with Ferdium via `asyncio` and polling the session D-Bus to see if Ferdium is running.
13
14The [`ferdium_bar.py`](dbus/ferdium_bar.py) implements a bar module to use with status bars such as waybar or polybar. See `ferdium_bar.py --help` and `ferdium_bar.py unread --help` for further indications on how to use it.
15
16## Low-level API
17
18The low-level API exposed over D-Bus is documented in [`org.ferdium.Ferdium.xml](docs/org.ferdium.Ferdium.xml) with standard D-Bus introspection syntax.
19
20Ferdium will take ownership of the bus name `org.ferdium.Ferdium` and expose and object implementing the `org.ferdium.Ferdium` interface at the object path `/org/ferdium`.
diff --git a/INTERNAL_SERVER.md b/docs/INTERNAL_SERVER.md
index 1a1284f7e..9e94f9bdf 100644
--- a/INTERNAL_SERVER.md
+++ b/docs/INTERNAL_SERVER.md
@@ -1,5 +1,5 @@
1<p align="center"> 1<p align="center">
2 <img src="./src/internal-server/public/images/logo.png" alt="" width="300"/> 2 <img src="../src/internal-server/public/images/logo.png" alt="" width="300"/>
3</p> 3</p>
4 4
5# ferdium-internal-server 5# ferdium-internal-server
diff --git a/MIGRATION.md b/docs/MIGRATION.md
index bb1ca315d..bb1ca315d 100644
--- a/MIGRATION.md
+++ b/docs/MIGRATION.md
diff --git a/docs/dbus/ferdium_bar.py b/docs/dbus/ferdium_bar.py
new file mode 100644
index 000000000..6fd5d8c30
--- /dev/null
+++ b/docs/dbus/ferdium_bar.py
@@ -0,0 +1,102 @@
1import asyncio
2import argparse
3import html
4
5from ferdium_dbus import Client
6
7
8async def toggle_window(client, args):
9 """Toggle window visibility"""
10
11 await client.toggle_window()
12
13
14async def toggle_mute(client, args):
15 """Toggle mute status"""
16
17 await client.toggle_mute()
18
19
20async def unread(client, args):
21 """Get unread messages count"""
22
23 def callback():
24 """Print unread count(s)"""
25
26 # For each service
27 counts = {}
28 for service in client.unread_services:
29 name, direct, indirect = service
30 safe_name = html.escape(name)
31
32 # If it's exactly the service we're looking for, just return the count
33 if safe_name == args.services:
34 count = direct
35 if not args.direct:
36 count += indirect
37 print(count)
38 return
39
40 # If the service in included in the services we're looking for
41 if args.services in ("total", "all") or safe_name in args.services:
42 counts[safe_name] = direct
43 if not args.direct:
44 counts[safe_name] += indirect
45
46 # Get total notifications
47 if args.services == "total":
48 print(sum(counts.values()))
49 return
50
51 # Finally, print each service notifications on a different line
52 print(
53 "\n".join(
54 f"{name}: {count}"
55 for name, count in counts.items()
56 )
57 )
58
59 # Do print counts and keep running if tail mode enabled
60 callback()
61 if args.tail:
62 client.on_change(callback)
63 await asyncio.get_running_loop().create_future()
64
65
66async def main():
67 """Main cli interface"""
68
69 # Define commands
70 commands = {
71 "unread": unread,
72 "toggle-mute": toggle_mute,
73 "toggle-window": toggle_window,
74 }
75
76 # Arguments parser
77 argparser = argparse.ArgumentParser(description="Script to interact with Ferdium on your bar")
78 subparsers = argparser.add_subparsers(dest="command", required=True)
79 # Unread command
80 argparser_unread = subparsers.add_parser("unread", help=unread.__doc__)
81 argparser_unread.add_argument("-s", "--services", default="total", help="Which services to get notifications from {total, all, <name>} (the name can be a comma-separated list)")
82 argparser_unread.add_argument("-d", "--direct", action="store_true", default=False, help="Get only direct (mentions or DM) messages")
83 argparser_unread.add_argument("-t", "--tail", action="store_true", default=False, help="Keep running and print on change")
84 # Toggle mute and toggle window commands
85 argparser_toggle_mute = subparsers.add_parser("toggle-mute", help=toggle_mute.__doc__)
86 argparser_toggle_window = subparsers.add_parser("toggle-window", help=toggle_window.__doc__)
87 # Get args
88 args = argparser.parse_args()
89
90 # Initialise ferdium client
91 client = Client()
92 await client.connect()
93 if not client.running:
94 print("not running")
95 return
96
97 # Execute command
98 await commands[args.command](client, args)
99
100
101if __name__ == "__main__":
102 asyncio.run(main())
diff --git a/docs/dbus/org.ferdium.Ferdium.xml b/docs/dbus/org.ferdium.Ferdium.xml
new file mode 100644
index 000000000..8c66a9e21
--- /dev/null
+++ b/docs/dbus/org.ferdium.Ferdium.xml
@@ -0,0 +1,80 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
3"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
4<node>
5 <!--
6 org.ferdium.Ferdium:
7 @short_description: Control Ferdium from the desktop
8
9 Interface for accessing Ferdium notification state, allowing notification
10 counts to be displayed in the desktop (e.g., on a status bar) and updating
11 the muted state of notifications.
12
13 The #org.ferdium.UnreadDirectMessageCount,
14 #org.ferdium.UnreadIndirectMessageCount, and #org.ferdium.UnreadServices
15 are affected by notification muting and hiding settings of Ferdium.
16 In particular, they are not updated if #org.ferdium.Muted is #TRUE.
17 Moreover, services with muted notifications or hidden indirect message
18 counts will not appear in the respective counts.
19 This behavior is consistent with the behavior of the Ferdium tray icon.
20 -->
21 <interface name="org.ferdium.Ferdium">
22 <!--
23 ToggleMute:
24
25 Toggles the muted state of notifcations.
26
27 Use the #org.ferdium.Ferdium.Muted property to get or set the current
28 muted state.
29 -->
30 <method name="ToggleMute" />
31 <!--
32 ToggleWindow:
33
34 Brings the Ferdium window into the foreground if it is not currently
35 focused. Hides the Ferdium window if is is currently focused.
36
37 Calling this method is equivalent to clicking on the Ferdium tray icon.
38 -->
39 <method name="ToggleWindow" />
40 <!--
41 Muted:
42
43 Gets or sets the current muted state of notifications.
44
45 #TRUE if notifications are currently muted, #FALSE otherwise.
46 -->
47 <property name="Muted" type="b" access="readwrite" />
48 <!--
49 UnreadDirectMessageCount:
50
51 The number of unread direct messages.
52 -->
53 <property name="UnreadDirectMessageCount" type="u" access="read" />
54 <!--
55 UnreadIndirectMessageCount:
56
57 The number of unread indirect messages.
58 -->
59 <property name="UnreadIndirectMessageCount" type="u" access="read" />
60 <!--
61 UnreadServices:
62
63 The list of services with unread messages.
64
65 The value of this property is an array of structs corresponding to each
66 service with unread messages.
67 The elements of a struct are the following:
68
69 1. The name of the service.
70
71 2. The number of unread direct messages of the service.
72
73 3. The number of unread indirect messages of the service.
74
75 Services with no unread direct or indirect messages (i.e., structs with
76 the second and third element set to 0) are omitted from the array.
77 -->
78 <property name="UnreadServices" type="a(suu)" access="read" />
79 </interface>
80</node>
diff --git a/docs/dbus/requirements.txt b/docs/dbus/requirements.txt
new file mode 100644
index 000000000..d08a849d9
--- /dev/null
+++ b/docs/dbus/requirements.txt
@@ -0,0 +1 @@
git+https://github.com/victorbnl/ferdium-dbus-py
diff --git a/scripts/migration/migrate-unix.sh b/scripts/migration/migrate-unix.sh
index 37f24a533..c51227f33 100755
--- a/scripts/migration/migrate-unix.sh
+++ b/scripts/migration/migrate-unix.sh
@@ -65,6 +65,6 @@ else
65 echo "WARNING: Your data was partially migrated!" 65 echo "WARNING: Your data was partially migrated!"
66 echo "It was detected that your account is using Ferdi servers to sync your data." 66 echo "It was detected that your account is using Ferdi servers to sync your data."
67 echo "Please, check this guide on how to export and import your data manually:" 67 echo "Please, check this guide on how to export and import your data manually:"
68 echo "https://github.com/ferdium/ferdi/blob/main/MIGRATION.md" 68 echo "https://github.com/ferdium/ferdi/blob/main/docs/MIGRATION.md"
69 echo "********************************************" 69 echo "********************************************"
70fi 70fi
diff --git a/scripts/migration/migrate-windows.ps1 b/scripts/migration/migrate-windows.ps1
index a7e67b94a..0a793077c 100644
--- a/scripts/migration/migrate-windows.ps1
+++ b/scripts/migration/migrate-windows.ps1
@@ -39,7 +39,7 @@ if (-not (Test-Path -Path $FERDIUM_PATH/server.sqlite)) {
39 Write-Host "" 39 Write-Host ""
40 Write-Host "It was detected that your account is using Ferdi servers to sync your data." 40 Write-Host "It was detected that your account is using Ferdi servers to sync your data."
41 Write-Host "Please, check this guide on how to export and import your data manually:" 41 Write-Host "Please, check this guide on how to export and import your data manually:"
42 Write-Host "https://github.com/ferdium/ferdi/blob/main/MIGRATION.md" 42 Write-Host "https://github.com/ferdium/ferdi/blob/main/docs/MIGRATION.md"
43 Write-Host "" 43 Write-Host ""
44 Write-Host "********************************************" 44 Write-Host "********************************************"
45 45
diff --git a/src/lib/DBus.ts b/src/lib/DBus.ts
index bbff405c4..530e30c85 100644
--- a/src/lib/DBus.ts
+++ b/src/lib/DBus.ts
@@ -1,28 +1,92 @@
1import { ipcMain } from 'electron';
2import { comparer } from 'mobx';
3
1import { MessageBus, sessionBus } from 'dbus-next'; 4import { MessageBus, sessionBus } from 'dbus-next';
2import { isLinux } from '../environment'; 5import { isLinux } from '../environment';
3import TrayIcon from './Tray'; 6import TrayIcon from './Tray';
7import Ferdium, { type UnreadServices } from './dbus/Ferdium';
4 8
5export default class DBus { 9export default class DBus {
6 bus: MessageBus | null = null; 10 private bus: MessageBus | null = null;
7 11
8 trayIcon: TrayIcon; 12 trayIcon: TrayIcon;
9 13
14 private ferdium: Ferdium | null = null;
15
16 muted = false;
17
18 unreadDirectMessageCount = 0;
19
20 unreadIndirectMessageCount = 0;
21
22 unreadServices: UnreadServices = [];
23
10 constructor(trayIcon: TrayIcon) { 24 constructor(trayIcon: TrayIcon) {
11 this.trayIcon = trayIcon; 25 this.trayIcon = trayIcon;
26 ipcMain.on('initialAppSettings', (_, appSettings) => {
27 this.updateSettings(appSettings);
28 });
29 ipcMain.on('updateAppSettings', (_, appSettings) => {
30 this.updateSettings(appSettings);
31 });
32 ipcMain.on(
33 'updateDBusUnread',
34 (
35 _,
36 unreadDirectMessageCount,
37 unreadIndirectMessageCount,
38 unreadServices,
39 ) => {
40 this.setUnread(
41 unreadDirectMessageCount,
42 unreadIndirectMessageCount,
43 unreadServices,
44 );
45 },
46 );
47 }
48
49 private updateSettings(appSettings): void {
50 const muted = !!appSettings.data.isAppMuted;
51 if (this.muted !== muted) {
52 this.muted = muted;
53 this.ferdium?.emitMutedChanged();
54 }
12 } 55 }
13 56
14 start() { 57 private setUnread(
58 unreadDirectMessageCount: number,
59 unreadIndirectMessageCount: number,
60 unreadServices: UnreadServices,
61 ): void {
62 if (
63 this.unreadDirectMessageCount !== unreadDirectMessageCount ||
64 this.unreadIndirectMessageCount !== unreadIndirectMessageCount ||
65 !comparer.structural(this.unreadServices, unreadServices)
66 ) {
67 this.unreadDirectMessageCount = unreadDirectMessageCount;
68 this.unreadIndirectMessageCount = unreadIndirectMessageCount;
69 this.unreadServices = unreadServices;
70 this.ferdium?.emitUnreadChanged();
71 }
72 }
73
74 async start() {
15 if (!isLinux || this.bus) { 75 if (!isLinux || this.bus) {
16 return; 76 return;
17 } 77 }
18 78
19 try { 79 try {
20 this.bus = sessionBus(); 80 this.bus = sessionBus();
81 await this.bus.requestName('org.ferdium.Ferdium', 0);
21 } catch { 82 } catch {
22 // Error connecting to the bus. 83 // Error connecting to the bus.
23 return; 84 return;
24 } 85 }
25 86
87 this.ferdium = new Ferdium(this);
88 this.bus.export('/org/ferdium', this.ferdium);
89
26 // HACK Hook onto the MessageBus to track StatusNotifierWatchers 90 // HACK Hook onto the MessageBus to track StatusNotifierWatchers
27 // @ts-expect-error Property '_addMatch' does not exist on type 'MessageBus'. 91 // @ts-expect-error Property '_addMatch' does not exist on type 'MessageBus'.
28 this.bus._addMatch( 92 this.bus._addMatch(
@@ -56,5 +120,6 @@ export default class DBus {
56 120
57 this.bus.disconnect(); 121 this.bus.disconnect();
58 this.bus = null; 122 this.bus = null;
123 this.ferdium = null;
59 } 124 }
60} 125}
diff --git a/src/lib/dbus/Ferdium.ts b/src/lib/dbus/Ferdium.ts
new file mode 100644
index 000000000..b2a9105f4
--- /dev/null
+++ b/src/lib/dbus/Ferdium.ts
@@ -0,0 +1,88 @@
1import * as dbus from 'dbus-next';
2
3import type DBus from '../DBus';
4
5export type UnreadServices = [string, number, number][];
6
7export default class Ferdium extends dbus.interface.Interface {
8 constructor(private readonly dbus: DBus) {
9 super('org.ferdium.Ferdium');
10 }
11
12 emitMutedChanged(): void {
13 Ferdium.emitPropertiesChanged(this, { Muted: this.dbus.muted }, []);
14 }
15
16 get Muted(): boolean {
17 return this.dbus.muted;
18 }
19
20 set Muted(muted: boolean) {
21 if (this.dbus.muted !== muted) {
22 this.ToggleMute();
23 }
24 }
25
26 ToggleMute(): void {
27 this.dbus.trayIcon.mainWindow?.webContents.send('muteApp');
28 }
29
30 ToggleWindow(): void {
31 this.dbus.trayIcon._toggleWindow();
32 }
33
34 emitUnreadChanged(): void {
35 Ferdium.emitPropertiesChanged(
36 this,
37 {
38 UnreadDirectMessageCount: this.dbus.unreadDirectMessageCount,
39 UnreadIndirectMessageCount: this.dbus.unreadIndirectMessageCount,
40 UnreadServices: this.dbus.unreadServices,
41 },
42 [],
43 );
44 }
45
46 get UnreadDirectMessageCount(): number {
47 return this.dbus.unreadDirectMessageCount;
48 }
49
50 get UnreadIndirectMessageCount(): number {
51 return this.dbus.unreadIndirectMessageCount;
52 }
53
54 get UnreadServices(): UnreadServices {
55 return this.dbus.unreadServices;
56 }
57}
58
59Ferdium.configureMembers({
60 methods: {
61 ToggleMute: {
62 inSignature: '',
63 outSignature: '',
64 },
65 ToggleWindow: {
66 inSignature: '',
67 outSignature: '',
68 },
69 },
70 properties: {
71 Muted: {
72 signature: 'b',
73 access: dbus.interface.ACCESS_READWRITE,
74 },
75 UnreadDirectMessageCount: {
76 signature: 'u',
77 access: dbus.interface.ACCESS_READ,
78 },
79 UnreadIndirectMessageCount: {
80 signature: 'u',
81 access: dbus.interface.ACCESS_READ,
82 },
83 UnreadServices: {
84 signature: 'a(suu)',
85 access: dbus.interface.ACCESS_READ,
86 },
87 },
88});
diff --git a/src/stores/ServicesStore.ts b/src/stores/ServicesStore.ts
index 0ab4dbc5b..829c64d76 100644
--- a/src/stores/ServicesStore.ts
+++ b/src/stores/ServicesStore.ts
@@ -1,4 +1,4 @@
1import { shell } from 'electron'; 1import { ipcRenderer, shell } from 'electron';
2import { action, reaction, computed, observable, makeObservable } from 'mobx'; 2import { action, reaction, computed, observable, makeObservable } from 'mobx';
3import { debounce, remove } from 'lodash'; 3import { debounce, remove } from 'lodash';
4import ms from 'ms'; 4import ms from 'ms';
@@ -23,6 +23,7 @@ import { cleanseJSObject } from '../jsUtils';
23import { SPELLCHECKER_LOCALES } from '../i18n/languages'; 23import { SPELLCHECKER_LOCALES } from '../i18n/languages';
24import { ferdiumVersion } from '../environment-remote'; 24import { ferdiumVersion } from '../environment-remote';
25import TypedStore from './lib/TypedStore'; 25import TypedStore from './lib/TypedStore';
26import type { UnreadServices } from '../lib/dbus/Ferdium';
26 27
27const debug = require('../preload-safe-debug')('Ferdium:ServiceStore'); 28const debug = require('../preload-safe-debug')('Ferdium:ServiceStore');
28 29
@@ -1230,26 +1231,29 @@ export default class ServicesStore extends TypedStore {
1230 const { showMessageBadgeWhenMuted } = this.stores.settings.all.app; 1231 const { showMessageBadgeWhenMuted } = this.stores.settings.all.app;
1231 const { showMessageBadgesEvenWhenMuted } = this.stores.ui; 1232 const { showMessageBadgesEvenWhenMuted } = this.stores.ui;
1232 1233
1233 const unreadDirectMessageCount = this.allDisplayed 1234 const unreadServices: UnreadServices = [];
1234 .filter( 1235 let unreadDirectMessageCount = 0;
1235 s => 1236 let unreadIndirectMessageCount = 0;
1236 (showMessageBadgeWhenMuted || s.isNotificationEnabled) && 1237
1237 showMessageBadgesEvenWhenMuted && 1238 if (showMessageBadgesEvenWhenMuted) {
1238 s.isBadgeEnabled, 1239 for (const s of this.allDisplayed) {
1239 ) 1240 if (s.isBadgeEnabled) {
1240 .map(s => s.unreadDirectMessageCount) 1241 const direct =
1241 .reduce((a, b) => a + b, 0); 1242 showMessageBadgeWhenMuted || s.isNotificationEnabled
1242 1243 ? s.unreadDirectMessageCount
1243 const unreadIndirectMessageCount = this.allDisplayed 1244 : 0;
1244 .filter( 1245 const indirect =
1245 s => 1246 showMessageBadgeWhenMuted && s.isIndirectMessageBadgeEnabled
1246 showMessageBadgeWhenMuted && 1247 ? s.unreadIndirectMessageCount
1247 showMessageBadgesEvenWhenMuted && 1248 : 0;
1248 s.isBadgeEnabled && 1249 unreadDirectMessageCount += direct;
1249 s.isIndirectMessageBadgeEnabled, 1250 unreadIndirectMessageCount += indirect;
1250 ) 1251 if (direct > 0 || indirect > 0) {
1251 .map(s => s.unreadIndirectMessageCount) 1252 unreadServices.push([s.name, direct, indirect]);
1252 .reduce((a, b) => a + b, 0); 1253 }
1254 }
1255 }
1256 }
1253 1257
1254 // We can't just block this earlier, otherwise the mobx reaction won't be aware of the vars to watch in some cases 1258 // We can't just block this earlier, otherwise the mobx reaction won't be aware of the vars to watch in some cases
1255 if (showMessageBadgesEvenWhenMuted) { 1259 if (showMessageBadgesEvenWhenMuted) {
@@ -1257,6 +1261,12 @@ export default class ServicesStore extends TypedStore {
1257 unreadDirectMessageCount, 1261 unreadDirectMessageCount,
1258 unreadIndirectMessageCount, 1262 unreadIndirectMessageCount,
1259 }); 1263 });
1264 ipcRenderer.send(
1265 'updateDBusUnread',
1266 unreadDirectMessageCount,
1267 unreadIndirectMessageCount,
1268 unreadServices,
1269 );
1260 } 1270 }
1261 } 1271 }
1262 1272