Skip to content

Repository files navigation

Rustino

Cross-platform native desktop windows with embedded web views, powered by Rust.

Inspired by Photino.NET.

Rustino replaces Photino's C++ native layer with Rust, using wry for the webview and tao for window management — the same libraries that power Tauri.

Architecture

Your .NET App
└── RustinoWindow (C#) ← Rustino.NET
└── P/Invoke
└── rustino_native ← Rustino.Native (Rust cdylib)
├── wry → WebView2 (Windows)
├── wry → WKWebView (macOS)
└── wry → WebKitGTK (Linux)

Quick Start

usingRustino.NET;varwindow=newRustinoWindow();window.SetTitle("My App").SetUseOsDefaultSize(false).SetSize(1280,800).SetResizable(true).Center().Load(newUri("https://example.com"));window.WaitForClose();

Migrating from Photino

The API is identical. Change two things:

- using Photino.NET;+ using Rustino.NET;- var window = new PhotinoWindow();+ var window = new RustinoWindow();

All .Set*(), .Center(), .Load(), and .WaitForClose() calls remain the same.

API Reference

Configuration (pre-run)

MethodDescription
SetTitle(string)Set the window title
SetSize(int, int)Set window dimensions in pixels
SetMinSize(int, int)Set minimum window size
SetMaxSize(int, int)Set maximum window size
SetPosition(int, int)Set window position
SetUseOsDefaultSize(bool)Use OS default window size
SetResizable(bool)Allow/prevent window resizing
SetTopMost(bool)Keep window above all others
SetChromeless(bool)Remove window decorations (title bar, borders)
SetTransparent(bool)Enable transparent background
SetMaximized(bool)Start maximized
SetBackgroundColor(r, g, b, a)Set webview background color
SetIconFile(string)Set window icon from .ico/.png file path
SetIcon(Stream)Set window icon from a .NET stream (e.g. embedded resource)
Center()Center window on the primary monitor
SetDevToolsEnabled(bool)Enable browser developer tools
SetJavascriptClipboardAccessEnabled(bool)Allow JS clipboard access
SetIgnoreCertificateErrorsEnabled(bool)Ignore SSL certificate errors
SetWebSecurityEnabled(bool)Enable/disable web security (CORS, etc.)
SetMediaAutoplayEnabled(bool)Allow media to autoplay
SetZoomHotkeysEnabled(bool)Enable Ctrl+/- zoom hotkeys
SetUserAgent(string)Set custom user agent string
SetUserDataFolder(string)Set webview data folder path
AddInitScript(string)Add JavaScript to run before page loads
Load(Uri) / Load(string)Navigate to a URL or local file
LogVerbositySet log verbosity (0 = silent)

Runtime (post-run)

MethodDescription
Minimize()Minimize the window
Maximize()Maximize the window
Restore()Restore from minimized/maximized
SetFullscreen(bool)Enter/exit fullscreen
SetVisible(bool)Show/hide the window
Focus()Bring focus to the window
Close()Close the window
ExecuteScript(string)Evaluate JavaScript in the webview
SendWebMessage(string)Post a message to the webview
SetZoom(double)Set webview zoom factor
SetBadgeCount(int?, string?, string?)Set taskbar/dock badge with optional bg/fg hex colors
ClearBadge()Remove the taskbar/dock badge
WaitForClose()Block until the window is closed
Dispose()Release native resources (RustinoWindow implements IDisposable)

Dialogs

Native cross-platform file dialogs (powered by rfd):

// Open file (single)string[]?files=window.ShowOpenFileDialog(title:"Select an image",filters:[newFileFilter("Images","jpg","png","gif")]);// Open files (multi-select)string[]?files=window.ShowOpenFileDialog(title:"Select files",multiSelect:true);// Save filestring?path=window.ShowSaveFileDialog(title:"Save as",defaultPath:"document.pdf",filters:[newFileFilter("PDF","pdf")]);// Select folderstring[]?folders=window.ShowSelectFolderDialog(title:"Choose output directory");

All dialogs return null when canceled. File filters use the format new FileFilter("Name", "ext1", "ext2", ...).

Notifications

Native cross-platform toast notifications (powered by notify-rust):

// Static — no window instance requiredRustinoWindow.ShowNotification("Download Complete","Your file has been saved.");// With icon (file path)RustinoWindow.ShowNotification("Alert","Something happened",iconPath:"/path/to/icon.png");// With icon (embedded resource stream)usingvarstream=Assembly.GetExecutingAssembly().GetManifestResourceStream("MyApp.notify.png")!;RustinoWindow.ShowNotification("Alert","Something happened",stream);

Uses WinRT Toast (Windows), NSUserNotification (macOS), and D-Bus (Linux).

Menus

Native cross-platform application menus and context menus (powered by muda):

// Application menu barvarmenu=newRustinoMenu().AddSubmenu("File", file =>file.AddItem("new","New",accelerator:"CmdOrCtrl+N").AddItem("open","Open...",accelerator:"CmdOrCtrl+O").AddSeparator().AddItem("exit","Exit")).AddSubmenu("Edit", edit =>edit.AddItem("undo","Undo",accelerator:"CmdOrCtrl+Z").AddItem("redo","Redo",accelerator:"CmdOrCtrl+Y").AddSeparator().AddCheckItem("wordwrap","Word Wrap",isChecked:true)).AddSubmenu("Help", help =>help.AddItem("about","About"));window.SetMenu(menu);// Context menu (right-click)varctx=newRustinoMenu().AddItem("cut","Cut").AddItem("copy","Copy").AddItem("paste","Paste");window.ShowContextMenu(ctx);// Handle clickswindow.MenuItemClicked+=(_,id)=>Console.WriteLine($"Clicked: {id}");// Remove menu barwindow.RemoveMenu();

System Tray

Native cross-platform system tray icon with optional context menu (powered by tray-icon):

// Tray icon with tooltip and context menuvartrayMenu=newRustinoMenu().AddItem("show","Show Window").AddItem("hide","Hide Window").AddSeparator().AddItem("quit","Quit");window.SetTrayIcon("icon.png",tooltip:"My App",menu:trayMenu);// From embedded resource (Stream)usingvarstream=Assembly.GetExecutingAssembly().GetManifestResourceStream("MyApp.tray.png")!;window.SetTrayIcon(stream,tooltip:"My App",menu:trayMenu);// Handle tray icon clickswindow.TrayIconClicked+=(_,_)=>window.SetVisible(true);// Remove tray iconwindow.RemoveTrayIcon();

Taskbar Badge

Set a numeric badge on the taskbar icon (Windows) or dock icon (macOS):

// Set badge with default colors (red background, white text)window.SetBadgeCount(5);// Set badge with custom colors (Windows only, hex format)window.SetBadgeCount(5,background:"#4A154B",foreground:"#FFFFFF");// Clear the badgewindow.ClearBadge();

On Windows, this renders an overlay icon on the taskbar button using a 32px anti-aliased circle with bold Segoe UI text. Numbers above 99 display as "99+". The background and foreground parameters accept #RRGGBB hex strings and default to #E01E5A (red) and #FFFFFF (white).

On macOS, the native dockTile.setBadgeLabel API is used — color parameters are ignored as the OS controls badge appearance.

Monitors

Enumerate connected displays with position, resolution, and DPI scale factor:

// Get all monitorsMonitorInfo[]monitors=window.GetMonitors();foreach(varminmonitors)Console.WriteLine($"{m.Name}: {m.Width}x{m.Height} at ({m.X},{m.Y}), scale={m.ScaleFactor}, primary={m.IsPrimary}");// Get the monitor containing this windowMonitorInfo?current=window.GetCurrentMonitor();// DPI-aware positioning: center window on a specific monitorvartarget=monitors.First(m =>!m.IsPrimary);var(w,h)=window.GetSize();window.SetPosition(target.X+(target.Width-w)/2,target.Y+(target.Height-h)/2);

MonitorInfo properties: Name, X, Y, Width, Height, ScaleFactor, IsPrimary.

State Queries

PropertyDescription
IsMinimizedWhether the window is minimized
IsMaximizedWhether the window is maximized
IsFullscreenWhether the window is in fullscreen
GetPosition()Returns (X, Y) position
GetSize()Returns (Width, Height) size
GetMonitors()Returns all connected MonitorInfo[]
GetCurrentMonitor()Returns MonitorInfo? for the monitor containing the window

Events

EventArgsDescription
WindowClosingCancelEventArgsFired before close (set Cancel = true to prevent)
WindowClosedEventArgsFired after the window is destroyed
SizeChangedSizeEventArgsFired on resize (.Width, .Height)
LocationChangedPointEventArgsFired on move (.X, .Y)
FocusChangedboolFired on focus/blur
WebMessageReceivedstringFired when JS calls window.ipc.postMessage(msg)
PageLoadedPageLoadEventArgsFired on page load start/finish (.IsStarted, .Url)
NavigatingNavigationEventArgsFired before navigation (.Url, set Cancel = true to block)
MenuItemClickedstringFired when a menu item is clicked (the item's ID)
TrayIconClickedEventArgsFired when the system tray icon is clicked

Observable Streams (IObservable<T>)

All events are also available as IObservable<T> properties for reactive programming (no System.Reactive dependency required):

PropertyTypeDescription
WhenSizeChangedIObservable<(int Width, int Height)>Size change stream
WhenLocationChangedIObservable<(int X, int Y)>Position change stream
WhenFocusChangedIObservable<bool>Focus/blur stream
WhenWebMessageReceivedIObservable<string>JS message stream
WhenPageLoadedIObservable<PageLoadEventArgs>Page load stream
WhenNavigatingIObservable<NavigationEventArgs>Navigation stream
WhenWindowClosedIObservable<EventArgs>Window closed stream
WhenMenuItemClickedIObservable<string>Menu item click stream
WhenTrayIconClickedIObservable<EventArgs>Tray icon click stream

All streams complete automatically when the window closes or is disposed.

Rustino.NET.Reactive (companion package)

For System.Reactive operators, add the Rustino.NET.Reactive package:

usingSystem.Reactive.Linq;usingRustino.NET.Reactive;// Throttled resizewindow.WhenSizeChangedThrottled(TimeSpan.FromMilliseconds(200)).Subscribe(size =>Console.WriteLine($"{size.Width}x{size.Height}"));// Message routing by prefixwindow.WhenWebMessageWithPrefix("cmd:").Subscribe(cmd =>HandleCommand(cmd));// Page load completion onlywindow.WhenPageLoadCompleted().Subscribe(e =>Console.WriteLine($"Loaded: {e.Url}"));// Throttled move eventswindow.WhenLocationChangedThrottled(TimeSpan.FromMilliseconds(100)).Subscribe(pos =>Console.WriteLine($"Moved to {pos.X},{pos.Y}"));// Distinct focus changeswindow.WhenFocusChangedDistinct().Subscribe(focused =>Console.WriteLine($"Focus: {focused}"));

Building from Source

Prerequisites

  • Rust toolchain (1.80+)
  • .NET SDK (10.0+)
  • Windows: WebView2 runtime (pre-installed on Windows 10/11)
  • macOS: Xcode Command Line Tools
  • Linux: libgtk-3-dev libwebkit2gtk-4.1-dev

Build

# Build the Rust native librarycd src/Rustino.Native
cargo build --release
# Build the .NET wrappercd ../Rustino.NET
dotnet build
# Run a samplecd ../Rustino.Samples/Rustino.Samples.HelloWorld
dotnet run

Cross-Platform Support

PlatformWebView EngineNative Library
Windows x64/ARM64WebView2 (Chromium)rustino_native.dll
macOS x64/ARM64WKWebView (WebKit)librustino_native.dylib
Linux x64/ARM64WebKitGTKlibrustino_native.so

License

MIT — see LICENSE.

Inspired by and API-compatible with Photino, originally created by TryPhotino (Apache-2.0).

About

Cross-platform native desktop windows with embedded web views, powered by Rust. Drop-in replacement for Photino.NET.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages