Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Presentation Screen in Secondary Display #388

Open
joabeliot opened this issue Jan 25, 2025 · 0 comments
Open

Presentation Screen in Secondary Display #388

joabeliot opened this issue Jan 25, 2025 · 0 comments

Comments

@joabeliot
Copy link

I am creating a desktop app that does presentations. The logic I am trying to implement is I want a child window that takes up the entire space of the secondary monitor exactly like PowerPoint does, this window renders a widget where I'll make change which has to be reflected in the Second Display.

I got to the point where I was able to create a second display with desktop_multi_window but I couldn't set it to take up all the screen. I don't want the title bar, close min action buttons, no taskbar, typical presentation screen

`
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:ui' as ui;

import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:flock_desktop/utils/widgets.dart';
import 'package:flock_desktop/widgets/AudioList.dart';
import 'package:flock_desktop/widgets/menu.dart';
import 'package:flock_desktop/widgets/player.dart';
import 'package:flutter_acrylic/flutter_acrylic.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:screen_retriever/screen_retriever.dart';
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:window_manager/window_manager.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';

late double minWidth;

class DisplayMonitor { // monitoring the changes in display connection and triggering New display and Display removed triggers
List previousDisplayIds = [];
Window? secondaryWindow; // Store the secondary window reference

// Call this method to start monitoring display changes
void startMonitoring() {
Timer.periodic(Duration(seconds: 2), (timer) async {
await detectDisplays();
});
}

// Detects displays and checks for new ones
Future detectDisplays() async {
try {
// Retrieve all displays
final displays = await screenRetriever.getAllDisplays();
List currentDisplayIds = [];

  // Iterate through each display and print its dimensions
  for (var display in displays) {
    final id = display.id;
    currentDisplayIds.add(id);
  }

  final newDisplays = currentDisplayIds
      .where((id) => !previousDisplayIds.contains(id))
      .toList();
  final removedDisplays = previousDisplayIds
      .where((id) => !currentDisplayIds.contains(id))
      .toList();

  // Handle new displays
  if (newDisplays.isNotEmpty) {
    for (var display in displays) {
      if (newDisplays.contains(display.id)) {
        final id = display.id;
        final displayName = display.name;
        final width = display.size.width;
        final height = display.size.height;
        final positionX = display.visiblePosition?.dx.toInt();
        final positionY = display.visiblePosition?.dy.toInt();

        Display primaryDisplay = await screenRetriever.getPrimaryDisplay();

        if (primaryDisplay.id != display.id) {
          print(
              'New Display ID: $id | Name: $displayName | Dimensions: ${width}x${height} | Position: $positionX, $positionY');
          if (isSecondMonitor(display)) {
            await createSecondaryWindow(display);
          }
        }
      }
    }
  }

  // Handle removed displays (screens that have been disconnected)
  if (removedDisplays.isNotEmpty) {
    for (var removedDisplayId in removedDisplays) {
      print('Display removed: $removedDisplayId');
      // Trigger the screen removed event (you can use a callback or custom event here)
      onScreenRemoved(removedDisplayId);
    }
  }

  previousDisplayIds = currentDisplayIds;
} catch (e) {
  print('Failed to retrieve displays: $e');
}

}

// Callback or event handler for screen removal
void onScreenRemoved(String removedDisplayId) {
// Handle the event for the removed display here
print('Handling removal for screen: $removedDisplayId');
// For example, you can destroy the secondary window associated with this display
if (secondaryWindow != null) {
// secondaryWindow?.close(); // Close the secondary window if one exists
secondaryWindow = null; // Reset the reference
}
// Additional logic, like freeing resources or updating UI, can go here
}

bool isSecondMonitor(Display display) {
return display.visiblePosition?.dx != 0;
}

Future createSecondaryWindow(Display display) async {
final width = display.size.width;
final height = display.size.height;
final positionX = display.visiblePosition?.dx.toDouble();
final positionY = display.visiblePosition?.dy.toDouble();
print("$width, $height, $positionX, $positionY");

final primaryDisplay = await screenRetriever.getPrimaryDisplay();

if (primaryDisplay.id != display.id) { 
   DesktopMultiWindow.createWindow(jsonEncode({'args1': 'Sub window'}))
    .then((value) {
  value
    ..setFrame(Offset(positionX!, positionY!) &
        ui.Size(width,
            height)) // Set the window size to secondary screen's size
    // ..setSkipTaskbar(true)  // Hide the window from the taskbar
    // ..setResizable(false) // Make the window non-resizable
    // ..setMinimizable(false) // Hide minimize button
    // ..setMaximizable(false) // Hide maximize button
    // ..setClosable(false) // Hide close button
    ..setTitle("") // Remove the title
    // ..setFullScreen(true) // Enable fullscreen mode
    ..show();
});
 }

}
}

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

await windowManager.ensureInitialized();
Display primaryDisplay = await screenRetriever.getPrimaryDisplay();
double displayWidth = primaryDisplay.size.width;
minWidth = displayWidth / 2;

final displayMonitor = DisplayMonitor();
displayMonitor.startMonitoring();

if (Platform.isWindows) {
WindowManager.instance.setMinimumSize(ui.Size((minWidth + 50), 640));
}
runApp(MyApp(
args
));
}

class MyApp extends StatelessWidget {
// final double minWidth;
final List args;
MyApp(
this.args,
{
super.key,
});

@OverRide
Widget build(BuildContext context) {
return args.firstOrNull == "multi_window"
? SecondaryWindow()
: const PrimaryWindow();
// return const PrimaryWindow();
}
}`

And when the second display is removed the second window should be closed... can you help me out this...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant