MixinNetwork / MixinNetwork/flutter-plugins

[desktop_multi_window] Failed to send message on startup

Open
#450 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
512
Forks
292
Avg merge
15h 8m
Merged PRs (30d)
7

Description

the app seemingly works correct, but I always have this message on startup

embedder.cc (2977): 'FlutterEngineSendPlatformMessage' returned 'kInvalidArguments'. Invalid engine handle.
2025-11-09 20:27:01.620 foilcap_app[78298:125658879] Failed to send message to Flutter engine on channel 'mixin.one/desktop_multi_window' (2).
2025-11-09 20:27:01.624 foilcap_app[78298:125658879] Running with merged UI and platform thread. Experimental.

My main.dart:

void main(List<String> args) async {
  WidgetsFlutterBinding.ensureInitialized();

  // Get the current window controller (for multi-window initialization)
  final windowController = await WindowController.fromCurrentEngine();

  print('window id: ${windowController.windowId}');
  print('window args: ${windowController.arguments}');

  // Parse arguments to determine window position and UUID
  Offset? windowPosition;
  String? windowUuid;
  
  if (windowController.arguments.isNotEmpty) {
    // This is an additional window - parse arguments
    try {
      final parts = windowController.arguments.split(',');
      if (parts.length >= 2) {
        final x = double.parse(parts[0]);
        final y = double.parse(parts[1]);
        windowPosition = Offset(x, y);
        
        // If there's a third parameter - it's the UUID
        if (parts.length >= 3) {
          windowUuid = parts[2];
        }
      }
    } catch (e) {
      print('Error parsing window arguments: $e');
    }
  } else {
    // This is the main window - check for temporary files
    final tempFiles = await SaveLoadStore.getAllTempFiles();
    if (tempFiles.isNotEmpty) {
      // Use UUID from the first temporary file for the main window
      final firstFile = tempFiles[0];
      final fileName = firstFile.path.split('/').last;
      windowUuid = fileName.replaceAll('.tmp.cap', '');
      print('Main window using UUID from first temp file: $windowUuid');
      
      // Create additional windows for remaining temporary files
      await _restoreWindowsFromTempFiles();
    }
  }

  // Initialize window manager
  await windowManager.ensureInitialized();

  WindowOptions windowOptions = WindowOptions(
    size: const Size(800, 600),
    minimumSize: const Size(640, 480),
    center: windowPosition == null, // Center only if position is not specified
    backgroundColor: Colors.transparent,
    skipTaskbar: false,
    titleBarStyle: TitleBarStyle.normal,
    title: 'FoilCap',
  );

  windowManager.waitUntilReadyToShow(windowOptions, () async {
    // If position is specified, set it
    if (windowPosition != null) {
      await windowManager.setPosition(windowPosition);
    }
    // Enable close interception to show save dialog
    await windowManager.setPreventClose(true);
    await windowManager.show();
    await windowManager.focus();
  });

  runApp(
    .....
    ),
  );
}

/// Restores windows from autosave temporary files
Future<void> _restoreWindowsFromTempFiles() async {
  try {
    final tempFiles = await SaveLoadStore.getAllTempFiles();
    print('Found temporary files: ${tempFiles.length}');

    if (tempFiles.isEmpty) {
      return;
    }

    // Create additional windows for each temporary file (except the first one)
    // The first file will be loaded in the main window automatically
    for (int i = 1; i < tempFiles.length; i++) {
      final file = tempFiles[i];
      // Extract UUID from filename (format: {uuid}.tmp.cap)
      final fileName = file.path.split('/').last;
      final uuid = fileName.replaceAll('.tmp.cap', '');
      
      final offset = 30.0 * i;
      await WindowController.create(
        WindowConfiguration(
          hiddenAtLaunch: false,
          arguments: '$offset,$offset,$uuid', // Pass position and UUID
        ),
      );
    }
  } catch (e) {
    print('Error restoring windows: $e');
  }
}

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the desktop_multi_window startup path and reproduce the reported logs using the supplied main.dart flow, especially WindowController.fromCurrentEngine() and window creation. Trace why the Flutter engine handle is invalid when the platform message is sent. Done means startup no longer reports the invalid engine handle or failed channel message while multi-window initialization still works.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, flutter
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.