mattercontrol/research/linux-migration.md

190 lines
5.1 KiB
Markdown
Raw Permalink Normal View History

2026-01-28 14:06:53 -08:00
# MatterControl Linux Migration Notes
## Current State
The project is a C# .NET 6.0 desktop application for 3D printing control. It currently targets Windows but has cross-platform foundations.
## Build Errors on Linux
```
error NETSDK1100: To build a project targeting Windows on this operating system, set the EnableWindowsTargeting property to true.
```
Affected projects:
- `MatterControl.Winforms/MatterControl.Winforms.csproj`
- `Submodules/agg-sharp/PlatformWin32/PlatformWin32.csproj`
- `Submodules/agg-sharp/Tests/TestInvoker/TestInvoker.csproj`
## Architecture Overview
### Platform Abstraction Layer
The project uses a provider pattern for platform-specific functionality:
1. **Window Providers** (in `Program.cs:167-172`):
- `MatterHackers.GlfwProvider.GlfwWindowProvider` - Cross-platform (GLFW)
- `MatterHackers.MatterControl.WinformsSingleWindowProvider` - Windows-only (WinForms)
2. **Platform Features** (`Program.cs:276`):
- `MatterHackers.MatterControl.WindowsPlatformsFeatures` - Windows implementation
### Key Projects
| Project | Target | Notes |
|---------|--------|-------|
| `MatterControl.csproj` | `net6.0-windows` | Main entry point, needs `net6.0` |
| `MatterControlLib.csproj` | `net6.0-windows` | Core library, needs `net6.0` |
| `MatterControl.Winforms.csproj` | `net6.0-windows` | WinForms provider, Windows-only |
| `GlfwProvider.csproj` | `net6.0` | Already cross-platform! |
| `PlatformWin32.csproj` | `net6.0-windows` | Windows-only |
### GLFW Provider (Cross-Platform)
Located at `Submodules/agg-sharp/Glfw/GlfwProvider.csproj` - already targets `net6.0` and provides cross-platform windowing via GLFW library.
## Windows-Specific Code in Program.cs
```csharp
// P/Invoke - Windows only
[DllImport("kernel32.dll")]
static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
[DllImport("Shcore.dll")]
static extern int SetProcessDpiAwareness(int PROCESS_DPI_AWARENESS);
```
These are used for:
- Preventing system sleep during prints (`KeepAwake`)
- High-DPI display support
## Windows-Specific Code in WindowsPlatformsFeatures.cs
- `System.Media.SoundPlayer` - Windows-only audio
- `WindowsFormsClipboard` - WinForms clipboard
- `WinformsEventSink.AllowInspector` - Debug inspector
- `InspectForm` - WinForms debug form
## Migration Strategy
### Phase 1: Project File Changes
1. Change target frameworks from `net6.0-windows` to `net6.0`:
- `MatterControl.csproj`
- `MatterControlLib.csproj`
2. Use conditional project references:
```xml
<ProjectReference Condition="'$(OS)' == 'Windows_NT'" Include="MatterControl.Winforms.csproj" />
```
3. Remove or conditionally exclude:
- `PrinterDriverInstaller` (Windows driver installer)
- `MatterControl.Winforms` reference on Linux
### Phase 2: Code Changes
1. **Program.cs** - Add platform detection:
```csharp
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
AggContext.Config.ProviderTypes.SystemWindowProvider =
"MatterHackers.GlfwProvider.GlfwWindowProvider, MatterHackers.GlfwProvider";
// Use Linux platform features
}
```
2. **Create LinuxPlatformFeatures.cs**:
- Implement `INativePlatformFeatures` for Linux
- Handle clipboard via X11/Wayland or cross-platform library
- Stub out Windows-specific features (sound, camera)
3. **Conditional P/Invoke**:
```csharp
static void KeepAwake(bool keepAwake)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return;
// Windows implementation
}
```
### Phase 3: Dependencies
1. **GLFW native library**: Need `libglfw.so` on Linux
```bash
# Debian/Ubuntu
sudo apt-get install libglfw3
# Or via Nix
pkgs.glfw
```
2. **OpenGL**: Need OpenGL drivers
```bash
sudo apt-get install libgl1-mesa-dev
```
3. **Serial ports**: Already have `System.IO.Ports` package (cross-platform)
### Phase 4: shell.nix Updates
```nix
{
pkgs ? import <nixpkgs> { },
}:
pkgs.mkShell {
packages = with pkgs; [
dotnet-sdk_8
glfw
libGL
xorg.libX11
xorg.libXcursor
xorg.libXrandr
xorg.libXinerama
xorg.libXi
];
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
pkgs.glfw
pkgs.libGL
];
}
```
## Files to Create
1. `MatterControl.Linux/LinuxPlatformFeatures.cs` - Linux platform implementation
2. `MatterControl.Linux/MatterControl.Linux.csproj` - Linux-specific project (optional)
## Files to Modify
1. `MatterControl.csproj` - Change TFM, conditional references
2. `MatterControlLib/MatterControlLib.csproj` - Change TFM
3. `Program.cs` - Platform detection, conditional code
4. `shell.nix` - Add native dependencies
## Alternative: Minimal Changes Approach
Instead of full platform abstraction, use `#if` directives:
```csharp
#if WINDOWS
// Windows-specific code
#else
// Linux/cross-platform code
#endif
```
And build with:
```bash
dotnet build -p:DefineConstants=LINUX
```
## Open Questions
1. Should the GLFW provider be the default for all platforms?
2. What Linux-specific features need implementation (file dialogs, etc.)?
3. Is the old `PlatformGtk` worth updating or should we focus on GLFW?
4. Should we create a separate solution file for Linux builds?