libnotify

This commit is contained in:
MeexReay 2025-04-21 00:49:06 +03:00
parent 88b66af84e
commit cdbe45254d
5 changed files with 286 additions and 111 deletions

196
Cargo.lock generated
View File

@ -94,9 +94,11 @@ version = "0.1.4+2.0"
dependencies = [
"chrono",
"clap",
"gdk-pixbuf 0.3.0",
"gtk4",
"homedir",
"lazy_static",
"libnotify",
"native-tls",
"rand",
"regex",
@ -106,6 +108,12 @@ dependencies = [
"socks",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.9.0"
@ -130,9 +138,9 @@ version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae50b5510d86cf96ac2370e66d8dc960882f3df179d6a5a1e52bd94a1416c0f7"
dependencies = [
"bitflags",
"bitflags 2.9.0",
"cairo-sys-rs",
"glib",
"glib 0.20.9",
"libc",
]
@ -142,7 +150,7 @@ version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f18b6bb8e43c7eb0f2aac7976afe0c61b6f5fc2ab7bc4c139537ea56c92290df"
dependencies = [
"glib-sys",
"glib-sys 0.20.9",
"libc",
"system-deps",
]
@ -405,27 +413,54 @@ dependencies = [
"slab",
]
[[package]]
name = "gdk-pixbuf"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16160d212ae91abe9f3324c3fb233929ba322dde63585d15cda3336f8c529ed1"
dependencies = [
"gdk-pixbuf-sys 0.5.0",
"glib 0.4.1",
"glib-sys 0.5.0",
"gobject-sys 0.5.0",
"libc",
]
[[package]]
name = "gdk-pixbuf"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7563afd6ff0a221edfbb70a78add5075b8d9cb48e637a40a24c3ece3fea414d0"
dependencies = [
"gdk-pixbuf-sys",
"gdk-pixbuf-sys 0.20.7",
"gio",
"glib",
"glib 0.20.9",
"libc",
]
[[package]]
name = "gdk-pixbuf-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "798f97101eea8180da363d0e80e07ec7ec6d1809306601c0100c1de5bc8b4f52"
dependencies = [
"bitflags 1.3.2",
"gio-sys 0.5.0",
"glib-sys 0.5.0",
"gobject-sys 0.5.0",
"libc",
"pkg-config",
]
[[package]]
name = "gdk-pixbuf-sys"
version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67f2587c9202bf997476bbba6aaed4f78a11538a2567df002a5f57f5331d0b5c"
dependencies = [
"gio-sys",
"glib-sys",
"gobject-sys",
"gio-sys 0.20.9",
"glib-sys 0.20.9",
"gobject-sys 0.20.9",
"libc",
"system-deps",
]
@ -437,10 +472,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4850c9d9c1aecd1a3eb14fadc1cdb0ac0a2298037e116264c7473e1740a32d60"
dependencies = [
"cairo-rs",
"gdk-pixbuf",
"gdk-pixbuf 0.20.9",
"gdk4-sys",
"gio",
"glib",
"glib 0.20.9",
"libc",
"pango",
]
@ -452,10 +487,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f6eb95798e2b46f279cf59005daf297d5b69555428f185650d71974a910473a"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"gdk-pixbuf-sys 0.20.7",
"gio-sys 0.20.9",
"glib-sys 0.20.9",
"gobject-sys 0.20.9",
"libc",
"pango-sys",
"pkg-config",
@ -484,42 +519,68 @@ dependencies = [
"futures-core",
"futures-io",
"futures-util",
"gio-sys",
"glib",
"gio-sys 0.20.9",
"glib 0.20.9",
"libc",
"pin-project-lite",
"smallvec",
]
[[package]]
name = "gio-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a303bbf7a5e75ab3b627117ff10e495d1b9e97e1d68966285ac2b1f6270091bc"
dependencies = [
"bitflags 1.3.2",
"glib-sys 0.5.0",
"gobject-sys 0.5.0",
"libc",
"pkg-config",
]
[[package]]
name = "gio-sys"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "160eb5250a26998c3e1b54e6a3d4ea15c6c7762a6062a19a7b63eff6e2b33f9e"
dependencies = [
"glib-sys",
"gobject-sys",
"glib-sys 0.20.9",
"gobject-sys 0.20.9",
"libc",
"system-deps",
"windows-sys",
]
[[package]]
name = "glib"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9b0452824cc63066940f01adc721804919f0b76cdba3cfab977b00b87f16d4a"
dependencies = [
"bitflags 1.3.2",
"glib-sys 0.5.0",
"gobject-sys 0.5.0",
"lazy_static",
"libc",
]
[[package]]
name = "glib"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707b819af8059ee5395a2de9f2317d87a53dbad8846a2f089f0bb44703f37686"
dependencies = [
"bitflags",
"bitflags 2.9.0",
"futures-channel",
"futures-core",
"futures-executor",
"futures-task",
"futures-util",
"gio-sys",
"gio-sys 0.20.9",
"glib-macros",
"glib-sys",
"gobject-sys",
"glib-sys 0.20.9",
"gobject-sys 0.20.9",
"libc",
"memchr",
"smallvec",
@ -538,6 +599,17 @@ dependencies = [
"syn",
]
[[package]]
name = "glib-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9693049613ff52b93013cc3d2590366d8e530366d288438724b73f6c7dc4be8"
dependencies = [
"bitflags 1.3.2",
"libc",
"pkg-config",
]
[[package]]
name = "glib-sys"
version = "0.20.9"
@ -548,13 +620,25 @@ dependencies = [
"system-deps",
]
[[package]]
name = "gobject-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60d507c87a71b1143c66ed21a969be9b99a76df234b342d733e787e6c9c7d7c2"
dependencies = [
"bitflags 1.3.2",
"glib-sys 0.5.0",
"libc",
"pkg-config",
]
[[package]]
name = "gobject-sys"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c773a3cb38a419ad9c26c81d177d96b4b08980e8bdbbf32dace883e96e96e7e3"
dependencies = [
"glib-sys",
"glib-sys 0.20.9",
"libc",
"system-deps",
]
@ -565,7 +649,7 @@ version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cbc5911bfb32d68dcfa92c9510c462696c2f715548fcd7f3f1be424c739de19"
dependencies = [
"glib",
"glib 0.20.9",
"graphene-sys",
"libc",
]
@ -576,7 +660,7 @@ version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11a68d39515bf340e879b72cecd4a25c1332557757ada6e8aba8654b4b81d23a"
dependencies = [
"glib-sys",
"glib-sys 0.20.9",
"libc",
"pkg-config",
"system-deps",
@ -590,7 +674,7 @@ checksum = "61f5e72f931c8c9f65fbfc89fe0ddc7746f147f822f127a53a9854666ac1f855"
dependencies = [
"cairo-rs",
"gdk4",
"glib",
"glib 0.20.9",
"graphene-rs",
"gsk4-sys",
"libc",
@ -605,8 +689,8 @@ checksum = "755059de55fa6f85a46bde8caf03e2184c96bfda1f6206163c72fb0ea12436dc"
dependencies = [
"cairo-sys-rs",
"gdk4-sys",
"glib-sys",
"gobject-sys",
"glib-sys 0.20.9",
"gobject-sys 0.20.9",
"graphene-sys",
"libc",
"pango-sys",
@ -622,10 +706,10 @@ dependencies = [
"cairo-rs",
"field-offset",
"futures-channel",
"gdk-pixbuf",
"gdk-pixbuf 0.20.9",
"gdk4",
"gio",
"glib",
"glib 0.20.9",
"graphene-rs",
"gsk4",
"gtk4-macros",
@ -653,11 +737,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41e03b01e54d77c310e1d98647d73f996d04b2f29b9121fe493ea525a7ec03d6"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gdk-pixbuf-sys 0.20.7",
"gdk4-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"gio-sys 0.20.9",
"glib-sys 0.20.9",
"gobject-sys 0.20.9",
"graphene-sys",
"gsk4-sys",
"libc",
@ -763,6 +847,34 @@ version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "libnotify"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10506a4f8bc6f8f7ccc6fde3a8290378d7aed3d1a26dca606a73e2ffe140cc2d"
dependencies = [
"gdk-pixbuf 0.3.0",
"gdk-pixbuf-sys 0.5.0",
"glib 0.4.1",
"glib-sys 0.5.0",
"gobject-sys 0.5.0",
"libnotify-sys",
]
[[package]]
name = "libnotify-sys"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0a716b9b7d24ed10f1eb431e1527fa13c9a4bf2d4fa68bb3e54da1d0747383c"
dependencies = [
"bitflags 1.3.2",
"gdk-pixbuf-sys 0.5.0",
"glib-sys 0.5.0",
"gobject-sys 0.5.0",
"libc",
"pkg-config",
]
[[package]]
name = "libyml"
version = "0.0.5"
@ -823,7 +935,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags",
"bitflags 2.9.0",
"cfg-if",
"cfg_aliases",
"libc",
@ -850,7 +962,7 @@ version = "0.10.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6"
dependencies = [
"bitflags",
"bitflags 2.9.0",
"cfg-if",
"foreign-types",
"libc",
@ -895,7 +1007,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b1f5dc1b8cf9bc08bfc0843a04ee0fa2e78f1e1fa4b126844a383af4f25f0ec"
dependencies = [
"gio",
"glib",
"glib 0.20.9",
"libc",
"pango-sys",
]
@ -906,8 +1018,8 @@ version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dbb9b751673bd8fe49eb78620547973a1e719ed431372122b20abd12445bab5"
dependencies = [
"glib-sys",
"gobject-sys",
"glib-sys 0.20.9",
"gobject-sys 0.20.9",
"libc",
"system-deps",
]
@ -1040,7 +1152,7 @@ version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags",
"bitflags 2.9.0",
"errno",
"libc",
"linux-raw-sys",
@ -1074,7 +1186,7 @@ version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags",
"bitflags 2.9.0",
"core-foundation",
"core-foundation-sys",
"libc",
@ -1541,7 +1653,7 @@ version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
dependencies = [
"bitflags",
"bitflags 2.9.0",
]
[[package]]

View File

@ -15,4 +15,10 @@ serde = { version = "1.0.219", features = ["serde_derive"] }
gtk4 = { version = "0.9.6", features = [ "v4_10" ] }
chrono = "0.4.40"
serde_default = "0.2.0"
socks = "0.3.4"
socks = "0.3.4"
libnotify = { version = "1.0.3", optional = true }
gdk-pixbuf = "0.3.0"
[features]
default = ["libnotify"]
libnotify = ["dep:libnotify"]

33
flake.lock generated
View File

@ -18,6 +18,23 @@
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"id": "flake-utils",
"type": "indirect"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1744463964,
@ -68,6 +85,7 @@
"root": {
"inputs": {
"flake-parts": "flake-parts",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
@ -89,6 +107,21 @@
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

View File

@ -7,53 +7,37 @@
rust-overlay.url = "github:oxalica/rust-overlay";
};
outputs = inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "x86_64-linux" ];
perSystem = { config, self', pkgs, lib, system, ... }:
let
devDeps = with pkgs; [ pkg-config openssl gtk4 pango ];
cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml);
msrv = cargoToml.package.rust-version;
mkDevShell = rustc:
pkgs.mkShell {
shellHook = ''
export RUST_SRC_PATH=${pkgs.rustPlatform.rustLibSrc}
'';
buildInputs = devDeps;
nativeBuildInputs = devDeps ++ [ rustc ];
};
in {
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
overlays = [ (import inputs.rust-overlay) ];
};
devShells.default = self'.devShells.stable;
packages.default = let
deps = with pkgs; [
pkg-config
openssl
gtk4
pango
];
in (pkgs.makeRustPlatform {
cargo = pkgs.rust-bin.stable.latest.minimal;
rustc = pkgs.rust-bin.stable.latest.minimal;
}).buildRustPackage {
inherit (cargoToml.package) name version;
src = ./.;
cargoLock.lockFile = ./Cargo.lock;
buildInputs = deps;
nativeBuildInputs = deps;
};
devShells.nightly = (mkDevShell (pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default)));
devShells.stable = (mkDevShell pkgs.rust-bin.stable.latest.default);
devShells.msrv = (mkDevShell pkgs.rust-bin.stable.${msrv}.default);
outputs = { self, nixpkgs, rust-overlay, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
devDeps = with pkgs; [ pkg-config openssl gtk4 pango libnotify ];
cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml);
overlays = [ (import rust-overlay) ];
pkgs = import nixpkgs {
inherit system overlays;
};
};
mkDevShell = rustc:
pkgs.mkShell {
shellHook = ''
export RUST_SRC_PATH=${pkgs.rustPlatform.rustLibSrc}
'';
buildInputs = devDeps;
nativeBuildInputs = devDeps ++ [ rustc ];
};
in {
devShells.nightly = (mkDevShell (pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default)));
devShells.default = (mkDevShell pkgs.rust-bin.stable.latest.default);
packages.default = (pkgs.makeRustPlatform {
cargo = pkgs.rust-bin.stable.latest.minimal;
rustc = pkgs.rust-bin.stable.latest.minimal;
}).buildRustPackage {
inherit (cargoToml.package) name version;
src = ./.;
cargoLock.lockFile = ./Cargo.lock;
buildInputs = devDeps;
nativeBuildInputs = devDeps ++ [ pkgs.rustc ];
};
}
);
}

View File

@ -1,22 +1,23 @@
use std::sync::{mpsc::{channel, Receiver}, Arc};
use std::{sync::{mpsc::{channel, Receiver}, Arc}, time::UNIX_EPOCH};
use std::cell::RefCell;
use std::time::{Duration, SystemTime};
use std::thread;
use chrono::Local;
use gtk4::{self as gtk, gio::Notification, glib::timeout_add_once};
use gtk4 as gtk;
use gtk::gdk_pixbuf::{Pixbuf, PixbufAnimation, PixbufLoader};
use gtk::prelude::*;
use gtk::gdk::{Cursor, Display, Texture};
use gtk::gdk_pixbuf::{Pixbuf, PixbufAnimation, PixbufLoader};
use gtk::gio::{self, ActionEntry, ApplicationFlags, MemoryInputStream, Menu};
use gtk::glib::clone;
use gtk::glib::{
self, clone::Downgrade,
timeout_add_local,
source::timeout_add_local_once,
ControlFlow
ControlFlow,
timeout_add_once
};
use gtk::pango::WrapMode;
use gtk::{
@ -31,7 +32,8 @@ ctx::Context, on_send_message, parse_message, print_message, recv_tick, sanitize
struct UiModel {
chat_box: GtkBox,
chat_scrolled: ScrolledWindow,
app: Application
app: Application,
window: ApplicationWindow
}
thread_local!(
@ -53,6 +55,13 @@ fn load_pixbuf(data: &[u8]) -> Pixbuf {
loader.pixbuf().unwrap()
}
fn load_gdk_pixbuf(data: &[u8]) -> gdk_pixbuf::Pixbuf {
let loader = gdk_pixbuf::PixbufLoader::new();
loader.loader_write(data).unwrap();
loader.close().unwrap();
loader.get_pixbuf().unwrap()
}
macro_rules! gui_entry_setting {
($e:expr, $i:ident, $ctx:ident, $vbox:ident) => {
{
@ -585,7 +594,8 @@ fn build_ui(ctx: Arc<Context>, app: &Application) -> UiModel {
UiModel {
chat_scrolled,
chat_box,
app: app.clone()
app: app.clone(),
window: window.clone()
}
}
@ -653,9 +663,26 @@ fn load_css() {
);
}
fn on_add_message(ctx: Arc<Context>, ui: &UiModel, message: String) {
let app = ui.app.clone();
#[cfg(feature = "libnotify")]
fn send_notification(_: Arc<Context>, _: &UiModel, title: &str, message: &str) {
use libnotify::Notification;
let notification = Notification::new(title, message, None);
notification.set_app_name("bRAC");
notification.set_image_from_pixbuf(&load_gdk_pixbuf(include_bytes!("images/icon.png")));
notification.show().expect("libnotify send error");
}
#[cfg(not(feature = "libnotify"))]
fn send_notification(ctx: Arc<Context>, ui: &UiModel, title: &str, message: &str) {
use gtk4::gio::Notification;
let notif = Notification::new(title);
notif.set_body(Some(&message));
ui.app.send_notification(None, &notif);
}
fn on_add_message(ctx: Arc<Context>, ui: &UiModel, message: String) {
let Some(message) = sanitize_message(message) else { return; };
if message.is_empty() {
@ -701,19 +728,21 @@ fn on_add_message(ctx: Arc<Context>, ui: &UiModel, message: String) {
hbox.append(&name_label);
if !app.windows()[0].is_active() {
if !ui.window.is_active() {
if ctx.config(|o| o.chunked_enabled) {
let notif = Notification::new(&format!("{}'s Message", &name));
notif.set_body(Some(&content));
app.send_notification(Some("user-message"), &notif);
send_notification(ctx.clone(), ui, &format!("{}'s Message", &name), &content);
// let notif = Notification::new(&format!("{}'s Message", &name));
// notif.set_body(Some(&content));
// app.send_notification(Some("user-message"), &notif);
}
}
} else {
if !app.windows()[0].is_active() {
if !ui.window.is_active() {
if ctx.config(|o| o.chunked_enabled) {
let notif = Notification::new("System Message");
notif.set_body(Some(&content));
app.send_notification(Some("system-message"), &notif);
send_notification(ctx.clone(), ui, "System Message", &content);
// let notif = Notification::new("System Message");
// notif.set_body(Some(&content));
// app.send_notification(Some("system-message"), &notif);
}
}
}
@ -743,11 +772,12 @@ fn on_add_message(ctx: Arc<Context>, ui: &UiModel, message: String) {
hbox.append(&content_label);
if !app.windows()[0].is_active() {
if !ui.window.is_active() {
if ctx.config(|o| o.chunked_enabled) {
let notif = Notification::new("Chat Message");
notif.set_body(Some(&message));
app.send_notification(Some("chat-message"), &notif);
send_notification(ctx.clone(), ui, "Chat Message", &message);
// let notif = Notification::new("Chat Message");
// notif.set_body(Some(&message));
// app.send_notification(Some("chat-message"), &notif);
}
}
}
@ -776,6 +806,11 @@ fn run_recv_loop(ctx: Arc<Context>) {
}
pub fn run_main_loop(ctx: Arc<Context>) {
#[cfg(feature = "libnotify")]
{
libnotify::init("ru.themixray.bRAC").expect("libnotify init error");
}
let application = Application::builder()
.application_id("ru.themixray.bRAC")
.flags(ApplicationFlags::FLAGS_NONE)
@ -800,4 +835,9 @@ pub fn run_main_loop(ctx: Arc<Context>) {
});
application.run_with_args::<&str>(&[]);
#[cfg(feature = "libnotify")]
{
libnotify::uninit();
}
}