Skip to content

Commit 12953e0

Browse files
committed
first version for notifications (closes #1470)
1 parent 5733758 commit 12953e0

File tree

13 files changed

+831
-15
lines changed

13 files changed

+831
-15
lines changed

Cargo.lock

Lines changed: 580 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ members = [
77
"rio-proc-macros",
88
"rio-backend",
99
"rio-window",
10+
"rio-notifier",
1011
"frontends/rioterm",
1112
]
1213
resolver = "2"
@@ -31,6 +32,7 @@ readme = "README.md"
3132
teletypewriter = { path = "teletypewriter", version = "0.3.0" }
3233
rio-backend = { path = "rio-backend", version = "0.3.0" }
3334
rio-window = { path = "rio-window", version = "0.3.0", default-features = false }
35+
rio-notifier = { path = "rio-notifier", version = "0.3.0" }
3436
sugarloaf = { path = "sugarloaf", version = "0.3.0" }
3537

3638
# Own dependencies

docs/docs/escape-sequence-support.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ brevity.
9898
| `OSC 2` | IMPLEMENTED | |
9999
| `OSC 4` | IMPLEMENTED | |
100100
| `OSC 8` | IMPLEMENTED | |
101+
| `OSC 9` | IMPLEMENTED | Desktop notifications and progress bar (9;4) |
101102
| `OSC 10` | IMPLEMENTED | |
102103
| `OSC 11` | IMPLEMENTED | |
103104
| `OSC 12` | IMPLEMENTED | |
@@ -107,6 +108,7 @@ brevity.
107108
| `OSC 110` | IMPLEMENTED | |
108109
| `OSC 111` | IMPLEMENTED | |
109110
| `OSC 112` | IMPLEMENTED | |
111+
| `OSC 777` | IMPLEMENTED | Desktop notifications (rxvt notify extension) |
110112

111113
### DCS (Device Control String) - `ESC P`
112114

docs/src/pages/changelog.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ language: 'en'
2929
- **Toggle Appearance Theme**: Switch between dark and light themes at runtime via key binding (`ToggleAppearanceTheme`) or command palette (only available when adaptive theme is configured)
3030
- **Custom Mouse Cursor**: Configurable mouse cursor effects via `effects.custom-mouse-cursor`
3131
- **Trail Cursor**: Smooth spring-animated cursor trail using neovide-style physics (enabled by default via `effects.trail-cursor`)
32+
- **Desktop Notifications**: Support for OSC 9 (iTerm2) and OSC 777 (rxvt) terminal notifications using native platform APIs (macOS `UNUserNotificationCenter`, Linux D-Bus, Windows Toast)
3233
- **Force Theme**: New `force-theme` configuration property to override the system theme when using adaptive themes
3334
- **Quake Window Mode**: Drop-down terminal from top of screen
3435
- **macOS Traffic Light Positioning**: Customize position of window control buttons

frontends/rioterm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ url = { workspace = true }
4848
smallvec = { workspace = true }
4949
rio-window = { workspace = true }
5050
lru = "0.16.0"
51+
rio-notifier = { workspace = true }
5152

5253
[target.'cfg(all(not(target_os = "macos"), not(target_os = "windows")))'.dependencies]
5354
cpal = { version = "0.15", optional = true }

frontends/rioterm/src/application.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ impl Application<'_> {
138138
}
139139
}
140140

141+
fn handle_desktop_notification(&self, title: &str, body: &str) {
142+
rio_notifier::send_notification(title, body);
143+
}
144+
141145
pub fn run(
142146
&mut self,
143147
event_loop: EventLoop<EventPayload>,
@@ -524,6 +528,9 @@ impl ApplicationHandler<EventPayload> for Application<'_> {
524528
self.handle_audio_bell();
525529
}
526530
}
531+
RioEventType::Rio(RioEvent::DesktopNotification { title, body }) => {
532+
self.handle_desktop_notification(&title, &body);
533+
}
527534
RioEventType::Rio(RioEvent::PrepareRender(millis)) => {
528535
if let Some(route) = self.router.routes.get(&window_id) {
529536
let timer_id = TimerId::new(

misc/osx/Rio.app/Contents/Info.plist

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,51 @@
165165
<string>A program running inside Rio requires elevated privileges.</string>
166166
<key>TICapsLockLanguageSwitchCapable</key>
167167
<true/>
168+
<key>NSHighResolutionCapable</key>
169+
<true/>
170+
<key>MDItemKeywords</key>
171+
<string>Terminal</string>
172+
<key>NSServices</key>
173+
<array>
174+
<dict>
175+
<key>NSMenuItem</key>
176+
<dict>
177+
<key>default</key>
178+
<string>New Rio Tab Here</string>
179+
</dict>
180+
<key>NSMessage</key>
181+
<string>openTab</string>
182+
<key>NSRequiredContext</key>
183+
<dict>
184+
<key>NSTextContent</key>
185+
<string>FilePath</string>
186+
</dict>
187+
<key>NSSendTypes</key>
188+
<array>
189+
<string>NSFilenamesPboardType</string>
190+
<string>public.plain-text</string>
191+
</array>
192+
</dict>
193+
<dict>
194+
<key>NSMenuItem</key>
195+
<dict>
196+
<key>default</key>
197+
<string>New Rio Window Here</string>
198+
</dict>
199+
<key>NSMessage</key>
200+
<string>openWindow</string>
201+
<key>NSRequiredContext</key>
202+
<dict>
203+
<key>NSTextContent</key>
204+
<string>FilePath</string>
205+
</dict>
206+
<key>NSSendTypes</key>
207+
<array>
208+
<string>NSFilenamesPboardType</string>
209+
<string>public.plain-text</string>
210+
</array>
211+
</dict>
212+
</array>
168213
<key>com.apple.security.automation.apple-events</key>
169214
<true/>
170215
</dict>

rio-backend/src/config/effects.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,9 @@
11
use serde::{Deserialize, Serialize};
22

3-
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
3+
#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)]
44
pub struct Effects {
55
#[serde(default = "bool::default", rename = "custom-mouse-cursor")]
66
pub custom_mouse_cursor: bool,
77
#[serde(default = "bool::default", rename = "trail-cursor")]
88
pub trail_cursor: bool,
99
}
10-
11-
impl Default for Effects {
12-
fn default() -> Effects {
13-
Effects {
14-
custom_mouse_cursor: false,
15-
trail_cursor: false,
16-
}
17-
}
18-
}

rio-backend/src/crosswords/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2580,6 +2580,14 @@ impl<U: EventListener> Handler for Crosswords<U> {
25802580
self.event_proxy.send_event(RioEvent::Bell, self.window_id);
25812581
}
25822582

2583+
#[inline]
2584+
fn desktop_notification(&mut self, title: String, body: String) {
2585+
self.event_proxy.send_event(
2586+
RioEvent::DesktopNotification { title, body },
2587+
self.window_id,
2588+
);
2589+
}
2590+
25832591
#[inline]
25842592
fn substitute(&mut self) {
25852593
warn!("[unimplemented] Substitute");

rio-backend/src/event/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,12 @@ pub enum RioEvent {
144144
/// Terminal bell ring.
145145
Bell,
146146

147+
/// Desktop notification from OSC 9 or OSC 777.
148+
DesktopNotification {
149+
title: String,
150+
body: String,
151+
},
152+
147153
/// Shutdown request.
148154
Exit,
149155

@@ -209,6 +215,9 @@ impl Debug for RioEvent {
209215
}
210216
RioEvent::Scroll(scroll) => write!(f, "Scroll {scroll:?}"),
211217
RioEvent::Bell => write!(f, "Bell"),
218+
RioEvent::DesktopNotification { title, body } => {
219+
write!(f, "DesktopNotification({title}, {body})")
220+
}
212221
RioEvent::Exit => write!(f, "Exit"),
213222
RioEvent::Quit => write!(f, "Quit"),
214223
RioEvent::CloseTerminal(route) => write!(f, "CloseTerminal {route}"),

0 commit comments

Comments
 (0)