diff --git a/briar-desktop/build.gradle.kts b/briar-desktop/build.gradle.kts index df9c9080f7cdad27b53c5f0ec13d1794f143b7fc..989a44aff2ccecab685232e1a0d8945ae904d349 100644 --- a/briar-desktop/build.gradle.kts +++ b/briar-desktop/build.gradle.kts @@ -50,6 +50,8 @@ dependencies { implementation("com.github.ajalt.clikt:clikt:3.4.0") implementation("com.ibm.icu:icu4j:70.1") implementation("net.java.dev.jna:jna:5.12.1") + implementation("net.java.dev.jna:jna-platform:5.12.1") + implementation("com.dorkbox:Utilities:1.22") implementation(project(path = ":briar-core", configuration = "default")) implementation(project(path = ":bramble-java", configuration = "default")) @@ -135,7 +137,7 @@ tasks.register<Jar>("notificationTest") { archiveFileName.set("notificationTest.jar") // Version-agnostic name of the jar duplicatesStrategy = DuplicatesStrategy.EXCLUDE manifest { - attributes("Main-Class" to "org.briarproject.briar.desktop.notification.linux.TestNativeNotificationsKt") + attributes("Main-Class" to "org.briarproject.briar.desktop.notification.windows.TestDorkBoxNotificationsKt") } // Provided we set it up in the application plugin configuration val sourcesTest = sourceSets.test.get() val contents = configurations.runtimeClasspath.get() diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/windows/DorkboxNotifications.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/windows/DorkboxNotifications.kt new file mode 100644 index 0000000000000000000000000000000000000000..1cbcadf1f32f5882a8ff28c3988bb2dd2d54344f --- /dev/null +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/windows/DorkboxNotifications.kt @@ -0,0 +1,55 @@ +/* + * Briar Desktop + * Copyright (C) 2021-2022 The Briar Project + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package org.briarproject.briar.desktop.notification.windows + +import com.sun.jna.platform.win32.User32 +import com.sun.jna.platform.win32.WinDef +import com.sun.jna.platform.win32.WinUser +import dorkbox.jna.windows.Shell32 +import dorkbox.jna.windows.structs.NOTIFYICONDATA +import java.io.File +import java.nio.file.Files +import java.nio.file.StandardCopyOption + +class DorkboxNotifications { + + fun notify(title: String, message: String) { + // Copy icon from resources to temporary file because LoadImage only works with files + val tmp = File.createTempFile("briar", ".ico") + Thread.currentThread().contextClassLoader.getResourceAsStream("images/logo_circle.ico").use { + Files.copy(it, tmp.toPath(), StandardCopyOption.REPLACE_EXISTING) + } + val image = + User32.INSTANCE.LoadImage(null, tmp.absolutePath, WinUser.IMAGE_ICON, 0, 0, WinUser.LR_LOADFROMFILE) + + val data = NOTIFYICONDATA() + val NIIF_NOSOUND = 0x10 // not in the dorkbox library yet + data.setBalloon(title, message, 10000, NOTIFYICONDATA.NIIF_NONE or NIIF_NOSOUND) + data.setIcon(WinDef.HICON(image)) + val ret = Shell32.Shell_NotifyIcon(Shell32.NIM_ADD, data) + println("return value: $ret") + } + + fun init() = uninit() + + fun uninit() { + val data = NOTIFYICONDATA() + Shell32.Shell_NotifyIcon(Shell32.NIM_DELETE, data) + } +} diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/windows/SystemTrayNotifications.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/windows/SystemTrayNotifications.kt index c8b7cc7c2d353bc6f72c9e09e5f1bebbf000b868..3ca95c7891a95efbb74ef89e75745023f944c8b9 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/windows/SystemTrayNotifications.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/windows/SystemTrayNotifications.kt @@ -64,5 +64,4 @@ class SystemTrayNotifications private constructor(image: Image?) { fun notify(title: String?, description: String?) { trayIcon.displayMessage(title, description, TrayIcon.MessageType.INFO) } - -} \ No newline at end of file +} diff --git a/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/notification/windows/TestDorkBoxNotifications.kt b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/notification/windows/TestDorkBoxNotifications.kt new file mode 100644 index 0000000000000000000000000000000000000000..ca41365974a37050c22888c5018847e03b3618b1 --- /dev/null +++ b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/notification/windows/TestDorkBoxNotifications.kt @@ -0,0 +1,34 @@ +/* + * Briar Desktop + * Copyright (C) 2021-2022 The Briar Project + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ +package org.briarproject.briar.desktop.notification.windows + +import kotlin.system.exitProcess + +/** + * Small program to test notification support for Windows. + */ +fun main() { + DorkboxNotifications().apply { + init() + notify("This is the title", "This is the description") + Thread.sleep(10000) + uninit() + + exitProcess(0) + } +}