mattercontrol/research/linux-migration.md
2026-01-28 14:06:53 -08:00

5.1 KiB

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

// 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:

    <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:

    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:

    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

    # Debian/Ubuntu
    sudo apt-get install libglfw3
    
    # Or via Nix
    pkgs.glfw
    
  2. OpenGL: Need OpenGL drivers

    sudo apt-get install libgl1-mesa-dev
    
  3. Serial ports: Already have System.IO.Ports package (cross-platform)

Phase 4: shell.nix Updates

{
  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:

#if WINDOWS
    // Windows-specific code
#else
    // Linux/cross-platform code
#endif

And build with:

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?