-
Notifications
You must be signed in to change notification settings - Fork 257
Closed
Description
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<String> 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<void> detectDisplays() async {
try {
// Retrieve all displays
final displays = await screenRetriever.getAllDisplays();
List<String> 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<void> 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<String> 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<String> 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...
Metadata
Metadata
Assignees
Labels
No labels