Test Notifications & Title Updates
All checks were successful
Build & Push Docker Image / build-and-publish (push) Successful in 56s

This commit is contained in:
2026-02-05 16:24:18 -05:00
parent 08b959d93e
commit e36e9bc4b5
3 changed files with 147 additions and 2 deletions

View File

@@ -19,6 +19,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
wget \
libnotify-bin \
notification-daemon \
dbus-x11 \
python3 \
python3-gi \
python3-xlib \
gir1.2-notify-0.7 \
xdotool \
wmctrl \
# GPU/OpenGL libraries for RuneLite GPU plugin
mesa-utils \
libgl1-mesa-dri \
@@ -33,13 +40,20 @@ RUN if [ -f /usr/share/selkies/www/index.html ]; then \
sed -i '/<\/head>/r /usr/share/selkies/www/webapp-meta.html' /usr/share/selkies/www/index.html ; \
fi
# Enable Selkies notification forwarding to browser
ENV SELKIES_ENABLE_NOTIFY="true"
ENV RUNELITE_URL="https://github.com/runelite/launcher/releases/latest/download/RuneLite.jar"
ADD runelite /usr/local/bin
COPY notification-bridge.py /usr/local/bin/notification-bridge
COPY window-title-sync.py /usr/local/bin/window-title-sync
RUN wget $RUNELITE_URL -P /usr/local/bin \
&& chmod +x /usr/local/bin/RuneLite.jar \
&& chmod +x /usr/local/bin/runelite
&& chmod +x /usr/local/bin/runelite \
&& chmod +x /usr/local/bin/notification-bridge \
&& chmod +x /usr/local/bin/window-title-sync
# Configure window manager to hide title bars and maximize windows
RUN mkdir -p /etc/xdg/openbox
@@ -49,7 +63,9 @@ COPY openbox-rc.xml /etc/xdg/openbox/rc.xml
# Use LinuxServer.io's autostart mechanism instead of custom cont-init.d
RUN mkdir -p /defaults && \
echo '/usr/local/bin/runelite' > /defaults/autostart
echo '/usr/local/bin/notification-bridge &' > /defaults/autostart && \
echo '/usr/local/bin/window-title-sync &' >> /defaults/autostart && \
echo '/usr/local/bin/runelite' >> /defaults/autostart
# Also create desktop autostart as backup
RUN mkdir -p /config/.config/autostart && \

36
notification-bridge.py Normal file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env python3
"""
D-Bus notification bridge for Selkies
Monitors desktop notifications and forwards them to the browser via Web Notifications API
"""
import gi # type: ignore
gi.require_version('Notify', '0.7') # type: ignore
from gi.repository import Notify, GLib # type: ignore
import sys
import os
def on_notification(notification):
"""Callback when a notification is received"""
# Selkies will automatically capture notifications sent via libnotify
# This script ensures the notification daemon is properly initialized
pass
def main():
# Initialize libnotify
if not Notify.init("notification-bridge"):
print("Failed to initialize libnotify", file=sys.stderr)
sys.exit(1)
print("Notification bridge started - forwarding desktop notifications to browser")
# Keep the script running to maintain D-Bus connection
try:
loop = GLib.MainLoop()
loop.run()
except KeyboardInterrupt:
print("\nNotification bridge stopped")
Notify.uninit()
if __name__ == "__main__":
main()

93
window-title-sync.py Normal file
View File

@@ -0,0 +1,93 @@
#!/usr/bin/env python3
"""
Window title synchronization for Selkies
Monitors the active window title and updates the browser tab title dynamically
Note: This script is designed to run inside a Linux container with X11 tools installed.
Pylance warnings about missing imports are expected in the development environment.
"""
import subprocess
import time
import os
import sys
def get_active_window_title():
"""Get the title of the currently active window"""
try:
# Try using xdotool first
result = subprocess.run(
['xdotool', 'getactivewindow', 'getwindowname'],
capture_output=True,
text=True,
timeout=1
)
if result.returncode == 0:
return result.stdout.strip()
except (subprocess.TimeoutExpired, FileNotFoundError):
pass
try:
# Fallback to wmctrl
result = subprocess.run(
['wmctrl', '-l'],
capture_output=True,
text=True,
timeout=1
)
if result.returncode == 0:
lines = result.stdout.strip().split('\n')
for line in lines:
if 'RuneLite' in line:
# Extract title (after the third column)
parts = line.split(None, 3)
if len(parts) >= 4:
return parts[3]
except (subprocess.TimeoutExpired, FileNotFoundError):
pass
return None
def update_browser_title(title):
"""Update the Selkies browser tab title"""
title_file = '/opt/gst-web/title'
# Create directory if it doesn't exist
os.makedirs(os.path.dirname(title_file), exist_ok=True)
try:
with open(title_file, 'w') as f:
f.write(title)
except Exception as e:
print(f"Error updating title file: {e}", file=sys.stderr)
def main():
print("Window title sync started - monitoring RuneLite window")
last_title = None
# Initial delay to let X11 and windows initialize
time.sleep(5)
while True:
try:
current_title = get_active_window_title()
# Only update if title has changed and contains "RuneLite"
if current_title and 'RuneLite' in current_title and current_title != last_title:
print(f"Window title changed to: {current_title}")
update_browser_title(current_title)
last_title = current_title
# Check every 2 seconds
time.sleep(2)
except KeyboardInterrupt:
print("\nWindow title sync stopped")
break
except Exception as e:
print(f"Error in title monitoring: {e}", file=sys.stderr)
time.sleep(5)
if __name__ == "__main__":
main()